Initial upload: shell-history-semantic-search v0.1.0
Some checks failed
CI / test (push) Has been cancelled
Some checks failed
CI / test (push) Has been cancelled
This commit is contained in:
109
src/shell_history_search/cli/commands.py
Normal file
109
src/shell_history_search/cli/commands.py
Normal file
@@ -0,0 +1,109 @@
|
||||
import click
|
||||
import json
|
||||
import logging
|
||||
from datetime import datetime
|
||||
|
||||
from ..core import SearchEngine, IndexingService
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@click.group()
|
||||
@click.option("-v", "--verbose", count=True, help="Increase verbosity")
|
||||
def cli(verbose: int) -> None:
|
||||
log_level = logging.WARNING
|
||||
if verbose == 1:
|
||||
log_level = logging.INFO
|
||||
elif verbose >= 2:
|
||||
log_level = logging.DEBUG
|
||||
logging.basicConfig(level=log_level, format="%(levelname)s: %(message)s")
|
||||
|
||||
|
||||
@cli.command()
|
||||
@click.option("--shell", type=str, help="Index only specific shell (bash, zsh, fish)")
|
||||
def index(shell: str | None) -> None:
|
||||
click.echo("Indexing shell history...")
|
||||
|
||||
indexing_service = IndexingService()
|
||||
|
||||
shell_type = shell.lower() if shell else None
|
||||
result = indexing_service.index_shell_history(shell_type)
|
||||
|
||||
click.echo(
|
||||
f"Indexed {result['total_indexed']} commands "
|
||||
f"(skipped {result['total_skipped']} duplicates)"
|
||||
)
|
||||
|
||||
|
||||
@cli.command()
|
||||
@click.argument("query")
|
||||
@click.option("--limit", "-n", type=int, default=10, help="Number of results to return")
|
||||
@click.option("--shell", type=str, help="Filter by shell type (bash, zsh, fish)")
|
||||
@click.option("--json", "json_output", is_flag=True, help="Output as JSON")
|
||||
def search(query: str, limit: int, shell: str | None, json_output: bool) -> None:
|
||||
search_engine = SearchEngine()
|
||||
|
||||
shell_type = shell.lower() if shell else None
|
||||
|
||||
results = search_engine.search(query, limit=limit, shell_type=shell_type)
|
||||
|
||||
if not results:
|
||||
click.echo("No results found.")
|
||||
return
|
||||
|
||||
if json_output:
|
||||
output = [
|
||||
{
|
||||
"command": r.command,
|
||||
"shell": r.shell_type,
|
||||
"timestamp": r.timestamp,
|
||||
"similarity": round(r.similarity, 4),
|
||||
}
|
||||
for r in results
|
||||
]
|
||||
click.echo(json.dumps(output, indent=2))
|
||||
else:
|
||||
for i, result in enumerate(results, 1):
|
||||
timestamp_str = ""
|
||||
if result.timestamp:
|
||||
dt = datetime.fromtimestamp(result.timestamp)
|
||||
timestamp_str = dt.strftime("%Y-%m-%d %H:%M")
|
||||
|
||||
similarity_pct = result.similarity * 100
|
||||
click.echo(f"{i}. [{result.shell_type}] {timestamp_str}")
|
||||
click.echo(f" {result.command}")
|
||||
click.echo(f" Similarity: {similarity_pct:.1f}%")
|
||||
click.echo()
|
||||
|
||||
|
||||
@cli.command()
|
||||
@click.option("--json", "json_output", is_flag=True, help="Output as JSON")
|
||||
def stats(json_output: bool) -> None:
|
||||
search_engine = SearchEngine()
|
||||
stats_data = search_engine.get_stats()
|
||||
|
||||
if json_output:
|
||||
click.echo(json.dumps(stats_data, indent=2))
|
||||
else:
|
||||
click.echo("Shell History Search Statistics")
|
||||
click.echo("=" * 40)
|
||||
click.echo(f"Total commands: {stats_data['total_commands']}")
|
||||
click.echo(f"Total embeddings: {stats_data['total_embeddings']}")
|
||||
click.echo(f"Embedding model: {stats_data['embedding_model']}")
|
||||
click.echo(f"Embedding dimension: {stats_data['embedding_dim']}")
|
||||
click.echo()
|
||||
click.echo("Commands by shell:")
|
||||
for shell_type, count in stats_data["shell_counts"].items():
|
||||
click.echo(f" {shell_type}: {count}")
|
||||
|
||||
|
||||
@cli.command()
|
||||
@click.confirmation_option(prompt="Are you sure you want to clear all indexed data?")
|
||||
def clear() -> None:
|
||||
search_engine = SearchEngine()
|
||||
search_engine.clear_all()
|
||||
click.echo("All indexed data has been cleared.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
cli()
|
||||
Reference in New Issue
Block a user