using System.CommandLine; using System.Threading.Tasks; using Toak.Commands; namespace Toak; public class Program { public static async Task Main(string[] args) { var rootCommand = new RootCommand("Toak: High-speed Linux Dictation"); var pipeOption = new Option(["--pipe", "-p"], "Output transcription to stdout instead of typing"); var copyOption = new Option("--copy", "Copy to clipboard instead of typing"); var verboseOption = new Option(["--verbose", "-v"], "Enable detailed debug logging"); rootCommand.AddGlobalOption(verboseOption); // Toggle Command var toggleCmd = new Command("toggle", "Starts or stops the recording"); toggleCmd.AddOption(pipeOption); toggleCmd.AddOption(copyOption); toggleCmd.SetHandler(ToggleCommand.ExecuteAsync, pipeOption, copyOption, verboseOption); rootCommand.AddCommand(toggleCmd); // Start Command var startCmd = new Command("start", "Explicitly starts the recording"); startCmd.SetHandler(StartCommand.ExecuteAsync, verboseOption); rootCommand.AddCommand(startCmd); // Stop Command var stopCmd = new Command("stop", "Explicitly stops the recording"); stopCmd.AddOption(pipeOption); stopCmd.AddOption(copyOption); stopCmd.SetHandler(StopCommand.ExecuteAsync, pipeOption, copyOption, verboseOption); rootCommand.AddCommand(stopCmd); // Status Command var statusCmd = new Command("status", "Outputs the current daemon status"); var jsonOption = new Option("--json", "Output status as JSON"); statusCmd.AddOption(jsonOption); statusCmd.SetHandler(StatusCommand.ExecuteAsync, jsonOption, verboseOption); rootCommand.AddCommand(statusCmd); // Daemon Command var daemonCmd = new Command("daemon", "Starts the background service"); daemonCmd.SetHandler(Toak.Core.DaemonService.StartAsync, verboseOption); rootCommand.AddCommand(daemonCmd); // Discard Command var discardCmd = new Command("discard", "Abort current recording without transcribing"); discardCmd.AddOption(pipeOption); discardCmd.SetHandler(DiscardCommand.ExecuteAsync, pipeOption, verboseOption); rootCommand.AddCommand(discardCmd); // Onboard Command var onboardCmd = new Command("onboard", "Configure the application"); onboardCmd.SetHandler(OnboardCommand.ExecuteAsync, verboseOption); rootCommand.AddCommand(onboardCmd); // Latency Test Command var latencyCmd = new Command("latency-test", "Benchmark full pipeline without recording"); latencyCmd.SetHandler(LatencyTestCommand.ExecuteAsync, verboseOption); rootCommand.AddCommand(latencyCmd); // Show Command var showCmd = new Command("show", "Show current configuration"); showCmd.SetHandler(ShowCommand.ExecuteAsync, verboseOption); rootCommand.AddCommand(showCmd); // Config Command var configCmd = new Command("config", "Update a specific configuration setting"); var keyArg = new Argument("key", "Configuration key (e.g., llm, whisper, lang)"); var valArg = new Argument("value", "Configuration value"); configCmd.AddArgument(keyArg); configCmd.AddArgument(valArg); configCmd.SetHandler(ConfigUpdaterCommand.ExecuteAsync, keyArg, valArg, verboseOption); rootCommand.AddCommand(configCmd); // Stats Command var statsCmd = new Command("stats", "Display usage statistics and analytics"); statsCmd.SetHandler(StatsCommand.ExecuteAsync, verboseOption); rootCommand.AddCommand(statsCmd); // History Command var historyCmd = new Command("history", "Display recent transcriptions with timestamps"); var numArg = new Option(["-n", "--num"], () => 10, "Number of recent entries to show"); var grepArg = new Option("--grep", "Search through transcription history"); var exportArg = new Option("--export", "Export transcription history to a Markdown file"); var shredArg = new Option("--shred", "Securely delete transcription history"); historyCmd.AddOption(numArg); historyCmd.AddOption(grepArg); historyCmd.AddOption(exportArg); historyCmd.AddOption(shredArg); historyCmd.SetHandler(HistoryCommand.ExecuteAsync, numArg, grepArg, exportArg, shredArg, verboseOption); rootCommand.AddCommand(historyCmd); // Skill Command rootCommand.AddCommand(SkillCommand.CreateCommand(verboseOption)); return await rootCommand.InvokeAsync(args); } }