Rename tool to taskgraph, use op dispatch field, add research reports
The built-in OpenCode 'task' tool spawns subagents for work delegation. Naming our plugin 'tasks' would create confusion with two 'task' tools that do completely different things. 'taskgraph' matches the core library, clearly differentiates from the built-in, and describes what the tool actually does. The dispatch field is renamed from 'tool' to 'op' (operation) to avoid collision with OpenCode's 'tool' terminology and match the Rust CLI's subcommand pattern. ADR-001 rewritten for taskgraph/op naming and Zod/TypeBox distinction. ADR-007 added documenting the naming decision and the three 'task' concepts (task, todowrite, taskgraph). Research reports added: - docs/research/opencode-task-tool-deep-dive.md - docs/research/open-coordinator-deep-dive.md Also: fixed SDD process link, resolved open question about 'show' including full body, added todowrite to relationship table, clarified Zod vs TypeBox roles, changed FileSource to async scan.
This commit is contained in:
@@ -11,7 +11,9 @@ The plugin exposes 14 distinct operations (list, show, deps, dependents, validat
|
||||
|
||||
## Decision
|
||||
|
||||
Collapse all operations into a single `tasks` tool that dispatches by `{tool: string, args?: Record<string, unknown>}`. The agent calls `tasks({tool: "help"})` to discover available operations on demand.
|
||||
Collapse all operations into a single `taskgraph` tool that dispatches by `{op, args}`. The agent calls `taskgraph({op: "help"})` to discover available operations on demand.
|
||||
|
||||
The dispatch field is named `op` (operation) rather than `tool` to avoid collision with OpenCode's own "tool" terminology. An agent calling `taskgraph({op: "list"})` reads clearly: "run the list operation on the taskgraph." This also matches the Rust CLI's subcommand pattern (`taskgraph parallel`, `taskgraph critical`).
|
||||
|
||||
This follows the pattern established by open-memory, which exposes 9 operations through a single `memory` tool.
|
||||
|
||||
@@ -21,19 +23,25 @@ This follows the pattern established by open-memory, which exposes 9 operations
|
||||
- Minimal context overhead (~250 tokens for one tool schema vs ~3500 for 14)
|
||||
- Adding new operations never increases context bloat
|
||||
- Agent always has access to the full operation set without schema pollution
|
||||
- Consistent with the alk.dev ecosystem pattern (memory, coordinator all use this)
|
||||
- Consistent with the alk.dev ecosystem pattern (memory, coordinator both use this)
|
||||
- `op` field name is unambiguous in OpenCode's context
|
||||
|
||||
**Negative:**
|
||||
- The `tool` and `args` fields are not validated by the outer Zod schema — validation happens inside the dispatch handler
|
||||
- The `op` and `args` fields are not individually validated by the outer schema — validation happens inside the dispatch handler
|
||||
- Agent must call help to discover operations; the tool description can only hint
|
||||
- Slightly more overhead per call (string dispatch vs direct function call)
|
||||
|
||||
**Mitigation for negatives:**
|
||||
- The `tool` field description enumerates all operation names, so the LLM can dispatch correctly
|
||||
- The `op` field description enumerates all operation names, so the LLM can dispatch correctly
|
||||
- Validation errors are clear and include usage guidance
|
||||
- The help operation provides complete reference with examples
|
||||
|
||||
## Note on Schema Libraries
|
||||
|
||||
The tool's outer parameter schema uses **Zod** (from `@opencode-ai/plugin`'s `tool()` helper) because that's what OpenCode's plugin SDK provides for tool definitions. The plugin's internal config schema uses **TypeBox** (from `@alkdev/typebox`, already a dependency via `@alkdev/taskgraph`) for compile-time types and runtime `Value.Check()`. These are two different concerns: Zod for OpenCode's tool interface, TypeBox for our own config. No conflict — each is used where it's the native choice.
|
||||
|
||||
## References
|
||||
|
||||
- open-memory `src/tools.ts`: proven pattern in production
|
||||
- OpenCode plugin SDK: `tool.schema` (Zod) for schema definition
|
||||
- OpenCode plugin SDK: `tool.schema` (Zod) for tool parameter schemas
|
||||
- ADR-007: naming decision — `taskgraph` not `tasks`, `op` not `tool`
|
||||
53
docs/architecture/decisions/007-naming-taskgraph.md
Normal file
53
docs/architecture/decisions/007-naming-taskgraph.md
Normal file
@@ -0,0 +1,53 @@
|
||||
---
|
||||
status: draft
|
||||
last_updated: 2026-04-28
|
||||
---
|
||||
|
||||
# ADR-007: Tool Naming — `taskgraph` not `tasks`
|
||||
|
||||
## Context
|
||||
|
||||
OpenCode has a built-in `task` tool that spawns subagents for work delegation. It creates child sessions, dispatches prompts to specialized agents, and returns results. It is deeply wired into the session, permission, and UI systems.
|
||||
|
||||
Our plugin was initially named `tasks` (plural), which creates three problems:
|
||||
|
||||
1. **Naming confusion**: `task` (spawning) vs `tasks` (analysis) — both deal with "tasks" but are fundamentally different. An LLM receiving a request like "look at the tasks" might invoke the wrong one.
|
||||
|
||||
2. **Semantic overlap**: `task` = delegation ("who should do this work?"), `tasks` = analysis ("what work exists and in what order?"), `todowrite` = progress tracking ("what am I working on right now?"). Three concepts, near-identical naming for two of them.
|
||||
|
||||
3. **Plugin shadowing risk**: OpenCode resolves tools into an object by ID. If a plugin registers a tool with the same ID as a built-in tool, the plugin wins. Accidentally shadowing the built-in `task` tool would break subagent spawning entirely.
|
||||
|
||||
Additionally, the dispatch field was initially named `tool` (matching open-memory's pattern). But the field name `tool` is ambiguous in OpenCode's context — every registered function is a "tool." The operation name `op` is more precise and matches the Rust CLI's subcommand pattern.
|
||||
|
||||
## Decision
|
||||
|
||||
- **Tool name**: `taskgraph` — directly matches the core library (`@alkdev/taskgraph`), clearly differentiates from the built-in `task`, and describes what the tool actually does.
|
||||
- **Dispatch field**: `op` (operation) — unambiguous in context, distinguishes from the outer "tool" concept, matches the Rust CLI's subcommand pattern (`taskgraph parallel`, `taskgraph critical`, etc.).
|
||||
|
||||
## Consequences
|
||||
|
||||
**Positive:**
|
||||
- No naming confusion with built-in `task`
|
||||
- `taskgraph({op: "list"})` reads clearly: "run the list operation on the taskgraph"
|
||||
- Matches the Rust CLI naming — users familiar with `taskgraph parallel` will recognize `taskgraph({op: "parallel"})`
|
||||
- The `op` field name is self-documenting: each value is an operation, not a nested tool
|
||||
|
||||
**Negative:**
|
||||
- Slightly longer tool name (10 chars vs 5 for `tasks`)
|
||||
- Deviates from open-memory's `memory({tool: ...})` pattern — but memory doesn't have a naming collision with a built-in tool
|
||||
|
||||
## The Three "Task" Concepts
|
||||
|
||||
| Tool | Concept | Scope | Persistence |
|
||||
|------|---------|-------|-------------|
|
||||
| `task` (built-in) | Delegation — spawn a subagent | Session-scoped | Ephemeral |
|
||||
| `todowrite` (built-in) | Progress tracking — what am I working on | Session-scoped | Ephemeral |
|
||||
| `taskgraph` (this plugin) | Analysis — dependencies, risk, cost | Project-scoped | Persistent files |
|
||||
|
||||
These are complementary, not competing. Future integration could make `taskgraph` feed analysis into `task` (e.g., use `parallel` groups to drive `spawn` decisions), but that's a v2 concern.
|
||||
|
||||
## References
|
||||
|
||||
- OpenCode built-in `task` tool: `/workspace/opencode/packages/opencode/src/tool/task.ts`
|
||||
- Research report: [docs/research/opencode-task-tool-deep-dive.md](../research/opencode-task-tool-deep-dive.md)
|
||||
- Open-coordinator deep dive: [docs/research/open-coordinator-deep-dive.md](../research/open-coordinator-deep-dive.md)
|
||||
Reference in New Issue
Block a user