feat: search command in REPL with topic-aware context

This commit is contained in:
kryptomrx 2026-05-17 00:38:19 +02:00
parent 58410f8d9f
commit 8576cc83a2
2 changed files with 62 additions and 0 deletions

View file

@ -0,0 +1,61 @@
using NozCli.Repl;
using Spectre.Console;
namespace NozCli.Commands;
public class SearchCommand : ICommand
{
public string Name => "search";
public string Description => "Full-text search via Meilisearch";
public string Usage => "search <query> [--topic <topic>] [--limit <n>]";
private static readonly Dictionary<string, string> StatusDot = new()
{
["seed"] = "[yellow]◦[/]",
["budding"] = "[magenta]◈[/]",
["evergreen"] = "[cyan]◉[/]",
};
public async Task ExecuteAsync(string[] args, ReplContext ctx, CancellationToken ct = default)
{
var topic = ParseFlag(args, "--topic") ?? ctx.CurrentTopic;
var limitRaw = ParseFlag(args, "--limit");
var limit = limitRaw is not null && int.TryParse(limitRaw, out var l) ? l : 10;
var query = string.Join(' ', args.Where(a => !a.StartsWith('-') &&
a != ParseFlag(args, "--topic") &&
a != ParseFlag(args, "--limit")));
if (string.IsNullOrWhiteSpace(query))
{
AnsiConsole.MarkupLine("[red]Usage:[/] search <query> [--topic <topic>] [--limit <n>]");
return;
}
List<NozCli.Core.Models.SearchHit> hits = [];
await AnsiConsole.Status().StartAsync($"Suche nach »{query}«…", async _ =>
hits = await ctx.Api.SearchAsync(query, topic, limit, ct));
if (hits.Count == 0)
{
AnsiConsole.MarkupLine($"[dim]Keine Treffer für »{Markup.Escape(query)}«.[/]");
return;
}
AnsiConsole.MarkupLine($"[dim]{hits.Count} Treffer[/]\n");
foreach (var h in hits)
{
var dot = StatusDot.GetValueOrDefault(h.Status, "·");
var desc = h.Description is { Length: > 0 } d ? $"\n [dim]{Markup.Escape(d)}[/]" : "";
AnsiConsole.MarkupLine($" {dot} [cyan]{Markup.Escape(h.Slug)}[/] [white]{Markup.Escape(h.Title)}[/]{desc}");
}
AnsiConsole.WriteLine();
}
private static string? ParseFlag(string[] args, string flag)
{
var idx = Array.IndexOf(args, flag);
return idx >= 0 && idx + 1 < args.Length ? args[idx + 1] : null;
}
}

View file

@ -25,6 +25,7 @@ public class CommandRegistry
new TreeCommand(), new TreeCommand(),
new MkdirCommand(), new MkdirCommand(),
new MvCommand(), new MvCommand(),
new SearchCommand(),
new LinkCommand(), new LinkCommand(),
new TemplatesCommand(), new TemplatesCommand(),
new VersionCommand(), new VersionCommand(),