/** * Generated by scripts/generate-tool-catalog.ts. Do not edit by hand. */ export interface ToolCatalogEntry { readonly name: string; readonly label?: string; readonly description?: string; readonly parameters?: Record; readonly strict?: boolean; readonly hidden?: boolean; readonly deferrable?: boolean; readonly loadMode?: "essential" | "discoverable"; readonly summary?: string; readonly nonAbortable?: boolean; readonly concurrency?: "shared" | "exclusive"; readonly lenientArgValidation?: boolean; readonly customWireName?: string; readonly customFormat?: { syntax: "lark" | "regex"; definition: string }; readonly mergeCallAndResult?: boolean; readonly inline?: boolean; readonly intent?: "omit" | "optional" | "require"; readonly platformExclusions?: readonly { platform: string; arch?: string }[]; } // biome-ignore format: generated JSON preserves deterministic serialization export const TOOL_CATALOG: Readonly> = { "read": { "name": "read", "label": "Read", "description": "Read files, directories, archives, SQLite databases, images, documents, internal resources, and web URLs through a single `path` string.\n\n\n- One tool for filesystem, archives, SQLite, images, documents (PDF/DOCX/PPTX/XLSX/RTF/EPUB/ipynb), internal URIs, and web URLs (reader-mode by default).\n- You SHOULD parallelize independent reads when exploring related files.\n- You SHOULD reach for `read` — not a browser/puppeteer tool — for fetching web content.\n\n\n## Parameters\n\n- `path` — required. Local path, internal URI (`agent://`, `artifact://`, `rule://`, `local://`), or URL. Append `:` for line ranges, raw mode, or special modes (e.g. `src/foo.ts:50-200`, `src/foo.ts:raw`, `db.sqlite:users:42`).\n- `truncation` — optional `head` | `last` | `both`; selects which end of an over-budget result to retain. Configured default: last (factory default: `last`); non-file routes such as URLs, directories and converted documents default to `head`. A line-range selector still bounds the selection — this only picks which end of that selection survives the byte/line cap. SQLite row queries page via their own `limit`/`offset` and ignore it.\n## Selectors\nAppend `:` to `path`. The bare path falls back to the default mode.\n\n- _(none)_ — parseable code → structural summary (signatures kept, bodies elided); a plain text file → a bounded receipt of about undefined lines or undefined KiB, whichever is smaller; the configured truncation direction is last (factory default: last). Line+hash anchors keep their real file line numbers and a footer names the omitted range. Archive members use the larger 3000-line / 50 KiB budget. Converted documents, notebooks, URLs and directory listings still start from the beginning.\n- `:50` / `:50-` — read from line 50 onward.\n- `:50-200` — lines 50–200 inclusive.\n- `:50+150` — 150 lines starting at line 50.\n- `:20+1` — exactly one line.\n- `:5-16,960-973` — multiple ranges in one call (sorted, overlaps merged).\n- `:raw` — verbatim text; no anchors, no summary, no line prefixes.\n- `:2-4:raw` or `:raw:2-4` — range AND verbatim; the two compose in either order.\n- `:conflicts` — one-line-per-block index of every unresolved git merge conflict.\n\n# Files\n\n- Reading a directory path returns a depth-limited dirent listing.\n- Parseable code without a selector returns a **structural summary**: declarations kept, large bodies collapsed to `..` (merged brace pair) or `…` (standalone). Summarized output ends with a footer of the form:\n\n `[NN lines across MM elided regions; read :raw or a line range like :1-9999 for verbatim content]`\n\n If the elided body is what you actually need, re-issue the **exact selector the footer names**. NEVER guess what's inside `..` / `…` — those markers carry no content.\n- Directional windows identify the retained first/last lines and the omitted range; use the `re-read :1-` or `:raw` hint in the footer to recover the full content.\n\n# Documents & Notebooks\n\nExtracts text from PDF, Word, PowerPoint, Excel, RTF, and EPUB. Notebooks (`.ipynb`) are shown as editable `# %% [type] cell:N` text; edits round-trip back to the underlying JSON preserving notebook metadata. Add `:raw` to a notebook to bypass the converter and read the JSON directly.\n\n# Images\n\nReading an image path returns the image itself for visual inspection by a vision-capable model.\n\n# Archives\n\nSupports `.tar`, `.tar.gz`, `.tgz`, `.zip`. Use `archive.ext:path/inside/archive` to read a member, and append a normal selector to the inner path: `archive.zip:dir/file.ts:50-60`.\n\n# SQLite\n\nFor `.sqlite`, `.sqlite3`, `.db`, `.db3`:\n- `file.db` — list tables with row counts\n- `file.db:table` — schema + sample rows\n- `file.db:table:key` — single row by primary key\n- `file.db:table?limit=50&offset=100` — paginated rows\n- `file.db:table?where=status='active'&order=created:desc` — filtered rows\n- `file.db?q=SELECT …` — read-only SELECT query\n\n# URLs\n\n- Default reader-mode: HTML pages, GitHub issues/PRs, Stack Overflow, Wikipedia, Reddit, NPM, arXiv, RSS/Atom, JSON endpoints, PDFs → clean text/markdown.\n- `:raw` returns untouched HTML; line selectors (`:50`, `:50-100`, `:50+150`) paginate the cached fetched output.\n- Bare `host:port` URLs collide with the selector grammar — add a trailing slash before the selector: `https://example.com/:80`.\n\n# Internal URIs\n\n`agent://`, `artifact://`, `rule://`, and `local://.md` resolve transparently and accept the same line selectors as filesystem paths. Use `artifact://` to recover full output that a previous bash/eval/tool result spilled or truncated.\n\n\n- Always include `path`; never call `read` with `{}`.\n- For line ranges, append the selector to `path`.\n- Re-issue the selector named by a summary footer before relying on elided content.\n", "parameters": { "type": "object", "properties": { "path": { "type": "string", "description": "path or url; append : for line ranges or raw mode (e.g. \"src/foo.ts:50-100\")" }, "truncation": { "description": "which end of an over-budget result to keep: head | last | both. Route defaults are route-aware: read.truncation is consulted for bare local and archive-member routes (factory default: last), while URL, converted, directory, range, internal, and other routes default to head. SQLite row, schema, and query reads ignore this parameter; raw reads honor explicit directions.", "type": "string", "enum": [ "head", "last", "both" ] } }, "required": [ "path" ], "additionalProperties": false }, "strict": true, "deferrable": false, "loadMode": "essential", "nonAbortable": true }, "bash": { "name": "bash", "label": "Bash", "description": "Executes bash command in shell session for terminal operations like git, bun, cargo, python.\n\n\n- Use `cwd` to set working directory, not `cd dir && …`\n- Prefer `env: { NAME: \"…\" }` for multiline, quote-heavy, or untrusted values; reference as `$NAME`\n- Quote variable expansions like `\"$NAME\"` to preserve exact content\n- PTY mode is opt-in: set `pty: true` only when the command needs a real terminal (e.g. `sudo`, `ssh` requiring user input); default is `false`\n- Use `;` only when later commands should run regardless of earlier failures\n- Internal URIs (`agent://`, `artifact://`, `rule://`, `local://`) are auto-resolved to filesystem paths\n\n\n\n- Use bash only for terminal operations that dedicated tools do not cover.\n- Never pipe through `| head -n N` or `| tail -n N` — output is already truncated. Recover omitted output only when the result includes an `artifact://` footer or metadata reference; truncation without a reference leaves the visible output incomplete with no recoverable artifact.\n- Never redirect with `2>&1` or `2>/dev/null` — stdout and stderr are already merged.\n\n\n\n- Returns output and exit code.\n- Truncated output is recoverable only when the result includes an `artifact://` footer or metadata reference; truncation evidence without such a reference means the visible output is incomplete and no artifact is recoverable.\n- Exit codes shown on non-zero exit\n\n\n# Waiting for background work\n\n- A long blocking `sleep N` (or `sleep N && …`) emits nothing for the entire duration and is indistinguishable from a hung session. Never use it to wait for subagents or background jobs.\n- To wait for detached task subagents, use `subagent await` — it emits periodic liveness while waiting.\n- To wait for background bash jobs, use `job poll` — it reports status on each tick.\n- Short sleeps for rate-limiting or pacing (e.g. `sleep 2` between retries) are fine.\n\n# Output minimizer\n\n- Bash stdout/stderr may be rewritten before you see it: long output keeps only the last 1 KiB by default to reduce noise and input-token use. Explicit `tools.artifactTailBytes` / `tools.artifactHeadBytes` settings can set the tail budget or retain both ends. Prefer focused commands and dedicated `search`/`find` tools over producing broad output. Test/lint runners (e.g. `bun test`, `cargo test`, ESLint) are also passed through heuristic filters that drop noise and keep failures.\n- When the local minimizer changes visible text, successful artifact storage appends a footer containing an `artifact://` reference. Complete artifacts are labeled as full output; hard-capped artifacts report omitted bytes instead. If artifact allocation/storage is unavailable before a writer/save operation is attempted, truncation may have no reference or diagnostic. If an artifact writer/save operation is attempted and fails, a bounded diagnostic is emitted without inventing an artifact URI.\n- ACP/client-terminal output can arrive already truncated from the beginning. Treat any truncation notice or metadata as evidence that the visible tail is incomplete. Recover omitted output only when an `artifact://` footer or metadata reference is present; truncation evidence without a reference means the visible output is incomplete and no artifact is recoverable. Output with neither truncation evidence nor an artifact reference is the complete emitted output.", "parameters": { "type": "object", "properties": { "command": { "type": "string", "description": "command to execute" }, "env": { "description": "extra env vars", "type": "object", "propertyNames": { "type": "string", "pattern": "^[A-Za-z_][A-Za-z0-9_]*$" }, "additionalProperties": { "type": "string" } }, "timeout": { "default": 300, "description": "timeout in seconds, NOT milliseconds (30 = 30s)", "type": "number" }, "cwd": { "type": "string", "description": "working directory" }, "pty": { "type": "boolean", "description": "run in pty mode" } }, "required": [ "command" ], "additionalProperties": false }, "strict": true, "deferrable": false, "loadMode": "essential", "concurrency": "exclusive" }, "edit": { "name": "edit", "label": "Edit", "description": "Performs string replacements in files with fuzzy whitespace matching.\n\n\n- Params MUST be `{ path, edits }`; `path` is required at the top level and applies to every replacement\n- You MUST use the smallest `old_text` that uniquely identifies the change\n- If `old_text` is not unique, you MUST expand it with more context or use `all: true` to replace all occurrences\n- You SHOULD prefer editing existing files over creating new ones\n\n\n\nReturns success/failure status. On success, file modified in place with replacement applied. On failure (e.g., `old_text` not found or matches multiple locations without `all: true`), returns error describing issue.\n\n\n\n- You MUST read the file at least once in the conversation before editing.\n- Use Replace when the _content itself_ identifies the location. For position-addressed changes (append, insert at line N, delete a line range), use the `write` or line-anchored edit tools — NEVER `cat`/`sed` pipelines.\n", "parameters": { "type": "object", "properties": { "path": { "type": "string", "description": "file path" }, "edits": { "minItems": 1, "type": "array", "items": { "type": "object", "properties": { "old_text": { "type": "string", "description": "text to find" }, "new_text": { "type": "string", "description": "replacement text" }, "all": { "type": "boolean", "description": "replace all occurrences" } }, "required": [ "old_text", "new_text" ], "additionalProperties": false }, "description": "replacements" } }, "required": [ "path", "edits" ], "additionalProperties": false }, "strict": true, "deferrable": false, "loadMode": "essential", "nonAbortable": true, "concurrency": "exclusive" }, "ast_grep": { "name": "ast_grep", "label": "AST Grep", "description": "Performs structural code search using AST matching via native ast-grep.\n\n\n- Use when syntax shape matters more than raw text (calls, declarations, specific language constructs)\n- `paths` is required and accepts an array of files, directories, globs, or internal URLs\n- Language is inferred from `paths`; narrow each call to one language when mixed-language trees could cause parse noise\n- `pat` is a single AST pattern. Run separate calls for distinct unrelated patterns\n- **Patterns match AST structure, not text** — whitespace/formatting is ignored\n- `$NAME` captures one node; `$_` matches one without binding; `$$$NAME` captures zero-or-more (lazy — stops at next matchable element); `$$$` matches zero-or-more without binding. Use `$$$NAME`, NOT `$$NAME` — the two-dollar form is invalid and produces a parse error\n- Metavariable names are UPPERCASE and must be the whole AST node — partial-text like `prefix$VAR`, `\"hello $NAME\"`, or `a $OP b` does NOT work; match the whole node instead\n- When the same metavariable appears twice, both occurrences MUST match identical code (`$A == $A` matches `x == x`, not `x == y`)\n- Patterns MUST parse as a single valid AST node for the inferred target language. For method fragments or body snippets that don't parse standalone, wrap in valid context (e.g. `class $_ { … }`)\n- C++ qualified calls used as expression statements need the statement semicolon in the pattern: use `ns::doThing($ARG);`, `$CALLEE($ARG);`, or wrap a statement snippet. Without `;`, tree-sitter-cpp may parse `ns::doThing($ARG)` as declaration-like syntax and return no matches\n- For TS declarations/methods, tolerate unknown annotations: `async function $NAME($$$ARGS): $_ { $$$BODY }` or `class $_ { method($ARG: $_): $_ { $$$BODY } }`\n- Declaration forms are structurally distinct — top-level `function foo`, class method `foo()`, and `const foo = () => {}` are different AST shapes; search the right form before concluding absence\n- Loosest existence check: `pat: \"executeBash\"` with narrow `paths`\n\n\n\n- Grouped matches with file path, byte range, line/column ranges, metavariable captures\n- Match lines are anchor-prefixed: `*LINE+ID|content` for the matched line and ` LINE+ID|content` (leading space) for surrounding context\n- Summary counts (`totalMatches`, `filesWithMatches`, `filesSearched`) and parse issues when present\n\n\n\n# Search TypeScript files under src\n`{\"pat\":\"console.log($$$)\",\"paths\":[\"src/**/*.ts\"]}`\n# Named imports from a specific package\n`{\"pat\":\"import { $$$IMPORTS } from \\\"react\\\"\",\"paths\":[\"src/**/*.ts\"]}`\n# Arrow functions assigned to a const\n`{\"pat\":\"const $NAME = ($$$ARGS) => $BODY\",\"paths\":[\"src/utils/**/*.ts\"]}`\n# Method call on any object, ignoring method name with `$_`\n`{\"pat\":\"logger.$_($$$ARGS)\",\"paths\":[\"src/**/*.ts\"]}`\n# Loosest existence check for a symbol in one file\n`{\"pat\":\"processItems\",\"paths\":[\"src/worker.ts\"]}`\n\n\n\n- Avoid repo-root scans — narrow `paths` first\n- Parse issues are query failure, not evidence of absence: repair the pattern or tighten `paths` before concluding \"no matches\"\n- For broad/open-ended inspection across subsystems, delegate a bounded fact-finding task to an appropriate canonical role agent (`planner` or `architect`) first\n", "parameters": { "type": "object", "properties": { "pat": { "type": "string", "description": "ast pattern" }, "paths": { "minItems": 1, "type": "array", "items": { "type": "string", "description": "file, directory, glob, or internal URL to search" }, "description": "files, directories, globs, or internal URLs to search" }, "skip": { "default": 0, "description": "matches to skip", "type": "number" } }, "required": [ "pat", "paths" ], "additionalProperties": false }, "strict": true, "deferrable": true, "loadMode": "discoverable", "summary": "Search code with AST patterns (structural grep)" }, "ast_edit": { "name": "ast_edit", "label": "AST Edit", "description": "Performs structural AST-aware rewrites via native ast-grep.\n\n\n- Use for codemods and structural rewrites where plain text replace is unsafe\n- `paths` is required and accepts an array of files, directories, globs, or internal URLs\n- Language is inferred from `paths`; narrow each call to one language for deterministic rewrites\n- Metavariables captured in `pat` (`$A`, `$$$ARGS`) are substituted into that entry's `out` template\n- **Patterns match AST structure, not text.** `$NAME` = one node (captured); `$_` = one without binding; `$$$NAME` = zero-or-more (lazy — stops at next matchable element); `$$$` = zero-or-more without binding. Use `$$$NAME`, NOT `$$NAME` — the two-dollar form is invalid. Metavariable names are UPPERCASE and MUST be the whole AST node — partial text like `prefix$VAR` or `\"hello $NAME\"` does NOT work\n- When the same metavariable appears twice, both occurrences MUST match identical code (`$A == $A` matches `x == x`, not `x == y`)\n- Rewrite patterns MUST parse as a single valid AST node. For method fragments or body snippets that don't parse standalone, wrap in context (e.g. `class $_ { … }`)\n- For TS declarations/methods, tolerate unknown annotations: `async function $NAME($$$ARGS): $_ { $$$BODY }` or `class $_ { method($ARG: $_): $_ { $$$BODY } }`\n- Delete matched code with empty `out`: `{\"pat\":\"console.log($$$)\",\"out\":\"\"}`\n- Each rewrite is a 1:1 structural substitution — cannot split one capture across multiple nodes or merge multiple captures into one\n\n\n\n- Output is a **staged preview** — nothing touches disk until you call `resolve` with `action: \"apply\"`; call `resolve` with `action: \"discard\"` to reject the staged rewrite\n- Replacement summary, per-file replacement counts, and change diffs as `-LINE+ID|before` / `+LINE+ID|after` lines\n- Parse issues when files cannot be processed\n\n\n\n# Rename a call site across TypeScript files\n`{\"ops\":[{\"pat\":\"oldApi($$$ARGS)\",\"out\":\"newApi($$$ARGS)\"}],\"paths\":[\"src/**/*.ts\"]}`\n# Delete matching calls\n`{\"ops\":[{\"pat\":\"console.log($$$ARGS)\",\"out\":\"\"}],\"paths\":[\"src/**/*.ts\"]}`\n# Rewrite import source path\n`{\"ops\":[{\"pat\":\"import { $$$IMPORTS } from \\\"old-package\\\"\",\"out\":\"import { $$$IMPORTS } from \\\"new-package\\\"\"}],\"paths\":[\"src/**/*.ts\"]}`\n# Modernize to optional chaining (same metavariable enforces identity)\n`{\"ops\":[{\"pat\":\"$A && $A()\",\"out\":\"$A?.()\"}],\"paths\":[\"src/**/*.ts\"]}`\n# Swap two arguments using captures\n`{\"ops\":[{\"pat\":\"assertEqual($A, $B)\",\"out\":\"assertEqual($B, $A)\"}],\"paths\":[\"tests/**/*.ts\"]}`\n# Python — convert print calls to logging\n`{\"ops\":[{\"pat\":\"print($$$ARGS)\",\"out\":\"logger.info($$$ARGS)\"}],\"paths\":[\"src/**/*.py\"]}`\n\n\n\n- Parse issues mean the rewrite is malformed or mis-scoped — fix the pattern before assuming a clean no-op\n- For one-off local text edits, prefer the Edit tool\n", "parameters": { "type": "object", "properties": { "ops": { "minItems": 1, "type": "array", "items": { "type": "object", "properties": { "pat": { "type": "string", "description": "ast pattern" }, "out": { "type": "string", "description": "replacement template" } }, "required": [ "pat", "out" ], "additionalProperties": false }, "description": "rewrite ops" }, "paths": { "minItems": 1, "type": "array", "items": { "type": "string", "description": "file, directory, glob, or internal URL to rewrite" }, "description": "files, directories, globs, or internal URLs to rewrite" } }, "required": [ "ops", "paths" ], "additionalProperties": false }, "strict": true, "deferrable": true, "loadMode": "discoverable", "summary": "Perform AST-aware code edits (structural refactoring)" }, "render_mermaid": { "name": "render_mermaid", "label": "RenderMermaid", "description": "Convert Mermaid graph source into ASCII diagram output.\n\nParameters:\n- `mermaid` (required): Mermaid graph text to render.\n- `config` (optional): JSON render configuration (spacing and layout options).\nBehavior:\n- Returns ASCII diagram text.\n- Saves full output to `artifact://` when storage is available.\n- Returns error when Mermaid input is invalid or rendering fails.", "parameters": { "type": "object", "properties": { "mermaid": { "type": "string", "description": "mermaid source" }, "config": { "type": "object", "properties": { "useAscii": { "type": "boolean" }, "paddingX": { "type": "number" }, "paddingY": { "type": "number" }, "boxBorderPadding": { "type": "number" } }, "additionalProperties": false } }, "required": [ "mermaid" ], "additionalProperties": false }, "strict": true, "deferrable": true, "loadMode": "discoverable", "summary": "Render a Mermaid diagram to an image" }, "ask": { "name": "ask", "label": "Ask", "description": "Asks user when you need clarification or input during task execution.\n\n\n- Multiple approaches exist with significantly different tradeoffs user should weigh\n\n\n\n- Use `recommended: ` to mark default (0-indexed); \" (Recommended)\" added automatically\n- Use `questions` for multiple related questions instead of asking one at a time\n- Set `multi: true` on question to allow multiple selections\n\n\n\n- Provide 2-5 concise, distinct options\n\n\n\n- **Default to action.** Resolve ambiguity yourself using repo conventions, existing patterns, and reasonable defaults. Exhaust existing sources (code, configs, docs, history) before asking. Only ask when options have materially different tradeoffs the user must decide.\n- **If multiple choices are acceptable**, pick the most conservative/standard option and proceed; state the choice.\n- **Do NOT include \"Other\" option** — UI automatically adds \"Other (type your own)\" to every question.\n\n\n\n# Single question\nquestions: [{\"id\": \"auth_method\", \"question\": \"Which authentication method should this API use?\", \"options\": [{\"label\": \"JWT\"}, {\"label\": \"OAuth2\"}, {\"label\": \"Session cookies\"}], \"recommended\": 0}]\n\n# Multiple questions\nquestions: [{\"id\": \"storage_type\", \"question\": \"Which storage backend?\", \"options\": [{\"label\": \"SQLite\"}, {\"label\": \"PostgreSQL\"}]}, {\"id\": \"auth_method\", \"question\": \"Which auth method?\", \"options\": [{\"label\": \"JWT\"}, {\"label\": \"Session cookies\"}]}]\n", "parameters": { "type": "object", "properties": { "questions": { "minItems": 1, "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "question id" }, "question": { "type": "string", "description": "question text" }, "options": { "type": "array", "items": { "type": "object", "properties": { "label": { "type": "string", "description": "display label" } }, "required": [ "label" ], "additionalProperties": false }, "description": "available options" }, "multi": { "type": "boolean", "description": "allow multiple selections" }, "recommended": { "type": "number", "description": "recommended option index" }, "workflowGate": { "type": "object", "properties": { "stage": { "type": "string", "enum": [ "deep-interview", "ralplan", "ultragoal" ], "description": "workflow gate stage" }, "kind": { "type": "string", "enum": [ "question", "approval", "execution" ], "description": "workflow gate kind" } }, "required": [ "stage", "kind" ], "additionalProperties": false, "description": "optional workflow gate stage/kind override" } }, "required": [ "id", "question", "options" ], "additionalProperties": false }, "description": "questions to ask" } }, "required": [ "questions" ], "additionalProperties": false }, "strict": true, "deferrable": true, "loadMode": "discoverable", "summary": "Ask the user a clarifying question" }, "debug": { "name": "debug", "label": "Debug", "description": "Provides debugger access through the Debug Adapter Protocol (DAP).\nUse for launching or attaching debuggers, setting breakpoints, stepping through execution, inspecting threads/stack/variables, evaluating expressions, capturing output, and interrupting hung programs.\n\n\n- Prefer over bash for program state, breakpoints, stepping, thread inspection, or interrupting a running process.\n- `action: \"launch\"` starts a session; `program` is required, `adapter` optional (auto-selected from target path and workspace).\n For Python, set `adapter: \"debugpy\"` and `program` to the target `.py` file; put interpreter/script flags in `args`.\n- `action: \"attach\"` connects to an existing process: `pid` for local attach, `port` for remote attach (where the adapter supports it), `adapter` to force a specific debugger.\n- **Breakpoints**: `set_breakpoint`/`remove_breakpoint` with source (`file`+`line`) or function (`function`); optional `condition` for conditional breakpoints.\n- **Flow control**: `continue` (resumes; briefly waits to observe whether the program stops or keeps running), `step_over`/`step_in`/`step_out` (single-step), `pause` (interrupt a running program so you can inspect state).\n- **Inspect**: `threads` (list), `stack_trace` (frames for current stopped thread), `scopes` (needs `frame_id` or a current stopped frame), `variables` (needs `variable_ref` or `scope_id`), `evaluate` (needs `expression`; `context: \"repl\"` for raw debugger commands when the adapter supports them), `output` (captured stdout/stderr/console), `sessions` (tracked debug sessions), `terminate`.\n- Timeouts apply per-request, not to the full session lifetime.\n\n\n\n- Only one active debug session is supported at a time.\n- Some adapters require a launched session to receive `configurationDone` before the target actually runs; if the tool says configuration is pending, set breakpoints and then call `continue`.\n- Adapter availability depends on local binaries. Common built-ins: `gdb`, `lldb-dap`, `python -m debugpy.adapter`, `dlv dap`.\n- `program` must be an executable file or debug target, not a directory or interpreter name that resolves to a workspace directory.\n\n\n\n# Launch and inspect hang\n1. `debug(action: \"launch\", program: \"./my_app\")`\n2. `debug(action: \"set_breakpoint\", file: \"src/main.c\", line: 42)`\n3. `debug(action: \"continue\")`\n4. If the program appears hung: `debug(action: \"pause\")`\n5. Inspect state with `threads`, `stack_trace`, `scopes`, and `variables`\n# Launch a Python script with debugpy\n`debug(action: \"launch\", adapter: \"debugpy\", program: \"scripts/job.py\", args: [\"--flag\"])`\n# Raw debugger command through repl\n`debug(action: \"evaluate\", expression: \"info registers\", context: \"repl\")`\n", "parameters": { "type": "object", "properties": { "action": { "type": "string", "enum": [ "launch", "attach", "set_breakpoint", "remove_breakpoint", "set_instruction_breakpoint", "remove_instruction_breakpoint", "data_breakpoint_info", "set_data_breakpoint", "remove_data_breakpoint", "continue", "step_over", "step_in", "step_out", "pause", "evaluate", "stack_trace", "threads", "scopes", "variables", "disassemble", "read_memory", "write_memory", "modules", "loaded_sources", "custom_request", "output", "terminate", "sessions" ] }, "program": { "type": "string", "description": "program path" }, "args": { "type": "array", "items": { "type": "string" }, "description": "program arguments" }, "adapter": { "type": "string", "description": "debugger adapter (gdb, lldb-dap, debugpy, dlv)" }, "cwd": { "type": "string" }, "file": { "type": "string", "description": "source file" }, "line": { "type": "number", "description": "source line" }, "function": { "type": "string", "description": "function name" }, "name": { "type": "string", "description": "variable or data name" }, "condition": { "type": "string", "description": "breakpoint condition" }, "hit_condition": { "type": "string" }, "expression": { "type": "string", "description": "expression to evaluate" }, "context": { "type": "string", "description": "evaluate context: watch | repl | hover | variables | clipboard" }, "frame_id": { "type": "number" }, "scope_id": { "type": "number", "description": "scope variables reference" }, "variable_ref": { "type": "number", "description": "variable reference" }, "pid": { "type": "number", "description": "process id for attach" }, "port": { "type": "number", "description": "remote attach port" }, "host": { "type": "string", "description": "remote attach host" }, "levels": { "type": "number", "description": "max stack frames" }, "memory_reference": { "type": "string", "description": "memory reference or address" }, "instruction_reference": { "type": "string" }, "instruction_count": { "type": "number" }, "instruction_offset": { "type": "number" }, "count": { "type": "number", "description": "bytes to read" }, "data": { "type": "string", "description": "base64 memory payload" }, "data_id": { "type": "string", "description": "data breakpoint id" }, "access_type": { "type": "string", "enum": [ "read", "write", "readWrite" ] }, "command": { "type": "string", "description": "custom dap request command" }, "arguments": { "type": "object", "propertyNames": { "type": "string" }, "additionalProperties": true, "description": "custom request arguments" }, "offset": { "type": "number" }, "resolve_symbols": { "type": "boolean" }, "allow_partial": { "type": "boolean" }, "start_module": { "type": "number" }, "module_count": { "type": "number" }, "timeout": { "type": "number", "description": "per-request timeout seconds" } }, "required": [ "action" ], "additionalProperties": false }, "strict": true, "deferrable": true, "loadMode": "discoverable", "summary": "Debug a running process with DAP (debugger adapter protocol)", "concurrency": "exclusive" }, "bisect": { "name": "bisect", "label": "Bisect", "description": "Find the exact commit that introduced (or fixed) a behavior by driving `git bisect` with a shell predicate, then restore the working tree and report the culprit.\n\nUse this instead of running `git bisect` by hand when you have a reproducible pass/fail check and a known-good and known-bad revision. The tool guarantees clean setup and teardown: it always runs `git bisect reset` and then discards any tracked-file edits the predicate made (`git reset --hard`), so it never leaves the repository stranded in a detached bisect state or with the predicate's tracked-file modifications behind. Untracked files the predicate creates are left in place (the tool never deletes files it did not create).\n\nParameters:\n- `good`: the OLDER endpoint — a commit that must be an ancestor of `bad`.\n- `bad`: the NEWER endpoint (defaults to `HEAD`).\n- `run`: the shell command evaluated at each revision. Exit `0` = good, `125` = skip (untestable revision), any other non-zero = bad.\n- `invert`: set true to find the commit that FIXED the behavior instead of the one that broke it.\n- `maxSteps` / `stepTimeoutMs`: bounds; a step that exceeds `stepTimeoutMs` is treated as a skip.\n\nSearch direction:\n- Default (find the regression): the predicate passes at `good` and fails at `bad`. The tool reports the first commit that turned it bad.\n- `invert` (find the fix): the predicate fails at `good` and passes at `bad`. The tool reports the first commit that turned it good.\n\nRules:\n- Requires a git repository and a clean working tree. Commit or stash uncommitted changes first — bisect checks out historical commits and would clobber them.\n- `good` must resolve, `bad` must resolve, they must differ, and `good` must be an ancestor of `bad`.\n- Make `run` self-contained and deterministic (build + test in one command). It always runs from the repository root (the top level of the working tree), even when the tool is invoked from a subdirectory — reference files by repo-relative paths, and do not assume the current subdirectory exists at every candidate commit.\n- Prefer a narrow predicate that targets only the behavior you are hunting, so unrelated breakage does not mislead the search.\n\nThe result reports the first bad (or first fixing) commit with its author, date, subject, and changed files, plus every revision tested. Every tracked file is restored to its pre-bisect state; if the predicate created untracked files they are reported and left in place.", "parameters": { "type": "object", "properties": { "good": { "type": "string", "minLength": 1, "description": "A known-good commit-ish (must be an ancestor of `bad`) where the predicate passes." }, "bad": { "default": "HEAD", "description": "A known-bad commit-ish (defaults to HEAD) where the predicate fails.", "type": "string", "minLength": 1 }, "run": { "type": "string", "minLength": 1, "description": "Shell command evaluated at each revision. Exit 0 = good, 125 = skip, any other non-zero = bad." }, "invert": { "default": false, "description": "Find the commit that FIXED the behavior instead of the one that broke it (exit 0 is treated as bad).", "type": "boolean" }, "maxSteps": { "default": 40, "description": "Maximum bisection steps before giving up.", "type": "integer", "exclusiveMinimum": 0, "maximum": 1000 }, "stepTimeoutMs": { "default": 600000, "description": "Per-step timeout in milliseconds; a timed-out step is treated as a skip.", "type": "integer", "exclusiveMinimum": 0 } }, "required": [ "good", "run" ], "additionalProperties": false }, "strict": true, "deferrable": true, "loadMode": "discoverable", "summary": "Find the commit that introduced a regression by driving git bisect with a shell predicate" }, "eval": { "name": "eval", "label": "Eval", "description": "Run code in a persistent kernel using a list of cells.\n\n\nEach call submits one or more cells. Cells run in array order. State persists within each language across cells **and across tool calls**.\n\nCell fields:\n\n- `language` — `\"js\"` for the persistent JavaScript VM.\n- `code` — cell body, verbatim. Newlines, quotes, and indentation are JSON-encoded; no fences, no headers.\n- `title` (optional) — short label shown in the transcript (e.g. `\"imports\"`, `\"load config\"`).\n- `timeout` (optional) — per-cell timeout in seconds (1-600). Default 30.\n- `reset` (optional) — wipe this cell's language kernel before running.\n\n**Work incrementally:**\n\n- One logical step per cell (imports, define, test, use).\n- Pass multiple small cells in one call.\n- Define small reusable functions for individual debugging.\n- Put workflow explanations in the assistant message or `title` — never inside cell code.\n\n**On failure:** errors identify the failing cell (e.g., \"Cell 3 failed\"). Resubmit only the fixed cell (or fixed cell + remaining cells).\n\n\n\nHelpers are async and `await`able. Trailing options are a final object literal.\n```\ndisplay(value) → None\n Render a value in the current cell output.\nprint(value, ...) → None\n Print to the cell's text output.\nread(path, offset?=1, limit?=None) → str\n Read file contents as text. offset/limit are 1-indexed line bounds.\nwrite(path, content) → str\n Write content to a file (creates parent directories). Returns the resolved path.\nappend(path, content) → str\n Append content to a file. Returns the resolved path.\ntree(path?=\".\", max_depth?=3, show_hidden?=False) → str\n Render a directory tree.\ndiff(a, b) → str\n Unified diff between two files.\nenv(key?=None, value?=None) → str | None | dict\n No args → full environment as dict. One arg → value of `key`. Two args → set `key=value` and return value.\noutput(*ids, format?=\"raw\", query?=None, offset?=None, limit?=None) → str | dict | list[dict]\n Read task/agent output by ID. Single id returns text/dict; multiple ids return a list.\ntool.(args) → unknown\n Invoke any session tool by name. `args` is the tool's parameter object.\n```\n\n\n\nCells render like a Jupyter notebook. `display(value)` renders non-presentable data as an interactive JSON tree. Presentable values (figures, images, dataframes, etc.) use their native representation.\n\n\n\n- **js**: the VM exposes a selective `process` subset, Web APIs, `Buffer`, `fs/promises`, and the `Bun` global.\n\n\n\n```json\n{\n \"cells\": [\n { \"language\": \"js\", \"title\": \"summary\", \"reset\": true, \"code\": \"const data = JSON.parse(await read('package.json'));\\ndisplay(data);\\nreturn data.name;\" }\n ]\n}\n```\n", "parameters": { "type": "object", "properties": { "cells": { "minItems": 1, "type": "array", "items": { "type": "object", "properties": { "language": { "type": "string", "enum": [ "py", "js" ], "description": "runtime: \"py\" for the IPython kernel, \"js\" for the persistent JS VM" }, "code": { "type": "string", "description": "cell body, verbatim. Use top-level await freely." }, "title": { "description": "short label shown in transcript (e.g. \"imports\", \"load config\")", "type": "string" }, "timeout": { "description": "per-cell timeout in seconds (1-600, default 30)", "type": "integer", "minimum": 1, "maximum": 600 }, "reset": { "description": "wipe this cell's language kernel before running. Other languages are untouched.", "type": "boolean" } }, "required": [ "language", "code" ], "additionalProperties": false }, "description": "cells executed in order. State persists within each language across cells and tool calls." } }, "required": [ "cells" ], "additionalProperties": false }, "strict": true, "deferrable": true, "loadMode": "discoverable", "summary": "Execute Python or JavaScript code in an in-process eval backend", "concurrency": "exclusive" }, "python": { "name": "python", "label": "Python", "description": "Execute Python in a persistent per-session REPL kernel.\n\nVariables, imports, and loaded data persist across calls in the current GJC session. The kernel runs in the session working directory. Each `execute` call is appended to a JSONL transcript under `.gjc/_session-{sessionid}/ipykernels/`; display artifacts are stored under `.gjc/_session-{sessionid}/ipykernels/artifacts/`.\n\n## Actions\n\n- `execute` (default) — run `code` in the persistent REPL. Requires `code`.\n- `clear` — dispose this session's Python kernel. The next `execute` starts a fresh kernel with no retained state.\n\n## Use\n\nUse this tool for stateful Python work. It is distinct from `eval`: each has a separate kernel and owner, so state is not shared between them.\n", "parameters": { "type": "object", "properties": { "action": { "default": "execute", "description": "\"execute\" runs `code` in the persistent per-session REPL and is the default. \"clear\" disposes this session's kernel; the next execute starts a fresh kernel.", "type": "string", "enum": [ "execute", "clear" ] }, "code": { "description": "Python source to execute when action is \"execute\" (required then, ignored for \"clear\").", "type": "string" } }, "additionalProperties": false }, "strict": true, "deferrable": true, "loadMode": "discoverable", "summary": "Execute Python in a persistent per-session REPL kernel (every call is appended to the session transcript)", "concurrency": "exclusive" }, "calc": { "name": "calc", "label": "Calc", "description": "Performs basic calculations.\n\n\n- Supports +, -, *, /, %, ** and parentheses\n- Supports decimal, hex (0x), binary (0b), and octal (0o) literals\n\n\n\nReturns each calculation result with its prefix and suffix applied.\n", "parameters": { "type": "object", "properties": { "calculations": { "type": "array", "items": { "type": "object", "properties": { "expression": { "type": "string", "description": "math expression" }, "prefix": { "type": "string", "description": "prefix text" }, "suffix": { "type": "string", "description": "suffix text" } }, "required": [ "expression", "prefix", "suffix" ], "additionalProperties": false }, "description": "calculations to evaluate" } }, "required": [ "calculations" ], "additionalProperties": false }, "strict": true, "deferrable": true, "loadMode": "discoverable", "summary": "Evaluate a mathematical expression" }, "ssh": { "name": "ssh", "label": "SSH", "description": "Runs commands on remote hosts.\n\n\nYou MUST build commands from the reference below.\nThe local coreutils restrictions (`cat`/`grep`/`find`/`head`/`tail` bans) do NOT apply on remote hosts — `read`/`search`/`find` cannot reach them, so these shell commands are the only tools available there.\n\n\n\n**linux/bash, linux/zsh, macos/bash, macos/zsh** — Unix-like:\n- Files: `ls`, `cat`, `head`, `tail`, `grep`, `find`\n- System: `ps`, `top`, `df`, `uname` (all), `free` (Linux only)\n- Navigation: `cd`, `pwd`\n**windows/bash, windows/sh** — Windows Unix layer (WSL, Cygwin, Git Bash):\n- Files/System/Navigation: same as Unix-like above, minus `free`\n**windows/powershell** — PowerShell:\n- Files: `Get-ChildItem`, `Get-Content`, `Select-String`\n- System: `Get-Process`, `Get-ComputerInfo`\n- Navigation: `Set-Location`, `Get-Location`\n**windows/cmd** — Command Prompt:\n- Files: `dir`, `type`, `findstr`, `where`\n- System: `tasklist`, `systeminfo`\n- Navigation: `cd`, `echo %CD%`\n\n\n\nYou MUST verify the shell type from \"Available hosts\" and use matching commands.\n\n\n\n# List files: Linux\nHost: server1 (10.0.0.1) | linux/bash. Command: `ls -la /home/user`\n# Show running processes: Windows cmd\nHost: winbox (192.168.1.5) | windows/cmd. Command: `tasklist /v`\n# Get system info: macOS\nHost: macbook (10.0.0.20) | macos/zsh. Command: `uname -a && sw_vers`\n", "parameters": { "type": "object", "properties": { "host": { "type": "string", "description": "ssh host" }, "command": { "type": "string", "description": "remote command" }, "cwd": { "description": "remote working directory", "type": "string" }, "timeout": { "default": 60, "description": "timeout in seconds", "type": "number" } }, "required": [ "host", "command" ], "additionalProperties": false }, "strict": true, "deferrable": true, "loadMode": "discoverable", "summary": "Execute a command on a remote host over SSH", "concurrency": "exclusive" }, "github": { "name": "github", "label": "GitHub", "description": "GitHub CLI tool with a single op-based dispatch. Wraps `gh` for repositories, pull requests, search, checkout, push, and Actions watch workflows. For reading a single issue or PR view, use the `issue://` or `pr://` URL schemes (cached automatically). For reading PR diffs, use `pr:///diff` (changed-file listing), `pr:///diff/` (single file slice, 1-indexed), or `pr:///diff/all` (full unified diff).\n\n\nPick the operation via `op`. Each op uses a subset of the parameters. Search ops (`search_issues`, `search_prs`, `search_code`, `search_commits`) default `repo` to the current checkout's `owner/repo` when omitted; pass an explicit `repo:`/`org:`/`user:` qualifier in `query` to search outside it.\n- `repo_view` — Read repository metadata. Optional `repo` (owner/repo) and `branch`. Falls back to the current checkout or default `gh` repo.\n- `pr_create` — Create a pull request. Either provide `title` (and optional `body`) or set `fill: true` to auto-fill from commits. Optional `base` (target, defaults to repo default), `head` (source, defaults to current branch), `draft`, `repo`, `reviewer[]`, `assignee[]`, `label[]`. Returns the new PR URL plus a summary.\n- `pr_checkout` — Check one or more pull requests out into dedicated git worktrees. Optional `pr` (number, URL, branch, or array of any of those — pass an array to batch-check-out multiple PRs in one call), `repo`, `force` (reset existing local branch).\n- `pr_push` — Push a checked-out PR branch back to its source branch. Requires the branch to have been checked out via `op: pr_checkout` (carries push metadata). Optional `branch`; defaults to the current checked-out git branch. Optional `forceWithLease`.\n- `search_issues` — Search issues using normal GitHub issue search syntax. Optional `query` (required unless `since`/`until` is set), `repo`, `limit`, `since`, `until`, `dateField`.\n- `search_prs` — Search pull requests using normal GitHub PR search syntax. Optional `query` (required unless `since`/`until` is set), `repo`, `limit`, `since`, `until`, `dateField`.\n- `search_code` — Search code with GitHub code search syntax. Required `query`. Optional `repo`, `limit`. Returns matching paths with surrounding fragments. Date filtering (`since`/`until`) is **not** supported by GitHub code search.\n- `search_commits` — Search commits across GitHub. Optional `query` (required unless `since`/`until` is set), `repo`, `limit`, `since`, `until`. `dateField` is ignored — always uses `committer-date`.\n- `search_repos` — Search repositories across GitHub. Optional `query` (required unless `since`/`until` is set), `limit`, `since`, `until`, `dateField` (use query qualifiers like `org:`, `language:` instead of `repo`).\n- Date filter format for `since` / `until`: relative duration `` (`m`/`h`/`d`/`w`/`mo`/`y`, e.g. `3d`, `12h`, `2w`), an ISO date `YYYY-MM-DD`, or an ISO datetime. Translated to a single GitHub-search qualifier (`created:≥…`, `created:≤…`, or `created:since..until`). `dateField: \"updated\"` maps to `updated:` for issues/prs and `pushed:` for repos. When you only want a date filter and no keywords, omit `query` entirely.\n- `run_watch` — Watch a GitHub Actions workflow run. Optional `run` (id or URL). Omitting `run` watches all workflow runs for the current HEAD commit; `branch` falls back to the current branch. Optional `tail` (log lines per failed job). Streams snapshots, fast-fails on the first detected job failure (with a brief grace period to capture concurrent failures), then fetches tailed logs for the failed jobs. The full failed-job logs are saved as a session artifact for on-demand reads.\n\n\n\nReturns a concise readable summary tailored to the chosen op (repo metadata, PR metadata, diff text, search results, checkout info, push target, or workflow run snapshot). For `run_watch`, the full failed-job logs are saved as a session artifact when failures occur.\n", "parameters": { "type": "object", "properties": { "op": { "type": "string", "enum": [ "repo_view", "pr_create", "pr_checkout", "pr_push", "search_issues", "search_prs", "search_code", "search_commits", "search_repos", "run_watch" ], "description": "github operation" }, "repo": { "type": "string", "description": "owner/repo" }, "branch": { "type": "string", "description": "branch" }, "pr": { "anyOf": [ { "type": "string" }, { "type": "array", "items": { "type": "string" } } ], "description": "pr number, url, or branch" }, "force": { "type": "boolean", "description": "reset existing local branch" }, "forceWithLease": { "type": "boolean", "description": "force-with-lease push" }, "title": { "type": "string", "description": "pr title" }, "body": { "type": "string", "description": "pr body markdown" }, "base": { "type": "string", "description": "pr base branch" }, "head": { "type": "string", "description": "pr head branch" }, "draft": { "type": "boolean", "description": "open pr as draft" }, "fill": { "type": "boolean", "description": "auto-fill pr title/body from commits" }, "reviewer": { "type": "array", "items": { "type": "string" }, "description": "reviewers" }, "assignee": { "type": "array", "items": { "type": "string" }, "description": "assignees" }, "label": { "type": "array", "items": { "type": "string" }, "description": "labels" }, "query": { "type": "string", "description": "search query" }, "since": { "type": "string", "description": "lower-bound date filter" }, "until": { "type": "string", "description": "upper-bound date filter" }, "dateField": { "default": "created", "type": "string", "enum": [ "created", "updated" ], "description": "date field" }, "limit": { "default": 10, "description": "max results", "type": "number" }, "run": { "type": "string", "description": "actions run id or url" }, "tail": { "default": 15, "description": "log lines per failed job", "type": "number" } }, "required": [ "op" ], "additionalProperties": false }, "strict": true, "deferrable": true, "loadMode": "discoverable", "summary": "Interact with GitHub issues, pull requests, and repositories" }, "find": { "name": "find", "label": "Find", "description": "Finds files using fast pattern matching that works with any codebase size.\n\n\n- `paths` is required and accepts an array of globs, files, or directories\n- Pass multiple targets as **separate array elements** (`paths: [\"a\", \"b\"]`), NEVER as a single comma-joined string (`paths: [\"a,b\"]` is rejected)\n- `gitignore` defaults to `true` and hides files matched by `.gitignore`. Set `gitignore: false` to find `.env*`, `*.log`, freshly-created build outputs, or anything else your repo ignores\n- `hidden` defaults to `true`; combine with `gitignore: false` to surface dotfiles that are also gitignored\n- `timeout` is in seconds (default 5, clamped to 0.5–60). On timeout, find returns whatever partial matches it has collected with `truncated: true` and a notice — increase `timeout` or narrow the pattern instead of retrying blindly\n- You SHOULD perform multiple searches in parallel when potentially useful\n\n\n\nMatching file paths sorted by modification time (most recent first). Truncated at 1000 entries or 50KB (configurable via `limit`).\n\n\n\n# Find files\n`{\"paths\": [\"src/**/*.ts\"], \"limit\": 1000}`\n# Multiple targets — separate array elements\n`{\"paths\": [\"src/**/*.ts\", \"test/**/*.ts\"]}`\n# Find gitignored files like .env\n`{\"paths\": [\".env*\"], \"gitignore\": false}`\n# Long-running search on a slow volume\n`{\"paths\": [\"/Volumes/Storage/**/*.py\"], \"timeout\": 30}`\n\n\n\nFor open-ended searches requiring multiple rounds of globbing and searching, delegate a bounded fact-finding task to an appropriate canonical role agent (`planner` for sequencing/context maps or `architect` for read-only architecture assessment) instead.\n\n\n\n- Use separate array entries for multiple path globs.\n- Set `gitignore: false` only when ignored files are intentionally in scope.\n", "parameters": { "type": "object", "properties": { "paths": { "minItems": 1, "type": "array", "items": { "type": "string", "description": "glob including search path" }, "description": "globs including search paths" }, "hidden": { "default": true, "description": "include hidden files", "type": "boolean" }, "gitignore": { "default": true, "description": "respect gitignore", "type": "boolean" }, "limit": { "default": 1000, "description": "max results", "type": "number" }, "timeout": { "default": 5, "description": "timeout in seconds (0.5–60)", "type": "number", "minimum": 0.5, "maximum": 60 } }, "required": [ "paths" ], "additionalProperties": false }, "strict": true, "deferrable": true, "loadMode": "discoverable", "summary": "Find files and directories matching a glob pattern" }, "search": { "name": "search", "label": "Search", "description": "Searches files using powerful regex matching.\n\n\n- Supports Rust regex syntax (RE2-style — no lookaround or backreferences). Use line anchors or post-filters instead of (?!…)/(?\n\n\n\n\n\n- Search paths are an array; pass separate entries rather than comma-joined paths.\n- Use a cross-line pattern only when the match actually spans lines.\n", "parameters": { "type": "object", "properties": { "pattern": { "type": "string", "description": "regex pattern" }, "paths": { "description": "files, directories, globs, or internal URLs to search (defaults to the working directory when omitted)", "minItems": 1, "type": "array", "items": { "type": "string", "description": "file, directory, glob, or internal URL to search" } }, "i": { "description": "case-insensitive search", "type": "boolean" }, "gitignore": { "description": "respect gitignore", "type": "boolean" }, "skip": { "description": "files to skip before collecting results — use to paginate when the prior call hit the file limit", "type": "number" } }, "required": [ "pattern" ], "additionalProperties": false }, "strict": true, "deferrable": true, "loadMode": "discoverable", "summary": "Search file contents using ripgrep (fast text search)" }, "lsp": { "name": "lsp", "label": "LSP", "description": "Interacts with Language Server Protocol servers for code intelligence.\n\n\n- `diagnostics`: Get errors/warnings for a concrete file or a glob of files\n- `definition`: Go to symbol definition → file path + position + 3-line source context\n- `type_definition`: Go to symbol type definition → file path + position + 3-line source context\n- `implementation`: Find concrete implementations → file path + position + 3-line source context\n- `references`: Find references → locations with 3-line source context (first 50), remaining location-only\n- `hover`: Get type info and documentation → type signature + docs\n- `symbols`: List symbols in a file, or search workspace with `file: \"*\"` and a `query`\n- `rename`: Rename symbol across codebase → preview or apply edits\n- `rename_file`: Rename or move a file/directory; sends `workspace/willRenameFiles` so LSP servers update import paths and other references → preview or apply edits + filesystem rename\n- `code_actions`: List available quick-fixes/refactors/import actions; apply one when `apply: true` and `query` matches title or index\n- `status`: Show active language servers\n- `capabilities`: Dump per-server capabilities (standard + experimental + executeCommand list) for discovery — file scopes to one server, omitted/`\"*\"` lists every active server\n- `request`: Send a raw LSP request to a server — `query` is the method name (e.g., `rust-analyzer/expandMacro`, `typescript/goToSourceDefinition`, `workspace/executeCommand`); use `payload` for arbitrary JSON params or let the tool auto-build them from `file`/`line`/`symbol`\n- `reload`: Restart a specific server (via `file`) or all servers with `file: \"*\"`\n\n\n\n- `file`: File path, glob pattern (e.g. `src/**/*.ts`), or `\"*\"` for workspace scope where supported. Globs are expanded locally before dispatch. `\"*\"` routes `symbols`/`reload` to their workspace-wide form; workspace build diagnostics are unavailable through `lsp`.\n- `line`: 1-indexed line number for position-based actions\n- `symbol`: Substring on the target line used to resolve column automatically. Append `#N` to pick the Nth occurrence on that line (1-indexed; default 1) — e.g. `foo#2` selects the second `foo`.\n- `query`: Symbol search query, code-action kind filter / selector (list/apply mode), or LSP method name when `action: request`\n- `new_name`: Required for `rename` (new symbol identifier) and `rename_file` (destination path)\n- `apply`: Apply edits for rename/rename_file/code_actions (default true for rename and rename_file; list mode for code_actions unless explicitly true)\n- `payload`: JSON-encoded params for `action: request`. Overrides the auto-built `{ textDocument, position }` shape when present.\n- `timeout`: Request timeout in seconds (clamped to 5-60, default 20)\n\n\n\n- Requires running LSP server for target language\n- Some operations require file to be saved to disk\n- Glob expansion samples up to 20 files per request; narrow broad patterns when they exceed that limit\n- When `symbol` is provided for position-based actions, missing symbols or out-of-bounds `#N` occurrence selectors return an explicit error instead of silently falling back\n\n\n\n- You MUST use `lsp` for symbol-aware operations (rename, find references, go to definition/implementation, code actions) whenever a language server is available — it is safer and more accurate than text-based alternatives.\n- You NEVER perform cross-file renames with `ast_edit`, `sed`, or manual edits when `lsp` `rename` can do it. Text-based renames miss shadowing, re-exports, and usages in other files.\n- Prefer `lsp` `code_actions` for imports, quick-fixes, and refactors the language server already knows how to apply.\n", "parameters": { "type": "object", "properties": { "action": { "type": "string", "enum": [ "diagnostics", "definition", "references", "hover", "symbols", "rename", "rename_file", "code_actions", "type_definition", "implementation", "status", "reload", "capabilities", "request" ] }, "file": { "type": "string", "description": "file path or source path for rename_file" }, "line": { "type": "number", "description": "line number (1-indexed)" }, "symbol": { "type": "string", "description": "symbol substring on the line" }, "query": { "type": "string", "description": "search query or code-action selector" }, "new_name": { "type": "string", "description": "new symbol name or destination path" }, "apply": { "type": "boolean", "description": "apply edits" }, "timeout": { "type": "number", "description": "request timeout in seconds" }, "payload": { "type": "string", "description": "json-encoded request params" } }, "required": [ "action" ], "additionalProperties": false }, "strict": true, "deferrable": true, "loadMode": "discoverable", "summary": "Query LSP (language server) for diagnostics, hover info, and references", "mergeCallAndResult": true, "inline": true }, "browser": { "name": "browser", "label": "Browser", "description": "Drives a real Chromium tab with full puppeteer access via JS execution.\n\n\n- For static web content (articles, docs, issues/PRs, JSON, PDFs, feeds), prefer the `read` tool with a URL. Use this tool only when you need JS execution, authentication, or interactive actions.\n- Four actions:\n - `open` — acquire (or reuse) a named tab. `name` defaults to `\"main\"`. Optional `url`, `viewport`, and `dialogs: \"accept\" | \"dismiss\"` (auto-handles `alert`/`confirm`/`beforeunload`). The `app` field selects the browser kind (spawned binary, saved Chrome profile, or existing CDP endpoint); omitted means headless Chromium with stealth patches.\n - `close` — release a tab by `name`, or every tab with `all: true`. `kill: true` also terminates a spawned-app process tree.\n - `act` — run a list of structured `actions` against an existing tab without writing JS (preferred for routine navigation/interaction). Each step is `{ verb, … }`; verbs: `navigate {url, wait_until?}`, `click {id|selector}`, `type {id|selector, text}`, `fill {selector, value}`, `select {selector, values}`, `press {key, selector?}`, `scroll {dx?, dy?}`, `back`, `wait {selector?|ms?}`, `observe {viewport_only?, include_all?}`, `extract {format?}`, `screenshot`. Address elements by the numeric `id` from a prior `observe` (preferred) or a selector. Steps run in order; the tool returns per-step results.\n - `run` — execute JS against an existing tab. `code` is the body of an async function with `page`, `browser`, `tab`, `display`, `assert`, `wait` in scope. The return value is JSON-stringified into the tool result; `display(value)` calls accumulate text/images. Use `run` only when an `act` verb does not cover what you need.\n- Tabs survive across `run` calls and across in-process subagents. Open once, reuse many times.\n- Browser kinds: no `app` launches headless Chromium; `app.path` reuses CDP or kills stale same-path processes before spawning — NEVER use it for a daily Chrome profile; use explicit `app.browser: \"chrome\"` profile mode instead. In profile mode, `path` defaults to installed Chrome/Chromium and `profile_directory` defaults to `\"Default\"`, but `user_data_dir` must name a separate non-default Chrome data directory: Chrome 136+ disables remote debugging for its default data directory. Only Chrome/Chromium executables are admitted; Edge, Brave, Vivaldi, Opera, unknown browser brands, and default Chrome data roots are rejected. Use `app.cdp_url` to attach to an already-authorized browser. Saved-profile/CDP automation has access to that profile's cookies and authenticated accounts. Profile mode refuses a matching non-CDP Chrome instead of killing/relaunching it, and `kill: true` can terminate only a Chrome process GJC launched; `app.cdp_url` is externally owned and disconnect-only. CDP must stay on `127.0.0.1`: it grants full browser-account access.\n- Inside `run`, `tab` exposes high-level helpers (`goto`, `observe`, `id`, `click`, `type`, `fill`, `press`, `waitFor`, `screenshot`, `extract`, …); reach for `page` (raw puppeteer Page) when they don't cover it.\n- Selectors accept CSS as well as puppeteer query handlers: `aria/Sign in`, `text/Continue`, `xpath/…`, `pierce/…`.\n- Runtime diagnostics are opt-in: pass `diagnostics: true` to `open` to subscribe the tab to page `Runtime.exceptionThrown` and `console.error` events. The next successful `act`/`run` response then includes at most 20 `runtimeDiagnostics` entries plus `runtimeDiagnosticsDropped`, then drains them. Entries contain only kind, time, origin-only URL, line/column, and a built-in error class from a fixed allowlist — never path segments, query strings, messages, console arguments, values, or stacks. Output is byte-bounded and marks truncation explicitly.\n- Full reference — helpers, browser kinds, CDP/security details, and more examples — read `gjc://tools/browser.md`.\n\n\n\n- You MUST call `open` before `run` or `act`. Neither implicitly creates a tab.\n- You MUST observe before taking a screenshot to understand page state; screenshot only when visual appearance matters.\n- After a `tab.goto()` or any navigation, prior element ids from `tab.observe()` are invalidated. Re-observe before referencing them.\n- `code` runs with full Node access. Treat it as your code, not sandboxed code.\n\n\n\n# Open a tab and read structured page data\n`{\"action\":\"open\",\"name\":\"docs\",\"url\":\"https://example.com\"}`\n`{\"action\":\"act\",\"name\":\"docs\",\"actions\":[{\"verb\":\"observe\"}]}`\n\n# Click an observed element, then fill and submit a form\n`{\"action\":\"act\",\"name\":\"docs\",\"actions\":[{\"verb\":\"click\",\"id\":12},{\"verb\":\"fill\",\"selector\":\"input[name=email]\",\"value\":\"me@example.com\"},{\"verb\":\"click\",\"selector\":\"text/Continue\"}]}`\n\n# Use `run` only when `act` has no suitable verb\n`{\"action\":\"run\",\"name\":\"docs\",\"code\":\"const count = await page.locator('canvas').count(); return { count };\"}`\n\n\n\n- Per call: any `display(value)` outputs (text/images) followed by the JSON-stringified return value of the `code` function. `run` always produces at least a status line.\n", "parameters": { "type": "object", "properties": { "action": { "type": "string", "enum": [ "open", "close", "run", "act" ], "description": "operation" }, "name": { "type": "string", "description": "tab id (default 'main')" }, "url": { "type": "string", "description": "url to open" }, "app": { "type": "object", "properties": { "path": { "type": "string", "description": "binary path to spawn (default: the installed Chrome/Chromium)" }, "cdp_url": { "type": "string", "description": "existing cdp endpoint" }, "browser": { "type": "string", "enum": [ "chrome" ], "description": "existing browser profile mode" }, "user_data_dir": { "type": "string", "description": "non-default Chrome user data directory containing profiles (required for Chrome 136+ CDP)" }, "profile_directory": { "type": "string", "description": "Chrome profile directory name, e.g. \"Profile 10\" (default \"Default\")" }, "background": { "type": "boolean", "description": "prefer background/hidden Chrome profile launch when supported" }, "no_focus": { "type": "boolean", "description": "avoid focusing Chrome during profile launch when supported" }, "cdp_port": { "type": "integer", "exclusiveMinimum": 0, "description": "local CDP port for launched Chrome profile" }, "args": { "type": "array", "items": { "type": "string" }, "description": "extra cli args" }, "target": { "type": "string", "description": "substring to pick a window" } }, "additionalProperties": false }, "viewport": { "type": "object", "properties": { "width": { "type": "number" }, "height": { "type": "number" }, "scale": { "type": "number" } }, "required": [ "width", "height" ], "additionalProperties": false }, "wait_until": { "type": "string", "enum": [ "load", "domcontentloaded", "networkidle0", "networkidle2" ], "description": "navigation wait condition" }, "dialogs": { "type": "string", "enum": [ "accept", "dismiss" ], "description": "auto-handle dialogs" }, "diagnostics": { "type": "boolean", "description": "opt-in: capture bounded page runtime diagnostics (page exceptions and console.error metadata) in the next successful run/act response" }, "code": { "type": "string", "description": "js body to run in tab" }, "actions": { "type": "array", "items": { "type": "object", "properties": { "verb": { "type": "string", "enum": [ "navigate", "click", "type", "fill", "select", "press", "scroll", "back", "wait", "observe", "extract", "screenshot" ], "description": "structured action verb" }, "id": { "type": "number", "description": "element id from a prior observe" }, "selector": { "type": "string", "description": "css/puppeteer selector" }, "text": { "type": "string", "description": "text to type" }, "value": { "type": "string", "description": "value for fill" }, "values": { "type": "array", "items": { "type": "string" }, "description": "option value(s) for select" }, "url": { "type": "string", "description": "url for navigate" }, "key": { "type": "string", "description": "key for press, e.g. Enter" }, "dx": { "type": "number", "description": "horizontal scroll delta" }, "dy": { "type": "number", "description": "vertical scroll delta" }, "ms": { "type": "number", "description": "sleep ms for wait without selector" }, "format": { "type": "string", "enum": [ "markdown", "text", "html" ], "description": "extract format" }, "wait_until": { "type": "string", "enum": [ "load", "domcontentloaded", "networkidle0", "networkidle2" ], "description": "navigation wait condition for navigate" }, "viewport_only": { "type": "boolean", "description": "observe: only viewport elements" }, "include_all": { "type": "boolean", "description": "observe: include non-interactive elements" } }, "required": [ "verb" ], "additionalProperties": false }, "description": "structured action steps for action 'act'" }, "timeout": { "default": 30, "description": "timeout in seconds (default 30, max 300)", "type": "number" }, "all": { "type": "boolean", "description": "close every tab" }, "kill": { "type": "boolean", "description": "also kill spawned-app browsers" } }, "required": [ "action" ], "additionalProperties": false }, "strict": true, "deferrable": true, "loadMode": "discoverable", "summary": "Control a headless browser to navigate and interact with web pages" }, "computer": { "name": "computer", "label": "Computer", "description": "# computer\n\n`computer` is available by default on supported Apple Silicon macOS. It controls the real desktop, so use it only when the task genuinely needs real desktop screenshot or input control.\n\n## Safety contract\n\n- Disabled means disabled: when the tool is disabled (`computer.alwaysOn=false` with `computer.enabled` unset/false) or the platform is unsupported, every action including `screenshot` fails with `COMPUTER_DISABLED` and captures nothing.\n- Callable only on Apple Silicon macOS (`arm64` darwin); available by default there, with `computer.alwaysOn=false` as the off-switch and `computer.enabled=true` as the manual enable path.\n- Native execution remains supervisor-gated. If the stop/suspend supervisor is unavailable, stale, suspended, permissioned off, display-stale, or cancelled, the action fails closed with a `COMPUTER_*` code. Coordinate actions carry the latest known screenshot display epoch when one is available so display-topology changes fail with `COMPUTER_DISPLAY_STALE`.\n- Respect the user's stop/suspend request immediately. Do not loop desktop actions after a stop/suspend/error.\n- The user can stop or suspend the session at any time with the configured kill-switch hotkey (default `Control+Option+Command+Escape`). If you see `COMPUTER_CANCELLED` or `COMPUTER_SUPERVISOR_NOT_LIVE`, stop and wait for the user.\n- Native side-effecting actions restore the global cursor after releasing held input. An input batch owns one serialized native capture-to-restore transaction across its ordered steps. This does not restore application focus or isolate input to a PID/window, and concurrent manual cursor movement can be overwritten.\n\n## Coordinate contract\n\nCoordinates are screenshot pixels, not CSS pixels and not normalized fractions. Use the latest successful `screenshot` dimensions and origin/scale metadata as the coordinate frame. Do not guess coordinates outside the screenshot bounds.\n\nFor stale-display protection to apply, derive pointer coordinates from a successful screenshot in the same tool session; a screenshot-first `batch` is preferred because later coordinate steps are validated against that screenshot and carry its display epoch into native execution. If a coordinate is out of bounds, the batch stops and reports `COMPUTER_COORD_INVALID`. Always capture a fresh screenshot before acting if the display may have changed.\n\n## Actions\n\nThe model action object uses exactly these snake_case actions and fields:\n\n- `screenshot` — capture the enabled desktop.\n- `click` — `x`, `y`, optional `button` (`left`, `right`, `middle`).\n- `double_click` — `x`, `y`, optional `button`.\n- `move` — `x`, `y`, optional `button`.\n- `drag` — `x`, `y`, `to_x`, `to_y`, optional `button`.\n- `scroll` — `x`, `y`, `scroll_x`, `scroll_y`.\n- `type` — `text`.\n- `keypress` — `keys` string array.\n- `wait` — `ms`.\n- `batch` — `actions`: a non-empty array of the single actions above. Steps run in order and the result includes per-step status and the last screenshot captured inside the batch.\n\nShared optional fields: `timeout` seconds and `include_screenshot` for a bounded post-action screenshot when supported.\n\nDo not use camelCase fields such as `doubleClick`, `toX`, `scrollX`, or `includeScreenshot` in the model action object.\n\n## Examples\n\nTake a single screenshot:\n\n```json\n{ \"action\": \"screenshot\" }\n```\n\nClick a coordinate from the latest screenshot:\n\n```json\n{ \"action\": \"click\", \"x\": 120, \"y\": 340 }\n```\n\nRun a focused sequence in one batch — screenshot first, then act, so coordinates are validated:\n\n```json\n{\n \"action\": \"batch\",\n \"actions\": [\n { \"action\": \"screenshot\" },\n { \"action\": \"click\", \"x\": 120, \"y\": 340 },\n { \"action\": \"type\", \"text\": \"hello\" },\n { \"action\": \"keypress\", \"keys\": [\"Return\"] }\n ]\n}\n```\n\n## Error recovery\n\n- `COMPUTER_COORD_INVALID`: the coordinate was outside the latest screenshot bounds. Capture a fresh screenshot and re-derive coordinates.\n- `COMPUTER_DISPLAY_STALE`: the display changed since the screenshot. Capture a fresh screenshot before acting.\n- `COMPUTER_SUPERVISOR_NOT_LIVE` / `COMPUTER_SUSPENDED` / `COMPUTER_CANCELLED`: stop acting and wait for the user.\n- `COMPUTER_PERMISSION_REQUIRED`: Accessibility permission is required for input. Ask the user to grant it.\n- `COMPUTER_SCREENSHOT_FAILED`: screen capture failed, commonly because Screen Recording permission is missing. Ask the user to grant it before retrying.\n- `COMPUTER_DISABLED`: the tool is disabled or the host is unsupported. Do not retry.\n- `COMPUTER_CURSOR_CAPTURE_FAILED`: no input was sent because the original cursor position could not be captured.\n- `COMPUTER_CURSOR_RESTORE_FAILED`: input may have completed, but cursor restoration failed. Stop and ask the user to inspect the desktop before retrying; a retained primary error describes any action failure.\n- `COMPUTER_TRANSACTION_FAILED`: native input cleanup could not be trusted. Stop and ask the user to inspect the desktop before retrying.\n\nAfter any error, resume with a fresh screenshot rather than guessing.", "parameters": { "anyOf": [ { "oneOf": [ { "type": "object", "properties": { "action": { "type": "string", "const": "screenshot" }, "timeout": { "description": "Maximum time in seconds for this action.", "type": "number", "exclusiveMinimum": 0 }, "include_screenshot": { "description": "Capture a bounded post-action screenshot when supported.", "type": "boolean" } }, "required": [ "action" ], "additionalProperties": false }, { "type": "object", "properties": { "action": { "type": "string", "const": "click" }, "x": { "type": "number" }, "y": { "type": "number" }, "button": { "type": "string", "enum": [ "left", "right", "middle" ] }, "timeout": { "description": "Maximum time in seconds for this action.", "type": "number", "exclusiveMinimum": 0 }, "include_screenshot": { "description": "Capture a bounded post-action screenshot when supported.", "type": "boolean" } }, "required": [ "action", "x", "y" ], "additionalProperties": false }, { "type": "object", "properties": { "action": { "type": "string", "const": "double_click" }, "x": { "type": "number" }, "y": { "type": "number" }, "button": { "type": "string", "enum": [ "left", "right", "middle" ] }, "timeout": { "description": "Maximum time in seconds for this action.", "type": "number", "exclusiveMinimum": 0 }, "include_screenshot": { "description": "Capture a bounded post-action screenshot when supported.", "type": "boolean" } }, "required": [ "action", "x", "y" ], "additionalProperties": false }, { "type": "object", "properties": { "action": { "type": "string", "const": "move" }, "x": { "type": "number" }, "y": { "type": "number" }, "button": { "type": "string", "enum": [ "left", "right", "middle" ] }, "timeout": { "description": "Maximum time in seconds for this action.", "type": "number", "exclusiveMinimum": 0 }, "include_screenshot": { "description": "Capture a bounded post-action screenshot when supported.", "type": "boolean" } }, "required": [ "action", "x", "y" ], "additionalProperties": false }, { "type": "object", "properties": { "action": { "type": "string", "const": "drag" }, "x": { "type": "number" }, "y": { "type": "number" }, "to_x": { "type": "number" }, "to_y": { "type": "number" }, "button": { "type": "string", "enum": [ "left", "right", "middle" ] }, "timeout": { "description": "Maximum time in seconds for this action.", "type": "number", "exclusiveMinimum": 0 }, "include_screenshot": { "description": "Capture a bounded post-action screenshot when supported.", "type": "boolean" } }, "required": [ "action", "x", "y", "to_x", "to_y" ], "additionalProperties": false }, { "type": "object", "properties": { "action": { "type": "string", "const": "scroll" }, "x": { "type": "number" }, "y": { "type": "number" }, "scroll_x": { "type": "number" }, "scroll_y": { "type": "number" }, "timeout": { "description": "Maximum time in seconds for this action.", "type": "number", "exclusiveMinimum": 0 }, "include_screenshot": { "description": "Capture a bounded post-action screenshot when supported.", "type": "boolean" } }, "required": [ "action", "x", "y", "scroll_x", "scroll_y" ], "additionalProperties": false }, { "type": "object", "properties": { "action": { "type": "string", "const": "type" }, "text": { "type": "string" }, "timeout": { "description": "Maximum time in seconds for this action.", "type": "number", "exclusiveMinimum": 0 }, "include_screenshot": { "description": "Capture a bounded post-action screenshot when supported.", "type": "boolean" } }, "required": [ "action", "text" ], "additionalProperties": false }, { "type": "object", "properties": { "action": { "type": "string", "const": "keypress" }, "keys": { "minItems": 1, "type": "array", "items": { "type": "string" } }, "timeout": { "description": "Maximum time in seconds for this action.", "type": "number", "exclusiveMinimum": 0 }, "include_screenshot": { "description": "Capture a bounded post-action screenshot when supported.", "type": "boolean" } }, "required": [ "action", "keys" ], "additionalProperties": false }, { "type": "object", "properties": { "action": { "type": "string", "const": "wait" }, "ms": { "type": "integer", "minimum": 0 }, "timeout": { "description": "Maximum time in seconds for this action.", "type": "number", "exclusiveMinimum": 0 }, "include_screenshot": { "description": "Capture a bounded post-action screenshot when supported.", "type": "boolean" } }, "required": [ "action", "ms" ], "additionalProperties": false } ] }, { "type": "object", "properties": { "action": { "type": "string", "const": "batch" }, "actions": { "minItems": 1, "type": "array", "items": { "oneOf": [ { "type": "object", "properties": { "action": { "type": "string", "const": "screenshot" }, "timeout": { "description": "Maximum time in seconds for this action.", "type": "number", "exclusiveMinimum": 0 }, "include_screenshot": { "description": "Capture a bounded post-action screenshot when supported.", "type": "boolean" } }, "required": [ "action" ], "additionalProperties": false }, { "type": "object", "properties": { "action": { "type": "string", "const": "click" }, "x": { "type": "number" }, "y": { "type": "number" }, "button": { "type": "string", "enum": [ "left", "right", "middle" ] }, "timeout": { "description": "Maximum time in seconds for this action.", "type": "number", "exclusiveMinimum": 0 }, "include_screenshot": { "description": "Capture a bounded post-action screenshot when supported.", "type": "boolean" } }, "required": [ "action", "x", "y" ], "additionalProperties": false }, { "type": "object", "properties": { "action": { "type": "string", "const": "double_click" }, "x": { "type": "number" }, "y": { "type": "number" }, "button": { "type": "string", "enum": [ "left", "right", "middle" ] }, "timeout": { "description": "Maximum time in seconds for this action.", "type": "number", "exclusiveMinimum": 0 }, "include_screenshot": { "description": "Capture a bounded post-action screenshot when supported.", "type": "boolean" } }, "required": [ "action", "x", "y" ], "additionalProperties": false }, { "type": "object", "properties": { "action": { "type": "string", "const": "move" }, "x": { "type": "number" }, "y": { "type": "number" }, "button": { "type": "string", "enum": [ "left", "right", "middle" ] }, "timeout": { "description": "Maximum time in seconds for this action.", "type": "number", "exclusiveMinimum": 0 }, "include_screenshot": { "description": "Capture a bounded post-action screenshot when supported.", "type": "boolean" } }, "required": [ "action", "x", "y" ], "additionalProperties": false }, { "type": "object", "properties": { "action": { "type": "string", "const": "drag" }, "x": { "type": "number" }, "y": { "type": "number" }, "to_x": { "type": "number" }, "to_y": { "type": "number" }, "button": { "type": "string", "enum": [ "left", "right", "middle" ] }, "timeout": { "description": "Maximum time in seconds for this action.", "type": "number", "exclusiveMinimum": 0 }, "include_screenshot": { "description": "Capture a bounded post-action screenshot when supported.", "type": "boolean" } }, "required": [ "action", "x", "y", "to_x", "to_y" ], "additionalProperties": false }, { "type": "object", "properties": { "action": { "type": "string", "const": "scroll" }, "x": { "type": "number" }, "y": { "type": "number" }, "scroll_x": { "type": "number" }, "scroll_y": { "type": "number" }, "timeout": { "description": "Maximum time in seconds for this action.", "type": "number", "exclusiveMinimum": 0 }, "include_screenshot": { "description": "Capture a bounded post-action screenshot when supported.", "type": "boolean" } }, "required": [ "action", "x", "y", "scroll_x", "scroll_y" ], "additionalProperties": false }, { "type": "object", "properties": { "action": { "type": "string", "const": "type" }, "text": { "type": "string" }, "timeout": { "description": "Maximum time in seconds for this action.", "type": "number", "exclusiveMinimum": 0 }, "include_screenshot": { "description": "Capture a bounded post-action screenshot when supported.", "type": "boolean" } }, "required": [ "action", "text" ], "additionalProperties": false }, { "type": "object", "properties": { "action": { "type": "string", "const": "keypress" }, "keys": { "minItems": 1, "type": "array", "items": { "type": "string" } }, "timeout": { "description": "Maximum time in seconds for this action.", "type": "number", "exclusiveMinimum": 0 }, "include_screenshot": { "description": "Capture a bounded post-action screenshot when supported.", "type": "boolean" } }, "required": [ "action", "keys" ], "additionalProperties": false }, { "type": "object", "properties": { "action": { "type": "string", "const": "wait" }, "ms": { "type": "integer", "minimum": 0 }, "timeout": { "description": "Maximum time in seconds for this action.", "type": "number", "exclusiveMinimum": 0 }, "include_screenshot": { "description": "Capture a bounded post-action screenshot when supported.", "type": "boolean" } }, "required": [ "action", "ms" ], "additionalProperties": false } ] }, "description": "Sequence of computer actions to execute in order." }, "timeout": { "description": "Maximum time in seconds for this action.", "type": "number", "exclusiveMinimum": 0 }, "include_screenshot": { "description": "Capture a bounded post-action screenshot when supported.", "type": "boolean" } }, "required": [ "action", "actions" ], "additionalProperties": false } ] }, "strict": true, "deferrable": true, "loadMode": "discoverable", "summary": "Control the macOS desktop (Apple Silicon) with screenshot, pointer, keyboard, scroll, and wait actions; available by default on supported hosts and supervisor-gated", "platformExclusions": [ { "platform": "linux" }, { "platform": "win32" }, { "platform": "darwin", "arch": "x64" } ] }, "checkpoint": { "name": "checkpoint", "label": "Checkpoint", "description": "Creates a context checkpoint before exploratory work so you can later rewind and keep only a concise report.\n\nUse this when you need to investigate with many intermediate tool calls (read/search/find/lsp/etc.) and want to minimize context cost afterward.\n\nRules:\n- You MUST call `rewind` before yielding after starting a checkpoint.\n- You MUST provide a clear `goal` explaining what you are investigating.\n- You NEVER call `checkpoint` while another checkpoint is active.\n- Not available in subagents.\n\nTypical flow:\n1. `checkpoint(goal: …)`\n2. Perform exploratory work\n3. `rewind(report: …)` with concise findings\n\nAfter rewind, intermediate checkpoint messages are removed from active context and replaced by the report.", "parameters": { "type": "object", "properties": { "goal": { "type": "string", "description": "investigation goal" } }, "required": [ "goal" ], "additionalProperties": false }, "strict": true, "deferrable": true, "loadMode": "discoverable", "summary": "Create a git-based checkpoint to save and restore session state" }, "rewind": { "name": "rewind", "label": "Rewind", "description": "End an active checkpoint. Rewind context to it, replacing intermediate exploration with your report.\n\nCall immediately after `checkpoint`-started investigative work.\n\nRequirements:\n- `report` is REQUIRED and must be concise, factual, and actionable.\n- Include key findings, decisions, and any unresolved risks.\n- Do not include raw scratch logs unless essential.\n- `checkpoint`'s must-rewind-before-yield rule applies: never yield with a checkpoint still active.\n\nBehavior:\n- If no checkpoint is active, this tool errors.\n- On success, the session rewinds and keeps your report as retained context.", "parameters": { "type": "object", "properties": { "report": { "type": "string", "description": "investigation findings" } }, "required": [ "report" ], "additionalProperties": false }, "strict": true, "deferrable": true, "loadMode": "discoverable", "summary": "Rewind to a previously created checkpoint" }, "task": { "name": "task", "label": "Task", "description": "Launches subagents to parallelize workflows.\n\n- Results are delivered automatically when complete.\n- The tool result lists the assigned task ids (e.g. `0-AuthLoader`) — those are the live agent ids.\n- Use `subagent` action `inspect` or `list` to snapshot manager state.\n- To wait or cancel, use the `subagent` tool; its await/cancel doctrine is authoritative.\n\nSubagents have no conversation history. Every fact, file path, and direction they need MUST be explicit in `context` or `assignment`.\n\n\n- `agent`: agent type for all tasks\n- `tasks`: tasks to execute in parallel\n - `.id`: filesystem-safe, ≤48 chars, matching `[A-Za-z0-9][A-Za-z0-9_-]*`; prefer CamelCase\n - `.description`: UI label only — subagent never sees it\n - `.assignment`: complete self-contained instructions; one-liners and missing acceptance criteria are PROHIBITED\n- `context`: shared background prepended to every assignment; session-specific only\n- `.inheritContext` (optional): fork-context mode for seeding the subagent with sanitized parent conversation. Omit it or set `\"none\"` for no copied context. `\"receipt\"` copies a minimal receipt-sized snapshot, `\"last-turn\"` copies only the latest exchange, `\"bounded\"` copies the bounded default snapshot, and `\"full\"` copies a larger snapshot up to the configured/model token cap. Non-`none` modes work only when global `task.forkContext.enabled` is true and the target agent declares `forkContext: allowed`; otherwise the call is rejected. Bundled agents that support it: `executor`, `architect`. Use inherited context only when the subagent's value depends on parent context; cloned tokens are billed to the child as fresh input and surfaced in task receipts as fork-context cloned-token accounting.\n\n- `schema`: JTD schema for expected structured output (do not put format rules in assignments)\n- `spawnPlan` (optional): required before any batch with more than 4 tasks; include whyParallel, whyNotLocal, independence, expectedReceiptShape, and maxInlineTokens.\n\n\n\n- HARD runtime gate: calls with more than 4 tasks are rejected before any child launches unless `spawnPlan` is complete.\n- NEVER assign tasks to run project-wide build/test/lint. Caller verifies after the batch.\n- **Subagents do not verify, lint, or format.** Every assignment MUST instruct the subagent to skip all gates and formatters. You run them once at the end across the union of changed files — avoids redundant runs and racing formatter passes.\n- Each task: ≤3–5 explicit files. No globs, no \"update all\", no package-wide scope. Fan out to a cluster instead.\n- Pass large payloads via `local://` URIs, not inline.\n- Put shared constraints in `context` once; do not duplicate across assignments.\n- Prefer agents that investigate **and** edit in one pass; only spin a read-only discovery step when affected files are genuinely unknown.\n\n\n\nTest: can task B run correctly without seeing A's output? If no, sequence A → B.\nSequential when one task produces a contract (types, API, schema, core module) the other consumes.\nParallel when tasks touch disjoint files or are independent refactors/tests.\n\n\n\n# Goal ← one sentence: what the batch accomplishes\n# Constraints ← MUST/NEVER rules and session decisions\n# Contract ← exact types/signatures if tasks share an interface\n\n\n\n# Target ← exact files and symbols; explicit non-goals\n# Change ← step-by-step add/remove/rename; APIs and patterns\n# Acceptance ← observable result; no project-wide commands\n\n\n\n# executor\nAutonomous implementation agent for bounded code changes, fixes, and verification-ready edits\n\n# architect\nRead-only architecture and code-review agent with severity-rated findings and status verdicts\n\n# planner\nRead-only planning agent for sequencing, acceptance criteria, risks, and handoff shape\n\n# critic\nRead-only plan critic that approves only actionable, verifiable execution plans\n", "parameters": { "type": "object", "properties": { "agent": { "type": "string", "description": "agent type" }, "tasks": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "maxLength": 48, "description": "filesystem-safe task identifier" }, "description": { "type": "string", "description": "ui label, not seen by subagent" }, "assignment": { "type": "string", "description": "per-task instructions; self-contained" }, "tier": { "description": "Advisory unless autorouting is enabled; omitted routes as balanced.", "type": "string", "enum": [ "fast", "balanced", "strong" ] }, "executionMode": { "description": "typed executor mode: default keeps ordinary executor behavior; ultragoal-red-team injects the Ultragoal QA/red-team prompt fragment. Prefer this over free-form assignment text (#2698).", "type": "string", "enum": [ "default", "ultragoal-red-team" ] }, "inheritContext": { "description": "fork-context mode: none/omitted copies no parent context; receipt copies a minimal receipt-sized snapshot; last-turn copies only the latest exchange; bounded copies the bounded default snapshot; full copies a larger sanitized snapshot up to the configured/model token cap", "type": "string", "enum": [ "none", "receipt", "last-turn", "bounded", "full" ] }, "repositoryBinding": { "description": "authoritative repository identity; omitted items are stamped from session cwd before discovery/spawn and still fail closed on sibling drift", "type": "object", "properties": { "schema": { "type": "string", "const": "gjc.repository_binding.v1" }, "worktreeRoot": { "type": "string", "minLength": 1, "description": "canonical git worktree root" }, "commonDir": { "anyOf": [ { "type": "string", "minLength": 1 }, { "type": "null" } ], "description": "git common dir, or null outside a git checkout" }, "relativeSubdir": { "description": "optional repo-relative subdirectory; not an absolute cwd", "type": "string", "minLength": 1 }, "displayPath": { "description": "human-facing path; never used for authority", "type": "string", "minLength": 1 }, "head": { "type": "string", "minLength": 1 }, "branch": { "type": "string", "minLength": 1 } }, "required": [ "schema", "worktreeRoot", "commonDir" ], "additionalProperties": false }, "duplicate_policy": { "description": "duplicate launch policy; defaults to warn", "type": "string", "enum": [ "warn", "supersede" ] } }, "required": [ "id", "description", "assignment" ], "additionalProperties": false }, "description": "tasks to execute in parallel" }, "spawnPlan": { "type": "object", "properties": { "whyParallel": { "type": "string" }, "whyNotLocal": { "type": "string" }, "independence": { "type": "string" }, "expectedReceiptShape": { "type": "string" }, "maxInlineTokens": { "type": "number" } }, "required": [ "whyParallel", "whyNotLocal", "independence", "expectedReceiptShape", "maxInlineTokens" ], "additionalProperties": false, "description": "justification required before spawning more than four tasks" }, "context": { "description": "shared background prepended to each assignment", "type": "string" }, "schema": { "description": "jtd schema for expected response shape", "type": "string" } }, "required": [ "agent", "tasks" ], "additionalProperties": false }, "strict": true, "deferrable": true, "loadMode": "discoverable", "summary": "Spawn a subagent to complete a parallel task" }, "subagent": { "name": "subagent", "label": "Subagent", "description": "Lists, inspects, awaits, pauses, resumes, steers, or cancels detached task subagents.\n\nTask launches return immediately. Use this tool when you need direct control over those running subagents. Prefer `subagent` for task subagents; generic `job` remains available for non-subagent jobs and compatibility fallback access.\n\n`verbosity` controls output size: `receipt` (default) returns status metadata plus a single ≤280-character result/error preview and an `agent://` output ref when available; `preview` returns ≤2000 characters; `full` returns ≤12000 characters and requires explicit `ids`.\n\n# Operations\n\n## `action: \"list\"`\nSnapshot your visible detached subagents, including `running`, `paused`, `queued`, and terminal subagents when retained. Optional `limit` (1–50) caps how many subagents are returned. Output is receipt-only by default; use `verbosity: \"preview\"` for a bounded preview or inspect explicit `ids` with `verbosity: \"full\"` when fuller retained text is necessary.\n\n## `action: \"inspect\"`\nInspect selected subagents by `ids`; omit `ids` to inspect current running subagents. Terminal subagents return receipt-only output by default, with an `agent://` ref when a verified output artifact is available. `verbosity: \"full\"` requires explicit `ids`.\n\n## `action: \"await\"`\nWait for selected subagents by `ids`; omit `ids` to wait for current running subagents.\n- Always set `timeout_ms` when the result is not immediately required forever.\n- Await timeout only bounds this tool call's wait; it does not stop the subagent and is not a failure reason.\n- On timeout, inspect progress and keep doing independent work. Never cancel just because an await timed out; cancel only if the subagent has actually failed, gone off-track, or become unrecoverably wrong.\n- Completed results are receipt-first by default: bounded preview plus `agent://` output ref when available, not full retained output.\n\n## `action: \"pause\"`\nRequest a graceful safe-boundary pause for selected subagents by `ids`.\n- Non-running subagents are a no-op and return their current status snapshot.\n- A paused subagent keeps its session context and can be resumed later.\n\n## `action: \"resume\"`\nResume one subagent by `id` (preferred) or a single-item `ids` array.\n- Optional `message` is delivered into that one resumed run.\n- Running subagents are a no-op and return their current status snapshot.\n- Terminal subagents require `message` to start a follow-up resume run; without `message`, the tool returns the current snapshot with guidance.\n- `paused` subagents resume from saved context; `queued` subagents are already waiting for capacity.\n- Multiple targets are rejected because one global `message` must not broadcast to several subagents.\n\n## `action: \"steer\"`\nSend a non-empty `message` to one subagent by `id` (preferred) or a single-item `ids` array.\n- A running subagent receives the message through its live handle.\n- Optional `pause: true` requests a safe-boundary pause after steering a running subagent.\n- `pause` only matters while the target is running.\n- A non-active subagent (`paused`, `queued`, or terminal) automatically resumes with the message; `pause` is ignored for that target.\n- Multiple targets are rejected because one global `message` must not broadcast to several subagents.\n\n## `action: \"cancel\"`\nStop selected subagents by `ids`, including running, paused, or queued subagents.\n- Use only when the subagent has actually failed, gone off-track, or become unrecoverably wrong; an await timeout alone is never a cancellation reason.\n- Cancellation keeps the subagent session file for possible later context recovery.\n\n# Statuses\n\n- `running` — currently executing.\n- `paused` — stopped at a safe boundary with resumable context.\n- `queued` — resume requested and waiting for execution capacity.\n- `completed` — finished successfully.\n- `failed` — finished with an error.\n- `cancelled` — stopped by cancellation.\n- `not_found` — no visible subagent matches the requested id.", "parameters": { "type": "object", "properties": { "action": { "type": "string", "enum": [ "list", "inspect", "await", "cancel", "pause", "resume", "steer" ], "description": "subagent control action" }, "ids": { "description": "subagent ids or backing job ids", "type": "array", "items": { "type": "string" } }, "id": { "description": "single subagent id or backing job id for resume/steer", "type": "string" }, "message": { "description": "message to deliver when resuming or steering a subagent", "type": "string" }, "pause": { "description": "pause after steering a currently running subagent", "type": "boolean" }, "condition": { "description": "terminal wait condition; defaults to all_terminal", "type": "string", "enum": [ "all_terminal", "any_terminal" ] }, "heartbeat_ms": { "description": "heartbeat interval; 0 disables", "type": "number" }, "timeout_ms": { "description": "await timeout in milliseconds", "type": "number", "minimum": 0, "maximum": 3600000 }, "limit": { "description": "maximum subagents to return", "type": "number", "minimum": 1, "maximum": 50 }, "verbosity": { "description": "output verbosity: receipt (default, <=280-char receipt preview), preview (<=2000 chars), or full (<=12000 chars; requires explicit ids)", "type": "string", "enum": [ "receipt", "preview", "full" ] } }, "required": [ "action" ], "additionalProperties": false }, "strict": true, "deferrable": true, "loadMode": "discoverable", "summary": "Manage detached task subagents" }, "job": { "name": "job", "label": "Job", "description": "Inspects, waits, or cancels async jobs.\n\nBackground job results are delivered automatically when complete. Jobs that back task subagents should be controlled via the `subagent` tool when it is available; use `job` for non-subagent jobs (async bash, monitors) and as a compatibility fallback. Running job output stays quiet by default to avoid flooding the conversation; use `tail` when you explicitly want to show/reopen retained output. Reach for this tool only when you need to inspect or intervene.\n\nIn the interactive TUI, supported managed foreground bash can be folded into a background job by pressing `Ctrl+B` twice while it is running. Raw shell `Ctrl+Z`/`bg` is not the supported path inside GJC because it bypasses job ownership and output-routing contracts.\n\n# Operations\n\n## `list: true`\nUse to inspect what's running.\n\n## `tail: [id, …]`\nShow the retained output buffer for one or more background jobs without waiting.\n- Use this to reopen/tail a backgrounded long-running bash/tool output after folding it away.\n- Output is bounded by the manager retention window; stale cursors may report that only the retained tail is available.\n- Prefer `tail` over polling when you only need to peek at progress, so the conversation can continue without flooding the TUI.\n\n## `poll: [id, …]`\nBlock until the specified jobs finish or the wait window (~30 s, not configurable) elapses.\n- Use when you are genuinely blocked on a result and have no other work to do.\n- Returns the current snapshot when the timer elapses; running jobs remain running.\n- Completed jobs include their final output in the returned snapshot.\n\n## `cancel: [id, …]`\nStop running jobs.\n- Use when a job is stalled, hung, or no longer needed.\n- Returns immediately after cancelling.", "parameters": { "type": "object", "properties": { "poll": { "description": "job ids to wait for", "type": "array", "items": { "type": "string" } }, "cancel": { "description": "job ids to cancel", "type": "array", "items": { "type": "string" } }, "list": { "description": "snapshot all jobs", "type": "boolean" }, "tail": { "description": "job ids whose retained output should be shown without waiting", "type": "array", "items": { "type": "string" } } }, "additionalProperties": false }, "strict": true, "deferrable": true, "loadMode": "discoverable", "summary": "Manage long-running background jobs (async bash/python)" }, "monitor": { "name": "monitor", "label": "Monitor", "description": "Start a background monitor that streams events from a long-running script. Each stdout line is captured; persistent notifications are latest-biased and coalesced over a short debounce window, while terminal completion flushes the newest pending line. Events arrive on their own schedule and are not replies from the user, even if one lands while you're waiting for the user to answer a question.\n\nPick by how many notifications you need:\n- **One** (\"tell me when the server is ready / the build finishes\") → use `bash` with `async: true`. That returns a single completion notification when the command exits.\n- **Many ongoing events** (logs, polling, file watching) → use `monitor`. The script keeps running and new stdout is captured; persistent notifications are coalesced so ordinary log traffic does not create one model turn per line.\n\n`monitor` uses the same permission rules as `bash`. To stop a monitor, cancel its background task via `job` with the returned `task_id`, or end the session.\n\n## When to reach for `monitor`\n\n- Tail a log file and flag errors as they appear (`tail -F server.log | grep -i error`).\n- Poll a PR or CI job and report when its status changes.\n- Watch a directory for file changes (`fswatch -r dist/`).\n- Track output from any long-running script you point it at.\n\n## Inputs\n\n- `command` (required): shell command to run as a background monitor. Stdout is captured line-by-line; persistent notifications are coalesced before delivery.\n- `kind` (required): one of `\"log\"`, `\"poll\"`, `\"watch\"`, `\"other\"`. Describes the monitoring strategy so listings can surface useful categories.\n- `description` (required): short human-readable description of what is being monitored. Appears in task listings.\n- `timeout` (optional): maximum wall-clock seconds the monitor may run before automatic shutdown. Omit for the session lifetime.\n- `persistent` (optional, default `false`): keep the monitor running past the current turn. Persistent monitors survive until session end or until cancelled via `job`.\n\n## Output\n\nReturns `Monitor started · task ` plus a task entry visible via `job({list: true})`. Persistent notifications contain the latest line and the count of earlier coalesced lines; terminal completion flushes the newest pending line.\n\n## Cancellation\n\nThere is no separate `monitor` kill tool. Cancel a running monitor via `job({cancel: [\"\"]})` using the returned `task_id`. Disposing the session also cancels every monitor the calling agent started.", "parameters": { "type": "object", "properties": { "command": { "type": "string", "description": "Shell command to run as a background monitor. Each stdout line is delivered as a separate task-notification event." }, "kind": { "type": "string", "enum": [ "log", "poll", "watch", "other" ], "description": "Category of monitor. 'log' tails a log file, 'poll' polls a status endpoint, 'watch' watches a directory, 'other' for arbitrary streams." }, "description": { "type": "string", "description": "Short human-readable description of what is being monitored. Appears in task listings." }, "timeout": { "description": "Optional maximum wall-clock seconds the monitor may run before automatic shutdown. Omit for indefinite (subject to session lifetime).", "type": "number", "minimum": 1 }, "persistent": { "description": "Whether to keep the monitor running past the originating turn. Persistent monitors survive until session end or explicit kill via the background-task stop tool.", "type": "boolean" } }, "required": [ "command", "kind", "description" ], "additionalProperties": false }, "strict": true, "deferrable": true, "loadMode": "discoverable", "summary": "Start a background monitor that streams stdout lines as task notifications" }, "cron": { "name": "cron", "label": "Cron", "description": "Schedule a prompt to fire on a recurring cron schedule, or one-shot at the next match. Cron tasks re-run an agent prompt automatically on an interval when every firing is allowed to produce a normal assistant response, such as a reminder or a scheduled status report.\n\nCron is not a silent polling primitive. Every firing starts an agent turn, and hiding the injected cron message does not hide that turn's assistant response. For ongoing logs, file watching, or PR/CI polling that should report only meaningful state changes, use `monitor` with a script that writes a line only when there is an event to process, and set `persistent: true` so the monitor survives the first emitted event. Do not schedule a cron prompt that asks the agent to suppress routine polls; prompt wording cannot make a cron-triggered assistant turn reliably silent.\n\nUse a single `op` field to select the operation:\n\n- `op: \"create\"` accepts a standard 5-field `cron_expression` in your local timezone, the `prompt` to run, and `recurring` (whether the job recurs or fires once). It returns an 8-character job id you can pass to `op: \"delete\"`. Each session can hold up to 50 scheduled tasks. Recurring tasks auto-expire 7 days after creation; one-shot tasks self-delete after firing.\n- `op: \"list\"` enumerates every scheduled task in the session.\n- `op: \"delete\"` cancels a task by `id`.\n\n## Cron expressions\n\n`op: \"create\"` accepts 5-field cron: `minute hour day-of-month month day-of-week`. All fields support `*`, single values (`5`), steps (`*/15`), ranges (`1-5`), and comma lists (`1,15,30`). Day-of-week uses `0`/`7` for Sunday through `6` for Saturday. Extended syntax like `L`, `W`, `?`, or month/weekday names is not supported.\n\n|Example|Meaning|\n|:---|:---|\n|`*/5 * * * *`|Every 5 minutes|\n|`0 * * * *`|Every hour on the hour|\n|`0 9 * * *`|Every day at 9am local|\n|`0 9 * * 1-5`|Weekdays at 9am local|\n\n## Lifecycle\n\n- Tasks fire between turns, never mid-response.\n- All times are interpreted in the local timezone.\n- Recurring tasks fire with up to 30 minutes of deterministic jitter (or up to half their interval for sub-hourly tasks). One-shot tasks scheduled for `:00` or `:30` may fire up to 90 s early. Pick an off-minute if exact timing matters.\n- Closing or replacing the session clears every scheduled task.", "parameters": { "type": "object", "properties": { "op": { "type": "string", "enum": [ "create", "list", "delete" ], "description": "operation: 'create' schedules a prompt on a cron expression, 'list' enumerates scheduled tasks, 'delete' cancels a task by id" }, "cron_expression": { "description": "(op=create, required) Standard 5-field cron expression in the user's local timezone: 'minute hour day-of-month month day-of-week'. Examples: '*/5 * * * *' (every 5 min), '0 9 * * *' (9am daily), '0 9 * * 1-5' (weekdays at 9am). Day-of-week uses 0/7 for Sunday through 6 for Saturday. When both day-of-month and day-of-week are constrained, a date matches if either field matches (vixie-cron semantics).", "type": "string" }, "prompt": { "description": "(op=create, required) Prompt to inject between turns when the cron fires. Every firing starts a normal agent turn whose response may be visible; use a persistent monitor, not cron, for ongoing polling that should emit only on state changes.", "type": "string" }, "recurring": { "description": "(op=create) true to fire on every match of the cron expression (recurring, auto-expires after 7 days); false to fire once at the next match and then self-delete.", "type": "boolean" }, "id": { "description": "(op=delete, required) The 8-character job ID returned by op=create.", "type": "string" } }, "required": [ "op" ], "additionalProperties": false }, "strict": true, "deferrable": true, "loadMode": "discoverable", "summary": "Schedule, list, and cancel cron-style prompts (op: create | list | delete)" }, "recipe": { "name": "recipe", "label": "Run", "description": "Run a recipe / script / target from the project's task runners.\n\n\n- `op` is a single string: task name plus any args, e.g. `{op: \"test\"}` or `{op: \"build --release\"}`.\n- In monorepos, package and Cargo target tasks are namespaced with `/`, e.g. `{op: \"pkg-a/test\"}` or `{op: \"crate/bin/server\"}`.\n- Runs in the session's cwd. Output and exit code are returned in the same shape as `bash`.\n", "parameters": { "type": "object", "properties": { "op": { "type": "string", "description": "task name and args, e.g. \"test\" or \"build --release\"" } }, "required": [ "op" ], "additionalProperties": false }, "strict": true, "deferrable": true, "loadMode": "discoverable", "summary": "Execute a saved bash recipe (multi-step shell command preset)", "concurrency": "exclusive", "mergeCallAndResult": true, "inline": true }, "irc": { "name": "irc", "label": "IRC", "description": "Sends short text messages to other live agents in this process and receives their prose replies.\n\n\n- The main agent is addressable as `0-Main`. Subagents reuse their task id (e.g. `0-AuthLoader`).\n- `op: \"list\"` returns the current set of visible peers. Use it before sending if you are not sure who is live.\n- `op: \"send\"` delivers `message` to `to`. `to` may be a specific id or `\"all\"` to broadcast.\n- `awaitReply` (optional): wait for a prose reply. Defaults to `true` for DMs and `false` for `to: \"all\"` broadcasts.\n- The recipient generates the reply via an ephemeral side-channel turn that uses their current model, system prompt, and history — it does **not** wait for the recipient's main loop to be free, so it is safe to IRC an agent that is currently inside a long-running tool call.\n- The exchange (incoming question + auto-reply) is queued for injection into the recipient's persisted history; the recipient sees it on its next turn and can follow up if needed.\n\n\n\nYou SHOULD reach for `irc` proactively when continuing alone is wasteful or wrong. When in doubt, prefer messaging.\n- **Unexpected state.** You hit something the original task did not describe — a missing file, a config that contradicts the assignment, an API behaving differently than you were told, a tool failing in a way that suggests the spec is wrong. DM `0-Main` (or the spawning agent) for guidance instead of guessing.\n- **Blocked by another agent.** A peer holds the file/branch/resource you need, has already started the change you are about to make, or owns a decision you depend on. DM that peer (or broadcast to discover who) before duplicating or stepping on work.\n- **Decision points outside your scope.** A genuine fork in the road that the assignment did not pre-decide (e.g. which of two viable APIs to use, whether to refactor adjacent code). Ask the requester rather than picking unilaterally.\n- **Coordination opportunities.** Before editing a shared file or relying on another agent's in-flight API, message the relevant peer; proactively share state that affects their work.\n\nDo **not** use `irc` for: routine progress updates, things you can verify with a tool call, or questions whose answer is already in your assignment / repo / docs.\n\n\n\nThese rules apply to both sending and replying.\n- **Plain prose only.** Do not send structured JSON status payloads (e.g. `{\"type\":\"task_completed\",…}`). Write a normal sentence: \"Done with the auth refactor — left a TODO in `src/server/auth.ts` for the rate limiter.\"\n- **Do not quote the message you are replying to.** The sender already saw it; the TUI already renders it. Lead with the answer.\n- **Use IRC, not terminal tools, to learn about peers.** Do not `search` artifacts, read other sessions' JSONL files, or shell-poke around to figure out what another agent is doing. DM them — they have the live answer and you do not.\n- **One round-trip is enough.** Replies arrive synchronously when the recipient is reachable. Do not follow up with \"did you get my message?\" — they did. If `delivered` is empty or the result was `failed`, the peer is unavailable; move on or report the blocker, do not retry in a loop.\n- **Stay terse.** A DM is a chat message, not a memo. One question per send when you can. Share file paths and artifacts via `local://` / `artifact://` URLs instead of pasting blobs.\n- **Address peers by id.** Use the exact id from `op: \"list\"` (e.g. `0-AuthLoader`, `0-Main`). Do not invent friendly names.\n- **Do not IRC for things a tool would answer.** If a `read`, `search`, or build command would resolve the question, do that first.\n- **When you receive an IRC message, answer it before continuing.** The recipient injects the question + your auto-reply into your history; address it directly, do not repeat it back to the user.\n\n\n\n- `send`: returns each recipient that received the message and any prose replies that arrived.\n- `list`: returns peers and channels visible to the caller.\n\n\n\n# List peers\n`{\"op\": \"list\"}`\n# Direct message to the main agent (waits for prose reply)\n`{\"op\": \"send\", \"to\": \"0-Main\", \"message\": \"Should I prefer JWT or session cookies for the auth flow?\"}`\n# Unexpected state — ask the originator\n`{\"op\": \"send\", \"to\": \"0-Main\", \"message\": \"Assignment says edit src/auth/jwt.ts but the file does not exist. Is the new path src/server/auth/jwt.ts?\"}`\n# Blocked by a peer — ask them directly\n`{\"op\": \"send\", \"to\": \"0-AuthLoader\", \"message\": \"Are you still touching src/server/auth.ts? I need to add a 401 path; OK to proceed or should I wait?\"}`\n# Broadcast to discover who owns something (no replies, just informs them)\n`{\"op\": \"send\", \"to\": \"all\", \"message\": \"About to refactor src/server/middleware/*. Anyone already in there?\", \"awaitReply\": false}`\n", "parameters": { "type": "object", "properties": { "op": { "type": "string", "enum": [ "send", "list" ], "description": "irc operation" }, "to": { "description": "recipient agent id or \"all\"", "type": "string" }, "message": { "description": "message body", "type": "string" }, "awaitReply": { "description": "wait for prose reply", "type": "boolean" } }, "required": [ "op" ], "additionalProperties": false }, "strict": true, "deferrable": true, "loadMode": "discoverable", "summary": "Send and receive messages between agents over IRC-like channels" }, "todo_write": { "name": "todo_write", "label": "Todo Write", "description": "**Tasks are referenced by their verbatim content string, not by any auto-generated ID. There is no \"task-1\"/\"task-N\" identifier — the tool never emits one. Pass the task's content text in the `task` field.**\n\nManages a phased task list. Pass `ops`: a flat array of operations.\nThe next pending task is auto-promoted to `in_progress` after each completion.\nAllowed `op` values are only `init`, `start`, `done`, `drop`, `rm`, `append`, and `note`. `pending` is a task status, not an `op`; leave not-yet-started tasks implicit in `init`/`append` lists.\n\n## Operations\n\n|`op`|Required fields|Effect|\n|---|---|---|\n|`init`|`list: [{phase, items: string[]}]`|Initialize the full list (replaces any existing list)|\n|`start`|`task`|Mark in progress|\n|`done`|`task` or `phase`|Mark completed|\n|`drop`|`task` or `phase`|Mark abandoned|\n|`rm`|`task` or `phase` or *(none = clear all tasks)*|Remove a task; with `phase`, empties the phase (the phase entry remains); bare `rm` clears every task in every phase|\n|`append`|`phase`, `items: string[]`|Append tasks to `phase`; lazily creates phase|\n|`note`|`task`, `text`|Append a note to a task. Reminders for future-you only.|\n\n## Anatomy\n- **Task content**: 5–10 words, what is being done, not how. This string *is* how you address the task — unique.\n- **Phase name**: short noun phrase (e.g. `Foundation`, `Auth`, `Verification`). Used as the phase identifier — unique. Do not add prefixes like `1.`, `A)`, `Phase 1:`, etc.\n\n## Rules\n- Mark tasks done immediately after finishing.\n- Complete phases in order.\n- On blockers, `append` a new task to the active phase to unblock yourself, or `drop`.\n- `task` and `phase` fields reference content/name verbatim; keep them stable once introduced.\n\n## When to create a list\n- Task requires 3+ distinct steps\n- User explicitly requests one\n- User provides a set of tasks to complete\n- New instructions arrive mid-task — capture before proceeding\n\n\n# Initial setup (multi-phase)\n`{\"ops\":[{\"op\":\"init\",\"list\":[{\"phase\":\"Foundation\",\"items\":[\"Scaffold crate\",\"Wire workspace\"]},{\"phase\":\"Auth\",\"items\":[\"Port credential store\",\"Wire OAuth providers\"]},{\"phase\":\"Verification\",\"items\":[\"Run cargo test\"]}]}]}`\n# Initial setup (single phase)\n`{\"ops\":[{\"op\":\"init\",\"list\":[{\"phase\":\"Implementation\",\"items\":[\"Apply fix\",\"Run tests\"]}]}]}`\n# Complete one task\n`{\"ops\":[{\"op\":\"done\",\"task\":\"Wire workspace\"}]}`\n# Complete a whole phase\n`{\"ops\":[{\"op\":\"done\",\"phase\":\"Auth\"}]}`\n# Remove all tasks\n`{\"ops\":[{\"op\":\"rm\"}]}`\n# Drop one task\n`{\"ops\":[{\"op\":\"drop\",\"task\":\"Run cargo test\"}]}`\n# Append tasks to a phase\n`{\"ops\":[{\"op\":\"append\",\"phase\":\"Auth\",\"items\":[\"Handle retries\",\"Run tests\"]}]}`\n", "parameters": { "type": "object", "properties": { "ops": { "minItems": 1, "type": "array", "items": { "type": "object", "properties": { "op": { "description": "operation to apply; use \"done\" to complete a task", "type": "string", "enum": [ "init", "start", "done", "rm", "drop", "append", "note" ] }, "list": { "description": "phased task list (init)", "type": "array", "items": { "type": "object", "properties": { "phase": { "type": "string", "description": "phase name" }, "items": { "minItems": 1, "type": "array", "items": { "type": "string", "description": "task content" }, "description": "tasks for this phase" } }, "required": [ "phase", "items" ], "additionalProperties": false } }, "task": { "description": "task content", "type": "string" }, "phase": { "description": "phase name", "type": "string" }, "items": { "description": "tasks to append", "minItems": 1, "type": "array", "items": { "type": "string", "description": "task content" } }, "text": { "description": "note text", "type": "string" } }, "required": [ "op" ], "additionalProperties": false }, "description": "ordered todo operations" } }, "required": [ "ops" ], "additionalProperties": false, "description": "apply ordered todo operations" }, "strict": true, "deferrable": true, "loadMode": "discoverable", "summary": "Write a structured todo list to track progress within a session", "concurrency": "exclusive" }, "web_search": { "name": "web_search", "label": "Web Search", "description": "Searches the web for up-to-date information beyond knowledge cutoff.\n\n\n- You SHOULD prefer primary sources (papers, official docs) and corroborate key claims with multiple sources\n- You MUST include links for cited sources in the final response\n- Provider-neutral params: `recency` (freshness window), `limit`/`num_search_results` (result counts), `max_tokens`, `temperature`\n\n\n\nThe parameters below apply ONLY when the active search provider is `xai`; ignore them (and never pass them) on any other provider.\n- With provider `xai`, use `xai_search_mode: \"web\"` for normal web search, `\"x\"` for X/Twitter search, or `\"web_and_x\"` when both surfaces are relevant.\n- xAI web filters: `allowed_domains` or `excluded_domains` (max 5, mutually exclusive), plus `enable_image_understanding` and `enable_image_search`.\n- xAI X filters: `allowed_x_handles` or `excluded_x_handles` (max 20, mutually exclusive), `from_date`, `to_date`, `enable_image_understanding`, and `enable_video_understanding`.\n- Use `no_inline_citations` with provider `xai` when the answer should omit inline citation markdown while still returning structured sources.\n\n\n\nSearches are performed automatically within a single API call—no pagination or follow-up requests needed.\n", "parameters": { "type": "object", "properties": { "query": { "type": "string", "description": "search query" }, "recency": { "type": "string", "enum": [ "day", "week", "month", "year" ], "description": "recency filter" }, "limit": { "type": "number", "description": "max results" }, "max_tokens": { "type": "number", "description": "max output tokens" }, "temperature": { "type": "number", "description": "sampling temperature" }, "num_search_results": { "type": "number", "description": "number of search results" }, "xai_search_mode": { "type": "string", "enum": [ "web", "x", "web_and_x" ], "description": "xAI only: use web_search, x_search, or both" }, "allowed_domains": { "maxItems": 5, "type": "array", "items": { "type": "string" }, "description": "xAI web_search only: allowed domains" }, "excluded_domains": { "maxItems": 5, "type": "array", "items": { "type": "string" }, "description": "xAI web_search only: excluded domains" }, "allowed_x_handles": { "maxItems": 20, "type": "array", "items": { "type": "string" }, "description": "xAI x_search only: allowed X handles" }, "excluded_x_handles": { "maxItems": 20, "type": "array", "items": { "type": "string" }, "description": "xAI x_search only: excluded X handles" }, "from_date": { "type": "string", "description": "xAI x_search only: start date in ISO8601 format" }, "to_date": { "type": "string", "description": "xAI x_search only: end date in ISO8601 format" }, "enable_image_understanding": { "type": "boolean", "description": "xAI only: analyze images encountered during search" }, "enable_image_search": { "type": "boolean", "description": "xAI web_search only: search for and embed image results" }, "enable_video_understanding": { "type": "boolean", "description": "xAI x_search only: analyze videos in X posts" }, "no_inline_citations": { "type": "boolean", "description": "xAI only: disable inline citation markdown in the answer" } }, "required": [ "query" ], "additionalProperties": false }, "strict": true, "deferrable": true, "loadMode": "discoverable", "summary": "Search the web for up-to-date information" }, "search_tool_bm25": { "name": "search_tool_bm25", "label": "SearchTools", "description": "Search hidden tool metadata to discover and activate tools.\n\nActivate hidden tools (MCP and built-in) when you need a capability not in your active tool set.\nInput:\n- `query` — required natural-language or keyword query\n- `limit` — optional maximum number of tools to return and activate (default `8`; start with 5–10 if unsure)\n\nBehavior:\n- Searches hidden tool metadata using BM25-style relevance ranking\n- Matches against tool name, label, server name, description/summary, and input schema keys\n- Activates the top matching tools for the rest of the current session\n- Repeated searches add to the active tool set; they do not remove earlier selections\n- Newly activated tools become available before the next model call in the same overall turn\n\nFollow-through:\n- Activation only changes the active tool set; it does not execute a discovered tool or complete its work.\n- If the task still needs a newly activated capability, call that tool in the next model turn. Do not claim that a browser action, web search, integration, or subagent ran until its tool result is present.\n- If discovery was the only requested action, report availability as availability, not as completed work.\n\nNot for repository/file/code search. Tool discovery only.\n\nReturns JSON with:\n- `query`\n- `activated_tools` — tools activated by this search call\n- `match_count` — number of ranked matches returned by the search\n- `total_tools`\n\nMatch details include:\n- `server_name` — MCP server name when the activated result is an MCP tool\n- `mcp_tool_name` — original MCP tool name when applicable\n- `schema_keys` — searchable input property names", "parameters": { "type": "object", "properties": { "query": { "type": "string", "description": "tool search query" }, "limit": { "description": "max matches", "type": "integer", "minimum": 1 } }, "required": [ "query" ], "additionalProperties": false }, "strict": true, "deferrable": false, "loadMode": "essential" }, "skill_discovery": { "name": "skill_discovery", "label": "SkillDiscovery", "description": "Discover project and user runtime skills without loading full skill content.\n\n\n- Searches canonical GJC skill locations in precedence order: project `.gjc/skills` (ancestors from cwd to repo root, closest first), then user locations under the home directory: canonical `/agent/skills`, configured legacy `/skills`, and historical legacy `.gjc/skills`. `` is the home-relative directory name from `GJC_CONFIG_DIR`, then `PI_CONFIG_DIR`, then `.gjc`; even an absolute-looking configured name is joined beneath ``. Project scope shadows user scope; within a scope, earlier locations above win. Bundled GJC workflow skills (`autoresearch`, `deep-interview`, `ralplan`, `ultragoal`) are always available and cannot be replaced by filesystem skills.\n- Returns thin metadata only: name, description, source scope, path, and use conditions when present.\n- Claude Code (`.claude/skills`) and Codex (`.codex/skills`) layouts are explicit import sources into `.gjc`, never invokable candidates. They are not returned as candidates; instead, each convention skill found in a trusted scope is reported in `diagnostics` with the exact copy command that enables it (copy into `.gjc/skills`), so a skill placed in a documented convention location is discoverable in a normal session without being silently loaded.\n- Discovery is on by default in a normal session. When zero candidates are returned because discovery config is disabled (`skills.enabled` master switch, or `skills.trustProjectSkills` / `skills.trustUserSkills` scope trust), the result carries a `notice` explaining which setting blocked the search — an empty result without a `notice` means the searched scopes genuinely contain no matching skills.\n- When skills were scanned but not advertised (protected-name collision with a bundled workflow skill, include/ignore/disable policy filters, invalid frontmatter, shadowing), the result carries a bounded `diagnostics` list explaining why.\n- To load a selected skill's full `SKILL.md`, invoke it through the existing `skill` tool with the exact `name` returned here.\n\n\nInput:\n- `query` (optional): words to match against skill name, description, source, or use conditions.\n- `source` (optional): `all`, `project`, or `user`.\n- `limit` (optional): maximum results, 1-50.", "parameters": { "type": "object", "properties": { "query": { "description": "words to match against skill name, description, source, or use conditions", "type": "string" }, "source": { "description": "skill source scope to search", "default": "all", "type": "string", "enum": [ "all", "project", "user" ] }, "limit": { "description": "maximum results", "default": 20, "type": "number", "minimum": 1, "maximum": 50 } }, "additionalProperties": false }, "strict": true, "deferrable": false, "loadMode": "essential", "summary": "Discover project and user runtime skills by thin metadata" }, "telegram_send": { "name": "telegram_send", "label": "TelegramSend", "description": "Send a file from the current workspace to the connected Telegram chat. Recognized images are converted to Telegram-compatible photos when possible, including WebP; other files are sent as documents with their MIME type preserved. The path must resolve (after following symlinks) to a regular file inside the project root; paths outside the workspace are rejected.", "parameters": { "type": "object", "properties": { "path": { "type": "string", "description": "file path (absolute or relative to cwd) to send to Telegram; must resolve inside the workspace" }, "caption": { "description": "optional caption", "type": "string" } }, "required": [ "path" ], "additionalProperties": false }, "strict": true, "deferrable": true, "loadMode": "discoverable", "summary": "Send a workspace file to Telegram" }, "write": { "name": "write", "label": "Write", "description": "Creates or overwrites file at specified path.\n\n\n- Creating new files explicitly required by task\n- Replacing entire file contents when editing would be more complex\n\n\n\n- Archives: write entries inside `.tar`, `.tar.gz`, `.tgz`, and `.zip` via `archive.ext:path/inside/archive`.\n- SQLite rows:\n - `db.sqlite:table` with JSON content — insert a row\n - `db.sqlite:table:key` with JSON content — update the row with that primary key\n - `db.sqlite:table:key` with empty content — DELETE that row (destructive; double-check the key)\n\n\n\n- You SHOULD use Edit tool for modifying existing files (more precise, preserves formatting)\n- You NEVER create documentation files (*.md, README) unless explicitly requested\n- You NEVER use emojis unless requested\n", "parameters": { "type": "object", "properties": { "path": { "type": "string", "description": "file path" }, "content": { "type": "string", "description": "file content" } }, "required": [ "path", "content" ], "additionalProperties": false }, "strict": true, "deferrable": true, "loadMode": "discoverable", "summary": "Write content to a file (creates or overwrites)", "nonAbortable": true, "concurrency": "exclusive" }, "skill": { "name": "skill", "label": "Skill", "description": "Invoke another available skill in the current turn.\n\n\n- A SKILL document instructs you to chain into another skill on completion (e.g. ralplan → ultragoal)\n- You finished one skill's workflow and the next step requires another skill's full prompt context\n\n\n\n- `name` is the skill name as it appears in `/skill:` (e.g. `ralplan`, `ultragoal`, `autoresearch`, `deep-interview`)\n- `args` is the free-form argument string the skill would receive after `/skill:` on the command line\n- The tool loads the callee's SKILL.md into the current turn and handles native workflow caller→callee state handoff when the caller is one of the built-in GJC workflows.\n- The chain is refused while a native workflow caller is still mid-flight. `autoresearch` chains from any of its phases (`intake`/`research`/`verdict`) — a research mission is always handoff-ready. `deep-interview` chains once its final spec is persisted (phase `handoff`), and `ralplan` chains from `final` or `handoff`. Only a mid-flight `ralplan` or `ultragoal` needs preparation first: `gjc state write --input '{\"current_phase\":\"handoff\"}' --json`; no other handoff command is needed. Runtime project/user skills do not use `gjc state `.\n- Call once per chain step. To chain `A → B → C`, A calls `skill(B)`; B's next agent turn calls `skill(C)`.\n\n\n\n- Do NOT use this tool to \"remind yourself\" of a skill you're already running. The current SKILL.md is already in your context.\n- Do NOT chain into the same skill recursively. If a skill's flow needs another iteration, follow its in-document instructions.\n- `name` MUST be one concrete skill name, NOT a glob or wildcard. Passing `*`, `?`, or a pattern like `git-*` is rejected immediately — the `--skills '*'` launch filter is unrelated to this tool's `name`.\n- The chained skill's planning/execution-boundary rules still apply. Chaining does not grant execution approval.\n\n\n\n# Hand off from ralplan to ultragoal after an approved plan\n{\"name\": \"ultragoal\", \"args\": \"track execution of .gjc/plans/ralplan//pending-approval.md\"}\n\n# Trigger deep-interview with no arguments\n{\"name\": \"deep-interview\"}\n", "parameters": { "type": "object", "properties": { "name": { "type": "string", "description": "skill name as it appears in /skill:" }, "args": { "type": "string", "description": "argument string passed to the skill" } }, "required": [ "name" ], "additionalProperties": false }, "strict": true, "deferrable": false, "loadMode": "essential", "summary": "Chain into another available skill in the current turn" }, "goal": { "name": "goal", "label": "Goal", "description": "Manage the active goal-mode objective.\n\nUse a single `op` field:\n- `create` starts a goal. Requires `objective`. Use only when no goal exists and no goal is paused.\n- `get` returns the current goal and usage state.\n- `resume` re-activates a paused goal so work can continue.\n- `complete` marks the goal complete after you have verified every deliverable against current evidence.\n- `drop` discards the current goal without completing it.\n- `pause` parks an active goal without completing or dropping it. While paused, the autonomous continuation loop stops re-activating the agent. Pause only when the goal is still alive but every outstanding deliverable is blocked on action only the user can perform (e.g. record, approve, a manual/physical step); it is never a substitute for `complete`. A paused goal keeps its progress and is resumable via `resume`.\n\nExamples:\n- `goal({\"op\":\"create\",\"objective\":\"Implement feature X\"})`\n- `goal({\"op\":\"get\"})`\n- `goal({\"op\":\"resume\"})`\n- `goal({\"op\":\"pause\"})`\n- `goal({\"op\":\"complete\"})`\n- `goal({\"op\":\"drop\"})`\n\nIf `get` shows a paused goal, call `resume` before continuing work on it.", "parameters": { "type": "object", "properties": { "op": { "type": "string", "enum": [ "create", "get", "complete", "resume", "drop", "pause" ], "description": "op: get | create | complete | drop | resume | pause — drop clears the active goal without exiting goal mode (tool stays callable for the next create); pause parks an active goal whose remaining work is blocked on human input so the autonomous continuation loop stops until resume" }, "objective": { "type": "string", "description": "goal objective" } }, "required": [ "op" ], "additionalProperties": false }, "strict": true, "deferrable": false, "loadMode": "essential", "intent": "omit" }, "move_session": { "name": "move_session", "label": "Move Session", "description": "Rescope the session to a narrower working directory.\n\nUse this only when the session's working directory is a broad launcher root (for example a\nmulti-repo workspace like `~/Projects`) and the task has clearly converged on one subdirectory\nor repository: after this call, every later turn resolves relative paths and the bash default\ncwd from the new directory, and project-scoped plugins/capabilities reload for it.\n\n- `path` must be an existing directory; relative paths resolve against the current session cwd.\n The canonical target must be strictly inside the current session directory — moves to a\n parent, a sibling project, or an unrelated absolute path are refused.\n- A session can be moved this way at most once, and never while another move is running; a\n rejected call does not consume the move. Use it once the target repo is identified — not\n speculatively — because the session file and caches move with the session.\n- This tool is unavailable in subagent sessions and restricted profiles; ask the top-level\n session to rescope instead.", "parameters": { "type": "object", "properties": { "path": { "type": "string", "description": "target directory: absolute, or relative to the current session cwd" } }, "required": [ "path" ], "additionalProperties": false }, "strict": true, "deferrable": false, "loadMode": "essential", "nonAbortable": true, "concurrency": "exclusive", "intent": "omit" }, "yield": { "name": "yield", "label": "Submit Result", "description": "Finish the task with structured JSON output. Call exactly once at the end of the task.\n\nPass `result: { data: }` for success, or `result: { error: \"message\" }` for failure.\nThe `data`/`error` wrapper is required — do not put your output directly in `result`.", "parameters": { "type": "object", "additionalProperties": false, "description": "submit data or error", "properties": { "result": { "anyOf": [ { "type": "object", "additionalProperties": false, "description": "task succeeded", "properties": { "data": { "type": "object", "additionalProperties": true, "description": "Structured JSON output (no schema specified)" } }, "required": [ "data" ] }, { "type": "object", "additionalProperties": false, "properties": { "error": { "type": "string", "description": "error message" } }, "required": [ "error" ] } ] } }, "required": [ "result" ] }, "strict": false, "hidden": true, "lenientArgValidation": true, "intent": "omit" }, "report_finding": { "name": "report_finding", "label": "Report Finding", "description": "Report a code review finding. Use this for each issue found. Call yield when done.", "parameters": { "type": "object", "properties": { "title": { "type": "string", "description": "prefixed imperative title" }, "body": { "type": "string", "description": "problem explanation" }, "priority": { "type": "string", "enum": [ "P0", "P1", "P2", "P3" ], "description": "priority 0-3" }, "confidence": { "type": "number", "minimum": 0, "maximum": 1, "description": "confidence score" }, "file_path": { "type": "string", "description": "file path" }, "line_start": { "type": "number", "description": "start line" }, "line_end": { "type": "number", "description": "end line" } }, "required": [ "title", "body", "priority", "confidence", "file_path", "line_start", "line_end" ], "additionalProperties": false }, "strict": true, "hidden": true, "intent": "omit" }, "resolve": { "name": "resolve", "label": "Resolve", "description": "Resolves a pending action by either applying or discarding it.\n- `action` is required:\n - `\"apply\"` persists / submits the pending action.\n - `\"discard\"` rejects the pending action.\n- `reason` is required: one short complete sentence explaining why, starting with a capital letter and ending with a period.\n- `extra` (optional) is free-form metadata passed to the resolving tool. When the pending action is a plan-approval gate, supply `extra.title` (kebab/PascalCase slug for the approved plan filename). For preview-style pending actions (e.g. `ast_edit`), `extra` is unused.\n\nValid whenever a pending action exists — either a preview-style staging (e.g. `ast_edit`) or a long-lived approval gate.\nCall fails with an error when no pending action exists.", "parameters": { "type": "object", "properties": { "action": { "type": "string", "enum": [ "apply", "discard" ] }, "reason": { "type": "string", "description": "reason for action" }, "extra": { "description": "free-form metadata", "type": "object", "propertyNames": { "type": "string" }, "additionalProperties": true } }, "required": [ "action", "reason" ], "additionalProperties": false }, "strict": true, "hidden": true } };