summaryrefslogtreecommitdiff
path: root/internal/askcli
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-04-11 22:20:57 +0300
committerPaul Buetow <paul@buetow.org>2026-04-11 22:20:57 +0300
commit69d3ec004b8de3b9f7cfeb34686b9c344c787db4 (patch)
tree857101184293efa61f9d1caba4c3b80b31e89a37 /internal/askcli
parent5bc434d71fb5057131f1e5c0b2371db42d3b4ed4 (diff)
Rename task CLI binary from do back to ask
- Move cmd/do to cmd/ask; mage builds and installs ask; Fish completions to ask.fish - Update askcli help text, errors, executor default label, and Fish script (__ask_*) - Task alias cache subdirectory under XDG cache: hexai/ask/ - Rename integration test files and helpers; refresh README and docs - Rename plan-do-uuid-wrapper.md to plan-ask-uuid-wrapper.md Made-with: Cursor
Diffstat (limited to 'internal/askcli')
-rw-r--r--internal/askcli/command_add.go8
-rw-r--r--internal/askcli/command_delete.go2
-rw-r--r--internal/askcli/command_dep.go8
-rw-r--r--internal/askcli/command_fish.go4
-rw-r--r--internal/askcli/command_info_add_test.go2
-rw-r--r--internal/askcli/command_write.go16
-rw-r--r--internal/askcli/completion.go132
-rw-r--r--internal/askcli/completion_test.go44
-rw-r--r--internal/askcli/dispatch.go52
-rw-r--r--internal/askcli/dispatch_test.go18
-rw-r--r--internal/askcli/formatter.go2
-rw-r--r--internal/askcli/task_alias_cache.go2
-rw-r--r--internal/askcli/taskexec.go6
-rw-r--r--internal/askcli/taskexec_test.go26
14 files changed, 173 insertions, 149 deletions
diff --git a/internal/askcli/command_add.go b/internal/askcli/command_add.go
index d2fb2ea..b94fe89 100644
--- a/internal/askcli/command_add.go
+++ b/internal/askcli/command_add.go
@@ -10,7 +10,7 @@ import (
func (d *Dispatcher) handleAdd(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) {
if len(args) < 2 {
- _, _ = io.WriteString(stderr, "error: do add requires a description\n")
+ _, _ = io.WriteString(stderr, "error: ask add requires a description\n")
return 1, nil
}
modifiers, description, dependencySelectors, err := parseAddArgs(args[1:])
@@ -19,7 +19,7 @@ func (d *Dispatcher) handleAdd(ctx context.Context, args []string, stdout, stder
return 1, nil
}
if strings.TrimSpace(description) == "" {
- _, _ = io.WriteString(stderr, "error: do add requires a description\n")
+ _, _ = io.WriteString(stderr, "error: ask add requires a description\n")
return 1, nil
}
dependencyUUIDs, code, err := d.resolveAddDependencyUUIDs(ctx, dependencySelectors, stderr)
@@ -112,14 +112,14 @@ func parseAddArgs(args []string) (modifiers []string, description string, depend
func parseAddDependencySelectors(arg string) ([]string, error) {
raw := strings.TrimSpace(strings.TrimPrefix(arg, "depends:"))
if raw == "" {
- return nil, fmt.Errorf("do add depends:<id|uuid>[,<id|uuid>...] requires at least one dependency ID or UUID")
+ return nil, fmt.Errorf("ask add depends:<id|uuid>[,<id|uuid>...] requires at least one dependency ID or UUID")
}
parts := strings.Split(raw, ",")
selectors := make([]string, 0, len(parts))
for _, part := range parts {
selector := strings.TrimSpace(part)
if selector == "" {
- return nil, fmt.Errorf("do add dependency selector list contains an empty item")
+ return nil, fmt.Errorf("ask add dependency selector list contains an empty item")
}
selectors = append(selectors, selector)
}
diff --git a/internal/askcli/command_delete.go b/internal/askcli/command_delete.go
index 7356753..801d4cf 100644
--- a/internal/askcli/command_delete.go
+++ b/internal/askcli/command_delete.go
@@ -8,7 +8,7 @@ import (
func (d *Dispatcher) handleDelete(ctx context.Context, args []string, stdin io.Reader, stdout, stderr io.Writer) (int, error) {
if len(args) < 2 {
- _, _ = io.WriteString(stderr, "error: do delete requires an ID or UUID argument\n")
+ _, _ = io.WriteString(stderr, "error: ask delete requires an ID or UUID argument\n")
return 1, nil
}
resolved, _, code, err := d.resolveTaskSelector(ctx, args[1], stderr)
diff --git a/internal/askcli/command_dep.go b/internal/askcli/command_dep.go
index b6fb2b9..aa28df8 100644
--- a/internal/askcli/command_dep.go
+++ b/internal/askcli/command_dep.go
@@ -10,7 +10,7 @@ import (
func (d *Dispatcher) handleDep(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) {
if len(args) < 2 {
- _, _ = io.WriteString(stderr, "error: do dep requires an operation (add/rm/list) and arguments\n")
+ _, _ = io.WriteString(stderr, "error: ask dep requires an operation (add/rm/list) and arguments\n")
return 1, nil
}
op := args[1]
@@ -20,14 +20,14 @@ func (d *Dispatcher) handleDep(ctx context.Context, args []string, stdout, stder
case "list":
return d.handleDepList(ctx, args, stdout, stderr)
default:
- fmt.Fprintf(stderr, "error: do dep: unknown operation %q (use add, rm, or list)\n", op)
+ fmt.Fprintf(stderr, "error: ask dep: unknown operation %q (use add, rm, or list)\n", op)
return 1, nil
}
}
func (d *Dispatcher) handleDepAddRm(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) {
if len(args) < 4 {
- _, _ = io.WriteString(stderr, "error: do dep add/rm requires <id|uuid> <dep-id|dep-uuid>\n")
+ _, _ = io.WriteString(stderr, "error: ask dep add/rm requires <id|uuid> <dep-id|dep-uuid>\n")
return 1, nil
}
resolved, _, code, err := d.resolveTaskSelector(ctx, args[2], stderr)
@@ -59,7 +59,7 @@ func (d *Dispatcher) handleDepAddRm(ctx context.Context, args []string, stdout,
func (d *Dispatcher) handleDepList(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) {
if len(args) < 3 {
- _, _ = io.WriteString(stderr, "error: do dep list requires <id|uuid>\n")
+ _, _ = io.WriteString(stderr, "error: ask dep list requires <id|uuid>\n")
return 1, nil
}
_, tasks, code, err := d.resolveTaskSelector(ctx, args[2], stderr)
diff --git a/internal/askcli/command_fish.go b/internal/askcli/command_fish.go
index 401a9e2..f4ca9e0 100644
--- a/internal/askcli/command_fish.go
+++ b/internal/askcli/command_fish.go
@@ -10,12 +10,12 @@ import (
func (d *Dispatcher) handleFish(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) {
_ = ctx
if len(args) != 1 {
- fmt.Fprintln(stderr, "usage: do fish")
+ fmt.Fprintln(stderr, "usage: ask fish")
return 1, nil
}
binaryPath, err := os.Executable()
if err != nil {
- binaryPath = "do"
+ binaryPath = "ask"
}
if _, err := io.WriteString(stdout, FishCompletionFor(binaryPath)); err != nil {
return 1, err
diff --git a/internal/askcli/command_info_add_test.go b/internal/askcli/command_info_add_test.go
index 8ca14a2..0e5b366 100644
--- a/internal/askcli/command_info_add_test.go
+++ b/internal/askcli/command_info_add_test.go
@@ -383,7 +383,7 @@ func TestHandleAdd_DependsModifierWithoutSelectors(t *testing.T) {
if code != 1 {
t.Fatalf("add code = %d, want 1", code)
}
- if got := stderr.String(); !strings.Contains(got, "do add depends:<id|uuid>[,<id|uuid>...] requires at least one dependency ID or UUID") {
+ if got := stderr.String(); !strings.Contains(got, "ask add depends:<id|uuid>[,<id|uuid>...] requires at least one dependency ID or UUID") {
t.Fatalf("stderr = %q, want depends: selector error", got)
}
}
diff --git a/internal/askcli/command_write.go b/internal/askcli/command_write.go
index 31a3f39..d8dbf5b 100644
--- a/internal/askcli/command_write.go
+++ b/internal/askcli/command_write.go
@@ -31,7 +31,7 @@ func (d *Dispatcher) runSingleTaskCommand(
func (d *Dispatcher) handleDenotate(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) {
if len(args) < 3 {
- _, _ = io.WriteString(stderr, "error: do denotate requires an ID or UUID and text argument\n")
+ _, _ = io.WriteString(stderr, "error: ask denotate requires an ID or UUID and text argument\n")
return 1, nil
}
text := args[2]
@@ -42,7 +42,7 @@ func (d *Dispatcher) handleDenotate(ctx context.Context, args []string, stdout,
func (d *Dispatcher) handleModify(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) {
if len(args) < 3 {
- _, _ = io.WriteString(stderr, "error: do modify requires an ID or UUID and modification args\n")
+ _, _ = io.WriteString(stderr, "error: ask modify requires an ID or UUID and modification args\n")
return 1, nil
}
modArgs := args[2:]
@@ -53,7 +53,7 @@ func (d *Dispatcher) handleModify(ctx context.Context, args []string, stdout, st
func (d *Dispatcher) handleAnnotate(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) {
if len(args) < 3 {
- _, _ = io.WriteString(stderr, "error: do annotate requires an ID or UUID and note argument\n")
+ _, _ = io.WriteString(stderr, "error: ask annotate requires an ID or UUID and note argument\n")
return 1, nil
}
note := strings.Join(args[2:], " ")
@@ -64,7 +64,7 @@ func (d *Dispatcher) handleAnnotate(ctx context.Context, args []string, stdout,
func (d *Dispatcher) handleStart(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) {
if len(args) < 2 {
- _, _ = io.WriteString(stderr, "error: do start requires an ID or UUID argument\n")
+ _, _ = io.WriteString(stderr, "error: ask start requires an ID or UUID argument\n")
return 1, nil
}
return d.runSingleTaskCommand(ctx, args[1], stdout, stderr, func(resolved resolvedTaskSelector) []string {
@@ -76,7 +76,7 @@ func (d *Dispatcher) handleStart(ctx context.Context, args []string, stdout, std
func (d *Dispatcher) handleStop(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) {
if len(args) < 2 {
- _, _ = io.WriteString(stderr, "error: do stop requires an ID or UUID argument\n")
+ _, _ = io.WriteString(stderr, "error: ask stop requires an ID or UUID argument\n")
return 1, nil
}
return d.runSingleTaskCommand(ctx, args[1], stdout, stderr, func(resolved resolvedTaskSelector) []string {
@@ -86,7 +86,7 @@ func (d *Dispatcher) handleStop(ctx context.Context, args []string, stdout, stde
func (d *Dispatcher) handleDone(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) {
if len(args) < 2 {
- _, _ = io.WriteString(stderr, "error: do done requires an ID or UUID argument\n")
+ _, _ = io.WriteString(stderr, "error: ask done requires an ID or UUID argument\n")
return 1, nil
}
return d.runSingleTaskCommand(ctx, args[1], stdout, stderr, func(resolved resolvedTaskSelector) []string {
@@ -96,7 +96,7 @@ func (d *Dispatcher) handleDone(ctx context.Context, args []string, stdout, stde
func (d *Dispatcher) handlePriority(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) {
if len(args) < 3 {
- _, _ = io.WriteString(stderr, "error: do priority requires an ID or UUID and priority (H/M/L)\n")
+ _, _ = io.WriteString(stderr, "error: ask priority requires an ID or UUID and priority (H/M/L)\n")
return 1, nil
}
priority := args[2]
@@ -107,7 +107,7 @@ func (d *Dispatcher) handlePriority(ctx context.Context, args []string, stdout,
func (d *Dispatcher) handleTag(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) {
if len(args) < 3 {
- _, _ = io.WriteString(stderr, "error: do tag requires an ID or UUID and +/-tag\n")
+ _, _ = io.WriteString(stderr, "error: ask tag requires an ID or UUID and +/-tag\n")
return 1, nil
}
tag := args[2]
diff --git a/internal/askcli/completion.go b/internal/askcli/completion.go
index 4d4b5d3..79dd923 100644
--- a/internal/askcli/completion.go
+++ b/internal/askcli/completion.go
@@ -1,6 +1,7 @@
package askcli
import (
+ "path/filepath"
"strings"
)
@@ -54,43 +55,60 @@ func fishAddDependencyModifierCompletionContext(positional []string, current str
return current == "depends" || strings.HasPrefix(current, "depends:")
}
-// FishCompletion returns the default Fish completion script for the do CLI.
+// FishCompletion returns the default Fish completion script for the ask CLI.
func FishCompletion() string {
- return FishCompletionFor("do")
+ return FishCompletionFor("ask")
+}
+
+// fishShellCommandName returns the argv0 basename used for `complete -c` wiring.
+func fishShellCommandName(binaryPath string) string {
+ first := strings.TrimSpace(binaryPath)
+ if i := strings.IndexByte(first, ' '); i >= 0 {
+ first = first[:i]
+ }
+ return filepath.Base(first)
}
// FishCompletionFor returns a Fish completion script that points to the provided binary path.
func FishCompletionFor(binaryPath string) string {
+ cmd := fishShellCommandName(binaryPath)
var b strings.Builder
- writeFishPreamble(&b)
+ writeFishPreamble(&b, cmd)
writeFishContextFunctions(&b)
writeFishTaskSelectorFunction(&b, binaryPath)
writeFishAddDependencyModifierFunction(&b)
- b.WriteString("complete -c do -f\n")
- b.WriteString("complete -c do -s j -l json -d 'Emit JSON output'\n")
+ b.WriteString("complete -c ")
+ b.WriteString(cmd)
+ b.WriteString(" -f\n")
+ b.WriteString("complete -c ")
+ b.WriteString(cmd)
+ b.WriteString(" -s j -l json -d 'Emit JSON output'\n")
for _, item := range []fishCompletionItem{
{name: "na", description: "Run against project tasks without +agent"},
{name: "no-agent", description: "Run against project tasks without +agent"},
{name: "proj:", description: "Run against an explicit project"},
} {
- writeFishCompletionLine(&b, "__do_needs_root_completion", item)
+ writeFishCompletionLine(&b, cmd, "__ask_needs_root_completion", item)
}
for _, entry := range commandRegistry.rootCompletionEntries() {
item := fishCompletionItem{name: entry.name, description: entry.description}
- writeFishCompletionLine(&b, "__do_needs_command_completion", item)
+ writeFishCompletionLine(&b, cmd, "__ask_needs_command_completion", item)
}
for _, item := range askDepCompletionItems {
- writeFishCompletionLine(&b, "__do_in_dep_context", item)
+ writeFishCompletionLine(&b, cmd, "__ask_in_dep_context", item)
}
- writeFishUUIDCompletionLine(&b, "__do_in_uuid_context", "Task selector")
- writeFishUUIDCompletionLine(&b, "__do_in_dep_uuid_context", "Task selector")
- writeFishFunctionCompletionLine(&b, "__do_in_add_dep_modifier_context", "__do_add_dependency_modifiers", "Task dependency")
+ writeFishUUIDCompletionLine(&b, cmd, "__ask_in_uuid_context", "Task selector")
+ writeFishUUIDCompletionLine(&b, cmd, "__ask_in_dep_uuid_context", "Task selector")
+ writeFishFunctionCompletionLine(&b, cmd, "__ask_in_add_dep_modifier_context", "__ask_add_dependency_modifiers", "Task dependency")
return b.String()
}
-func writeFishPreamble(b *strings.Builder) {
- b.WriteString("# Fish completion for do.\n")
- b.WriteString("# Source with: do fish | source\n\n")
+func writeFishPreamble(b *strings.Builder, cmd string) {
+ b.WriteString("# Fish completion for ")
+ b.WriteString(cmd)
+ b.WriteString(".\n# Source with: ")
+ b.WriteString(cmd)
+ b.WriteString(" fish | source\n\n")
}
func writeFishContextFunctions(b *strings.Builder) {
@@ -106,7 +124,7 @@ func writeFishContextFunctions(b *strings.Builder) {
}
func writeFishPositionalTokensFunction(b *strings.Builder) {
- b.WriteString("function __do_positional_tokens\n")
+ b.WriteString("function __ask_positional_tokens\n")
b.WriteString(" set -l tokens (commandline -opc)\n")
b.WriteString(" set -l positional\n")
b.WriteString(" for token in $tokens[2..-1]\n")
@@ -122,11 +140,11 @@ func writeFishPositionalTokensFunction(b *strings.Builder) {
}
func writeFishCommandPositionalsFunction(b *strings.Builder) {
- b.WriteString("function __do_command_positionals\n")
- b.WriteString(" set -l positional (__do_positional_tokens)\n")
+ b.WriteString("function __ask_command_positionals\n")
+ b.WriteString(" set -l positional (__ask_positional_tokens)\n")
b.WriteString(" while test (count $positional) -gt 0\n")
b.WriteString(" switch $positional[1]\n")
- b.WriteString(" case na no-agent proj:*\n")
+ b.WriteString(" case na no-agent 'proj:*'\n")
b.WriteString(" set positional $positional[2..-1]\n")
b.WriteString(" case '*'\n")
b.WriteString(" break\n")
@@ -139,11 +157,11 @@ func writeFishCommandPositionalsFunction(b *strings.Builder) {
}
func writeFishScopePrefixFunction(b *strings.Builder) {
- b.WriteString("function __do_scope_prefix\n")
- b.WriteString(" set -l positional (__do_positional_tokens)\n")
+ b.WriteString("function __ask_scope_prefix\n")
+ b.WriteString(" set -l positional (__ask_positional_tokens)\n")
b.WriteString(" while test (count $positional) -gt 0\n")
b.WriteString(" switch $positional[1]\n")
- b.WriteString(" case na no-agent proj:*\n")
+ b.WriteString(" case na no-agent 'proj:*'\n")
b.WriteString(" printf '%s\\n' $positional[1]\n")
b.WriteString(" set positional $positional[2..-1]\n")
b.WriteString(" case '*'\n")
@@ -155,8 +173,8 @@ func writeFishScopePrefixFunction(b *strings.Builder) {
}
func writeFishNeedsRootCompletionFunction(b *strings.Builder) {
- b.WriteString("function __do_needs_root_completion\n")
- b.WriteString(" set -l positional (__do_positional_tokens)\n")
+ b.WriteString("function __ask_needs_root_completion\n")
+ b.WriteString(" set -l positional (__ask_positional_tokens)\n")
b.WriteString(" if test (count $positional) -eq 0\n")
b.WriteString(" return 0\n")
b.WriteString(" end\n")
@@ -165,14 +183,14 @@ func writeFishNeedsRootCompletionFunction(b *strings.Builder) {
}
func writeFishNeedsCommandCompletionFunction(b *strings.Builder) {
- b.WriteString("function __do_needs_command_completion\n")
- b.WriteString(" set -l positional (__do_positional_tokens)\n")
+ b.WriteString("function __ask_needs_command_completion\n")
+ b.WriteString(" set -l positional (__ask_positional_tokens)\n")
b.WriteString(" if test (count $positional) -eq 0\n")
b.WriteString(" return 0\n")
b.WriteString(" end\n")
b.WriteString(" if test (count $positional) -eq 1\n")
b.WriteString(" switch $positional[1]\n")
- b.WriteString(" case na no-agent proj:*\n")
+ b.WriteString(" case na no-agent 'proj:*'\n")
b.WriteString(" return 0\n")
b.WriteString(" end\n")
b.WriteString(" end\n")
@@ -181,8 +199,8 @@ func writeFishNeedsCommandCompletionFunction(b *strings.Builder) {
}
func writeFishDepContextFunction(b *strings.Builder) {
- b.WriteString("function __do_in_dep_context\n")
- b.WriteString(" set -l positional (__do_command_positionals)\n")
+ b.WriteString("function __ask_in_dep_context\n")
+ b.WriteString(" set -l positional (__ask_command_positionals)\n")
b.WriteString(" if test (count $positional) -lt 1\n")
b.WriteString(" return 1\n")
b.WriteString(" end\n")
@@ -194,8 +212,8 @@ func writeFishDepContextFunction(b *strings.Builder) {
}
func writeFishUUIDContextFunction(b *strings.Builder) {
- b.WriteString("function __do_in_uuid_context\n")
- b.WriteString(" set -l positional (__do_command_positionals)\n")
+ b.WriteString("function __ask_in_uuid_context\n")
+ b.WriteString(" set -l positional (__ask_command_positionals)\n")
b.WriteString(" if test (count $positional) -eq 0\n")
b.WriteString(" return 1\n")
b.WriteString(" end\n")
@@ -215,8 +233,8 @@ func writeFishUUIDContextFunction(b *strings.Builder) {
}
func writeFishDepUUIDContextFunction(b *strings.Builder) {
- b.WriteString("function __do_in_dep_uuid_context\n")
- b.WriteString(" set -l positional (__do_command_positionals)\n")
+ b.WriteString("function __ask_in_dep_uuid_context\n")
+ b.WriteString(" set -l positional (__ask_command_positionals)\n")
b.WriteString(" if test (count $positional) -lt 2\n")
b.WriteString(" return 1\n")
b.WriteString(" end\n")
@@ -240,8 +258,8 @@ func writeFishDepUUIDContextFunction(b *strings.Builder) {
}
func writeFishAddDependencyModifierContextFunction(b *strings.Builder) {
- b.WriteString("function __do_in_add_dep_modifier_context\n")
- b.WriteString(" set -l positional (__do_command_positionals)\n")
+ b.WriteString("function __ask_in_add_dep_modifier_context\n")
+ b.WriteString(" set -l positional (__ask_command_positionals)\n")
b.WriteString(" if test (count $positional) -lt 1\n")
b.WriteString(" return 1\n")
b.WriteString(" end\n")
@@ -257,38 +275,38 @@ func writeFishAddDependencyModifierContextFunction(b *strings.Builder) {
}
func writeFishTaskSelectorFunction(b *strings.Builder, binaryPath string) {
- b.WriteString("function __do_task_selectors\n")
- b.WriteString(" set -l do_bin ")
+ b.WriteString("function __ask_task_selectors\n")
+ b.WriteString(" set -l ask_bin ")
b.WriteString(quoteFishString(binaryPath))
b.WriteString("\n")
- b.WriteString(" set -l scope_prefix (__do_scope_prefix)\n")
+ b.WriteString(" set -l scope_prefix (__ask_scope_prefix)\n")
b.WriteString(" set -l cache_key default\n")
b.WriteString(" if test (count $scope_prefix) -gt 0\n")
b.WriteString(" set cache_key (string join ' ' $scope_prefix)\n")
b.WriteString(" end\n")
b.WriteString(" set -l now (date +%s)\n")
- b.WriteString(" if set -q __do_task_selector_cache_until; and test $__do_task_selector_cache_until -ge $now; and set -q __do_task_selector_cache_key; and test \"$__do_task_selector_cache_key\" = \"$cache_key\"\n")
- b.WriteString(" printf '%s\\n' $__do_task_selector_cache\n")
+ b.WriteString(" if set -q __ask_task_selector_cache_until; and test $__ask_task_selector_cache_until -ge $now; and set -q __ask_task_selector_cache_key; and test \"$__ask_task_selector_cache_key\" = \"$cache_key\"\n")
+ b.WriteString(" printf '%s\\n' $__ask_task_selector_cache\n")
b.WriteString(" return 0\n")
b.WriteString(" end\n")
b.WriteString(" set -l selectors\n")
b.WriteString(" if test (count $scope_prefix) -gt 0\n")
- b.WriteString(" set selectors (command $do_bin $scope_prefix complete-aliases 2>/dev/null)\n")
+ b.WriteString(" set selectors (command $ask_bin $scope_prefix complete-aliases 2>/dev/null)\n")
b.WriteString(" else\n")
- b.WriteString(" set selectors (command $do_bin complete-aliases 2>/dev/null)\n")
+ b.WriteString(" set selectors (command $ask_bin complete-aliases 2>/dev/null)\n")
b.WriteString(" end\n")
b.WriteString(" if test $status -ne 0\n")
b.WriteString(" return 1\n")
b.WriteString(" end\n")
- b.WriteString(" set -g __do_task_selector_cache $selectors\n")
- b.WriteString(" set -g __do_task_selector_cache_until (math $now + 2)\n")
- b.WriteString(" set -g __do_task_selector_cache_key $cache_key\n")
+ b.WriteString(" set -g __ask_task_selector_cache $selectors\n")
+ b.WriteString(" set -g __ask_task_selector_cache_until (math $now + 2)\n")
+ b.WriteString(" set -g __ask_task_selector_cache_key $cache_key\n")
b.WriteString(" printf '%s\\n' $selectors\n")
b.WriteString("end\n\n")
}
func writeFishAddDependencyModifierFunction(b *strings.Builder) {
- b.WriteString("function __do_add_dependency_modifiers\n")
+ b.WriteString("function __ask_add_dependency_modifiers\n")
b.WriteString(" set -l current (commandline -ct)\n")
b.WriteString(" if test $current = depends\n")
b.WriteString(" printf '%s\\n' 'depends:'\n")
@@ -307,9 +325,9 @@ func writeFishAddDependencyModifierFunction(b *strings.Builder) {
b.WriteString(" set chosen $pieces[1..-2]\n")
b.WriteString(" end\n")
b.WriteString(" end\n")
- // Each item from __do_task_selectors is "selector\tdescription"; extract
+ // Each item from __ask_task_selectors is "selector\tdescription"; extract
// just the selector (before the tab) for matching and output purposes.
- b.WriteString(" for item in (__do_task_selectors)\n")
+ b.WriteString(" for item in (__ask_task_selectors)\n")
b.WriteString(" set -l selector (string split -m1 '\\t' -- $item)[1]\n")
b.WriteString(" if contains -- $selector $chosen\n")
b.WriteString(" continue\n")
@@ -326,8 +344,10 @@ func writeFishAddDependencyModifierFunction(b *strings.Builder) {
b.WriteString("end\n\n")
}
-func writeFishCompletionLine(b *strings.Builder, condition string, item fishCompletionItem) {
- b.WriteString("complete -c do -n '")
+func writeFishCompletionLine(b *strings.Builder, cmd, condition string, item fishCompletionItem) {
+ b.WriteString("complete -c ")
+ b.WriteString(cmd)
+ b.WriteString(" -n '")
b.WriteString(condition)
b.WriteString("' -a '")
b.WriteString(item.name)
@@ -336,16 +356,20 @@ func writeFishCompletionLine(b *strings.Builder, condition string, item fishComp
b.WriteString("'\n")
}
-func writeFishUUIDCompletionLine(b *strings.Builder, condition, description string) {
- b.WriteString("complete -c do -n '")
+func writeFishUUIDCompletionLine(b *strings.Builder, cmd, condition, description string) {
+ b.WriteString("complete -c ")
+ b.WriteString(cmd)
+ b.WriteString(" -n '")
b.WriteString(condition)
- b.WriteString("' -a '(__do_task_selectors)' -d '")
+ b.WriteString("' -a '(__ask_task_selectors)' -d '")
b.WriteString(strings.ReplaceAll(description, "'", "\\'"))
b.WriteString("'\n")
}
-func writeFishFunctionCompletionLine(b *strings.Builder, condition, functionName, description string) {
- b.WriteString("complete -c do -n '")
+func writeFishFunctionCompletionLine(b *strings.Builder, cmd, condition, functionName, description string) {
+ b.WriteString("complete -c ")
+ b.WriteString(cmd)
+ b.WriteString(" -n '")
b.WriteString(condition)
b.WriteString("' -a '(")
b.WriteString(functionName)
diff --git a/internal/askcli/completion_test.go b/internal/askcli/completion_test.go
index 7d85c7b..d3f08e5 100644
--- a/internal/askcli/completion_test.go
+++ b/internal/askcli/completion_test.go
@@ -18,40 +18,40 @@ func TestFishCompletion_IncludesCommandsAndExcludesExport(t *testing.T) {
}
}
for _, line := range []string{
- "# Source with: do fish | source",
- "complete -c do -n '__do_in_dep_context' -a 'add' -d 'Add a dependency'",
- "complete -c do -n '__do_in_dep_context' -a 'rm' -d 'Remove a dependency'",
- "complete -c do -n '__do_in_dep_context' -a 'list' -d 'List dependencies'",
- "function __do_command_positionals",
- "function __do_scope_prefix",
- "function __do_task_selectors",
- "function __do_add_dependency_modifiers",
- `set -l do_bin "do"`,
+ "# Source with: ask fish | source",
+ "complete -c ask -n '__ask_in_dep_context' -a 'add' -d 'Add a dependency'",
+ "complete -c ask -n '__ask_in_dep_context' -a 'rm' -d 'Remove a dependency'",
+ "complete -c ask -n '__ask_in_dep_context' -a 'list' -d 'List dependencies'",
+ "function __ask_command_positionals",
+ "function __ask_scope_prefix",
+ "function __ask_task_selectors",
+ "function __ask_add_dependency_modifiers",
+ `set -l ask_bin "ask"`,
"set -l selectors",
- "set selectors (command $do_bin complete-aliases 2>/dev/null)",
- "set selectors (command $do_bin $scope_prefix complete-aliases 2>/dev/null)",
- "case na no-agent proj:*",
+ "set selectors (command $ask_bin complete-aliases 2>/dev/null)",
+ "set selectors (command $ask_bin $scope_prefix complete-aliases 2>/dev/null)",
+ "case na no-agent 'proj:*'",
"set cache_key (string join ' ' $scope_prefix)",
- "complete -c do -n '__do_in_uuid_context' -a '(__do_task_selectors)' -d 'Task selector'",
- "complete -c do -n '__do_in_dep_uuid_context' -a '(__do_task_selectors)' -d 'Task selector'",
- "complete -c do -n '__do_in_add_dep_modifier_context' -a '(__do_add_dependency_modifiers)' -d 'Task dependency'",
+ "complete -c ask -n '__ask_in_uuid_context' -a '(__ask_task_selectors)' -d 'Task selector'",
+ "complete -c ask -n '__ask_in_dep_uuid_context' -a '(__ask_task_selectors)' -d 'Task selector'",
+ "complete -c ask -n '__ask_in_add_dep_modifier_context' -a '(__ask_add_dependency_modifiers)' -d 'Task dependency'",
// The dep modifier function must extract just the selector (before the
// tab) from each tab-separated "selector\tdescription" completion item.
- "for item in (__do_task_selectors)",
+ "for item in (__ask_task_selectors)",
"set -l selector (string split -m1 '\\t' -- $item)[1]",
} {
if !strings.Contains(script, line) {
t.Fatalf("script missing dep completion line %q", line)
}
}
- if strings.Contains(script, "do export") {
+ if strings.Contains(script, "ask export") {
t.Fatalf("script should not advertise non-existent export command")
}
- if strings.Contains(script, "assets/do.fish") {
+ if strings.Contains(script, "assets/ask.fish") {
t.Fatalf("script should not reference a static asset")
}
for _, name := range []string{"info", "annotate", "start", "stop", "done", "priority", "tag", "modify", "denotate", "delete"} {
- if strings.Contains(script, "complete -c do -n '__do_in_uuid_context' -a '"+name+"'") {
+ if strings.Contains(script, "complete -c ask -n '__ask_in_uuid_context' -a '"+name+"'") {
t.Fatalf("script should not hard-code UUID completion item %q", name)
}
}
@@ -141,10 +141,10 @@ func TestFishAddDependencyModifierCompletionContext(t *testing.T) {
}
func TestFishCompletionFor_EmbedsBinaryPath(t *testing.T) {
- script := FishCompletionFor(`/tmp/do "$HOME"`)
+ script := FishCompletionFor(`/tmp/ask "$HOME"`)
for _, line := range []string{
- `set -l do_bin "/tmp/do \"\$HOME\""`,
- "set selectors (command $do_bin complete-aliases 2>/dev/null)",
+ `set -l ask_bin "/tmp/ask \"\$HOME\""`,
+ "set selectors (command $ask_bin complete-aliases 2>/dev/null)",
} {
if !strings.Contains(script, line) {
t.Fatalf("script missing %q", line)
diff --git a/internal/askcli/dispatch.go b/internal/askcli/dispatch.go
index 69310c7..e326017 100644
--- a/internal/askcli/dispatch.go
+++ b/internal/askcli/dispatch.go
@@ -6,7 +6,7 @@ import (
"io"
)
-// Runner performs CLI work that would otherwise be handled by the do CLI itself.
+// Runner performs CLI work that would otherwise be handled by the ask CLI itself.
//
// The interface is implemented by the executor that ultimately proxies commands to Taskwarrior.
type Runner interface {
@@ -22,7 +22,7 @@ type Dispatcher struct {
// NewDispatcher creates a Dispatcher backed by the provided Runner or a default executor when nil.
func NewDispatcher(runner Runner) *Dispatcher {
if runner == nil {
- e := NewExecutor("do")
+ e := NewExecutor("ask")
runner = &e
}
return &Dispatcher{runner: runner}
@@ -68,36 +68,36 @@ func (d *Dispatcher) Dispatch(ctx context.Context, args []string, stdin io.Reade
}
func (d *Dispatcher) help(w io.Writer) (int, error) {
- _, _ = io.WriteString(w, "do - task management CLI\n")
+ _, _ = io.WriteString(w, "ask - task management CLI\n")
_, _ = io.WriteString(w, "\nProject prefixes:\n")
- _, _ = io.WriteString(w, " do proj:<name> <subcommand...> Run a subcommand against an explicit project\n")
+ _, _ = io.WriteString(w, " ask proj:<name> <subcommand...> Run a subcommand against an explicit project\n")
_, _ = io.WriteString(w, "\nScope prefixes:\n")
- _, _ = io.WriteString(w, " do na <subcommand...> Run a subcommand against project tasks without +agent\n")
- _, _ = io.WriteString(w, " do no-agent <subcommand...> Alias for do na\n")
+ _, _ = io.WriteString(w, " ask na <subcommand...> Run a subcommand against project tasks without +agent\n")
+ _, _ = io.WriteString(w, " ask no-agent <subcommand...> Alias for ask na\n")
_, _ = io.WriteString(w, "\nSubcommands:\n")
- _, _ = io.WriteString(w, " do add [mods...] [depends:<id|uuid>,...] <description...> Create a new task and print created task <id>\n")
- _, _ = io.WriteString(w, " do list [filters] List active tasks (default)\n")
- _, _ = io.WriteString(w, " do ready List READY tasks (not blocked)\n")
- _, _ = io.WriteString(w, " do all [filters] List all tasks including completed/deleted\n")
- _, _ = io.WriteString(w, " do info [id|uuid] Show task details or current started task\n")
- _, _ = io.WriteString(w, " do annotate <id|uuid> \"note\" Add annotation to task\n")
- _, _ = io.WriteString(w, " do start <id|uuid> Start working on task\n")
- _, _ = io.WriteString(w, " do stop <id|uuid> Stop work on a task\n")
- _, _ = io.WriteString(w, " do done <id|uuid> Mark task complete\n")
- _, _ = io.WriteString(w, " do priority <id|uuid> <P> Set priority (H/M/L)\n")
- _, _ = io.WriteString(w, " do tag <id|uuid> +/-<tag> Add or remove tag\n")
- _, _ = io.WriteString(w, " do dep add <id|uuid> <dep> Add dependency\n")
- _, _ = io.WriteString(w, " do dep rm <id|uuid> <dep> Remove dependency\n")
- _, _ = io.WriteString(w, " do dep list <id|uuid> List dependencies\n")
- _, _ = io.WriteString(w, " do urgency List tasks sorted by urgency\n")
- _, _ = io.WriteString(w, " do modify <id|uuid> <args...> Modify task fields\n")
- _, _ = io.WriteString(w, " do denotate <id|uuid> \"text\" Remove annotation\n")
- _, _ = io.WriteString(w, " do delete <id|uuid> Delete a task\n")
- _, _ = io.WriteString(w, " do fish Emit Fish shell completion script\n")
+ _, _ = io.WriteString(w, " ask add [mods...] [depends:<id|uuid>,...] <description...> Create a new task and print created task <id>\n")
+ _, _ = io.WriteString(w, " ask list [filters] List active tasks (default)\n")
+ _, _ = io.WriteString(w, " ask ready List READY tasks (not blocked)\n")
+ _, _ = io.WriteString(w, " ask all [filters] List all tasks including completed/deleted\n")
+ _, _ = io.WriteString(w, " ask info [id|uuid] Show task details or current started task\n")
+ _, _ = io.WriteString(w, " ask annotate <id|uuid> \"note\" Add annotation to task\n")
+ _, _ = io.WriteString(w, " ask start <id|uuid> Start working on task\n")
+ _, _ = io.WriteString(w, " ask stop <id|uuid> Stop work on a task\n")
+ _, _ = io.WriteString(w, " ask done <id|uuid> Mark task complete\n")
+ _, _ = io.WriteString(w, " ask priority <id|uuid> <P> Set priority (H/M/L)\n")
+ _, _ = io.WriteString(w, " ask tag <id|uuid> +/-<tag> Add or remove tag\n")
+ _, _ = io.WriteString(w, " ask dep add <id|uuid> <dep> Add dependency\n")
+ _, _ = io.WriteString(w, " ask dep rm <id|uuid> <dep> Remove dependency\n")
+ _, _ = io.WriteString(w, " ask dep list <id|uuid> List dependencies\n")
+ _, _ = io.WriteString(w, " ask urgency List tasks sorted by urgency\n")
+ _, _ = io.WriteString(w, " ask modify <id|uuid> <args...> Modify task fields\n")
+ _, _ = io.WriteString(w, " ask denotate <id|uuid> \"text\" Remove annotation\n")
+ _, _ = io.WriteString(w, " ask delete <id|uuid> Delete a task\n")
+ _, _ = io.WriteString(w, " ask fish Emit Fish shell completion script\n")
return 0, nil
}
func (d *Dispatcher) unknownCommand(w io.Writer, subcommand string) (int, error) {
- fmt.Fprintf(w, "do: unknown subcommand %q\n", subcommand)
+ fmt.Fprintf(w, "ask: unknown subcommand %q\n", subcommand)
return 1, nil
}
diff --git a/internal/askcli/dispatch_test.go b/internal/askcli/dispatch_test.go
index 68f1e3b..d8f1458 100644
--- a/internal/askcli/dispatch_test.go
+++ b/internal/askcli/dispatch_test.go
@@ -23,22 +23,22 @@ func TestDispatcher_Help(t *testing.T) {
t.Fatalf("help returned error: %v", err)
}
output := stdout.String()
- if !strings.Contains(output, "do - task management CLI") {
+ if !strings.Contains(output, "ask - task management CLI") {
t.Fatalf("help missing title: %s", output)
}
- if !strings.Contains(output, "do proj:<name> <subcommand...>") {
+ if !strings.Contains(output, "ask proj:<name> <subcommand...>") {
t.Fatalf("help missing project prefix: %s", output)
}
- if !strings.Contains(output, "do na <subcommand...>") || !strings.Contains(output, "do no-agent <subcommand...>") {
+ if !strings.Contains(output, "ask na <subcommand...>") || !strings.Contains(output, "ask no-agent <subcommand...>") {
t.Fatalf("help missing no-agent scope prefixes: %s", output)
}
- if !strings.Contains(output, "do list") {
+ if !strings.Contains(output, "ask list") {
t.Fatalf("help missing list subcommand: %s", output)
}
- if !strings.Contains(output, "do all") {
+ if !strings.Contains(output, "ask all") {
t.Fatalf("help missing all subcommand: %s", output)
}
- if !strings.Contains(output, "do fish") {
+ if !strings.Contains(output, "ask fish") {
t.Fatalf("help missing fish subcommand: %s", output)
}
}
@@ -131,8 +131,8 @@ func TestDispatcher_LongHelp(t *testing.T) {
d.Dispatch(context.Backgrou