Skip to content

Agentic usage

btw is built primarily as a tool for an LLM agent (Claude Code) to call from a thin slash command. Match resolution, ID generation, slug generation, and formatting all live in the CLI so the agent never has to read or rewrite task files itself. A read-only list or show costs the agent only the bytes the CLI prints, not the entire file store.

This page documents the contract between the CLI and an agent wrapper: the JSON schema returned by every subcommand, the error envelopes the agent must branch on, and the dispatch pattern the reference slash command uses.

Pass --format=json to any subcommand to get machine-readable output. The schema is documented as stable.

list returns an array of:

{
"id": "abcdef12",
"created": "2026-04-29T11:30:00Z",
"description": "buy milk",
"completed": "2026-04-30T08:00:00Z"
}

completed is omitted on open tasks.

show returns the same fields plus body (the full body string after the first description line) and path (the absolute, cleaned filesystem path of the task file; symlinks in the configured tasks directory are preserved verbatim). Two optional research fields are emitted only when the task has been researched: last_researched (RFC 3339 timestamp in UTC) and last_research_log (absolute path to the research log file). Both mirror the YAML frontmatter keys and are omitted when empty.

Golden fixtures for the JSON schema live in internal/render/testdata/ in the repo and are the authoritative reference for any wire-format edge cases.

When a <fragment> resolves ambiguously or not at all, the command exits non-zero. In --format=json, both cases produce a stable JSON envelope with an error discriminator so agents can branch without parsing prose.

{ "error": "ambiguous", "fragment": "milk", "matches": [{ "id": "...", "description": "...", "tags": [] }] }
{ "error": "no_match", "fragment": "zzz", "open_tasks": [ /* same shape as list */ ] }

For the underlying resolution rules, see Match resolution on the CLI reference page.

The reference slash command for Claude Code is a thin wrapper. It does not read or parse task files directly — the CLI owns all of that.

SubcommandsHow the wrapper invokes themNotes
add, list, show, update, append, close, reopenShell out with --format=json. On exit 0, pass success output through. On non-zero exit, branch on the error discriminator.Uniform shape across all of them.
editDoes not shell out. Validate the fragment via show, then tell the user to run btw edit <id> from their own shell.The binary syscall.Execs $EDITOR, which is unusable from an agent shell.

A vendored reference implementation of the Claude Code slash command lives in this repo at docs/src/content/docs/examples/bytheway-slash-command.md. The full source is rendered on the Reference slash command page — read it end-to-end to see the dispatch table, error-envelope branching, and the edit / research special cases in their working form.

btw research spawns a headless Claude Code subagent under --permission-mode=bypassPermissions, with an explicit --allowed-tools list. That list is the security boundary, and it is config-driven on a per-machine basis: the shipped binary contributes a vanilla baseline of five built-in read-only tools (Read, Glob, Grep, WebSearch, WebFetch), and the user’s config.toml extends it via research_extra_tools. MCP tool names and pattern-restricted Bash(...) invocations belong in the config, not in the binary.

If you are wrapping btw research from another agent, you do not need to thread tool names through the wrapper — they live in the operator’s config.toml. The CLI surface (subcommand name, flags, JSON output, exit-code envelope) is unchanged by the allowlist mechanism.

Claude Code also exposes a wrapper surface called skills alongside slash commands. There is no shipped btw skill, and there will not be one — the soak phase between capture and investigation requires explicit user control over when investigation fires, which a wrapper that auto-chains stages would erase. The canonical end-to-end pattern is documented as recipes against existing CLI primitives on the Agentic recipes page.