Documentation
¶
Overview ¶
Package cli — `clawtool a2a` subcommand. Phase 1 surface for ADR-024 (A2A networking): emits the agent's A2A Agent Card to stdout. mDNS announce, HTTP server, peer discovery, and capability tier enforcement land in phase 2+; today this is just "tell me what this clawtool instance would advertise".
Once phase 2 lands the HTTP server, the same card produced here will be served at /.well-known/agent-card.json. Keeping the CLI thin around the same renderer lets operators inspect the card BEFORE wiring up the network surface.
Package cli implements clawtool's user-facing subcommands.
Subcommand layout (ADR-004 §4):
clawtool init interactive wizard: pick recipes, apply to repo clawtool serve run as MCP server (delegates to internal/server) clawtool version print version clawtool help print top-level usage clawtool tools list list known tools and resolved enabled state clawtool tools enable <s> set tools.<selector>.enabled = true clawtool tools disable <s> set tools.<selector>.enabled = false clawtool tools status <s> print resolved state and the rule that won
Source / profile / group subcommands are scaffolded in main.go usage but not wired in v0.2 — they land alongside the source-instance feature.
`clawtool daemon` — manage the persistent shared MCP server every host (Codex / OpenCode / Gemini / Claude Code) fans into. The adapter (internal/agents/mcp_host.go) calls daemon.Ensure under the hood when the operator runs `clawtool agents claim <host>`, but the CLI exposes the lifecycle directly so the operator can start / stop / inspect the daemon without going through claim.
Package cli — `clawtool dashboard` (alias `clawtool tui`). Two modes:
default Bubble Tea TUI in alt-screen (interactive) --plain one-shot or repeat-print to stdout (Monitor-pair / chat-visible)
The plain mode exists for the case where the operator wants the dashboard's content visible inside Claude Code's chat (via the native Monitor tool) — the TUI's alt-screen rendering doesn't survive that path. Plain mode is just `task list + agent list` printed with a clean header on a 1 s cadence.
Package cli — `clawtool doctor` is the one-command diagnostic. It surveys binary / agents / sources / recipes and prints a colour-coded checklist with suggested fix commands. Pure composition of existing internal helpers — no new deps.
`clawtool egress` — runs the egress allowlist proxy (ADR-029 phase 4, task #209). Sandbox workers route their HTTP_PROXY / HTTPS_PROXY through this binary so model-generated network calls pass through an explicit allowlist before reaching the host network.
Operator path:
clawtool egress --listen :3128 \
--allow api.openai.com,api.anthropic.com,.github.com
In the worker container:
docker run -e HTTP_PROXY=http://egress:3128 \
-e HTTPS_PROXY=http://egress:3128 \
clawtool-worker:0.21 ...
Package cli — wizard-side install-prompt UX. Implements setup.Prompter (the abstraction the runner uses for missing prereqs) on top of huh + os/exec, plus the CommandRunner that actually shells out the per-platform install commands.
Kept in a separate file from init_wizard.go so the prompter + runner pair can be swapped or wrapped (e.g. by a dry-run wrapper) without touching the rest of the wizard. Test files inject a recordingRunner and a scriptedPrompter against the same interfaces — the wizard surface stays huh-bound, but every install decision is exercised in unit tests.
Package cli — `clawtool init` wizard. Two-scope welcome screen: repo (recipes) and user-global (agents + sources + secrets), with "both" and a read-only "show me what's available" preview path.
Honors --yes for non-interactive runs and falls back to the same path when stdin/stdout aren't TTYs (CI / containers).
Package cli — `clawtool mcp` subcommand surface (ADR-019).
v0.17 fills in `new`, `list`, `run`, `build`, `install`. The `new` verb runs the huh.Form wizard implemented in mcp_wizard.go; `install` lives in mcp_install.go; this file keeps the dispatcher + the read-only `list` walker.
Package cli — `clawtool mcp install` (ADR-019).
Reads `.clawtool/mcp.toml` from the project at <path>, derives the launch command from the project's language + transport, writes a [sources.<name>] block into ~/.config/clawtool/config.toml. Same surface as `clawtool source add` for catalog entries — just auto-discovers the command instead of asking.
Package cli — `clawtool mcp new` interactive wizard (ADR-019).
huh.Form sequence collects the operator's spec, hands it to internal/mcpgen which renders + writes the project. Tests substitute mcpgenDeps to drive the wizard without hitting disk.
Package cli — `clawtool` (no args) launches a friendly TUI landing menu that points at the most-used flows. Designed for users who'd rather not memorise subcommands; pure huh.Select.
Package cli — `clawtool orchestrator` (alias `clawtool orch`). Phase 2 of ADR-028: split-pane Bubble Tea TUI that auto-spawns one stdout-tail pane per active BIAM dispatch. Subscribes to the daemon's task-watch Unix socket so transitions reach the screen in real time.
`clawtool overview` — one-screen status of the running system (UX gap from the #193 smoke pass). Operators wanted a single verb that reports daemon + sandbox-worker + agents + bridges without remembering five subcommand names.
This deliberately skips diagnostic depth (`clawtool doctor` remains the deep checklist). Overview is the at-a-glance "is everything wired?" answer.
Package cli — `clawtool portal` subcommand surface (ADR-018).
Read-only + persistence operations land in v0.16.1. The interactive `ask` flow that drives Obscura over CDP arrives in v0.16.2; today it returns a clear "deferred" error so the surface is discoverable before the engine ships.
Package cli — `clawtool portal add` interactive wizard (ADR-018, v0.16.3).
Rebuilt on top of the chromedp-backed BrowserSession (ADR-007). Spawns the user's installed Chrome with --headless=false + a temp profile, waits for them to log in (optionally with a copy/paste prompt for the Claude in Chrome side-panel), pulls cookies via Network.getAllCookies, collects the three CSS selectors + a "response done" predicate template, and writes config.toml + secrets.toml.
Per ADR-017 we never wrap claude-in-chrome — the wizard generates a plain-text prompt the operator can paste. clawtool stays MCP-server-free for the wizard transport.
Package cli — `clawtool rules` subcommand. Lifecycle management for the operator's predicate-based invariants in .clawtool/rules.toml (project-local) or ~/.config/clawtool/rules.toml (user-global).
Operator-facing surface:
clawtool rules list show every loaded rule + its source clawtool rules show <name> detail view of one rule clawtool rules new <name> [flags] add a new rule (asks scope when ambiguous) clawtool rules remove <name> delete a rule clawtool rules path [--user|--local] print the rules file path clawtool rules check <event> [flags] one-shot evaluation against current state
Why this lives in CLI: the operator wants to add a rule from a fresh-context shell without firing up an editor; the parallel MCP-side tool (RulesAdd) is a thin wrapper that calls the same rules.AppendRule helper this CLI does.
Package cli — `clawtool sandbox` subcommand surface (ADR-020).
v0.18 ships read-only verbs (list / show / doctor) plus the surface stub for `run`. The dispatch-time integration (`clawtool send --sandbox <profile>`) lands v0.18.1+ alongside the per-OS engine implementations.
`clawtool sandbox-worker` — runs the sandbox worker (ADR-029 phase 1). Mirrors `clawtool serve --listen` semantics but for the worker leg of the orchestrator+worker pair: bearer-auth'd WebSocket endpoint that the daemon dials to route Bash / Read / Edit / Write tool calls into an isolated container.
Operator runs this inside a docker / runsc container; the daemon is the only trusted dialer. Auth is a shared bearer token; the worker reads it from a file or stdin so it never lands in argv.
Package cli — `clawtool setup` is the unified first-run entry. Phase 2 of ADR-027: one huh form with a per-feature opt-in matrix instead of the onboard → init verb chain. --legacy falls back to the Phase 1 sequential dispatch for operators who hit a bug or prefer the old prompts.
Package cli — Phase 2 setup state machine. Collapses onboard + init into one huh form with a single per-feature opt-in matrix. Per ADR-027: probe → matrix → required options → apply → verify.
Phase 2 v1 ships the matrix for: bridge installs, MCP host claims, daemon up, BIAM identity, secrets store init, telemetry, AND the subset of recipes that are Stable + don't require any caller-supplied options. Recipes with required options (license, codeowners, …) still flow through `clawtool init`'s per-recipe prompts since the matrix can't ask for option values inline.
`clawtool setup --legacy` falls back to the Phase 1 chain (onboard → init) for operators who prefer the old verb shape.
Package cli — helper wiring for setup_wizard.go. Lives alongside onboard.go so the production callbacks share one import set (daemon, agents, biam, secrets) without bloating setup_wizard.go.
Package cli — `clawtool skill` subcommand. Scaffolds and lists Agent Skills per the agentskills.io spec: a folder containing SKILL.md (required, with frontmatter name + description) plus optional scripts/, references/, assets/ subdirectories.
The standard was authored by Anthropic and is now open. clawtool's skill subcommand is the bootstrap layer — `clawtool skill new` is the analogue of `npm init` for Agent Skills.
Package cli — `clawtool task watch` (ADR-026, Gemini design pass b8ab4c9a). Streams BIAM task state transitions as one stdout line per event so the operator can pair it with Claude Code's native Monitor tool and see dispatch progress as inline chat events.
Two modes:
clawtool task watch <task_id> single task, exits when terminal
clawtool task watch --all every active task, runs forever
(or until SIGINT / pipe close)
Output format defaults to human-readable; --json switches to NDJSON for downstream tooling.
Polling cadence is 250ms by default — sub-second feel with negligible disk pressure on SQLite WAL. Tunable via --poll-interval.
Per the ADR's security clause, watch lines NEVER carry the task's body / completion text — only metadata (status, agent, message_count, last_message preview capped at 80 chars). A gigabyte-sized completion blob landing in the operator's chat would be its own outage.
Package cli — `clawtool unattended` subcommand. Operator-facing trust management for ADR-023's --unattended dispatch mode.
Two surfaces:
clawtool unattended status [<repo>] show whether <repo> (or cwd) is trusted clawtool unattended grant [<repo>] explicitly trust <repo> for unattended dispatch clawtool unattended revoke [<repo>] remove the trust grant clawtool unattended list list every granted repo clawtool unattended path print the trust file location
`clawtool yolo` is a deliberately-jokey alias so operators searching docs / muscle-memory the Cline term find it.
Package cli — `clawtool uninstall` removes every artifact clawtool drops on the host. Designed for the tester / dogfooder who installs the binary fresh ten times a day and ends up with duplicate sources / portals / sticky defaults.
The cleanup is intentionally exhaustive — config + secrets + caches + data dirs + sticky pointers + worktrees + BIAM SQLite + telemetry id. The binary itself is opt-in (--purge-binary) because the user may have installed via Homebrew / curl / Go and the right removal command differs by source.
Per ADR-007 doesn't apply here: this is "rm -rf clawtool's own files", which is by definition not delegable to an upstream. We still rely on stdlib os.RemoveAll for the actual removal.
Index ¶
- func IsOnboarded() bool
- type App
- func (a *App) AgentUnset() error
- func (a *App) AgentUse(instance string) error
- func (a *App) AgentWhich() error
- func (a *App) BridgeAdd(family string) error
- func (a *App) BridgeList() error
- func (a *App) BridgeRemove(family string) error
- func (a *App) HooksList() error
- func (a *App) HooksShow(event string) error
- func (a *App) HooksTest(event string, payload map[string]any) error
- func (a *App) Init() error
- func (a *App) McpList(argv []string) error
- func (a *App) Path() string
- func (a *App) PortalAdd(name string) error
- func (a *App) PortalAsk(argv []string) error
- func (a *App) PortalList() error
- func (a *App) PortalRemove(name string) error
- func (a *App) PortalUnset() error
- func (a *App) PortalUse(name string) error
- func (a *App) PortalWhich() error
- func (a *App) RecipeApply(name string, kvs []string) error
- func (a *App) RecipeList(category string) error
- func (a *App) RecipeStatus(name string) error
- func (a *App) Run(argv []string) int
- func (a *App) SandboxDoctor() error
- func (a *App) SandboxList() error
- func (a *App) SandboxShow(name string) error
- func (a *App) SecretsPath() string
- func (a *App) Send(args sendArgs) error
- func (a *App) SendList() error
- func (a *App) SetSecretsPath(p string)
- func (a *App) TaskCancel(taskID string) error
- func (a *App) TaskGet(taskID string) error
- func (a *App) TaskList(limit int, filter taskFilter, statusOverride string) error
- func (a *App) TaskWait(taskID string, timeout time.Duration) error
- func (a *App) ToolsDisable(selector string) error
- func (a *App) ToolsEnable(selector string) error
- func (a *App) ToolsList() error
- func (a *App) ToolsStatus(selector string) error
- func (a *App) Uninstall(args uninstallArgs) error
- func (a *App) WorktreeGC(minAge time.Duration) error
- func (a *App) WorktreeList() error
- func (a *App) WorktreeShow(taskID string) error
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func IsOnboarded ¶ added in v0.22.13
func IsOnboarded() bool
IsOnboarded reports whether the operator has completed the onboard wizard at least once. Exported so the SessionStart hook (claude_bootstrap.go) and the no-args first-run check can both consume the same signal.
Types ¶
type App ¶
type App struct {
Stdout io.Writer
Stderr io.Writer
Stdin io.Reader
// ConfigPath overrides the default config location. Empty = config.DefaultPath().
ConfigPath string
// contains filtered or unexported fields
}
App holds CLI dependencies. Stdout/stderr are injected so tests can capture.
func New ¶
func New() *App
New returns an App writing to the process's stdout/stderr and using the default config path.
func (*App) AgentUnset ¶ added in v0.20.0
AgentUnset clears the sticky default file. Idempotent.
func (*App) AgentUse ¶ added in v0.20.0
AgentUse persists the sticky default. We validate the instance exists in the supervisor's registry up front so the user gets a clean error here rather than at the next `clawtool send`.
func (*App) AgentWhich ¶ added in v0.20.0
AgentWhich resolves the empty selector and prints the result. Same precedence chain Send uses, exposed read-only for the user to inspect what would happen.
func (*App) BridgeAdd ¶ added in v0.20.0
BridgeAdd resolves the family to its recipe and applies it. Idempotent; if the bridge is already installed Detect returns Applied and Apply short-circuits.
func (*App) BridgeList ¶ added in v0.20.0
BridgeList prints all known bridge recipes with their Detect state.
func (*App) BridgeRemove ¶ added in v0.20.0
BridgeRemove is a placeholder. Claude Code's `claude plugin remove` surface isn't standardized yet across plugin types; v0.10.x will add proper uninstall semantics. For now we print a manual hint.
func (*App) HooksList ¶ added in v0.20.0
HooksList prints every configured event with its entry count. Empty config → friendly hint.
func (*App) HooksTest ¶ added in v0.20.0
HooksTest synthesises the event with the given payload and runs every configured entry. Prints per-entry success/failure so the operator can iterate on hook scripts without firing the real lifecycle event (which might be hard to reproduce).
func (*App) Init ¶
Init writes a default config to disk if the file does not already exist. Returns an "already exists" error if it does — callers can ignore that.
func (*App) McpList ¶ added in v0.20.0
McpList walks `root` (default cwd) for `.clawtool/mcp.toml` markers and prints one line per project. Skips node_modules / vendor / .git so a recursive walk doesn't melt on a typical repo.
func (*App) PortalAdd ¶ added in v0.20.0
PortalAdd opens $EDITOR with a TOML template for the named portal. On save we validate the parsed stanza and append it to config.toml. The validation refuses anything that wouldn't drive an Ask flow successfully, so a fat-finger landing in config never reaches the dispatch path.
func (*App) PortalAsk ¶ added in v0.20.0
PortalAsk is the deferred-feature placeholder. Validates the resolved portal so the operator gets the same diagnostics they will get in v0.16.2, then surfaces the deferred error.
func (*App) PortalList ¶ added in v0.20.0
PortalList prints the configured portals one per line — same shape as `clawtool send --list` so the operator sees both surfaces consistently.
func (*App) PortalRemove ¶ added in v0.20.0
PortalRemove rewrites config.toml without the [portals.<name>] stanza. Cookies in secrets.toml are left in place so a temporary remove-then-re-add doesn't lose the export. Operators clean secrets manually when they want a true uninstall.
func (*App) PortalUnset ¶ added in v0.20.0
PortalUnset removes the sticky-default file. Idempotent.
func (*App) PortalUse ¶ added in v0.20.0
PortalUse persists the sticky default for `clawtool portal ask`.
func (*App) PortalWhich ¶ added in v0.20.0
PortalWhich resolves the sticky-default portal. Same precedence chain as the agent sticky default (env > sticky file > single- configured fallback).
func (*App) RecipeApply ¶ added in v0.9.0
RecipeApply runs the recipe against the current working directory. Options are key=value strings; comma-separated values become []string. v0.9 keeps options simple — wizard / MCP path will pass richer types as the surface evolves.
func (*App) RecipeList ¶ added in v0.9.0
RecipeList prints every registered recipe grouped by category with its Detect state in the cwd.
func (*App) RecipeStatus ¶ added in v0.9.0
RecipeStatus prints the Detect output for one recipe or all recipes.
func (*App) Run ¶
Run dispatches argv (excluding program name) to the right subcommand. Returns the exit code; 0 = success, 2 = usage error, 1 = runtime failure.
Every dispatch is timed and emitted as a `cli.command` telemetry event (when telemetry is opted in) — command, subcommand, exit_code, duration_ms, error_class. Long-running verbs (`serve`, `dashboard`, `daemon` foreground) emit on dispatcher exit so a 2-hour `serve` session lands as one event with the full uptime.
func (*App) SandboxDoctor ¶ added in v0.20.0
SandboxDoctor reports every registered engine's availability.
func (*App) SandboxList ¶ added in v0.20.0
SandboxList prints every configured profile + the engine that would run it on this host.
func (*App) SandboxShow ¶ added in v0.20.0
SandboxShow parses one profile + prints the resolved view.
func (*App) SecretsPath ¶
SecretsPath returns the secrets-store path. Tests can shadow App.SecretsPath to point at a tmp file; production uses secrets.DefaultPath().
func (*App) SendList ¶ added in v0.20.0
SendList prints the supervisor's agent registry — same shape as the MCP `AgentList` response and the HTTP `GET /v1/agents` body.
func (*App) SetSecretsPath ¶
SetSecretsPath lets tests redirect the secrets store to a tmp file.
func (*App) TaskCancel ¶ added in v0.21.5
TaskCancel flips a pending/active task to "cancelled". The CLI invocation is a separate process from the runner that owns the dispatch goroutine, so we do a store-only flip + Notifier publish here — the runner side handles in-process cancel via Runner.Cancel when the same caller already holds it. Cross-process pollers (`clawtool task watch`) wake on the Notifier broadcast.
Audit fix #204: pairs with Runner.Cancel — without this the CLI had no way to abort a runaway --async dispatch short of kill -9 on the binary.
func (*App) TaskGet ¶ added in v0.20.0
TaskGet prints the task row + every message envelope for the task, JSON-formatted so a script can parse it.
func (*App) TaskList ¶ added in v0.20.0
TaskList prints the recent BIAM task summary, filtered by `filter`. When filter == taskFilterStatus, `statusOverride` names the single status to keep (done | failed | cancelled | expired). To honour the operator-supplied --limit while still filtering meaningfully, we pull a wider window from the store (10× limit, capped at 1000) and slice client-side.
func (*App) TaskWait ¶ added in v0.20.0
TaskWait blocks until the task is terminal, then dumps the same shape TaskGet does.
func (*App) ToolsDisable ¶
ToolsDisable writes tools.<selector>.enabled = false.
func (*App) ToolsEnable ¶
ToolsEnable writes tools.<selector>.enabled = true.
func (*App) ToolsStatus ¶
ToolsStatus prints the resolved enabled state for a selector and the rule that won, per ADR-004 §4.
func (*App) Uninstall ¶ added in v0.20.0
Uninstall performs the cleanup. Public so the MCP tool surface + integration tests can call it without going through argv.
func (*App) WorktreeGC ¶ added in v0.20.0
WorktreeGC reaps orphans (dead PID + minAge cutoff).
func (*App) WorktreeList ¶ added in v0.20.0
WorktreeList prints every worktree under ~/.cache/clawtool/worktrees with its marker info. Useful before running gc to see what's reapable.
func (*App) WorktreeShow ¶ added in v0.20.0
WorktreeShow dumps the marker JSON for one worktree.
Source Files
¶
- a2a.go
- agent.go
- agents.go
- agents_test_helpers.go
- biam_bootstrap.go
- bridge.go
- claude_bootstrap.go
- cli.go
- daemon.go
- dashboard.go
- doctor.go
- egress.go
- hooks.go
- init_prereq.go
- init_wizard.go
- mcp.go
- mcp_install.go
- mcp_wizard.go
- menu.go
- onboard.go
- orchestrator.go
- overview.go
- portal.go
- portal_wizard.go
- recipe.go
- rules.go
- sandbox.go
- sandbox_worker.go
- send.go
- setup.go
- setup_wizard.go
- setup_wizard_helpers.go
- skill.go
- source.go
- source_catalog.go
- task.go
- task_watch.go
- telemetry.go
- unattended.go
- uninstall.go
- upgrade.go
- worktree.go