summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore4
-rw-r--r--Magefile.go12
-rw-r--r--README.md6
-rwxr-xr-xcmd/ask/askbin4322459 -> 0 bytes
-rw-r--r--cmd/do/main.go (renamed from cmd/ask/main.go)0
-rw-r--r--cmd/do/main_test.go (renamed from cmd/ask/main_test.go)0
-rw-r--r--docs/buildandinstall.md6
-rw-r--r--docs/fish-completion.md22
-rw-r--r--docs/plan-ask-uuid-wrapper.md108
-rw-r--r--docs/usage.md84
-rw-r--r--integrationtests/do_scope_test.go (renamed from integrationtests/ask_scope_test.go)54
-rw-r--r--integrationtests/do_test.go (renamed from integrationtests/ask_test.go)156
-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.go92
-rw-r--r--internal/askcli/completion_test.go42
-rw-r--r--internal/askcli/dispatch.go50
-rw-r--r--internal/askcli/dispatch_test.go16
-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.go22
-rw-r--r--internal/taskproxy/run_test.go12
27 files changed, 369 insertions, 367 deletions
diff --git a/.gitignore b/.gitignore
index 90b1ee1..49978b8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,6 @@
-/ask
+/do
+/cmd/do/do
+/cmd/do/ask
/hexai
/hexai-lsp-server
/hexai-mcp-server
diff --git a/Magefile.go b/Magefile.go
index 65748fd..fb19689 100644
--- a/Magefile.go
+++ b/Magefile.go
@@ -25,15 +25,15 @@ var (
// Build builds binaries.
func Build() error {
- mg.Deps(BuildAsk, BuildHexaiLSP, BuildHexaiCLI, BuildHexaiTmuxAction, BuildHexaiTmuxEdit, BuildHexaiMCPServer)
+ mg.Deps(BuildDo, BuildHexaiLSP, BuildHexaiCLI, BuildHexaiTmuxAction, BuildHexaiTmuxEdit, BuildHexaiMCPServer)
printCoverage()
return nil
}
-// BuildAsk builds the Taskwarrior proxy wrapper.
-func BuildAsk() error {
+// BuildDo builds the Taskwarrior proxy wrapper.
+func BuildDo() error {
printCoverage()
- return sh.RunV("go", "build", "-o", "ask", "./cmd/ask")
+ return sh.RunV("go", "build", "-o", "do", "./cmd/do")
}
// BuildHexaiLSP builds the LSP server binary.
@@ -70,7 +70,7 @@ func BuildHexaiMCPServer() error {
func Dev() error {
printCoverage()
mg.Deps(Test, Vet, Lint)
- if err := sh.RunV("go", "build", "-race", "-o", "ask", "./cmd/ask"); err != nil {
+ if err := sh.RunV("go", "build", "-race", "-o", "do", "./cmd/do"); err != nil {
return err
}
if err := sh.RunV("go", "build", "-race", "-o", "hexai-lsp-server", "./cmd/hexai-lsp-server"); err != nil {
@@ -120,7 +120,7 @@ func Install() error {
return err
}
for _, name := range []string{
- "ask",
+ "do",
"hexai-lsp-server",
"hexai",
"hexai-tmux-action",
diff --git a/README.md b/README.md
index 510705f..9e46ed5 100644
--- a/README.md
+++ b/README.md
@@ -14,12 +14,12 @@ It has got improved capabilities for Go code understanding (for example, create
* Stand-alone command line tool for LLM interaction
- Includes `--tps-simulation` to preview how fast a model would feel by streaming placeholder text or piped stdin at a chosen token-per-second rate
* Task management CLI for agent-managed project work
- - Entrypoint: `ask`
+ - Entrypoint: `do`
- Auto-scopes to `project:<repo> +agent` (derived from git repo root)
- Never exposes numeric task IDs — uses UUIDs only
- Machine-friendly output: UUID-only tables, suppressed decorative text
- - Subcommands: `ask add`, `ask list`, `ask info`, `ask annotate`, `ask start`, `ask stop`, `ask done`, `ask priority`, `ask tag`, `ask dep`, `ask urgency`, `ask modify`, `ask denotate`, `ask delete`, `ask fish`, `ask help`
- - Fish completion generator: `ask fish`
+ - Subcommands: `do add`, `do list`, `do info`, `do annotate`, `do start`, `do stop`, `do done`, `do priority`, `do tag`, `do dep`, `do urgency`, `do modify`, `do denotate`, `do delete`, `do fish`, `do help`
+ - Fish completion generator: `do fish`
* Parallel completions and CLI responses from multiple providers/models for side-by-side comparison
* **MCP server for prompt/runbook management** (`hexai-mcp-server`) - **⚠️ DEPRECATED/EXPERIMENTAL**
- Create, update, delete, and retrieve prompts via MCP protocol
diff --git a/cmd/ask/ask b/cmd/ask/ask
deleted file mode 100755
index cffc885..0000000
--- a/cmd/ask/ask
+++ /dev/null
Binary files differ
diff --git a/cmd/ask/main.go b/cmd/do/main.go
index afab992..afab992 100644
--- a/cmd/ask/main.go
+++ b/cmd/do/main.go
diff --git a/cmd/ask/main_test.go b/cmd/do/main_test.go
index db6b436..db6b436 100644
--- a/cmd/ask/main_test.go
+++ b/cmd/do/main_test.go
diff --git a/docs/buildandinstall.md b/docs/buildandinstall.md
index a707faa..abca741 100644
--- a/docs/buildandinstall.md
+++ b/docs/buildandinstall.md
@@ -3,7 +3,7 @@
Hexai uses Mage for developer tasks. Install Mage, then run targets like build, dev, test, and install.
- Install Mage: `go install github.com/magefile/mage@latest`
-- Build binaries: `mage build` (produces `ask`, `hexai`, `hexai-lsp-server`, `hexai-tmux-action`, and `hexai-tmux-edit`)
+- Build binaries: `mage build` (produces `do`, `hexai`, `hexai-lsp-server`, `hexai-tmux-action`, and `hexai-tmux-edit`)
- Dev build (+ tests, vet, lint): `mage dev`
- Run tests: `mage test`
- Run tests with coverage: `go test ./... -cover`
@@ -11,7 +11,7 @@ Hexai uses Mage for developer tasks. Install Mage, then run targets like build,
- In restricted sandboxes/CI (no sockets), skip network-based tests:
- `HEXAI_TEST_SKIP_NET=1 go test ./... -cover`
- Install binaries to `GOPATH/bin`: `mage install`
-- Load Fish completions in the current shell: `~/go/bin/ask fish | source`
+- Load Fish completions in the current shell: `~/go/bin/do fish | source`
Note: `mage lint` uses `golangci-lint`. Install via `mage devinstall` if needed.
@@ -19,7 +19,7 @@ Note: `mage lint` uses `golangci-lint`. Install via `mage devinstall` if needed.
Either use the Mage method as mentioned above, or install directly with:
-- Taskwarrior proxy: `go install codeberg.org/snonux/hexai/cmd/ask@latest`
+- Taskwarrior proxy: `go install codeberg.org/snonux/hexai/cmd/do@latest`
- CLI: `go install codeberg.org/snonux/hexai/cmd/hexai@latest`
- LSP: `go install codeberg.org/snonux/hexai/cmd/hexai-lsp-server@latest`
- Action runner: `go install codeberg.org/snonux/hexai/cmd/hexai-tmux-action@latest`
diff --git a/docs/fish-completion.md b/docs/fish-completion.md
index d707b77..f55e4cf 100644
--- a/docs/fish-completion.md
+++ b/docs/fish-completion.md
@@ -1,34 +1,34 @@
# Fish Completion
-The `ask` task-management CLI embeds its Fish completion script in the binary and prints it with `ask fish`.
+The `do` task-management CLI embeds its Fish completion script in the binary and prints it with `do fish`.
-It completes the top-level `ask` subcommands and the nested `ask dep` operations.
-It also completes task selectors for UUID-taking commands by reading pending tasks through `ask complete-uuids`, which uses the local alias cache for stable short IDs.
+It completes the top-level `do` subcommands and the nested `do dep` operations.
+It also completes task selectors for UUID-taking commands by reading pending tasks through `do complete-uuids`, which uses the local alias cache for stable short IDs.
Fish suggests each task's alias ID first and also keeps the raw UUID available as a fallback selector.
-Selector suggestions stop once a command has consumed its selector argument, and `ask dep add` / `ask dep rm` suggest selectors for both task positions.
-When typing `ask add depends:...`, Fish also completes the comma-separated dependency selector list inside the `depends:` modifier.
+Selector suggestions stop once a command has consumed its selector argument, and `do dep add` / `do dep rm` suggest selectors for both task positions.
+When typing `do add depends:...`, Fish also completes the comma-separated dependency selector list inside the `depends:` modifier.
The script preserves the global `--json` flag.
Load it into the current Fish session:
```sh
-ask fish | source
+do fish | source
```
If you installed with `mage install` and `~/go/bin` is not on your `PATH` yet, use:
```sh
-~/go/bin/ask fish | source
+~/go/bin/do fish | source
```
To enable it automatically for new Fish sessions, add this to your Fish config or a file in `~/.config/fish/conf.d/`:
```fish
-set -l ask_bin ~/go/bin/ask
+set -l do_bin ~/go/bin/do
-if test -x $ask_bin
- $ask_bin fish | source
+if test -x $do_bin
+ $do_bin fish | source
end
```
-No external `ask.fish` file is required.
+No external `do.fish` file is required.
diff --git a/docs/plan-ask-uuid-wrapper.md b/docs/plan-ask-uuid-wrapper.md
index dcaf44c..31d719b 100644
--- a/docs/plan-ask-uuid-wrapper.md
+++ b/docs/plan-ask-uuid-wrapper.md
@@ -1,8 +1,8 @@
-# Plan: `ask` as UUID-only Taskwarrior Wrapper
+# Plan: `do` as UUID-only Taskwarrior Wrapper
## Goal
-Rewrite the `ask` command from a thin pass-through proxy into a **subcommand-based CLI** that wraps Taskwarrior. The wrapper never exposes numeric task IDs to the caller — only UUIDs. Output is minimal and machine-friendly for coding agents.
+Rewrite the `do` command from a thin pass-through proxy into a **subcommand-based CLI** that wraps Taskwarrior. The wrapper never exposes numeric task IDs to the caller — only UUIDs. Output is minimal and machine-friendly for coding agents.
The existing `project:<repo> +agent` auto-injection is preserved.
@@ -10,39 +10,39 @@ The existing `project:<repo> +agent` auto-injection is preserved.
| Subcommand | Example | Taskwarrior equivalent |
|---|---|---|
-| `ask add "Implement X"` | create task | `task project:P +agent add "Implement X"` |
-| `ask add priority:H +cli "Fix bug"` | create with priority & tag | same + `priority:H +cli` |
-| `ask list` | list pending tasks | `task project:P +agent status:pending export` → reformat |
-| `ask info <uuid>` | show one task | `task uuid:<uuid> export` → filtered fields |
-| `ask annotate <uuid> "note"` | add annotation | `task uuid:<uuid> annotate "note"` |
-| `ask start <uuid>` | start work | `task uuid:<uuid> start` |
-| `ask stop <uuid>` | stop work | `task uuid:<uuid> stop` |
-| `ask done <uuid>` | mark complete | `task uuid:<uuid> done` |
-| `ask priority <uuid> H` | set priority | `task uuid:<uuid> modify priority:H` |
-| `ask tag <uuid> +foo` | add tag | `task uuid:<uuid> modify +foo` |
-| `ask tag <uuid> -foo` | remove tag | `task uuid:<uuid> modify -foo` |
-| `ask dep add <uuid> <dep-uuid>` | add dependency | `task uuid:<uuid> modify depends:<dep-uuid>` |
-| `ask dep rm <uuid> <dep-uuid>` | remove dependency | `task uuid:<uuid> modify depends:-<dep-uuid>` |
-| `ask dep list <uuid>` | show dependencies | `task uuid:<uuid> export` → `depends` field |
-| `ask urgency` | list by urgency | `task project:P +agent export` → sort by urgency |
-| `ask modify <uuid> <args...>` | general modify | `task uuid:<uuid> modify <args...>` (priority, tags, depends, /old/new/) |
-| `ask denotate <uuid> "text"` | remove annotation | `task uuid:<uuid> denotate "text"` |
-| `ask delete <uuid>` | delete task | `task uuid:<uuid> delete` |
-| `ask export` | raw JSON dump | `task project:P +agent export` → pass through |
+| `do add "Implement X"` | create task | `task project:P +agent add "Implement X"` |
+| `do add priority:H +cli "Fix bug"` | create with priority & tag | same + `priority:H +cli` |
+| `do list` | list pending tasks | `task project:P +agent status:pending export` → reformat |
+| `do info <uuid>` | show one task | `task uuid:<uuid> export` → filtered fields |
+| `do annotate <uuid> "note"` | add annotation | `task uuid:<uuid> annotate "note"` |
+| `do start <uuid>` | start work | `task uuid:<uuid> start` |
+| `do stop <uuid>` | stop work | `task uuid:<uuid> stop` |
+| `do done <uuid>` | mark complete | `task uuid:<uuid> done` |
+| `do priority <uuid> H` | set priority | `task uuid:<uuid> modify priority:H` |
+| `do tag <uuid> +foo` | add tag | `task uuid:<uuid> modify +foo` |
+| `do tag <uuid> -foo` | remove tag | `task uuid:<uuid> modify -foo` |
+| `do dep add <uuid> <dep-uuid>` | add dependency | `task uuid:<uuid> modify depends:<dep-uuid>` |
+| `do dep rm <uuid> <dep-uuid>` | remove dependency | `task uuid:<uuid> modify depends:-<dep-uuid>` |
+| `do dep list <uuid>` | show dependencies | `task uuid:<uuid> export` → `depends` field |
+| `do urgency` | list by urgency | `task project:P +agent export` → sort by urgency |
+| `do modify <uuid> <args...>` | general modify | `task uuid:<uuid> modify <args...>` (priority, tags, depends, /old/new/) |
+| `do denotate <uuid> "text"` | remove annotation | `task uuid:<uuid> denotate "text"` |
+| `do delete <uuid>` | delete task | `task uuid:<uuid> delete` |
+| `do export` | raw JSON dump | `task project:P +agent export` → pass through |
### List filters, sort, and limit
-`ask list` accepts optional filters, sort, and limit arguments:
+`do list` accepts optional filters, sort, and limit arguments:
| Example | Taskwarrior equivalent |
|---|---|
-| `ask list` | `task project:P +agent status:pending export` (default sort: priority-, urgency-) |
-| `ask list +READY` | `task project:P +agent +READY export` |
-| `ask list +BLOCKED` | `task project:P +agent +BLOCKED export` |
-| `ask list +frontend` | `task project:P +agent +frontend export` |
-| `ask list started` | `task project:P +agent start.any: export` |
-| `ask list limit:3` | show only first 3 results |
-| `ask list +READY limit:1` | next ready task |
+| `do list` | `task project:P +agent status:pending export` (default sort: priority-, urgency-) |
+| `do list +READY` | `task project:P +agent +READY export` |
+| `do list +BLOCKED` | `task project:P +agent +BLOCKED export` |
+| `do list +frontend` | `task project:P +agent +frontend export` |
+| `do list started` | `task project:P +agent start.any: export` |
+| `do list limit:3` | show only first 3 results |
+| `do list +READY limit:1` | next ready task |
## Data Retrieval: `task export`
@@ -81,7 +81,7 @@ If an argument looks like a bare numeric ID where a UUID is expected, reject wit
## Package Layout
```
-cmd/ask/main.go — parse subcommand, dispatch to askcli
+cmd/do/main.go — parse subcommand, dispatch to askcli
internal/askcli/ — NEW package
├── dispatch.go — subcommand router (switch args[0])
├── taskexec.go — wraps Taskwarrior execution (binary lookup, repo detection, run)
@@ -108,45 +108,45 @@ Each `command_*.go` file gets a corresponding `command_*_test.go`.
## Changes to Existing Code
-- **`cmd/ask/main.go`** — stops calling `taskproxy.Runner.Run` directly; delegates to `askcli.Dispatch()`.
+- **`cmd/do/main.go`** — stops calling `taskproxy.Runner.Run` directly; delegates to `askcli.Dispatch()`.
- **`internal/taskproxy/`** — reused by `askcli/taskexec.go` for binary lookup (`findTaskBinary`) and repo root detection (`detectRepoRoot`). The `Runner.Run` pass-through method becomes unused and can be removed.
## Task Breakdown
1. Scaffold `internal/askcli/` — dispatch, taskexec, taskexport, formatter
-2. Implement `ask add` (UUID extraction from Taskwarrior stdout)
-3. Implement `ask list` (export → UUID-only table)
-4. Implement `ask info <uuid>` (export → filtered fields)
-5. Implement `ask annotate <uuid> "note"`
-6. Implement `ask start <uuid>` / `ask stop <uuid>`
-7. Implement `ask done <uuid>`
-8. Implement `ask priority <uuid> <P>`
-9. Implement `ask tag <uuid> +/-tag`
-10. Implement `ask dep add/rm/list`
-11. Implement `ask urgency`
-12. Implement `ask modify <uuid> <args...>` (general-purpose modify)
-13. Implement `ask denotate <uuid> "text"` (remove annotation)
-14. Implement `ask delete <uuid>`
-15. Implement `ask export` (raw JSON)
-16. Add filter/sort/limit support to `ask list` (+READY, +BLOCKED, +tag, started, limit:N)
-17. Wire `cmd/ask/main.go` to `askcli.Dispatch`, remove old pass-through
+2. Implement `do add` (UUID extraction from Taskwarrior stdout)
+3. Implement `do list` (export → UUID-only table)
+4. Implement `do info <uuid>` (export → filtered fields)
+5. Implement `do annotate <uuid> "note"`
+6. Implement `do start <uuid>` / `do stop <uuid>`
+7. Implement `do done <uuid>`
+8. Implement `do priority <uuid> <P>`
+9. Implement `do tag <uuid> +/-tag`
+10. Implement `do dep add/rm/list`
+11. Implement `do urgency`
+12. Implement `do modify <uuid> <args...>` (general-purpose modify)
+13. Implement `do denotate <uuid> "text"` (remove annotation)
+14. Implement `do delete <uuid>`
+15. Implement `do export` (raw JSON)
+16. Add filter/sort/limit support to `do list` (+READY, +BLOCKED, +tag, started, limit:N)
+17. Wire `cmd/do/main.go` to `askcli.Dispatch`, remove old pass-through
18. Update docs and README
-19. Create `agent-task-management` skill (replacement for `taskwarrior-task-management`) — uses only `ask` subcommands, no Taskwarrior references
-20. Update Pi coding agent: rename `taskwarrior-plan-mode` extension → `agent-plan-mode`, rewrite to use `ask` subcommands only
-21. Audit `agent-task-management` skill and `agent-plan-mode` extension: ensure zero Taskwarrior leakage — agents must see `ask` as the native task system, not a wrapper
+19. Create `agent-task-management` skill (replacement for `taskwarrior-task-management`) — uses only `do` subcommands, no Taskwarrior references
+20. Update Pi coding agent: rename `taskwarrior-plan-mode` extension → `agent-plan-mode`, rewrite to use `do` subcommands only
+21. Audit `agent-task-management` skill and `agent-plan-mode` extension: ensure zero Taskwarrior leakage — agents must see `do` as the native task system, not a wrapper
## Skill & Extension Migration
-After the `ask` CLI is complete and documented, three follow-up tasks abstract away the Taskwarrior implementation detail:
+After the `do` CLI is complete and documented, three follow-up tasks abstract away the Taskwarrior implementation detail:
### 19. `agent-task-management` skill
-Create a new skill at `~/.agents/skills/agent-task-management/` by copying the structure from `taskwarrior-task-management` (SKILL.md + references/00-context.md through 5-review-overview-tasks.md). Rewrite all content to use `ask` subcommands (`ask add`, `ask list`, `ask info`, `ask start`, `ask stop`, `ask done`, `ask annotate`, `ask denotate`, `ask modify`, `ask priority`, `ask tag`, `ask dep`, `ask urgency`, `ask delete`, `ask export`). Remove all mentions of Taskwarrior, raw `task` command, numeric IDs, and `_uuid` lookups.
+Create a new skill at `~/.agents/skills/agent-task-management/` by copying the structure from `taskwarrior-task-management` (SKILL.md + references/00-context.md through 5-review-overview-tasks.md). Rewrite all content to use `do` subcommands (`do add`, `do list`, `do info`, `do start`, `do stop`, `do done`, `do annotate`, `do denotate`, `do modify`, `do priority`, `do tag`, `do dep`, `do urgency`, `do delete`, `do export`). Remove all mentions of Taskwarrior, raw `task` command, numeric IDs, and `_uuid` lookups.
### 20. `agent-plan-mode` Pi extension
-Rename `~/git/hyperstack/pi/agent/extensions/taskwarrior-plan-mode/` → `agent-plan-mode/`. Update `index.ts`, `utils.ts`, `README.md` to use new `ask` subcommands instead of raw pass-through calls. Rename `TaskwarriorTask` type, update state keys, command names, descriptions, and UI messages.
+Rename `~/git/hyperstack/pi/agent/extensions/taskwarrior-plan-mode/` → `agent-plan-mode/`. Update `index.ts`, `utils.ts`, `README.md` to use new `do` subcommands instead of raw pass-through calls. Rename `TaskwarriorTask` type, update state keys, command names, descriptions, and UI messages.
### 21. Taskwarrior leakage audit
-Grep all files in the new skill and extension for `taskwarrior` (any casing), `task warrior`, raw `task ` command patterns, numeric task ID usage, `_uuid` lookups, and any hint that `ask` wraps another tool. **Agents must believe `ask` IS the task management system — not a proxy.** This prevents agents from attempting raw Taskwarrior commands or mentioning Taskwarrior in annotations/descriptions.
+Grep all files in the new skill and extension for `taskwarrior` (any casing), `task warrior`, raw `task ` command patterns, numeric task ID usage, `_uuid` lookups, and any hint that `do` wraps another tool. **Agents must believe `do` IS the task management system — not a proxy.** This prevents agents from attempting raw Taskwarrior commands or mentioning Taskwarrior in annotations/descriptions.
diff --git a/docs/usage.md b/docs/usage.md
index 0786a00..cc78300 100644
--- a/docs/usage.md
+++ b/docs/usage.md
@@ -125,77 +125,77 @@ cat SOMEFILE.txt | hexai --tps-simulation 20
## Task management
-`ask` is a task management CLI for the current git project. By default it auto-scopes to `project:<repo> +agent` so operations are confined to agent-managed project tasks.
+`do` is a task management CLI for the current git project. By default it auto-scopes to `project:<repo> +agent` so operations are confined to agent-managed project tasks.
-Use `ask na <subcommand...>` or `ask no-agent <subcommand...>` to run the same subcommands against project tasks without the `+agent` tag. Those prefixes keep the project scope but replace the default tag filter with `-agent`.
+Use `do na <subcommand...>` or `do no-agent <subcommand...>` to run the same subcommands against project tasks without the `+agent` tag. Those prefixes keep the project scope but replace the default tag filter with `-agent`.
-`ask` never exposes Taskwarrior numeric task IDs. Human-facing output uses stable local alias IDs where practical, while `ask info` shows both the alias ID and the UUID. Commands that accept a task selector support either the alias ID or the UUID.
+`do` never exposes Taskwarrior numeric task IDs. Human-facing output uses stable local alias IDs where practical, while `do info` shows both the alias ID and the UUID. Commands that accept a task selector support either the alias ID or the UUID.
-`ask` must be run inside a git repository so the project name can be derived from the repo root.
+`do` must be run inside a git repository so the project name can be derived from the repo root.
### Subcommands
| Subcommand | Description |
|---|---|
-| `ask add "description"` | Create a new task and print `created task <alias-id>` |
-| `ask add depends:<id\|uuid>,<id\|uuid> "description"` | Create task with inline dependencies |
-| `ask add priority:H "description"` | Create task with priority |
-| `ask add +tag "description"` | Create task with tag |
-| `ask na add "description"` | Create a project task without the `+agent` tag |
-| `ask list` | List pending tasks only (alias-ID table) |
-| `ask na list` | List pending project tasks without the `+agent` tag |
-| `ask all` | List all tasks including completed/deleted |
-| `ask list +READY` | List only ready tasks |
-| `ask list +BLOCKED` | List blocked tasks |
-| `ask list +tag` | Filter by tag |
-| `ask list started` | List started tasks |
-| `ask list limit:N` | Limit results |
-| `ask list sort:priority-,urgency-` | Sort by priority then urgency |
-| `ask info [id\|uuid]` | Show task details, or the current started task if no selector is provided |
-| `ask annotate <id\|uuid> "note"` | Add annotation |
-| `ask start <id\|uuid>` | Start working on a task |
-| `ask stop <id\|uuid>` | Stop work on a task |
-| `ask done <id\|uuid>` | Mark task complete |
-| `ask priority <id\|uuid> H\|M\|L` | Set priority |
-| `ask tag <id\|uuid> +tag` | Add tag |
-| `ask tag <id\|uuid> -tag` | Remove tag |
-| `ask dep add <id\|uuid> <dep-id\|dep-uuid>` | Add dependency |
-| `ask dep rm <id\|uuid> <dep-id\|dep-uuid>` | Remove dependency |
-| `ask dep list <id\|uuid>` | List dependencies |
-| `ask urgency` | List tasks by urgency |
-| `ask modify <id\|uuid> <args...>` | General-purpose modify |
-| `ask denotate <id\|uuid> "text"` | Remove annotation |
-| `ask delete <id\|uuid>` | Delete a task |
+| `do add "description"` | Create a new task and print `created task <alias-id>` |
+| `do add depends:<id\|uuid>,<id\|uuid> "description"` | Create task with inline dependencies |
+| `do add priority:H "description"` | Create task with priority |
+| `do add +tag "description"` | Create task with tag |
+| `do na add "description"` | Create a project task without the `+agent` tag |
+| `do list` | List pending tasks only (alias-ID table) |
+| `do na list` | List pending project tasks without the `+agent` tag |
+| `do all` | List all tasks including completed/deleted |
+| `do list +READY` | List only ready tasks |
+| `do list +BLOCKED` | List blocked tasks |
+| `do list +tag` | Filter by tag |
+| `do list started` | List started tasks |
+| `do list limit:N` | Limit results |
+| `do list sort:priority-,urgency-` | Sort by priority then urgency |
+| `do info [id\|uuid]` | Show task details, or the current started task if no selector is provided |
+| `do annotate <id\|uuid> "note"` | Add annotation |
+| `do start <id\|uuid>` | Start working on a task |
+| `do stop <id\|uuid>` | Stop work on a task |
+| `do done <id\|uuid>` | Mark task complete |
+| `do priority <id\|uuid> H\|M\|L` | Set priority |
+| `do tag <id\|uuid> +tag` | Add tag |
+| `do tag <id\|uuid> -tag` | Remove tag |
+| `do dep add <id\|uuid> <dep-id\|dep-uuid>` | Add dependency |
+| `do dep rm <id\|uuid> <dep-id\|dep-uuid>` | Remove dependency |
+| `do dep list <id\|uuid>` | List dependencies |
+| `do urgency` | List tasks by urgency |
+| `do modify <id\|uuid> <args...>` | General-purpose modify |
+| `do denotate <id\|uuid> "text"` | Remove annotation |
+| `do delete <id\|uuid>` | Delete a task |
### Examples
```sh
# Create a task
-ask add priority:H "Implement new feature"
+do add priority:H "Implement new feature"
# Create a non-agent task
-ask na add "Follow up manually"
+do na add "Follow up manually"
# Create a task with dependencies
-ask add +cli depends:0,1 "Implement dependent feature"
+do add +cli depends:0,1 "Implement dependent feature"
# List tasks
-ask list +READY limit:5
+do list +READY limit:5
# List non-agent tasks
-ask no-agent list
+do no-agent list
# Show alias and UUID for a task
-ask info 0
+do info 0
# Show a non-agent task
-ask na info 0
+do na info 0
# Start working
-ask start 0
+do start 0
# Done
-ask done 0
+do done 0
```
## Hexai Action (TUI)
diff --git a/integrationtests/ask_scope_test.go b/integrationtests/do_scope_test.go
index a328881..f24f5ca 100644
--- a/integrationtests/ask_scope_test.go
+++ b/integrationtests/do_scope_test.go
@@ -13,7 +13,7 @@ import (
"codeberg.org/snonux/hexai/internal/askcli"
)
-func scopedAskArgs(scopePrefix string, args ...string) []string {
+func scopedDoArgs(scopePrefix string, args ...string) []string {
if strings.TrimSpace(scopePrefix) == "" {
return append([]string(nil), args...)
}
@@ -22,28 +22,28 @@ func scopedAskArgs(scopePrefix string, args ...string) []string {
}
func createTaskInScope(ctx context.Context, scopePrefix, desc string) (taskInfo, error) {
- stdout, stderr, code := runAsk(ctx, scopedAskArgs(scopePrefix, "add", "+integrationtest", desc))
+ stdout, stderr, code := runDo(ctx, scopedDoArgs(scopePrefix, "add", "+integrationtest", desc))
if code != 0 {
return taskInfo{}, fmt.Errorf("create task failed (code %d): stdout=%s stderr=%s", code, stdout.String(), stderr.String())
}
id := extractTaskIDFromAddOutput(stdout.String())
if id == "" {
- return taskInfo{}, fmt.Errorf("could not extract task ID from ask add output: %s", stdout.String())
+ return taskInfo{}, fmt.Errorf("could not extract task ID from do add output: %s", stdout.String())
}
info, ok := getTaskInfoInScope(ctx, scopePrefix, id)
if !ok {
- return taskInfo{}, fmt.Errorf("could not resolve task ID %q after ask %s add", id, scopePrefix)
+ return taskInfo{}, fmt.Errorf("could not resolve task ID %q after do %s add", id, scopePrefix)
}
if info.UUID == "" {
- return taskInfo{}, fmt.Errorf("ask %s info %q did not return a UUID", scopePrefix, id)
+ return taskInfo{}, fmt.Errorf("do %s info %q did not return a UUID", scopePrefix, id)
}
return info, nil
}
func getTaskInfoInScope(ctx context.Context, scopePrefix, selector string) (taskInfo, bool) {
- stdout, _, code := runAsk(ctx, scopedAskArgs(scopePrefix, "info", selector))
+ stdout, _, code := runDo(ctx, scopedDoArgs(scopePrefix, "info", selector))
if code != 0 {
return taskInfo{}, false
}
@@ -143,28 +143,28 @@ func TestNoAgentListSeparatesScopedTasks(t *testing.T) {
}
defer deleteTask(ctx, noAgentInfo.UUID)
- stdout, stderr, code := runAsk(ctx, []string{"list"})
+ stdout, stderr, code := runDo(ctx, []string{"list"})
if code != 0 {
- t.Fatalf("ask list failed with code %d: stdout=%s stderr=%s", code, stdout.String(), stderr.String())
+ t.Fatalf("do list failed with code %d: stdout=%s stderr=%s", code, stdout.String(), stderr.String())
}
if !strings.Contains(stdout.String(), agentDesc) {
- t.Fatalf("ask list should contain agent task %q: %s", agentDesc, stdout.String())
+ t.Fatalf("do list should contain agent task %q: %s", agentDesc, stdout.String())
}
if strings.Contains(stdout.String(), noAgentDesc) {
- t.Fatalf("ask list should not contain no-agent task %q: %s", noAgentDesc, stdout.String())
+ t.Fatalf("do list should not contain no-agent task %q: %s", noAgentDesc, stdout.String())
}
for _, prefix := range []string{"na", "no-agent"} {
t.Run(prefix, func(t *testing.T) {
- scopedStdout, scopedStderr, scopedCode := runAsk(ctx, []string{prefix, "list"})
+ scopedStdout, scopedStderr, scopedCode := runDo(ctx, []string{prefix, "list"})
if scopedCode != 0 {
- t.Fatalf("ask %s list failed with code %d: stdout=%s stderr=%s", prefix, scopedCode, scopedStdout.String(), scopedStderr.String())
+ t.Fatalf("do %s list failed with code %d: stdout=%s stderr=%s", prefix, scopedCode, scopedStdout.String(), scopedStderr.String())
}
if !strings.Contains(scopedStdout.String(), noAgentDesc) {
- t.Fatalf("ask %s list should contain no-agent task %q: %s", prefix, noAgentDesc, scopedStdout.String())
+ t.Fatalf("do %s list should contain no-agent task %q: %s", prefix, noAgentDesc, scopedStdout.String())
}
if strings.Contains(scopedStdout.String(), agentDesc) {
- t.Fatalf("ask %s list should not contain agent task %q: %s", prefix, agentDesc, scopedStdout.String())
+ t.Fatalf("do %s list should not contain agent task %q: %s", prefix, agentDesc, scopedStdout.String())
}
})
}
@@ -182,9 +182,9 @@ func TestNoAgentSelectorCommandsUseScopedTasks(t *testing.T) {
}
defer deleteTask(ctx, info.UUID)
- _, stderr, code := runAsk(ctx, []string{"info", info.ID})
+ _, stderr, code := runDo(ctx, []string{"info", info.ID})
if code == 0 {
- t.Fatalf("ask info %s unexpectedly succeeded outside no-agent scope", info.ID)
+ t.Fatalf("do info %s unexpectedly succeeded outside no-agent scope", info.ID)
}
if !strings.Contains(stderr.String(), "current scope") {
t.Fatalf("stderr = %q, want current-scope guidance", stderr.String())
@@ -192,19 +192,19 @@ func TestNoAgentSelectorCommandsUseScopedTasks(t *testing.T) {
for _, prefix := range []string{"na", "no-agent"} {
t.Run(prefix, func(t *testing.T) {
- stdout, scopedStderr, scopedCode := runAsk(ctx, []string{prefix, "info", info.ID})
+ stdout, scopedStderr, scopedCode := runDo(ctx, []string{prefix, "info", info.ID})
if scopedCode != 0 {
- t.Fatalf("ask %s info failed with code %d: stdout=%s stderr=%s", prefix, scopedCode, stdout.String(), scopedStderr.String())
+ t.Fatalf("do %s info failed with code %d: stdout=%s stderr=%s", prefix, scopedCode, stdout.String(), scopedStderr.String())
}
if !strings.Contains(stdout.String(), "UUID: "+info.UUID) {
- t.Fatalf("ask %s info output missing UUID %q: %s", prefix, info.UUID, stdout.String())
+ t.Fatalf("do %s info output missing UUID %q: %s", prefix, info.UUID, stdout.String())
}
})
}
- stdout, stderr, code := runAsk(ctx, []string{"na", "done", info.ID})
+ stdout, stderr, code := runDo(ctx, []string{"na", "done", info.ID})
if code != 0 {
- t.Fatalf("ask na done failed with code %d: stdout=%s stderr=%s", code, stdout.String(), stderr.String())
+ t.Fatalf("do na done failed with code %d: stdout=%s stderr=%s", code, stdout.String(), stderr.String())
}
task, err := exportTaskByUUID(ctx, info.UUID)
@@ -234,9 +234,9 @@ func TestNoAgentCompleteUUIDsUsesScopedTasks(t *testing.T) {
}
defer deleteTask(ctx, noAgentInfo.UUID)
- defaultStdout, defaultStderr, defaultCode := runAsk(ctx, []string{"complete-uuids"})
+ defaultStdout, defaultStderr, defaultCode := runDo(ctx, []string{"complete-uuids"})
if defaultCode != 0 {
- t.Fatalf("ask complete-uuids failed with code %d: stdout=%s stderr=%s", defaultCode, defaultStdout.String(), defaultStderr.String())
+ t.Fatalf("do complete-uuids failed with code %d: stdout=%s stderr=%s", defaultCode, defaultStdout.String(), defaultStderr.String())
}
if !hasSelectorLine(defaultStdout.String(), agentAlias) || !hasSelectorLine(defaultStdout.String(), agentUUID) {
t.Fatalf("default complete-uuids should contain agent selectors: %s", defaultStdout.String())
@@ -247,15 +247,15 @@ func TestNoAgentCompleteUUIDsUsesScopedTasks(t *testing.T) {
for _, prefix := range []string{"na", "no-agent"} {
t.Run(prefix, func(t *testing.T) {
- stdout, stderr, code := runAsk(ctx, []string{prefix, "complete-uuids"})
+ stdout, stderr, code := runDo(ctx, []string{prefix, "complete-uuids"})
if code != 0 {
- t.Fatalf("ask %s complete-uuids failed with code %d: stdout=%s stderr=%s", prefix, code, stdout.String(), stderr.String())
+ t.Fatalf("do %s complete-uuids failed with code %d: stdout=%s stderr=%s", prefix, code, stdout.String(), stderr.String())
}
if !hasSelectorLine(stdout.String(), noAgentInfo.ID) || !hasSelectorLine(stdout.String(), noAgentInfo.UUID) {
- t.Fatalf("ask %s complete-uuids should contain no-agent selectors: %s", prefix, stdout.String())
+ t.Fatalf("do %s complete-uuids should contain no-agent selectors: %s", prefix, stdout.String())
}
if hasSelectorLine(stdout.String(), agentAlias) || hasSelectorLine(stdout.String(), agentUUID) {
- t.Fatalf("ask %s complete-uuids should not contain agent selectors: %s", prefix, stdout.String())
+ t.Fatalf("do %s complete-uuids should not contain agent selectors: %s", prefix, stdout.String())
}
})
}
diff --git a/integrationtests/ask_test.go b/integrationtests/do_test.go
index 0ebdb01..8462f3f 100644
--- a/integrationtests/ask_test.go
+++ b/integrationtests/do_test.go
@@ -44,12 +44,12 @@ func findRepoRoot() string {
return ""
}
-func askBinaryPath() string {
- return filepath.Join(repoRoot, "cmd", "ask", "ask")
+func doBinaryPath() string {
+ return filepath.Join(repoRoot, "cmd", "do", "do")
}
-func runAsk(ctx context.Context, args []string) (stdout, stderr bytes.Buffer, exitCode int) {
- cmd := exec.CommandContext(ctx, askBinaryPath(), args...)
+func runDo(ctx context.Context, args []string) (stdout, stderr bytes.Buffer, exitCode int) {
+ cmd := exec.CommandContext(ctx, doBinaryPath(), args...)
cmd.Dir = repoRoot
cmd.Stdout = &stdout
cmd.Stderr = &stderr
@@ -64,10 +64,10 @@ func runAsk(ctx context.Context, args []string) (stdout, stderr bytes.Buffer, ex
return stdout, stderr, ee.ExitCode()
}
-// runAskWithStdin runs ask with the given stdin. Only use this for commands
+// runDoWithStdin runs do with the given stdin. Only use this for commands
// that actually forward stdin to taskwarrior (currently only: delete).
-func runAskWithStdin(ctx context.Context, args []string, stdin string) (stdout, stderr bytes.Buffer, exitCode int) {
- cmd := exec.CommandContext(ctx, askBinaryPath(), args...)
+func runDoWithStdin(ctx context.Context, args []string, stdin string) (stdout, stderr bytes.Buffer, exitCode int) {
+ cmd := exec.CommandContext(ctx, doBinaryPath(), args...)
cmd.Dir = repoRoot
cmd.Stdin = strings.NewReader(stdin)
cmd.Stdout = &stdout
@@ -116,23 +116,23 @@ func runTaskWithStdin(ctx context.Context, args []string, stdin string) (stdout,
return stdout, stderr, ee.ExitCode()
}
-// createTask creates a new task via ask add and returns its UUID.
-// ask add prints a human-facing created-task message, so we resolve the created UUID via ask info.
+// createTask creates a new task via do add and returns its UUID.
+// do add prints a human-facing created-task message, so we resolve the created UUID via do info.
func createTask(ctx context.Context, desc string) (string, error) {
- stdout, stderr, code := runAsk(ctx, []string{"add", "+integrationtest", desc})
+ stdout, stderr, code := runDo(ctx, []string{"add", "+integrationtest", desc})
if code != 0 {
return "", fmt.Errorf("create task failed (code %d): stdout=%s stderr=%s", code, stdout.String(), stderr.String())
}
id := extractTaskIDFromAddOutput(stdout.String())
if id == "" {
- return "", fmt.Errorf("could not extract task ID from ask add output: %s", stdout.String())
+ return "", fmt.Errorf("could not extract task ID from do add output: %s", stdout.String())
}
info, ok := getTaskInfoFast(ctx, id)
if !ok {
- return "", fmt.Errorf("could not resolve task ID %q after ask add", id)
+ return "", fmt.Errorf("could not resolve task ID %q after do add", id)
}
if info.UUID == "" {
- return "", fmt.Errorf("ask info %q did not return a UUID", id)
+ return "", fmt.Errorf("do info %q did not return a UUID", id)
}
return info.UUID, nil
}
@@ -241,16 +241,16 @@ func parseTaskInfoText(output string, uuid string) taskInfo {
}
func getTaskInfoFast(ctx context.Context, uuid string) (taskInfo, bool) {
- stdout, _, code := runAsk(ctx, []string{"info", uuid})
+ stdout, _, code := runDo(ctx, []string{"info", uuid})
if code != 0 {
return taskInfo{}, false
}
return parseTaskInfoText(stdout.String(), uuid), true
}
-// getTaskInfoRaw returns the raw text output of ask info for a given UUID.
+// getTaskInfoRaw returns the raw text output of do info for a given UUID.
func getTaskInfoRaw(ctx context.Context, uuid string) (string, bool) {
- stdout, _, code := runAsk(ctx, []string{"info", uuid})
+ stdout, _, code := runDo(ctx, []string{"info", uuid})
if code != 0 {
return "", false
}
@@ -272,7 +272,7 @@ func mustTaskAlias(t *testing.T, ctx context.Context, uuid string) string {
func aliasCachePath(t *testing.T, cacheRoot string) string {
t.Helper()
- return filepath.Join(cacheRoot, "hexai", "ask", "task-aliases-v2.json")
+ return filepath.Join(cacheRoot, "hexai", "do", "task-aliases-v2.json")
}
// cleanupOrphanedIntegrationTasks deletes any tasks with the +integrationtest
@@ -306,11 +306,11 @@ func TestMain(m *testing.M) {
os.Exit(1)
}
// Always rebuild the binary so tests reflect the current source.
- askBin := askBinaryPath()
- cmd := exec.Command("go", "build", "-o", askBin, "./cmd/ask/")
+ doBin := doBinaryPath()
+ cmd := exec.Command("go", "build", "-o", doBin, "./cmd/do/")
cmd.Dir = repoRoot
if out, err := cmd.CombinedOutput(); err != nil {
- fmt.Fprintf(os.Stderr, "failed to build ask binary: %v\n%s\n", err, out)
+ fmt.Fprintf(os.Stderr, "failed to build do binary: %v\n%s\n", err, out)
os.Exit(1)
}
// Remove any tasks left over from previous integration test runs to avoid
@@ -342,37 +342,37 @@ func TestAdd(t *testing.T) {
}
}
-// TestAddReturnsAlias verifies that ask add outputs the human-facing alias ID in its creation message.
+// TestAddReturnsAlias verifies that do add outputs the human-facing alias ID in its creation message.
func TestAddReturnsAlias(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
- stdout, _, code := runAsk(ctx, []string{"add", "+integrationtest", "uuid format check"})
+ stdout, _, code := runDo(ctx, []string{"add", "+integrationtest", "uuid format check"})
if code != 0 {
- t.Fatalf("ask add failed with code %d", code)
+ t.Fatalf("do add failed with code %d", code)
}
rawOutput := strings.TrimSpace(stdout.String())
id := extractTaskIDFromAddOutput(rawOutput)
info, ok := getTaskInfoFast(ctx, id)
if !ok {
- t.Fatalf("ask info %q failed after add", id)
+ t.Fatalf("do info %q failed after add", id)
}
defer deleteTask(ctx, info.UUID)
if id == "" {
- t.Fatal("ask add returned an empty task ID")
+ t.Fatal("do add returned an empty task ID")
}
if rawOutput != "created task "+id {
- t.Fatalf("ask add output = %q, want %q", rawOutput, "created task "+id)
+ t.Fatalf("do add output = %q, want %q", rawOutput, "created task "+id)
}
if uuidFormatRx.MatchString(id) {
- t.Fatalf("ask add output %q leaked a UUID, want alias ID", id)
+ t.Fatalf("do add output %q leaked a UUID, want alias ID", id)
}
if info.ID != id {
- t.Fatalf("ask info ID = %q, want %q", info.ID, id)
+ t.Fatalf("do info ID = %q, want %q", info.ID, id)
}
if !uuidFormatRx.MatchString(info.UUID) {
- t.Fatalf("ask info UUID = %q, want valid UUID", info.UUID)
+ t.Fatalf("do info UUID = %q, want valid UUID", info.UUID)
}
}
@@ -396,7 +396,7 @@ func TestAddWithDependsModifier(t *testing.T) {
dep1Alias := mustTaskAlias(t, ctx, dep1UUID)
dep2Alias := mustTaskAlias(t, ctx, dep2UUID)
- stdout, stderr, code := runAsk(ctx, []string{
+ stdout, stderr, code := runDo(ctx, []string{
"add",
"+integrationtest",
"depends:" + dep1Alias + "," + dep2Alias,
@@ -408,13 +408,13 @@ func TestAddWithDependsModifier(t *testing.T) {
"depends",
})
if code != 0 {
- t.Fatalf("ask add with depends modifier failed with code %d: stdout=%s stderr=%s", code, stdout.String(), stderr.String())
+ t.Fatalf("do add with depends modifier failed with code %d: stdout=%s stderr=%s", code, stdout.String(), stderr.String())
}
id := extractTaskIDFromAddOutput(stdout.String())
info, ok := getTaskInfoFast(ctx, id)
if !ok {
- t.Fatalf("ask info %q failed after add", id)
+ t.Fatalf("do info %q failed after add", id)
}
defer deleteTask(ctx, info.UUID)
@@ -439,7 +439,7 @@ func TestList(t *testing.T) {
}
defer deleteTask(ctx, uuid)
- stdout, _, code := runAsk(ctx, []string{"list"})
+ stdout, _, code := runDo(ctx, []string{"list"})
if code != 0 {
t.Fatalf("list failed with code %d: %s", code, stdout.String())
}
@@ -465,7 +465,7 @@ func TestAll(t *testing.T) {
}
defer deleteTask(ctx, uuid)
- stdout, _, code := runAsk(ctx, []string{"all"})
+ stdout, _, code := runDo(ctx, []string{"all"})
if code != 0 {
t.Fatalf("all failed with code %d: %s", code, stdout.String())
}
@@ -484,7 +484,7 @@ func TestReady(t *testing.T) {
}
defer deleteTask(ctx, uuid)
- stdout, _, code := runAsk(ctx, []string{"ready"})
+ stdout, _, code := runDo(ctx, []string{"ready"})
if code != 0 {
t.Fatalf("ready failed with code %d: %s", code, stdout.String())
}
@@ -553,10 +553,10 @@ func TestInfoShowsAllDependencies(t *testing.T) {
}
defer deleteTask(ctx, dependent)
- if stdout, stderr, code := runAsk(ctx, []string{"dep", "add", dependent, dependency2}); code != 0 {
+ if stdout, stderr, code := runDo(ctx, []string{"dep", "add", dependent, dependency2}); code != 0 {
t.Fatalf("dep add for second dependency failed with code %d: stdout=%s stderr=%s", code, stdout.String(), stderr.String())
}
- if stdout, stderr, code := runAsk(ctx, []string{"dep", "add", dependent, dependency1}); code != 0 {
+ if stdout, stderr, code := runDo(ctx, []string{"dep", "add", dependent, dependency1}); code != 0 {
t.Fatalf("dep add for first dependency failed with code %d: stdout=%s stderr=%s", code, stdout.String(), stderr.String())
}
@@ -591,7 +591,7 @@ func TestAnnotate(t *testing.T) {
defer deleteTask(ctx, uuid)
note := "this is a test annotation"
- stdout, _, code := runAsk(ctx, []string{"annotate", uuid, note})
+ stdout, _, code := runDo(ctx, []string{"annotate", uuid, note})
if code != 0 {
t.Fatalf("annotate failed with code %d: %s", code, stdout.String())
}
@@ -615,7 +615,7 @@ func TestStart(t *testing.T) {
}
defer deleteTask(ctx, uuid)
- stdout, _, code := runAsk(ctx, []string{"start", uuid})
+ stdout, _, code := runDo(ctx, []string{"start", uuid})
if code != 0 {
t.Fatalf("start failed with code %d: %s", code, stdout.String())
}
@@ -642,9 +642,9 @@ func TestStop(t *testing.T) {
}
defer deleteTask(ctx, uuid)
- runAsk(ctx, []string{"start", uuid})
+ runDo(ctx, []string{"start", uuid})
- stdout, _, code := runAsk(ctx, []string{"stop", uuid})
+ stdout, _, code := runDo(ctx, []string{"stop", uuid})
if code != 0 {
t.Fatalf("stop failed with code %d: %s", code, stdout.String())
}
@@ -670,7 +670,7 @@ func TestDone(t *testing.T) {
t.Fatalf("failed to create task: %v", err)
}
- stdout, _, code := runAsk(ctx, []string{"done", uuid})
+ stdout, _, code := runDo(ctx, []string{"done", uuid})
if code != 0 {
t.Fatalf("done failed with code %d: %s", code, stdout.String())
}
@@ -696,7 +696,7 @@ func TestPriority(t *testing.T) {
}
defer deleteTask(ctx, uuid)
- stdout, _, code := runAsk(ctx, []string{"priority", uuid, "H"})
+ stdout, _, code := runDo(ctx, []string{"priority", uuid, "H"})
if code != 0 {
t.Fatalf("priority failed with code %d: %s", code, stdout.String())
}
@@ -720,7 +720,7 @@ func TestTag(t *testing.T) {
}
defer deleteTask(ctx, uuid)
- stdout, _, code := runAsk(ctx, []string{"tag", uuid, "+cli"})
+ stdout, _, code := runDo(ctx, []string{"tag", uuid, "+cli"})
if code != 0 {
t.Fatalf("tag add failed with code %d: %s", code, stdout.String())
}
@@ -740,7 +740,7 @@ func TestTag(t *testing.T) {
t.Errorf("tag cli not found on task: %+v", ti.Tags)
}
- runAsk(ctx, []string{"tag", uuid, "-cli"})
+ runDo(ctx, []string{"tag", uuid, "-cli"})
ti2, _ := getTaskInfoFast(ctx, uuid)
for _, tg := range ti2.Tags {
@@ -767,7 +767,7 @@ func TestDepAdd(t *testing.T) {
}
defer deleteTask(ctx, uuid2)
- stdout, _, code := runAsk(ctx, []string{"dep", "add", uuid2, uuid1})
+ stdout, _, code := runDo(ctx, []string{"dep", "add", uuid2, uuid1})
if code != 0 {
t.Fatalf("dep add failed with code %d: %s", code, stdout.String())
}
@@ -807,9 +807,9 @@ func TestDepList(t *testing.T) {
}
defer deleteTask(ctx, uuid2)
- runAsk(ctx, []string{"dep", "add", uuid2, uuid1})
+ runDo(ctx, []string{"dep", "add", uuid2, uuid1})
- stdout, _, code := runAsk(ctx, []string{"dep", "list", uuid2})
+ stdout, _, code := runDo(ctx, []string{"dep", "list", uuid2})
if code != 0 {
t.Fatalf("dep list failed with code %d: %s", code, stdout.String())
}
@@ -838,9 +838,9 @@ func TestDepRm(t *testing.T) {
}
defer deleteTask(ctx, uuid2)
- runAsk(ctx, []string{"dep", "add", uuid2, uuid1})
+ runDo(ctx, []string{"dep", "add", uuid2, uuid1})
- stdout, _, code := runAsk(ctx, []string{"dep", "rm", uuid2, uuid1})
+ stdout, _, code := runDo(ctx, []string{"dep", "rm", uuid2, uuid1})
if code != 0 {
t.Fatalf("dep rm failed with code %d: %s", code, stdout.String())
}
@@ -869,7 +869,7 @@ func TestModify(t *testing.T) {
}
defer deleteTask(ctx, uuid)
- stdout, _, code := runAsk(ctx, []string{"modify", uuid, "priority:H"})
+ stdout, _, code := runDo(ctx, []string{"modify", uuid, "priority:H"})
if code != 0 {
t.Fatalf("modify failed with code %d: %s", code, stdout.String())
}
@@ -894,7 +894,7 @@ func TestDenotate(t *testing.T) {
defer deleteTask(ctx, uuid)
note := "annotation to remove"
- runAsk(ctx, []string{"annotate", uuid, note})
+ runDo(ctx, []string{"annotate", uuid, note})
// Verify the annotation is present before denotating.
rawBefore, _ := getTaskInfoRaw(ctx, uuid)
@@ -902,7 +902,7 @@ func TestDenotate(t *testing.T) {
t.Fatalf("annotation %q not found before denotate", note)
}
- _, _, code := runAsk(ctx, []string{"denotate", uuid, note})
+ _, _, code := runDo(ctx, []string{"denotate", uuid, note})
if code != 0 {
t.Fatalf("denotate returned non-zero code: %d", code)
}
@@ -924,7 +924,7 @@ func TestDelete(t *testing.T) {
}
// delete forwards stdin to taskwarrior for confirmation.
- stdout, _, code := runAskWithStdin(ctx, []string{"delete", uuid}, "yes\n")
+ stdout, _, code := runDoWithStdin(ctx, []string{"delete", uuid}, "yes\n")
if code != 0 {
t.Fatalf("delete failed with code %d: %s", code, stdout.String())
}
@@ -948,7 +948,7 @@ func TestUrgency(t *testing.T) {
}
defer deleteTask(ctx, uuid)
- stdout, _, code := runAsk(ctx, []string{"urgency"})
+ stdout, _, code := runDo(ctx, []string{"urgency"})
if code != 0 {
t.Fatalf("urgency failed with code %d: %s", code, stdout.String())
}
@@ -967,7 +967,7 @@ func TestDefaultCommand(t *testing.T) {
}
defer deleteTask(ctx, uuid)
- stdout, _, code := runAsk(ctx, []string{})
+ stdout, _, code := runDo(ctx, []string{})
if code != 0 {
t.Fatalf("default command (list) failed with code %d: %s", code, stdout.String())
}
@@ -980,7 +980,7 @@ func TestHelp(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
- stdout, _, code := runAsk(ctx, []string{"help"})
+ stdout, _, code := runDo(ctx, []string{"help"})
if code != 0 {
t.Fatalf("help returned non-zero exit code %d", code)
}
@@ -996,13 +996,13 @@ func TestFish(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
- stdout, stderr, code := runAsk(ctx, []string{"fish"})
+ stdout, stderr, code := runDo(ctx, []string{"fish"})
if code != 0 {
t.Fatalf("fish returned non-zero exit code %d: stderr=%s", code, stderr.String())
}
out := stdout.String()
for _, fragment := range []string{
- "# Source with: ask fish | source",
+ "# Source with: do fish | source",
"complete -c",
"complete-uuids",
"annotate",
@@ -1021,14 +1021,14 @@ func TestFishRejectsExtraArgs(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
- stdout, stderr, code := runAsk(ctx, []string{"fish", "extra"})
+ stdout, stderr, code := runDo(ctx, []string{"fish", "extra"})
if code == 0 {
t.Fatalf("expected non-zero exit code for fish extra args, got 0")
}
if stdout.Len() != 0 {
t.Errorf("fish with extra args wrote unexpected stdout: %s", stdout.String())
}
- if !strings.Contains(stderr.String(), "usage: ask fish") {
+ if !strings.Contains(stderr.String(), "usage: do fish") {
t.Errorf("fish with extra args stderr missing usage text: %s", stderr.String())
}
}
@@ -1044,7 +1044,7 @@ func TestCompleteUUIDs(t *testing.T) {
}
defer deleteTask(ctx, uuid)
- stdout, stderr, code := runAsk(ctx, []string{"complete-uuids"})
+ stdout, stderr, code := runDo(ctx, []string{"complete-uuids"})
if code != 0 {
t.Fatalf("complete-uuids returned non-zero exit code %d: stderr=%s", code, stderr.String())
}
@@ -1079,7 +1079,7 @@ func TestAliasSelectorsAcrossUUIDCommands(t *testing.T) {
}
note := "integration alias annotation"
- stdout, _, code := runAsk(ctx, []string{"annotate", alias, note})
+ stdout, _, code := runDo(ctx, []string{"annotate", alias, note})
if code != 0 {
t.Fatalf("annotate by alias failed with code %d: %s", code, stdout.String())
}
@@ -1093,10 +1093,10 @@ func TestAliasSelectorsAcrossUUIDCommands(t *testing.T) {
}
note2 := "remove me via alias"
- if _, _, code = runAsk(ctx, []string{"annotate", alias, note2}); code != 0 {
+ if _, _, code = runDo(ctx, []string{"annotate", alias, note2}); code != 0 {
t.Fatalf("setup annotate for denotate failed with code %d", code)
}
- stdout, _, code = runAsk(ctx, []string{"denotate", alias, note2})
+ stdout, _, code = runDo(ctx, []string{"denotate", alias, note2})
if code != 0 {
t.Fatalf("denotate by alias failed with code %d: %s", code, stdout.String())
}
@@ -1105,7 +1105,7 @@ func TestAliasSelectorsAcrossUUIDCommands(t *testing.T) {
t.Fatalf("annotation %q still present after alias denotate: %s", note2, raw)
}
- stdout, _, code = runAsk(ctx, []string{"start", alias})
+ stdout, _, code = runDo(ctx, []string{"start", alias})
if code != 0 {
t.Fatalf("start by alias failed with code %d: %s", code, stdout.String())
}
@@ -1114,7 +1114,7 @@ func TestAliasSelectorsAcrossUUIDCommands(t *testing.T) {
t.Fatalf("task not started after alias start: %+v", ti)
}
- stdout, _, code = runAsk(ctx, []string{"stop", alias})
+ stdout, _, code = runDo(ctx, []string{"stop", alias})
if code != 0 {
t.Fatalf("stop by alias failed with code %d: %s", code, stdout.String())
}
@@ -1123,7 +1123,7 @@ func TestAliasSelectorsAcrossUUIDCommands(t *testing.T) {
t.Fatalf("task not stopped after alias stop: %+v", ti)
}
- stdout, _, code = runAsk(ctx, []string{"priority", alias, "H"})
+ stdout, _, code = runDo(ctx, []string{"priority", alias, "H"})
if code != 0 {
t.Fatalf("priority by alias failed with code %d: %s", code, stdout.String())
}
@@ -1132,7 +1132,7 @@ func TestAliasSelectorsAcrossUUIDCommands(t *testing.T) {
t.Fatalf("task priority not updated after alias priority: %+v", ti)
}
- stdout, _, code = runAsk(ctx, []string{"modify", alias, "priority:L"})
+ stdout, _, code = runDo(ctx, []string{"modify", alias, "priority:L"})
if code != 0 {
t.Fatalf("modify by alias failed with code %d: %s", code, stdout.String())
}
@@ -1141,7 +1141,7 @@ func TestAliasSelectorsAcrossUUIDCommands(t *testing.T) {
t.Fatalf("task priority not updated after alias modify: %+v", ti)
}
- stdout, _, code = runAsk(ctx, []string{"tag", alias, "+aliascheck"})
+ stdout, _, code = runDo(ctx, []string{"tag", alias, "+aliascheck"})
if code != 0 {
t.Fatalf("tag by alias failed with code %d: %s", code, stdout.String())
}
@@ -1157,12 +1157,12 @@ func TestAliasSelectorsAcrossUUIDCommands(t *testing.T) {
defer deleteTask(ctx, depUUID)
depAlias := mustTaskAlias(t, ctx, depUUID)
- stdout, _, code = runAsk(ctx, []string{"dep", "add", alias, depAlias})
+ stdout, _, code = runDo(ctx, []string{"dep", "add", alias, depAlias})
if code != 0 {
t.Fatalf("dep add by alias failed with code %d: %s", code, stdout.String())
}
- stdout, _, code = runAsk(ctx, []string{"dep", "list", alias})
+ stdout, _, code = runDo(ctx, []string{"dep", "list", alias})
if code != 0 {
t.Fatalf("dep list by alias failed with code %d: %s", code, stdout.String())
}
@@ -1170,11 +1170,11 @@ func TestAliasSelectorsAcrossUUIDCommands(t *testing.T) {
t.Fatalf("dep list by alias output = %q, want alias %q without raw UUID", stdout.String(), depAlias)
}
- stdout, _, code = runAsk(ctx, []string{"dep", "rm", alias, depAlias})
+ stdout, _, code = runDo(ctx, []string{"dep", "rm", alias, depAlias})
if code != 0 {
t.Fatalf("dep rm by alias failed with code %d: %s", code, stdout.String())
}
- stdout, _, code = runAsk(ctx, []string{"dep", "list", alias})
+ stdout, _, code = runDo(ctx, []string{"dep", "list", alias})
if code != 0 {
t.Fatalf("dep list after rm failed with code %d: %s", code, stdout.String())
}
@@ -1187,7 +1187,7 @@ func TestAliasSelectorsAcrossUUIDCommands(t *testing.T) {
t.Fatalf("failed to create done task: %v", err)
}
doneAlias := mustTaskAlias(t, ctx, doneUUID)
- stdout, _, code = runAsk(ctx, []string{"done", doneAlias})
+ stdout, _, code = runDo(ctx, []string{"done", doneAlias})
if code != 0 {
t.Fatalf("done by alias failed with code %d: %s", code, stdout.String())
}
@@ -1202,7 +1202,7 @@ func TestAliasSelectorsAcrossUUIDCommands(t *testing.T) {
t.Fatalf("failed to create delete task: %v", err)
}
deleteAlias := mustTaskAlias(t, ctx, deleteUUID)
- stdout, _, code = runAskWithStdin(ctx, []string{"delete", deleteAlias}, "yes\n")
+ stdout, _, code = runDoWithStdin(ctx, []string{"delete", deleteAlias}, "yes\n")
if code != 0 {
t.Fatalf("delete by alias failed with code %d: %s", code, stdout.String())
}
@@ -1246,7 +1246,7 @@ func TestAliasCachePrunesExpiredEntriesOlderThan120Days(t *testing.T) {
t.Fatalf("WriteFile(%s): %v", cachePath, err)
}
- stdout, stderr, code := runAsk(ctx, []string{"info", uuid})
+ stdout, stderr, code := runDo(ctx, []string{"info", uuid})
if code != 0 {
t.Fatalf("info failed with code %d: stdout=%s stderr=%s", code, stdout.String(), stderr.String())
}
@@ -1273,7 +1273,7 @@ func TestUnknownCommand(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
- _, stderr, code := runAsk(ctx, []string{"notacommand"})
+ _, stderr, code := runDo(ctx, []string{"notacommand"})
if code == 0 {
t.Fatalf("expected non-zero exit code for unknown command, got 0")
}
diff --git a/internal/askcli/command_add.go b/internal/askcli/command_add.go
index b94fe89..d2fb2ea 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: ask add requires a description\n")
+ _, _ = io.WriteString(stderr, "error: do 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: ask add requires a description\n")
+ _, _ = io.WriteString(stderr, "error: do 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("ask add depends:<id|uuid>[,<id|uuid>...] requires at least one dependency ID or UUID")
+ return nil, fmt.Errorf("do 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("ask add dependency selector list contains an empty item")
+ return nil, fmt.Errorf("do 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 801d4cf..7356753 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: ask delete requires an ID or UUID argument\n")
+ _, _ = io.WriteString(stderr, "error: do 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 aa28df8..b6fb2b9 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: ask dep requires an operation (add/rm/list) and arguments\n")
+ _, _ = io.WriteString(stderr, "error: do 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: ask dep: unknown operation %q (use add, rm, or list)\n", op)
+ fmt.Fprintf(stderr, "error: do 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: ask dep add/rm requires <id|uuid> <dep-id|dep-uuid>\n")
+ _, _ = io.WriteString(stderr, "error: do 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: ask dep list requires <id|uuid>\n")
+ _, _ = io.WriteString(stderr, "error: do 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 f4ca9e0..401a9e2 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: ask fish")
+ fmt.Fprintln(stderr, "usage: do fish")
return 1, nil
}
binaryPath, err := os.Executable()
if err != nil {
- binaryPath = "ask"
+ binaryPath = "do"
}
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 74b2380..0a07479 100644
--- a/internal/askcli/command_info_add_test.go
+++ b/internal/askcli/command_info_add_test.go
@@ -334,7 +334,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, "ask add depends:<id|uuid>[,<id|uuid>...] requires at least one dependency ID or UUID") {
+ if got := stderr.String(); !strings.Contains(got, "do 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 d8dbf5b..31a3f39 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: ask denotate requires an ID or UUID and text argument\n")
+ _, _ = io.WriteString(stderr, "error: do 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: ask modify requires an ID or UUID and modification args\n")
+ _, _ = io.WriteString(stderr, "error: do 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: ask annotate requires an ID or UUID and note argument\n")
+ _, _ = io.WriteString(stderr, "error: do 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: ask start requires an ID or UUID argument\n")
+ _, _ = io.WriteString(stderr, "error: do 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: ask stop requires an ID or UUID argument\n")
+ _, _ = io.WriteString(stderr, "error: do 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: ask done requires an ID or UUID argument\n")
+ _, _ = io.WriteString(stderr, "error: do 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: ask priority requires an ID or UUID and priority (H/M/L)\n")
+ _, _ = io.WriteString(stderr, "error: do 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: ask tag requires an ID or UUID and +/-tag\n")
+ _, _ = io.WriteString(stderr, "error: do 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 0d8b584..3e30c6c 100644
--- a/internal/askcli/completion.go
+++ b/internal/askcli/completion.go
@@ -54,9 +54,9 @@ func fishAddDependencyModifierCompletionContext(positional []string, current str
return current == "depends" || strings.HasPrefix(current, "depends:")
}
-// FishCompletion returns the default Fish completion script for the ask CLI.
+// FishCompletion returns the default Fish completion script for the do CLI.
func FishCompletion() string {
- return FishCompletionFor("ask")
+ return FishCompletionFor("do")
}
// FishCompletionFor returns a Fish completion script that points to the provided binary path.
@@ -66,30 +66,30 @@ func FishCompletionFor(binaryPath string) string {
writeFishContextFunctions(&b)
writeFishTaskSelectorFunction(&b, binaryPath)
writeFishAddDependencyModifierFunction(&b)
- b.WriteString("complete -c ask -f\n")
- b.WriteString("complete -c ask -s j -l json -d 'Emit JSON output'\n")
+ b.WriteString("complete -c do -f\n")
+ b.WriteString("complete -c do -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"},
} {
- writeFishCompletionLine(&b, "__ask_needs_root_completion", item)
+ writeFishCompletionLine(&b, "__do_needs_root_completion", item)
}
for _, entry := range commandRegistry.rootCompletionEntries() {
item := fishCompletionItem{name: entry.name, description: entry.description}
- writeFishCompletionLine(&b, "__ask_needs_command_completion", item)
+ writeFishCompletionLine(&b, "__do_needs_command_completion", item)
}
for _, item := range askDepCompletionItems {
- writeFishCompletionLine(&b, "__ask_in_dep_context", item)
+ writeFishCompletionLine(&b, "__do_in_dep_context", item)
}
- writeFishUUIDCompletionLine(&b, "__ask_in_uuid_context", "Task selector")
- writeFishUUIDCompletionLine(&b, "__ask_in_dep_uuid_context", "Task selector")
- writeFishFunctionCompletionLine(&b, "__ask_in_add_dep_modifier_context", "__ask_add_dependency_modifiers", "Task dependency")
+ 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")
return b.String()
}
func writeFishPreamble(b *strings.Builder) {
- b.WriteString("# Fish completion for ask.\n")
- b.WriteString("# Source with: ask fish | source\n\n")
+ b.WriteString("# Fish completion for do.\n")
+ b.WriteString("# Source with: do fish | source\n\n")
}
func writeFishContextFunctions(b *strings.Builder) {
@@ -105,7 +105,7 @@ func writeFishContextFunctions(b *strings.Builder) {
}
func writeFishPositionalTokensFunction(b *strings.Builder) {
- b.WriteString("function __ask_positional_tokens\n")
+ b.WriteString("function __do_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")
@@ -121,8 +121,8 @@ func writeFishPositionalTokensFunction(b *strings.Builder) {
}
func writeFishCommandPositionalsFunction(b *strings.Builder) {
- b.WriteString("function __ask_command_positionals\n")
- b.WriteString(" set -l positional (__ask_positional_tokens)\n")
+ b.WriteString("function __do_command_positionals\n")
+ b.WriteString(" set -l positional (__do_positional_tokens)\n")
b.WriteString(" if test (count $positional) -gt 0\n")
b.WriteString(" switch $positional[1]\n")
b.WriteString(" case na no-agent\n")
@@ -139,8 +139,8 @@ func writeFishCommandPositionalsFunction(b *strings.Builder) {
}
func writeFishScopePrefixFunction(b *strings.Builder) {
- b.WriteString("function __ask_scope_prefix\n")
- b.WriteString(" set -l positional (__ask_positional_tokens)\n")
+ b.WriteString("function __do_scope_prefix\n")
+ b.WriteString(" set -l positional (__do_positional_tokens)\n")
b.WriteString(" if test (count $positional) -eq 0\n")
b.WriteString(" return 1\n")
b.WriteString(" end\n")
@@ -156,8 +156,8 @@ func writeFishScopePrefixFunction(b *strings.Builder) {
}
func writeFishNeedsRootCompletionFunction(b *strings.Builder) {
- b.WriteString("function __ask_needs_root_completion\n")
- b.WriteString(" set -l positional (__ask_positional_tokens)\n")
+ b.WriteString("function __do_needs_root_completion\n")
+ b.WriteString(" set -l positional (__do_positional_tokens)\n")
b.WriteString(" if test (count $positional) -eq 0\n")
b.WriteString(" return 0\n")
b.WriteString(" end\n")
@@ -166,8 +166,8 @@ func writeFishNeedsRootCompletionFunction(b *strings.Builder) {
}
func writeFishNeedsCommandCompletionFunction(b *strings.Builder) {
- b.WriteString("function __ask_needs_command_completion\n")
- b.WriteString(" set -l positional (__ask_positional_tokens)\n")
+ b.WriteString("function __do_needs_command_completion\n")
+ b.WriteString(" set -l positional (__do_positional_tokens)\n")
b.WriteString(" if test (count $positional) -eq 0\n")
b.WriteString(" return 0\n")
b.WriteString(" end\n")
@@ -182,8 +182,8 @@ func writeFishNeedsCommandCompletionFunction(b *strings.Builder) {
}
func writeFishDepContextFunction(b *strings.Builder) {
- b.WriteString("function __ask_in_dep_context\n")
- b.WriteString(" set -l positional (__ask_command_positionals)\n")
+ b.WriteString("function __do_in_dep_context\n")
+ b.WriteString(" set -l positional (__do_command_positionals)\n")
b.WriteString(" if test (count $positional) -lt 1\n")
b.WriteString(" return 1\n")
b.WriteString(" end\n")
@@ -195,8 +195,8 @@ func writeFishDepContextFunction(b *strings.Builder) {
}
func writeFishUUIDContextFunction(b *strings.Builder) {
- b.WriteString("function __ask_in_uuid_context\n")
- b.WriteString(" set -l positional (__ask_command_positionals)\n")
+ b.WriteString("function __do_in_uuid_context\n")
+ b.WriteString(" set -l positional (__do_command_positionals)\n")
b.WriteString(" if test (count $positional) -eq 0\n")
b.WriteString(" return 1\n")
b.WriteString(" end\n")
@@ -216,8 +216,8 @@ func writeFishUUIDContextFunction(b *strings.Builder) {
}
func writeFishDepUUIDContextFunction(b *strings.Builder) {
- b.WriteString("function __ask_in_dep_uuid_context\n")
- b.WriteString(" set -l positional (__ask_command_positionals)\n")
+ b.WriteString("function __do_in_dep_uuid_context\n")
+ b.WriteString(" set -l positional (__do_command_positionals)\n")
b.WriteString(" if test (count $positional) -lt 2\n")
b.WriteString(" return 1\n")
b.WriteString(" end\n")
@@ -241,8 +241,8 @@ func writeFishDepUUIDContextFunction(b *strings.Builder) {
}
func writeFishAddDependencyModifierContextFunction(b *strings.Builder) {
- b.WriteString("function __ask_in_add_dep_modifier_context\n")
- b.WriteString(" set -l positional (__ask_command_positionals)\n")
+ b.WriteString("function __do_in_add_dep_modifier_context\n")
+ b.WriteString(" set -l positional (__do_command_positionals)\n")
b.WriteString(" if test (count $positional) -lt 1\n")
b.WriteString(" return 1\n")
b.WriteString(" end\n")
@@ -258,38 +258,38 @@ func writeFishAddDependencyModifierContextFunction(b *strings.Builder) {
}
func writeFishTaskSelectorFunction(b *strings.Builder, binaryPath string) {
- b.WriteString("function __ask_task_selectors\n")
- b.WriteString(" set -l ask_bin ")
+ b.WriteString("function __do_task_selectors\n")
+ b.WriteString(" set -l do_bin ")
b.WriteString(quoteFishString(binaryPath))
b.WriteString("\n")
- b.WriteString(" set -l scope_prefix (__ask_scope_prefix)\n")
+ b.WriteString(" set -l scope_prefix (__do_scope_prefix)\n")
b.WriteString(" set -l cache_key default\n")
b.WriteString(" if test -n \"$scope_prefix\"\n")
b.WriteString(" set cache_key $scope_prefix\n")
b.WriteString(" end\n")
b.WriteString(" set -l now (date +%s)\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(" 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(" return 0\n")
b.WriteString(" end\n")
b.WriteString(" set -l selectors\n")
b.WriteString(" if test -n \"$scope_prefix\"\n")
- b.WriteString(" set selectors (command $ask_bin $scope_prefix complete-uuids 2>/dev/null)\n")
+ b.WriteString(" set selectors (command $do_bin $scope_prefix complete-uuids 2>/dev/null)\n")
b.WriteString(" else\n")
- b.WriteString(" set selectors (command $ask_bin complete-uuids 2>/dev/null)\n")
+ b.WriteString(" set selectors (command $do_bin complete-uuids 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 __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(" 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(" printf '%s\\n' $selectors\n")
b.WriteString("end\n\n")
}
func writeFishAddDependencyModifierFunction(b *strings.Builder) {
- b.WriteString("function __ask_add_dependency_modifiers\n")
+ b.WriteString("function __do_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")
@@ -308,9 +308,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 __ask_task_selectors is "selector\tdescription"; extract
+ // Each item from __do_task_selectors is "selector\tdescription"; extract
// just the selector (before the tab) for matching and output purposes.
- b.WriteString(" for item in (__ask_task_selectors)\n")
+ b.WriteString(" for item in (__do_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")
@@ -328,7 +328,7 @@ func writeFishAddDependencyModifierFunction(b *strings.Builder) {
}
func writeFishCompletionLine(b *strings.Builder, condition string, item fishCompletionItem) {
- b.WriteString("complete -c ask -n '")
+ b.WriteString("complete -c do -n '")
b.WriteString(condition)
b.WriteString("' -a '")
b.WriteString(item.name)
@@ -338,15 +338,15 @@ func writeFishCompletionLine(b *strings.Builder, condition string, item fishComp
}
func writeFishUUIDCompletionLine(b *strings.Builder, condition, description string) {
- b.WriteString("complete -c ask -n '")
+ b.WriteString("complete -c do -n '")
b.WriteString(condition)
- b.WriteString("' -a '(__ask_task_selectors)' -d '")
+ b.WriteString("' -a '(__do_task_selectors)' -d '")
b.WriteString(strings.ReplaceAll(description, "'", "\\'"))
b.WriteString("'\n")
}
func writeFishFunctionCompletionLine(b *strings.Builder, condition, functionName, description string) {
- b.WriteString("complete -c ask -n '")
+ b.WriteString("complete -c do -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 baa3d84..012927d 100644
--- a/internal/askcli/completion_test.go
+++ b/internal/askcli/completion_test.go
@@ -18,38 +18,38 @@ func TestFishCompletion_IncludesCommandsAndExcludesExport(t *testing.T) {
}
}
for _, line := range []string{
- "# 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"`,
+ "# 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"`,
"set -l selectors",
- "set selectors (command $ask_bin complete-uuids 2>/dev/null)",
- "set selectors (command $ask_bin $scope_prefix complete-uuids 2>/dev/null)",
- "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'",
+ "set selectors (command $do_bin complete-uuids 2>/dev/null)",
+ "set selectors (command $do_bin $scope_prefix complete-uuids 2>/dev/null)",
+ "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'",
// The dep modifier function must extract just the selector (before the
// tab) from each tab-separated "selector\tdescription" completion item.
- "for item in (__ask_task_selectors)",
+ "for item in (__do_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, "ask export") {
+ if strings.Contains(script, "do export") {
t.Fatalf("script should not advertise non-existent export command")
}
- if strings.Contains(script, "assets/ask.fish") {
+ if strings.Contains(script, "assets/do.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 ask -n '__ask_in_uuid_context' -a '"+name+"'") {
+ if strings.Contains(script, "complete -c do -n '__do_in_uuid_context' -a '"+name+"'") {
t.Fatalf("script should not hard-code UUID completion item %q", name)
}
}
@@ -136,10 +136,10 @@ func TestFishAddDependencyModifierCompletionContext(t *testing.T) {
}
func TestFishCompletionFor_EmbedsBinaryPath(t *testing.T) {
- script := FishCompletionFor(`/tmp/ask "$HOME"`)
+ script := FishCompletionFor(`/tmp/do "$HOME"`)
for _, line := range []string{
- `set -l ask_bin "/tmp/ask \"\$HOME\""`,
- "set selectors (command $ask_bin complete-uuids 2>/dev/null)",
+ `set -l do_bin "/tmp/do \"\$HOME\""`,
+ "set selectors (command $do_bin complete-uuids 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 eab793b..3167421 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 ask itself.
+// Runner performs CLI work that would otherwise be handled by the do 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("ask")
+ e := NewExecutor("do")
runner = &e
}
return &Dispatcher{runner: runner}
@@ -65,34 +65,34 @@ func (d *Dispatcher) Dispatch(ctx context.Context, args []string, stdin io.Reade
}
func (d *Dispatcher) help(w io.Writer) (int, error) {
- _, _ = io.WriteString(w, "ask - task management CLI\n")
+ _, _ = io.WriteString(w, "do - task management CLI\n")
_, _ = io.WriteString(w, "\nScope prefixes:\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, " 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, "\nSubcommands:\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")
+ _, _ = 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")
return 0, nil
}
func (d *Dispatcher) unknownCommand(w io.Writer, subcommand string) (int, error) {
- fmt.Fprintf(w, "ask: unknown subcommand %q\n", subcommand)
+ fmt.Fprintf(w, "do: unknown subcommand %q\n", subcommand)
return 1, nil
}
diff --git a/internal/askcli/dispatch_test.go b/internal/askcli/dispatch_test.go
index e027b43..90c1b99 100644
--- a/internal/askcli/dispatch_test.go
+++ b/internal/askcli/dispatch_test.go
@@ -23,19 +23,19 @@ func TestDispatcher_Help(t *testing.T) {
t.Fatalf("help returned error: %v", err)
}
output := stdout.String()
- if !strings.Contains(output, "ask - task management CLI") {
+ if !strings.Contains(output, "do - task management CLI") {
t.Fatalf("help missing title: %s", output)
}
- if !strings.Contains(output, "ask na <subcommand...>") || !strings.Contains(output, "ask no-agent <subcommand...>") {
+ if !strings.Contains(output, "do na <subcommand...>") || !strings.Contains(output, "do no-agent <subcommand...>") {
t.Fatalf("help missing no-agent scope prefixes: %s", output)
}
- if !strings.Contains(output, "ask list") {
+ if !strings.Contains(output, "do list") {
t.Fatalf("help missing list subcommand: %s", output)
}
- if !strings.Contains(output, "ask all") {
+ if !strings.Contains(output, "do all") {
t.Fatalf("help missing all subcommand: %s", output)
}
- if !strings.Contains(output, "ask fish") {
+ if !strings.Contains(output, "do fish") {
t.Fatalf("help missing fish subcommand: %s", output)
}
}
@@ -96,8 +96,8 @@ func TestDispatcher_LongHelp(t *testing.T) {
d.Dispatch(context.Background(), []string{"help"}, nil, &stdout, io.Discard)
output := stdout.String()
for _, sub := range []string{"add", "list", "all", "ready", "info", "annotate", "start", "stop", "done", "priority", "tag", "dep", "urgency", "modify", "denotate", "delete", "fish"} {
- if !strings.Contains(output, "ask "+sub) {
- t.Errorf("help missing subcommand: ask %s", sub)
+ if !strings.Contains(output, "do "+sub) {
+ t.Errorf("help missing subcommand: do %s", sub)
}
}
}
@@ -137,7 +137,7 @@ func TestDispatcher_FishSubcommandRejectsExtraArgs(t *testing.T) {
if stdout.Len() != 0 {
t.Fatalf("fish extra args wrote unexpected stdout: %q", stdout.String())
}
- if got := stderr.String(); !strings.Contains(got, "usage: ask fish") {
+ if got := stderr.String(); !strings.Contains(got, "usage: do fish") {
t.Fatalf("fish extra args stderr = %q, want usage", got)
}
}
diff --git a/internal/askcli/formatter.go b/internal/askcli/formatter.go
index d801f8a..fc4a1d9 100644
--- a/internal/askcli/formatter.go
+++ b/internal/askcli/formatter.go
@@ -168,7 +168,7 @@ func FormatSuccess(alias string) string {
return fmt.Sprintf("ok %s\n", alias)
}
-// FormatCreatedTask returns the success string written to stdout after ask add creates a task.
+// FormatCreatedTask returns the success string written to stdout after do add creates a task.
func FormatCreatedTask(alias string) string {
return fmt.Sprintf("created task %s\n", alias)
}
diff --git a/internal/askcli/task_alias_cache.go b/internal/askcli/task_alias_cache.go
index e89dbb5..ff682d6 100644
--- a/internal/askcli/task_alias_cache.go
+++ b/internal/askcli/task_alias_cache.go
@@ -114,7 +114,7 @@ func taskAliasCachePath() (string, error) {
// v2 uses reversed alias strings (e.g. "10" instead of "01") so that the
// first character varies more often, improving shell auto-completion. The
// old v1 file is intentionally abandoned so the mapping starts fresh.
- return filepath.Join(dir, "ask", "task-aliases-v2.json"), nil
+ return filepath.Join(dir, "do", "task-aliases-v2.json"), nil
}
func (c *taskAliasCache) validate() error {
diff --git a/internal/askcli/taskexec.go b/internal/askcli/taskexec.go
index a1ede37..e3915d9 100644
--- a/internal/askcli/taskexec.go
+++ b/internal/askcli/taskexec.go
@@ -16,7 +16,7 @@ type repoTopLevelDetector func(context.Context) (string, error)
type commandRunner func(context.Context, string, []string, io.Reader, io.Writer, io.Writer) error
-// Executor encapsulates how ask communicates with the Taskwarrior binary.
+// Executor encapsulates how the do CLI communicates with the Taskwarrior binary.
type Executor struct {
commandName string
findBinary binaryFinder
@@ -86,14 +86,14 @@ func (e Executor) Run(ctx context.Context, args []string, stdin io.Reader, stdou
func (e Executor) label() string {
label := strings.TrimSpace(e.commandName)
if label == "" {
- return "ask"
+ return "do"
}
return label
}
func normalizeExecutor(e Executor) Executor {
if e.commandName == "" {
- e.commandName = "ask"
+ e.commandName = "do"
}
if e.findBinary == nil {
e.findBinary = findTaskBinary
diff --git a/internal/askcli/taskexec_test.go b/internal/askcli/taskexec_test.go
index 90da61a..4db988b 100644
--- a/internal/askcli/taskexec_test.go
+++ b/internal/askcli/taskexec_test.go
@@ -12,7 +12,7 @@ import (
)
func TestExecutorTaskArgs(t *testing.T) {
- exec_ := NewExecutor("ask")
+ exec_ := NewExecutor("do")
args, err := exec_.taskArgs(context.Background(), "/tmp/work/hexai", []string{"list", "limit:1"})
if err != nil {
t.Fatalf("taskArgs returned error: %v", err)
@@ -24,7 +24,7 @@ func TestExecutorTaskArgs(t *testing.T) {
}
func TestExecutorTaskArgs_NoAgentScope(t *testing.T) {
- exec_ := NewExecutor("ask")
+ exec_ := NewExecutor("do")
ctx := contextWithTaskScope(context.Background(), taskScopeNoAgent)
args, err := exec_.taskArgs(ctx, "/tmp/work/hexai", []string{"list", "limit:1"})
if err != nil {
@@ -37,7 +37,7 @@ func TestExecutorTaskArgs_NoAgentScope(t *testing.T) {
}
func TestExecutorTaskArgs_AddDefaultScope(t *testing.T) {
- exec_ := NewExecutor("ask")
+ exec_ := NewExecutor("do")
args, err := exec_.taskArgs(context.Background(), "/tmp/work/hexai", []string{"add", "rc.verbose=nothing", "rc.verbose=new-uuid", "new task"})
if err != nil {
t.Fatalf("taskArgs returned error: %v", err)
@@ -49,7 +49,7 @@ func TestExecutorTaskArgs_AddDefaultScope(t *testing.T) {
}
func TestExecutorTaskArgs_AddNoAgentScope(t *testing.T) {
- exec_ := NewExecutor("ask")
+ exec_ := NewExecutor("do")
ctx := contextWithTaskScope(context.Background(), taskScopeNoAgent)
args, err := exec_.taskArgs(ctx, "/tmp/work/hexai", []string{"add", "rc.verbose=nothing", "rc.verbose=new-uuid", "new task"})
if err != nil {
@@ -65,7 +65,7 @@ func TestExecutorRun_InjectsProjectFilterAndAgentTag(t *testing.T) {
var gotName string
var gotArgs []string
exec_ := Executor{
- commandName: "ask",
+ commandName: "do",
findBinary: func() (string, error) { return "/usr/bin/task", nil },
detectRepoRoot: func(context.Context) (string, error) { return "/tmp/work/hexai", nil },
runCommand: func(_ context.Context, name string, args []string, stdin io.Reader, stdout, stderr io.Writer) error {
@@ -94,7 +94,7 @@ func TestExecutorRun_InjectsProjectFilterAndAgentTag(t *testing.T) {
func TestExecutorRun_InjectsProjectFilterAndNoAgentTag(t *testing.T) {
var gotArgs []string
exec_ := Executor{
- commandName: "ask",
+ commandName: "do",
findBinary: func() (string, error) { return "/usr/bin/task", nil },
detectRepoRoot: func(context.Context) (string, error) { return "/tmp/work/hexai", nil },
runCommand: func(_ context.Context, name string, args []string, stdin io.Reader, stdout, stderr io.Writer) error {
@@ -119,7 +119,7 @@ func TestExecutorRun_InjectsProjectFilterAndNoAgentTag(t *testing.T) {
func TestExecutorRun_OutsideGitRepo_IsActionable(t *testing.T) {
exec_ := Executor{
- commandName: "ask",
+ commandName: "do",
findBinary: func() (string, error) { return "/usr/bin/task", nil },
detectRepoRoot: func(context.Context) (string, error) { return "", errors.New("git failed") },
runCommand: func(context.Context, string, []string, io.Reader, io.Writer, io.Writer) error {
@@ -139,7 +139,7 @@ func TestExecutorRun_OutsideGitRepo_IsActionable(t *testing.T) {
func TestExecutorRun_PreservesTaskwarriorExitCode(t *testing.T) {
exec_ := Executor{
- commandName: "ask",
+ commandName: "do",
findBinary: func() (string, error) { return "/usr/bin/task", nil },
detectRepoRoot: func(context.Context) (string, error) { return "/tmp/work/hexai", nil },
runCommand: func(context.Context, string, []string, io.Reader, io.Writer, io.Writer) error {
@@ -160,7 +160,7 @@ func TestExecutorRun_PreservesStdoutAndStderr(t *testing.T) {
var stdout bytes.Buffer
var stderr bytes.Buffer
exec_ := Executor{
- commandName: "ask",
+ commandName: "do",
findBinary: func() (string, error) { return "/usr/bin/task", nil },
detectRepoRoot: func(context.Context) (string, error) { return "/tmp/work/hexai", nil },
runCommand: func(_ context.Context, name string, args []string, stdin io.Reader, out, errOut io.Writer) error {
@@ -187,7 +187,7 @@ func TestExecutorRun_PreservesStdoutAndStderr(t *testing.T) {
func TestExecutorRun_TaskLookupFailure_IsActionable(t *testing.T) {
exec_ := Executor{
- commandName: "ask",
+ commandName: "do",
findBinary: func() (string, error) { return "", errors.New("not found") },
}
@@ -202,7 +202,7 @@ func TestExecutorRun_TaskLookupFailure_IsActionable(t *testing.T) {
func TestExecutorRun_EmptyRepoName_IsActionable(t *testing.T) {
exec_ := Executor{
- commandName: "ask",
+ commandName: "do",
findBinary: func() (string, error) { return "/usr/bin/task", nil },
detectRepoRoot: func(context.Context) (string, error) { return "/", nil },
}
diff --git a/internal/taskproxy/run_test.go b/internal/taskproxy/run_test.go
index 15c5fbb..2414d6a 100644
--- a/internal/taskproxy/run_test.go
+++ b/internal/taskproxy/run_test.go
@@ -15,7 +15,7 @@ func TestRunnerRun_InjectsProjectFilterAndAgentTag(t *testing.T) {
var gotName string
var gotArgs []string
runner := Runner{
- CommandName: "ask",
+ CommandName: "do",
findTaskBinary: func() (string, error) { return "/usr/bin/task", nil },
detectRepoRoot: func(context.Context) (string, error) { return "/tmp/work/hexai", nil },
runCommand: func(_ context.Context, name string, args []string, stdin io.Reader, stdout, stderr io.Writer) error {
@@ -43,7 +43,7 @@ func TestRunnerRun_InjectsProjectFilterAndAgentTag(t *testing.T) {
func TestRunnerRun_OutsideGitRepo_IsActionable(t *testing.T) {
runner := Runner{
- CommandName: "ask",
+ CommandName: "do",
findTaskBinary: func() (string, error) { return "/usr/bin/task", nil },
detectRepoRoot: func(context.Context) (string, error) { return "", errors.New("git failed") },
runCommand: func(context.Context, string, []string, io.Reader, io.Writer, io.Writer) error {
@@ -63,7 +63,7 @@ func TestRunnerRun_OutsideGitRepo_IsActionable(t *testing.T) {
func TestRunnerRun_PreservesTaskwarriorExitCode(t *testing.T) {
runner := Runner{
- CommandName: "ask",
+ CommandName: "do",
findTaskBinary: func() (string, error) { return "/usr/bin/task", nil },
detectRepoRoot: func(context.Context) (string, error) { return "/tmp/work/hexai", nil },
runCommand: func(context.Context, string, []string, io.Reader, io.Writer, io.Writer) error {
@@ -84,7 +84,7 @@ func TestRunnerRun_PreservesStdoutAndStderr(t *testing.T) {
var stdout bytes.Buffer
var stderr bytes.Buffer
runner := Runner{
- CommandName: "ask",
+ CommandName: "do",
findTaskBinary: func() (string, error) { return "/usr/bin/task", nil },
detectRepoRoot: func(context.Context) (string, error) { return "/tmp/work/hexai", nil },
runCommand: func(_ context.Context, name string, args []string, stdin io.Reader, out, errOut io.Writer) error {
@@ -111,7 +111,7 @@ func TestRunnerRun_PreservesStdoutAndStderr(t *testing.T) {
func TestRunnerRun_TaskLookupFailure_IsActionable(t *testing.T) {
runner := Runner{
- CommandName: "ask",
+ CommandName: "do",
findTaskBinary: func() (string, error) { return "", errors.New("not found") },
}
@@ -126,7 +126,7 @@ func TestRunnerRun_TaskLookupFailure_IsActionable(t *testing.T) {
func TestRunnerRun_EmptyRepoName_IsActionable(t *testing.T) {
runner := Runner{
- CommandName: "ask",
+ CommandName: "do",
findTaskBinary: func() (string, error) { return "/usr/bin/task", nil },
detectRepoRoot: func(context.Context) (string, error) { return "/", nil },
}