import type { ExtensionAPI, ToolDefinition } from "@earendil-works/pi-coding-agent"; export interface ForgeToolDefs { store: ToolDefinition; commit: ToolDefinition; collate: ToolDefinition; validateStore: ToolDefinition; config: ToolDefinition; storeDescribe: ToolDefinition; storeTemplate: ToolDefinition; storeQuery: ToolDefinition; verifyApply: ToolDefinition; artifact: ToolDefinition; preflight: ToolDefinition; banner: ToolDefinition; markdown: ToolDefinition; } /** * Register tools that every subagent dispatch should receive in addition to the * forge tool surface. Called once at extension init after the host session * registers them. Idempotent — last call wins. */ export declare function setExtraSubagentTools(tools: ToolDefinition[]): void; /** * Return all forge tool definitions for subagent injection. * * Every subagent gets the full tool surface (~2K tokens, <4% of session cost). * Transcript analysis showed per-persona filtering provided no benefit — models * never picked the wrong tool, and withholding tools forced bash workarounds. */ export declare function getSubagentTools(defs: ForgeToolDefs, _personaName?: string): ToolDefinition[]; /** * The tool-discipline system prompt block appended to subagent prompts when * forge tools are injected. Exported so forge-subagent.ts can include it * without duplicating the text. */ export declare const FORGE_TOOL_DISCIPLINE = "\n## Forge Tool Discipline\n\nAll forge_* tools wrap local .cjs scripts via direct exec \u2014 deterministic, no LLM,\nno agent loop. Prefer them over shelling out.\n\n- Store CRUD: call `forge_store` (named tool). Canonical write is 2-positional:\n `{command:\"write\", args:[\"\",\"\"]}`. The id lives INSIDE the json\n (e.g. `{\"sprintId\":\"X-S01\",\"title\":\"...\",\"status\":\"planning\",\"taskIds\":[],\"createdAt\":\"...\"}`).\n DO NOT pass id as a separate arg \u2014 `[\"sprint\",\"X-S01\",\"\"]` (3-arg) FAILS.\n- Before writing any record, call `forge_store_template` for the canonical shape and\n `forge_store_describe` for required fields, status enums, and FK constraints.\n- Use `forge_store_query` (nlp/query/schema) for lookups instead of grepping `.forge/store/`.\n- Use `forge_collate` to refresh the KB; `forge_validate_store` for integrity checks;\n `forge_config` for project config reads/writes.\n- Use `forge_artifact` to read/write/list phase artifacts (PLAN.md, PROGRESS.md, *-SUMMARY.json).\n Never construct artifact paths manually \u2014 the tool resolves them from entity IDs.\n- Use `forge_verify_apply` after applying edits to confirm changes landed on disk.\n If `unchanged` is non-empty, re-apply those edits.\n- Use `forge_preflight` for pre-flight gate checks \u2014 do NOT shell out to preflight-gate.cjs.\n- Use `forge_banner` for phase banners \u2014 do NOT shell out to banners.cjs.\n- Use `forge_markdown` to read Markdown STRUCTURE instead of whole files: `operation:\"outline\"`\n maps a long KB doc / brief cheaply (then `operation:\"section\"` pulls one heading's text),\n `\"tables\"`/`\"frontmatter\"` return structured data, `\"ast\"` a compact tree. Prefer it over\n reading or regex-parsing flat markdown.\n- `$FORGE_ROOT` is already set in your environment. If you must use bash, reference\n `$FORGE_ROOT` directly \u2014 do NOT resolve it via `node -e \"console.log(require(...)...)\"`.\n- Never `bash node \"$FORGE_ROOT/tools/store-cli.cjs\" ...` \u2014 use the named MCP tool instead.\n The tool is schema-validated and shorter.\n- Workflow text saying `forge_store write sprint ''` means: call the MCP tool\n `forge_store` with that 2-positional shape. Not a shell command.\n"; /** * Build all Forge .cjs tool definitions, register them with pi, and return * the definitions so callers can inject them into subagent sessions via * `customTools`. */ export declare function registerForgeTools(pi: ExtensionAPI, forgeRoot: string, projectRoot: string): ForgeToolDefs;