From 0088bf27368265511d6ff3c49309df843c528d42 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Tue, 26 May 2026 10:15:58 +0300 Subject: feat(askcli): add watch subcommand Implements `ask watch [subcommand...]` which re-runs a read-only subcommand every 2 seconds and redraws output when it changes, similar to gnu-watch. Safety features: - Restricted to read-only subcommands (list, all, ready, info, urgency, help, dep list) - Recursive watch is blocked - Captures stderr so error messages are visible in the watched display Also adds readOnly field to commandEntry registry for maintainability. --- internal/askcli/commands_registry.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'internal/askcli/commands_registry.go') diff --git a/internal/askcli/commands_registry.go b/internal/askcli/commands_registry.go index 1c2e60d..f999ca3 100644 --- a/internal/askcli/commands_registry.go +++ b/internal/askcli/commands_registry.go @@ -21,6 +21,7 @@ type commandEntry struct { handler commandHandler includeInCompletion bool singleSelector bool + readOnly bool } type commandTable struct { @@ -82,18 +83,21 @@ var commandRegistry = newCommandTable([]commandEntry{ description: "List active tasks", handler: wrapSimpleCommand((*Dispatcher).handleList), includeInCompletion: true, + readOnly: true, }, { name: "all", description: "List all tasks", handler: wrapSimpleCommand((*Dispatcher).handleAll), includeInCompletion: true, + readOnly: true, }, { name: "ready", description: "List READY tasks", handler: wrapSimpleCommand((*Dispatcher).handleReady), includeInCompletion: true, + readOnly: true, }, { name: "info", @@ -101,6 +105,7 @@ var commandRegistry = newCommandTable([]commandEntry{ handler: wrapSimpleCommand((*Dispatcher).handleInfo), includeInCompletion: true, singleSelector: true, + readOnly: true, }, { name: "annotate", @@ -176,10 +181,17 @@ var commandRegistry = newCommandTable([]commandEntry{ description: "List tasks sorted by urgency", handler: wrapSimpleCommand((*Dispatcher).handleUrgency), includeInCompletion: true, + readOnly: true, }, }) func init() { + commandRegistry.add(commandEntry{ + name: "watch", + description: "Repeatedly run a subcommand and redraw when output changes", + handler: wrapSimpleCommand((*Dispatcher).handleWatch), + includeInCompletion: true, + }) commandRegistry.add(commandEntry{ name: "fish", description: "Emit Fish shell completion script", @@ -189,6 +201,7 @@ func init() { commandRegistry.add(commandEntry{ name: "help", description: "Show help", + readOnly: true, handler: func(d *Dispatcher, ctx context.Context, args []string, stdin io.Reader, stdout, stderr io.Writer) (int, error) { _ = ctx _ = args -- cgit v1.2.3