@kolisachint/hoocode-agent 0.4.88 → 0.4.90

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cli/args.d.ts +2 -0
  3. package/dist/cli/args.d.ts.map +1 -1
  4. package/dist/cli/args.js +6 -0
  5. package/dist/cli/args.js.map +1 -1
  6. package/dist/core/agent-frontmatter.d.ts.map +1 -1
  7. package/dist/core/agent-frontmatter.js +3 -0
  8. package/dist/core/agent-frontmatter.js.map +1 -1
  9. package/dist/core/agent-session-services.d.ts +1 -0
  10. package/dist/core/agent-session-services.d.ts.map +1 -1
  11. package/dist/core/agent-session-services.js +1 -0
  12. package/dist/core/agent-session-services.js.map +1 -1
  13. package/dist/core/sdk.d.ts +7 -0
  14. package/dist/core/sdk.d.ts.map +1 -1
  15. package/dist/core/sdk.js +4 -1
  16. package/dist/core/sdk.js.map +1 -1
  17. package/dist/core/settings-defaults.d.ts +1 -0
  18. package/dist/core/settings-defaults.d.ts.map +1 -1
  19. package/dist/core/settings-defaults.js +1 -0
  20. package/dist/core/settings-defaults.js.map +1 -1
  21. package/dist/core/settings-manager.d.ts +3 -0
  22. package/dist/core/settings-manager.d.ts.map +1 -1
  23. package/dist/core/settings-manager.js +8 -0
  24. package/dist/core/settings-manager.js.map +1 -1
  25. package/dist/core/tools/docedit.d.ts +42 -0
  26. package/dist/core/tools/docedit.d.ts.map +1 -0
  27. package/dist/core/tools/docedit.js +105 -0
  28. package/dist/core/tools/docedit.js.map +1 -0
  29. package/dist/core/tools/docread.d.ts +22 -0
  30. package/dist/core/tools/docread.d.ts.map +1 -0
  31. package/dist/core/tools/docread.js +112 -0
  32. package/dist/core/tools/docread.js.map +1 -0
  33. package/dist/core/tools/docwrite.d.ts +44 -0
  34. package/dist/core/tools/docwrite.d.ts.map +1 -0
  35. package/dist/core/tools/docwrite.js +92 -0
  36. package/dist/core/tools/docwrite.js.map +1 -0
  37. package/dist/core/tools/filetools-shared.d.ts +146 -0
  38. package/dist/core/tools/filetools-shared.d.ts.map +1 -0
  39. package/dist/core/tools/filetools-shared.js +208 -0
  40. package/dist/core/tools/filetools-shared.js.map +1 -0
  41. package/dist/core/tools/index.d.ts +10 -1
  42. package/dist/core/tools/index.d.ts.map +1 -1
  43. package/dist/core/tools/index.js +27 -0
  44. package/dist/core/tools/index.js.map +1 -1
  45. package/dist/core/tools/read.d.ts.map +1 -1
  46. package/dist/core/tools/read.js +29 -0
  47. package/dist/core/tools/read.js.map +1 -1
  48. package/dist/main.d.ts.map +1 -1
  49. package/dist/main.js +7 -0
  50. package/dist/main.js.map +1 -1
  51. package/dist/utils/tools-manager.d.ts +1 -1
  52. package/dist/utils/tools-manager.d.ts.map +1 -1
  53. package/dist/utils/tools-manager.js +24 -0
  54. package/dist/utils/tools-manager.js.map +1 -1
  55. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  56. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  57. package/examples/extensions/sandbox/package.json +1 -1
  58. package/examples/extensions/with-deps/package.json +1 -1
  59. package/package.json +4 -4
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.4.90] - 2026-06-26
4
+
5
+ ## [0.4.89] - 2026-06-26
6
+
7
+ ### Added
8
+
9
+ - Document tools `DocRead`, `DocEdit`, and `DocWrite` (off by default; enable with
10
+ `--enable-filetools` or the `enableFileTools` setting). They shell out to the
11
+ `filetools` binary (resolved from PATH or downloaded from GitHub releases) to
12
+ losslessly project structured/binary documents (XML, drawio, docx/xlsx/pptx,
13
+ PDF) into editable, id-addressed JSON: `DocRead` extracts a document to an
14
+ id-addressed envelope, `DocEdit` applies an id-based RFC-6902 patch in place and
15
+ re-extracts, and `DocWrite` reconstructs a patched document to a new path,
16
+ leaving the source untouched. `read` now redirects to `DocRead` when given an
17
+ OOXML or PDF file instead of dumping binary bytes.
18
+
3
19
  ## [0.4.88] - 2026-06-24
4
20
 
5
21
  ## [0.4.87] - 2026-06-24
@@ -40,6 +40,8 @@ export interface Args {
40
40
  todoWrite?: boolean;
41
41
  /** Enable the webfetch + websearch tools (off by default). */
42
42
  enableWebTools?: boolean;
43
+ /** Enable the DocRead + DocEdit + DocWrite document tools (off by default). */
44
+ enableFileTools?: boolean;
43
45
  /** Path to an explicit PEM CA bundle to trust additively for hoocode's own TLS traffic. */
44
46
  caCert?: string;
45
47
  /** Trust the OS/system CA store additively (opt-in) for hoocode's own TLS traffic. */
@@ -1 +1 @@
1
- {"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * CLI argument parsing and help display\n */\n\nimport type { ThinkingLevel } from \"@kolisachint/hoocode-agent-core\";\nimport chalk from \"chalk\";\nimport { APP_NAME, CONFIG_DIR_NAME, ENV_AGENT_DIR, ENV_SESSION_DIR } from \"../config.js\";\nimport type { ExtensionFlag } from \"../core/extensions/types.js\";\n\nexport type Mode = \"text\" | \"json\" | \"rpc\";\n\nexport interface Args {\n\tprovider?: string;\n\tmodel?: string;\n\tapiKey?: string;\n\tsystemPrompt?: string;\n\tthinking?: ThinkingLevel;\n\tcontinue?: boolean;\n\tresume?: boolean;\n\thelp?: boolean;\n\tversion?: boolean;\n\tmode?: Mode;\n\tnoSession?: boolean;\n\t/** Internal: task id assigned by SubagentPool when this process is a spawned subagent. */\n\ttaskId?: string;\n\t/** Hard cap on assistant turns. Near the cap the agent is asked to wrap up; at the cap it is stopped. */\n\tmaxTurns?: number;\n\tsession?: string;\n\t/** Base URL of a hooteams server to bridge into the task panel's teams view, or \"auto\" to discover a config and spawn one locally. */\n\tteam?: string;\n\tfork?: string;\n\tsessionDir?: string;\n\tmodels?: string[];\n\ttools?: string[];\n\tdisallowedTools?: string[];\n\tnoTools?: boolean;\n\tnoBuiltinTools?: boolean;\n\tsubagent?: boolean;\n\t/** Dispatch eligible subagents on reused warm RPC workers (overrides the warmSubagents setting). */\n\twarmSubagents?: boolean;\n\t/** Tree-wide subagent nesting cap (overrides the maxSubagentDepth setting). */\n\tmaxSubagentDepth?: number;\n\t/** Internal: restricts which subagent types this process may delegate to. */\n\tdelegateAllow?: string[];\n\ttodoWrite?: boolean;\n\t/** Enable the webfetch + websearch tools (off by default). */\n\tenableWebTools?: boolean;\n\t/** Path to an explicit PEM CA bundle to trust additively for hoocode's own TLS traffic. */\n\tcaCert?: string;\n\t/** Trust the OS/system CA store additively (opt-in) for hoocode's own TLS traffic. */\n\tuseSystemCa?: boolean;\n\textensions?: string[];\n\tnoExtensions?: boolean;\n\tprint?: boolean;\n\texport?: string;\n\tnoSkills?: boolean;\n\tskills?: string[];\n\tagents?: string[];\n\tpromptTemplates?: string[];\n\tnoPromptTemplates?: boolean;\n\tslashCommands?: string[];\n\tnoSlashCommands?: boolean;\n\tthemes?: string[];\n\tnoThemes?: boolean;\n\tmodePaths?: string[];\n\tnoContextFiles?: boolean;\n\tlistModels?: string | true;\n\toffline?: boolean;\n\tverbose?: boolean;\n\tmessages: string[];\n\tfileArgs: string[];\n\t/** Unknown flags (potentially extension flags) - map of flag name to value */\n\tunknownFlags: Map<string, boolean | string>;\n\tdiagnostics: Array<{ type: \"warning\" | \"error\"; message: string }>;\n}\n\nconst VALID_THINKING_LEVELS = [\"off\", \"minimal\", \"low\", \"medium\", \"high\", \"xhigh\"] as const;\n\nexport function isValidThinkingLevel(level: string): level is ThinkingLevel {\n\treturn VALID_THINKING_LEVELS.includes(level as ThinkingLevel);\n}\n\nexport function parseArgs(args: string[]): Args {\n\tconst result: Args = {\n\t\tmessages: [],\n\t\tfileArgs: [],\n\t\tunknownFlags: new Map(),\n\t\tdiagnostics: [],\n\t};\n\n\tfor (let i = 0; i < args.length; i++) {\n\t\tconst arg = args[i];\n\n\t\tif (arg === \"--help\" || arg === \"-h\") {\n\t\t\tresult.help = true;\n\t\t} else if (arg === \"--version\" || arg === \"-v\") {\n\t\t\tresult.version = true;\n\t\t} else if (arg === \"--mode\" && i + 1 < args.length) {\n\t\t\tconst mode = args[++i];\n\t\t\tif (mode === \"text\" || mode === \"json\" || mode === \"rpc\") {\n\t\t\t\tresult.mode = mode;\n\t\t\t}\n\t\t} else if (arg === \"--continue\" || arg === \"-c\") {\n\t\t\tresult.continue = true;\n\t\t} else if (arg === \"--resume\" || arg === \"-r\") {\n\t\t\tresult.resume = true;\n\t\t} else if (arg === \"--provider\" && i + 1 < args.length) {\n\t\t\tresult.provider = args[++i];\n\t\t} else if (arg === \"--model\" && i + 1 < args.length) {\n\t\t\tresult.model = args[++i];\n\t\t} else if (arg === \"--api-key\" && i + 1 < args.length) {\n\t\t\tresult.apiKey = args[++i];\n\t\t} else if (arg === \"--system-prompt\" && i + 1 < args.length) {\n\t\t\tresult.systemPrompt = args[++i];\n\t\t} else if (arg === \"--no-session\") {\n\t\t\tresult.noSession = true;\n\t\t} else if (arg === \"--task-id\" && i + 1 < args.length) {\n\t\t\tresult.taskId = args[++i];\n\t\t} else if (arg === \"--max-turns\" && i + 1 < args.length) {\n\t\t\tconst n = Number.parseInt(args[++i], 10);\n\t\t\tif (Number.isInteger(n) && n > 0) {\n\t\t\t\tresult.maxTurns = n;\n\t\t\t}\n\t\t} else if (arg === \"--session\" && i + 1 < args.length) {\n\t\t\tresult.session = args[++i];\n\t\t} else if (arg === \"--team\" && i + 1 < args.length) {\n\t\t\tresult.team = args[++i];\n\t\t} else if (arg === \"--fork\" && i + 1 < args.length) {\n\t\t\tresult.fork = args[++i];\n\t\t} else if (arg === \"--session-dir\" && i + 1 < args.length) {\n\t\t\tresult.sessionDir = args[++i];\n\t\t} else if (arg === \"--models\" && i + 1 < args.length) {\n\t\t\tresult.models = args[++i].split(\",\").map((s) => s.trim());\n\t\t} else if (arg === \"--no-tools\" || arg === \"-nt\") {\n\t\t\tresult.noTools = true;\n\t\t} else if (arg === \"--no-builtin-tools\" || arg === \"-nbt\") {\n\t\t\tresult.noBuiltinTools = true;\n\t\t} else if (arg === \"--enable-subagents\") {\n\t\t\tresult.subagent = true;\n\t\t} else if (arg === \"--warm-subagents\") {\n\t\t\tresult.warmSubagents = true;\n\t\t} else if (arg === \"--max-subagent-depth\" && i + 1 < args.length) {\n\t\t\tconst n = Number.parseInt(args[++i], 10);\n\t\t\tif (Number.isInteger(n) && n >= 1) {\n\t\t\t\tresult.maxSubagentDepth = n;\n\t\t\t}\n\t\t} else if (arg === \"--delegate-allow\" && i + 1 < args.length) {\n\t\t\tresult.delegateAllow = args[++i]\n\t\t\t\t.split(\",\")\n\t\t\t\t.map((s) => s.trim())\n\t\t\t\t.filter((name) => name.length > 0);\n\t\t} else if (arg === \"--enable-todowrite\") {\n\t\t\tresult.todoWrite = true;\n\t\t} else if (arg === \"--enable-webtools\") {\n\t\t\tresult.enableWebTools = true;\n\t\t} else if (arg === \"--ca-cert\" && i + 1 < args.length) {\n\t\t\tresult.caCert = args[++i];\n\t\t} else if (arg === \"--use-system-ca\") {\n\t\t\tresult.useSystemCa = true;\n\t\t} else if ((arg === \"--tools\" || arg === \"-t\") && i + 1 < args.length) {\n\t\t\tresult.tools = args[++i]\n\t\t\t\t.split(\",\")\n\t\t\t\t.map((s) => s.trim())\n\t\t\t\t.filter((name) => name.length > 0);\n\t\t} else if (arg === \"--disallowed-tools\" && i + 1 < args.length) {\n\t\t\tresult.disallowedTools = args[++i]\n\t\t\t\t.split(\",\")\n\t\t\t\t.map((s) => s.trim())\n\t\t\t\t.filter((name) => name.length > 0);\n\t\t} else if (arg === \"--thinking\" && i + 1 < args.length) {\n\t\t\tconst level = args[++i];\n\t\t\tif (isValidThinkingLevel(level)) {\n\t\t\t\tresult.thinking = level;\n\t\t\t} else {\n\t\t\t\tresult.diagnostics.push({\n\t\t\t\t\ttype: \"warning\",\n\t\t\t\t\tmessage: `Invalid thinking level \"${level}\". Valid values: ${VALID_THINKING_LEVELS.join(\", \")}`,\n\t\t\t\t});\n\t\t\t}\n\t\t} else if (arg === \"--print\" || arg === \"-p\") {\n\t\t\tresult.print = true;\n\t\t\tconst next = args[i + 1];\n\t\t\tif (next !== undefined && !next.startsWith(\"@\") && (!next.startsWith(\"-\") || next.startsWith(\"---\"))) {\n\t\t\t\tresult.messages.push(next);\n\t\t\t\ti++;\n\t\t\t}\n\t\t} else if (arg === \"--export\" && i + 1 < args.length) {\n\t\t\tresult.export = args[++i];\n\t\t} else if ((arg === \"--extension\" || arg === \"-e\") && i + 1 < args.length) {\n\t\t\tresult.extensions = result.extensions ?? [];\n\t\t\tresult.extensions.push(args[++i]);\n\t\t} else if (arg === \"--no-extensions\" || arg === \"-ne\") {\n\t\t\tresult.noExtensions = true;\n\t\t} else if (arg === \"--skill\" && i + 1 < args.length) {\n\t\t\tresult.skills = result.skills ?? [];\n\t\t\tresult.skills.push(args[++i]);\n\t\t} else if (arg === \"--agent\" && i + 1 < args.length) {\n\t\t\tresult.agents = result.agents ?? [];\n\t\t\tresult.agents.push(args[++i]);\n\t\t} else if (arg === \"--prompt-template\" && i + 1 < args.length) {\n\t\t\tresult.promptTemplates = result.promptTemplates ?? [];\n\t\t\tresult.promptTemplates.push(args[++i]);\n\t\t} else if (arg === \"--slash-command\" && i + 1 < args.length) {\n\t\t\tresult.slashCommands = result.slashCommands ?? [];\n\t\t\tresult.slashCommands.push(args[++i]);\n\t\t} else if (arg === \"--theme\" && i + 1 < args.length) {\n\t\t\tresult.themes = result.themes ?? [];\n\t\t\tresult.themes.push(args[++i]);\n\t\t} else if (arg === \"--mode-path\" && i + 1 < args.length) {\n\t\t\tresult.modePaths = result.modePaths ?? [];\n\t\t\tresult.modePaths.push(args[++i]);\n\t\t} else if (arg === \"--no-skills\" || arg === \"-ns\") {\n\t\t\tresult.noSkills = true;\n\t\t} else if (arg === \"--no-prompt-templates\" || arg === \"-np\") {\n\t\t\tresult.noPromptTemplates = true;\n\t\t} else if (arg === \"--no-slash-commands\" || arg === \"-nsc\") {\n\t\t\tresult.noSlashCommands = true;\n\t\t} else if (arg === \"--no-themes\") {\n\t\t\tresult.noThemes = true;\n\t\t} else if (arg === \"--no-context-files\" || arg === \"-nc\") {\n\t\t\tresult.noContextFiles = true;\n\t\t} else if (arg === \"--list-models\") {\n\t\t\t// Check if next arg is a search pattern (not a flag or file arg)\n\t\t\tif (i + 1 < args.length && !args[i + 1].startsWith(\"-\") && !args[i + 1].startsWith(\"@\")) {\n\t\t\t\tresult.listModels = args[++i];\n\t\t\t} else {\n\t\t\t\tresult.listModels = true;\n\t\t\t}\n\t\t} else if (arg === \"--verbose\") {\n\t\t\tresult.verbose = true;\n\t\t} else if (arg === \"--offline\") {\n\t\t\tresult.offline = true;\n\t\t} else if (arg.startsWith(\"@\")) {\n\t\t\tresult.fileArgs.push(arg.slice(1)); // Remove @ prefix\n\t\t} else if (arg.startsWith(\"--\")) {\n\t\t\tconst eqIndex = arg.indexOf(\"=\");\n\t\t\tif (eqIndex !== -1) {\n\t\t\t\tresult.unknownFlags.set(arg.slice(2, eqIndex), arg.slice(eqIndex + 1));\n\t\t\t} else {\n\t\t\t\tconst flagName = arg.slice(2);\n\t\t\t\tconst next = args[i + 1];\n\t\t\t\tif (next !== undefined && !next.startsWith(\"-\") && !next.startsWith(\"@\")) {\n\t\t\t\t\tresult.unknownFlags.set(flagName, next);\n\t\t\t\t\ti++;\n\t\t\t\t} else {\n\t\t\t\t\tresult.unknownFlags.set(flagName, true);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (arg.startsWith(\"-\") && !arg.startsWith(\"--\")) {\n\t\t\tresult.diagnostics.push({ type: \"error\", message: `Unknown option: ${arg}` });\n\t\t} else if (!arg.startsWith(\"-\")) {\n\t\t\tresult.messages.push(arg);\n\t\t}\n\t}\n\n\treturn result;\n}\n\nexport function printHelp(extensionFlags?: ExtensionFlag[]): void {\n\tconst extensionFlagsText =\n\t\textensionFlags && extensionFlags.length > 0\n\t\t\t? `\\n${chalk.bold(\"Extension CLI Flags:\")}\\n${extensionFlags\n\t\t\t\t\t.map((flag) => {\n\t\t\t\t\t\tconst value = flag.type === \"string\" ? \" <value>\" : \"\";\n\t\t\t\t\t\tconst description = flag.description ?? `Registered by ${flag.extensionPath}`;\n\t\t\t\t\t\treturn ` --${flag.name}${value}`.padEnd(30) + description;\n\t\t\t\t\t})\n\t\t\t\t\t.join(\"\\n\")}\\n`\n\t\t\t: \"\";\n\tconsole.log(`${chalk.bold(APP_NAME)} - AI coding assistant with read, bash, edit, write tools\n\n${chalk.bold(\"Usage:\")}\n ${APP_NAME} [options] [@files...] [messages...]\n\n${chalk.bold(\"Commands:\")}\n ${APP_NAME} install <source> [-l] Install extension source and add to settings\n ${APP_NAME} remove <source> [-l] Remove extension source from settings\n ${APP_NAME} uninstall <source> [-l] Alias for remove\n ${APP_NAME} update [source|self|pi] Update hoocode and installed extensions\n ${APP_NAME} list List installed extensions from settings\n ${APP_NAME} config Open TUI to enable/disable package resources\n ${APP_NAME} resources List discovered skills, subagents, slash commands, and MCP servers\n ${APP_NAME} <command> --help Show help for install/remove/uninstall/update/list\n\n${chalk.bold(\"Options:\")}\n --provider <name> Provider name (default: google)\n --model <pattern> Model pattern or ID (supports \"provider/id\" and optional \":<thinking>\")\n --api-key <key> API key (defaults to env vars)\n --system-prompt <text> System prompt (default: coding assistant prompt)\n --mode <mode> Output mode: text (default), json, or rpc\n --print, -p Non-interactive mode: process prompt and exit\n --continue, -c Continue previous session\n --resume, -r Select a session to resume\n --session <path|id> Use specific session file or partial UUID\n --fork <path|id> Fork specific session file or partial UUID into a new session\n --session-dir <dir> Directory for session storage and lookup\n --no-session Don't save session (ephemeral)\n --team <url|auto> Bridge a hooteams server into the task panel's teams view\n (focus roles, nudge, attach, answer approval gates);\n \"auto\" finds .agents/teams/default.json\n or hooteams.config.json upward from cwd and spawns hooteams locally\n --models <patterns> Comma-separated model patterns for Ctrl+P cycling\n Supports globs (anthropic/*, *sonnet*) and fuzzy matching\n --no-tools, -nt Disable all tools by default (built-in and extension)\n --no-builtin-tools, -nbt Disable built-in tools by default but keep extension/custom tools enabled\n --tools, -t <tools> Comma-separated allowlist of tool names to enable\n Applies to built-in, extension, and custom tools\n --disallowed-tools <tools> Comma-separated denylist of tool names to disable\n (subtracted from the allowlist or default set)\n --max-turns <n> Hard cap on assistant turns; the agent is asked to wrap up near the\n cap and stopped at it (mainly used for spawned subagents)\n --enable-subagents Enable the subagent tool (delegate tasks to isolated agent loops)\n --warm-subagents Dispatch eligible subagents on reused warm RPC workers (experimental)\n --max-subagent-depth <n> Tree-wide subagent nesting cap (default 1 = no nesting). Overrides\n the \"maxSubagentDepth\" setting\n Can also be enabled via the \"enableSubagent\" setting\n --enable-todowrite Enable the TodoWrite tool (maintain a live todo list in the task panel)\n Can also be enabled via the \"enableTodoWrite\" setting\n --enable-webtools Enable the webfetch + websearch tools (network access, off by default)\n Can also be enabled via the \"enableWebTools\" setting\n Block hosts with a .webtoolsignore file (gitignore syntax)\n --thinking <level> Set thinking level: off, minimal, low, medium, high, xhigh\n --extension, -e <path> Load an extension file (can be used multiple times)\n --no-extensions, -ne Disable extension discovery (explicit -e paths still work)\n --skill <path> Load a skill file or directory (can be used multiple times)\n --no-skills, -ns Disable skills discovery and loading\n --agent <path> Load an agent file or directory (can be used multiple times)\n --prompt-template <path> Load a prompt template / slash command file or directory (repeatable)\n --slash-command <path> Alias of --prompt-template (prompts and slash commands are one feature)\n --no-prompt-templates, -np Disable prompt template / slash command discovery (same as --no-slash-commands)\n --no-slash-commands, -nsc Disable prompt template / slash command discovery (same as --no-prompt-templates)\n --theme <path> Load a theme file or directory (can be used multiple times)\n --no-themes Disable theme discovery and loading\n --mode-path <dir> Add a directory to search for {name}/system.md mode files (can be used multiple times)\n --no-context-files, -nc Disable AGENTS.md and CLAUDE.md discovery and loading\n --export <file> Export session file to HTML and exit\n --list-models [search] List available models (with optional fuzzy search)\n --verbose Force verbose startup (overrides quietStartup setting)\n --offline Disable startup network operations (same as HOOCODE_OFFLINE=1)\n --ca-cert <path> Trust an extra PEM CA bundle for hoocode's own TLS traffic (provider\n calls, GitHub API, downloads). Additive to the bundled roots;\n verification stays ON. Also: HOOCODE_CA_CERT / NODE_EXTRA_CA_CERTS.\n Does not affect the webfetch/websearch binary.\n --use-system-ca Also trust the OS/system CA store (opt-in). Same as\n HOOCODE_USE_SYSTEM_CA=1\n --help, -h Show this help\n --version, -v Show version number\n\nExtensions can register additional flags (e.g., --plan from plan-mode extension).${extensionFlagsText}\n\n${chalk.bold(\"Examples:\")}\n # Interactive mode\n ${APP_NAME}\n\n # Interactive mode with initial prompt\n ${APP_NAME} \"List all .ts files in src/\"\n\n # Include files in initial message\n ${APP_NAME} @prompt.md @image.png \"What color is the sky?\"\n\n # Non-interactive mode (process and exit)\n ${APP_NAME} -p \"List all .ts files in src/\"\n\n # Multiple messages (interactive)\n ${APP_NAME} \"Read package.json\" \"What dependencies do we have?\"\n\n # Continue previous session\n ${APP_NAME} --continue \"What did we discuss?\"\n\n # Use different model\n ${APP_NAME} --provider openai --model gpt-4o-mini \"Help me refactor this code\"\n\n # Use model with provider prefix (no --provider needed)\n ${APP_NAME} --model openai/gpt-4o \"Help me refactor this code\"\n\n # Use model with thinking level shorthand\n ${APP_NAME} --model sonnet:high \"Solve this complex problem\"\n\n # Limit model cycling to specific models\n ${APP_NAME} --models claude-sonnet,claude-haiku,gpt-4o\n\n # Limit to a specific provider with glob pattern\n ${APP_NAME} --models \"github-copilot/*\"\n\n # Cycle models with fixed thinking levels\n ${APP_NAME} --models sonnet:high,haiku:low\n\n # Start with a specific thinking level\n ${APP_NAME} --thinking high \"Solve this complex problem\"\n\n # Read-only mode (no file modifications possible)\n ${APP_NAME} --tools read,grep,find,ls -p \"Review the code in src/\"\n\n # Export a session file to HTML\n ${APP_NAME} --export ~/${CONFIG_DIR_NAME}/agent/sessions/--path--/session.jsonl\n ${APP_NAME} --export session.jsonl output.html\n\n${chalk.bold(\"Environment Variables:\")}\n ANTHROPIC_API_KEY - Anthropic Claude API key\n ANTHROPIC_OAUTH_TOKEN - Anthropic OAuth token (alternative to API key)\n OPENAI_API_KEY - OpenAI GPT API key\n AZURE_OPENAI_API_KEY - Azure OpenAI API key\n AZURE_OPENAI_BASE_URL - Azure OpenAI/Cognitive Services base URL (e.g. https://{resource}.openai.azure.com)\n AZURE_OPENAI_RESOURCE_NAME - Azure OpenAI resource name (alternative to base URL)\n AZURE_OPENAI_API_VERSION - Azure OpenAI API version (default: v1)\n AZURE_OPENAI_DEPLOYMENT_NAME_MAP - Azure OpenAI model=deployment map (comma-separated)\n DEEPSEEK_API_KEY - DeepSeek API key\n GEMINI_API_KEY - Google Gemini API key\n GROQ_API_KEY - Groq API key\n CEREBRAS_API_KEY - Cerebras API key\n XAI_API_KEY - xAI Grok API key\n FIREWORKS_API_KEY - Fireworks API key\n TOGETHER_API_KEY - Together AI API key\n OPENROUTER_API_KEY - OpenRouter API key\n AI_GATEWAY_API_KEY - Vercel AI Gateway API key\n ZAI_API_KEY - ZAI API key\n MISTRAL_API_KEY - Mistral API key\n MINIMAX_API_KEY - MiniMax API key\n MOONSHOT_API_KEY - Moonshot AI API key\n OPENCODE_API_KEY - OpenCode Zen/OpenCode Go API key\n KIMI_API_KEY - Kimi For Coding API key\n CLOUDFLARE_API_KEY - Cloudflare API token (Workers AI and AI Gateway)\n CLOUDFLARE_ACCOUNT_ID - Cloudflare account id (required for both)\n CLOUDFLARE_GATEWAY_ID - Cloudflare AI Gateway slug (required for AI Gateway)\n XIAOMI_API_KEY - Xiaomi MiMo API key (api.xiaomimimo.com billing)\n XIAOMI_TOKEN_PLAN_CN_API_KEY - Xiaomi MiMo Token Plan API key (China region)\n XIAOMI_TOKEN_PLAN_AMS_API_KEY - Xiaomi MiMo Token Plan API key (Amsterdam region)\n XIAOMI_TOKEN_PLAN_SGP_API_KEY - Xiaomi MiMo Token Plan API key (Singapore region)\n NVIDIA_API_KEY - NVIDIA API key (integrate.api.nvidia.com)\n AWS_PROFILE - AWS profile for Amazon Bedrock\n AWS_ACCESS_KEY_ID - AWS access key for Amazon Bedrock\n AWS_SECRET_ACCESS_KEY - AWS secret key for Amazon Bedrock\n AWS_BEARER_TOKEN_BEDROCK - Bedrock API key (bearer token)\n AWS_REGION - AWS region for Amazon Bedrock (e.g., us-east-1)\n ${ENV_AGENT_DIR.padEnd(32)} - Config directory (default: ~/${CONFIG_DIR_NAME}/agent)\n ${ENV_SESSION_DIR.padEnd(32)} - Session storage directory (overridden by --session-dir)\n HOOCODE_PACKAGE_DIR - Override package directory (for Nix/Guix store paths). Legacy: PI_PACKAGE_DIR\n HOOCODE_OFFLINE - Disable startup network operations when set to 1/true/yes. Legacy: PI_OFFLINE\n HOOCODE_CA_CERT - Path to an extra PEM CA bundle to trust for hoocode's own TLS traffic\n (additive; verification stays on). Precedence: --ca-cert > this > NODE_EXTRA_CA_CERTS\n HOOCODE_USE_SYSTEM_CA - Also trust the OS/system CA store when set to 1/true/yes (same as --use-system-ca)\n NODE_EXTRA_CA_CERTS - Standard Node path to an extra PEM CA bundle (used as the lowest-precedence CA source)\n HOOCODE_WEBTOOLS_CA_CERT - Path to a PEM CA bundle forwarded to the webtools binary (webfetch/websearch) as --ca-cert\n HOOCODE_WEBTOOLS_INSECURE - Forward --insecure to the webtools binary (disables its TLS verification) when set to 1/true/yes\n HOOCODE_TELEMETRY - Override install telemetry when set to 1/true/yes or 0/false/no. Legacy: PI_TELEMETRY\n HOOCODE_SHARE_VIEWER_URL - Base URL for /share command (default: https://pi.dev/session/). Legacy: PI_SHARE_VIEWER_URL\n\n${chalk.bold(\"Built-in Tool Names:\")}\n read - Read file contents\n bash - Execute bash commands\n edit - Edit files with find/replace\n write - Write files (creates/overwrites)\n grep - Search file contents (read-only, off by default)\n find - Find files by glob pattern (read-only, off by default)\n ls - List directory contents (read-only, off by default)\n`);\n}\n"]}
1
+ {"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * CLI argument parsing and help display\n */\n\nimport type { ThinkingLevel } from \"@kolisachint/hoocode-agent-core\";\nimport chalk from \"chalk\";\nimport { APP_NAME, CONFIG_DIR_NAME, ENV_AGENT_DIR, ENV_SESSION_DIR } from \"../config.js\";\nimport type { ExtensionFlag } from \"../core/extensions/types.js\";\n\nexport type Mode = \"text\" | \"json\" | \"rpc\";\n\nexport interface Args {\n\tprovider?: string;\n\tmodel?: string;\n\tapiKey?: string;\n\tsystemPrompt?: string;\n\tthinking?: ThinkingLevel;\n\tcontinue?: boolean;\n\tresume?: boolean;\n\thelp?: boolean;\n\tversion?: boolean;\n\tmode?: Mode;\n\tnoSession?: boolean;\n\t/** Internal: task id assigned by SubagentPool when this process is a spawned subagent. */\n\ttaskId?: string;\n\t/** Hard cap on assistant turns. Near the cap the agent is asked to wrap up; at the cap it is stopped. */\n\tmaxTurns?: number;\n\tsession?: string;\n\t/** Base URL of a hooteams server to bridge into the task panel's teams view, or \"auto\" to discover a config and spawn one locally. */\n\tteam?: string;\n\tfork?: string;\n\tsessionDir?: string;\n\tmodels?: string[];\n\ttools?: string[];\n\tdisallowedTools?: string[];\n\tnoTools?: boolean;\n\tnoBuiltinTools?: boolean;\n\tsubagent?: boolean;\n\t/** Dispatch eligible subagents on reused warm RPC workers (overrides the warmSubagents setting). */\n\twarmSubagents?: boolean;\n\t/** Tree-wide subagent nesting cap (overrides the maxSubagentDepth setting). */\n\tmaxSubagentDepth?: number;\n\t/** Internal: restricts which subagent types this process may delegate to. */\n\tdelegateAllow?: string[];\n\ttodoWrite?: boolean;\n\t/** Enable the webfetch + websearch tools (off by default). */\n\tenableWebTools?: boolean;\n\t/** Enable the DocRead + DocEdit + DocWrite document tools (off by default). */\n\tenableFileTools?: boolean;\n\t/** Path to an explicit PEM CA bundle to trust additively for hoocode's own TLS traffic. */\n\tcaCert?: string;\n\t/** Trust the OS/system CA store additively (opt-in) for hoocode's own TLS traffic. */\n\tuseSystemCa?: boolean;\n\textensions?: string[];\n\tnoExtensions?: boolean;\n\tprint?: boolean;\n\texport?: string;\n\tnoSkills?: boolean;\n\tskills?: string[];\n\tagents?: string[];\n\tpromptTemplates?: string[];\n\tnoPromptTemplates?: boolean;\n\tslashCommands?: string[];\n\tnoSlashCommands?: boolean;\n\tthemes?: string[];\n\tnoThemes?: boolean;\n\tmodePaths?: string[];\n\tnoContextFiles?: boolean;\n\tlistModels?: string | true;\n\toffline?: boolean;\n\tverbose?: boolean;\n\tmessages: string[];\n\tfileArgs: string[];\n\t/** Unknown flags (potentially extension flags) - map of flag name to value */\n\tunknownFlags: Map<string, boolean | string>;\n\tdiagnostics: Array<{ type: \"warning\" | \"error\"; message: string }>;\n}\n\nconst VALID_THINKING_LEVELS = [\"off\", \"minimal\", \"low\", \"medium\", \"high\", \"xhigh\"] as const;\n\nexport function isValidThinkingLevel(level: string): level is ThinkingLevel {\n\treturn VALID_THINKING_LEVELS.includes(level as ThinkingLevel);\n}\n\nexport function parseArgs(args: string[]): Args {\n\tconst result: Args = {\n\t\tmessages: [],\n\t\tfileArgs: [],\n\t\tunknownFlags: new Map(),\n\t\tdiagnostics: [],\n\t};\n\n\tfor (let i = 0; i < args.length; i++) {\n\t\tconst arg = args[i];\n\n\t\tif (arg === \"--help\" || arg === \"-h\") {\n\t\t\tresult.help = true;\n\t\t} else if (arg === \"--version\" || arg === \"-v\") {\n\t\t\tresult.version = true;\n\t\t} else if (arg === \"--mode\" && i + 1 < args.length) {\n\t\t\tconst mode = args[++i];\n\t\t\tif (mode === \"text\" || mode === \"json\" || mode === \"rpc\") {\n\t\t\t\tresult.mode = mode;\n\t\t\t}\n\t\t} else if (arg === \"--continue\" || arg === \"-c\") {\n\t\t\tresult.continue = true;\n\t\t} else if (arg === \"--resume\" || arg === \"-r\") {\n\t\t\tresult.resume = true;\n\t\t} else if (arg === \"--provider\" && i + 1 < args.length) {\n\t\t\tresult.provider = args[++i];\n\t\t} else if (arg === \"--model\" && i + 1 < args.length) {\n\t\t\tresult.model = args[++i];\n\t\t} else if (arg === \"--api-key\" && i + 1 < args.length) {\n\t\t\tresult.apiKey = args[++i];\n\t\t} else if (arg === \"--system-prompt\" && i + 1 < args.length) {\n\t\t\tresult.systemPrompt = args[++i];\n\t\t} else if (arg === \"--no-session\") {\n\t\t\tresult.noSession = true;\n\t\t} else if (arg === \"--task-id\" && i + 1 < args.length) {\n\t\t\tresult.taskId = args[++i];\n\t\t} else if (arg === \"--max-turns\" && i + 1 < args.length) {\n\t\t\tconst n = Number.parseInt(args[++i], 10);\n\t\t\tif (Number.isInteger(n) && n > 0) {\n\t\t\t\tresult.maxTurns = n;\n\t\t\t}\n\t\t} else if (arg === \"--session\" && i + 1 < args.length) {\n\t\t\tresult.session = args[++i];\n\t\t} else if (arg === \"--team\" && i + 1 < args.length) {\n\t\t\tresult.team = args[++i];\n\t\t} else if (arg === \"--fork\" && i + 1 < args.length) {\n\t\t\tresult.fork = args[++i];\n\t\t} else if (arg === \"--session-dir\" && i + 1 < args.length) {\n\t\t\tresult.sessionDir = args[++i];\n\t\t} else if (arg === \"--models\" && i + 1 < args.length) {\n\t\t\tresult.models = args[++i].split(\",\").map((s) => s.trim());\n\t\t} else if (arg === \"--no-tools\" || arg === \"-nt\") {\n\t\t\tresult.noTools = true;\n\t\t} else if (arg === \"--no-builtin-tools\" || arg === \"-nbt\") {\n\t\t\tresult.noBuiltinTools = true;\n\t\t} else if (arg === \"--enable-subagents\") {\n\t\t\tresult.subagent = true;\n\t\t} else if (arg === \"--warm-subagents\") {\n\t\t\tresult.warmSubagents = true;\n\t\t} else if (arg === \"--max-subagent-depth\" && i + 1 < args.length) {\n\t\t\tconst n = Number.parseInt(args[++i], 10);\n\t\t\tif (Number.isInteger(n) && n >= 1) {\n\t\t\t\tresult.maxSubagentDepth = n;\n\t\t\t}\n\t\t} else if (arg === \"--delegate-allow\" && i + 1 < args.length) {\n\t\t\tresult.delegateAllow = args[++i]\n\t\t\t\t.split(\",\")\n\t\t\t\t.map((s) => s.trim())\n\t\t\t\t.filter((name) => name.length > 0);\n\t\t} else if (arg === \"--enable-todowrite\") {\n\t\t\tresult.todoWrite = true;\n\t\t} else if (arg === \"--enable-webtools\") {\n\t\t\tresult.enableWebTools = true;\n\t\t} else if (arg === \"--enable-filetools\") {\n\t\t\tresult.enableFileTools = true;\n\t\t} else if (arg === \"--ca-cert\" && i + 1 < args.length) {\n\t\t\tresult.caCert = args[++i];\n\t\t} else if (arg === \"--use-system-ca\") {\n\t\t\tresult.useSystemCa = true;\n\t\t} else if ((arg === \"--tools\" || arg === \"-t\") && i + 1 < args.length) {\n\t\t\tresult.tools = args[++i]\n\t\t\t\t.split(\",\")\n\t\t\t\t.map((s) => s.trim())\n\t\t\t\t.filter((name) => name.length > 0);\n\t\t} else if (arg === \"--disallowed-tools\" && i + 1 < args.length) {\n\t\t\tresult.disallowedTools = args[++i]\n\t\t\t\t.split(\",\")\n\t\t\t\t.map((s) => s.trim())\n\t\t\t\t.filter((name) => name.length > 0);\n\t\t} else if (arg === \"--thinking\" && i + 1 < args.length) {\n\t\t\tconst level = args[++i];\n\t\t\tif (isValidThinkingLevel(level)) {\n\t\t\t\tresult.thinking = level;\n\t\t\t} else {\n\t\t\t\tresult.diagnostics.push({\n\t\t\t\t\ttype: \"warning\",\n\t\t\t\t\tmessage: `Invalid thinking level \"${level}\". Valid values: ${VALID_THINKING_LEVELS.join(\", \")}`,\n\t\t\t\t});\n\t\t\t}\n\t\t} else if (arg === \"--print\" || arg === \"-p\") {\n\t\t\tresult.print = true;\n\t\t\tconst next = args[i + 1];\n\t\t\tif (next !== undefined && !next.startsWith(\"@\") && (!next.startsWith(\"-\") || next.startsWith(\"---\"))) {\n\t\t\t\tresult.messages.push(next);\n\t\t\t\ti++;\n\t\t\t}\n\t\t} else if (arg === \"--export\" && i + 1 < args.length) {\n\t\t\tresult.export = args[++i];\n\t\t} else if ((arg === \"--extension\" || arg === \"-e\") && i + 1 < args.length) {\n\t\t\tresult.extensions = result.extensions ?? [];\n\t\t\tresult.extensions.push(args[++i]);\n\t\t} else if (arg === \"--no-extensions\" || arg === \"-ne\") {\n\t\t\tresult.noExtensions = true;\n\t\t} else if (arg === \"--skill\" && i + 1 < args.length) {\n\t\t\tresult.skills = result.skills ?? [];\n\t\t\tresult.skills.push(args[++i]);\n\t\t} else if (arg === \"--agent\" && i + 1 < args.length) {\n\t\t\tresult.agents = result.agents ?? [];\n\t\t\tresult.agents.push(args[++i]);\n\t\t} else if (arg === \"--prompt-template\" && i + 1 < args.length) {\n\t\t\tresult.promptTemplates = result.promptTemplates ?? [];\n\t\t\tresult.promptTemplates.push(args[++i]);\n\t\t} else if (arg === \"--slash-command\" && i + 1 < args.length) {\n\t\t\tresult.slashCommands = result.slashCommands ?? [];\n\t\t\tresult.slashCommands.push(args[++i]);\n\t\t} else if (arg === \"--theme\" && i + 1 < args.length) {\n\t\t\tresult.themes = result.themes ?? [];\n\t\t\tresult.themes.push(args[++i]);\n\t\t} else if (arg === \"--mode-path\" && i + 1 < args.length) {\n\t\t\tresult.modePaths = result.modePaths ?? [];\n\t\t\tresult.modePaths.push(args[++i]);\n\t\t} else if (arg === \"--no-skills\" || arg === \"-ns\") {\n\t\t\tresult.noSkills = true;\n\t\t} else if (arg === \"--no-prompt-templates\" || arg === \"-np\") {\n\t\t\tresult.noPromptTemplates = true;\n\t\t} else if (arg === \"--no-slash-commands\" || arg === \"-nsc\") {\n\t\t\tresult.noSlashCommands = true;\n\t\t} else if (arg === \"--no-themes\") {\n\t\t\tresult.noThemes = true;\n\t\t} else if (arg === \"--no-context-files\" || arg === \"-nc\") {\n\t\t\tresult.noContextFiles = true;\n\t\t} else if (arg === \"--list-models\") {\n\t\t\t// Check if next arg is a search pattern (not a flag or file arg)\n\t\t\tif (i + 1 < args.length && !args[i + 1].startsWith(\"-\") && !args[i + 1].startsWith(\"@\")) {\n\t\t\t\tresult.listModels = args[++i];\n\t\t\t} else {\n\t\t\t\tresult.listModels = true;\n\t\t\t}\n\t\t} else if (arg === \"--verbose\") {\n\t\t\tresult.verbose = true;\n\t\t} else if (arg === \"--offline\") {\n\t\t\tresult.offline = true;\n\t\t} else if (arg.startsWith(\"@\")) {\n\t\t\tresult.fileArgs.push(arg.slice(1)); // Remove @ prefix\n\t\t} else if (arg.startsWith(\"--\")) {\n\t\t\tconst eqIndex = arg.indexOf(\"=\");\n\t\t\tif (eqIndex !== -1) {\n\t\t\t\tresult.unknownFlags.set(arg.slice(2, eqIndex), arg.slice(eqIndex + 1));\n\t\t\t} else {\n\t\t\t\tconst flagName = arg.slice(2);\n\t\t\t\tconst next = args[i + 1];\n\t\t\t\tif (next !== undefined && !next.startsWith(\"-\") && !next.startsWith(\"@\")) {\n\t\t\t\t\tresult.unknownFlags.set(flagName, next);\n\t\t\t\t\ti++;\n\t\t\t\t} else {\n\t\t\t\t\tresult.unknownFlags.set(flagName, true);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (arg.startsWith(\"-\") && !arg.startsWith(\"--\")) {\n\t\t\tresult.diagnostics.push({ type: \"error\", message: `Unknown option: ${arg}` });\n\t\t} else if (!arg.startsWith(\"-\")) {\n\t\t\tresult.messages.push(arg);\n\t\t}\n\t}\n\n\treturn result;\n}\n\nexport function printHelp(extensionFlags?: ExtensionFlag[]): void {\n\tconst extensionFlagsText =\n\t\textensionFlags && extensionFlags.length > 0\n\t\t\t? `\\n${chalk.bold(\"Extension CLI Flags:\")}\\n${extensionFlags\n\t\t\t\t\t.map((flag) => {\n\t\t\t\t\t\tconst value = flag.type === \"string\" ? \" <value>\" : \"\";\n\t\t\t\t\t\tconst description = flag.description ?? `Registered by ${flag.extensionPath}`;\n\t\t\t\t\t\treturn ` --${flag.name}${value}`.padEnd(30) + description;\n\t\t\t\t\t})\n\t\t\t\t\t.join(\"\\n\")}\\n`\n\t\t\t: \"\";\n\tconsole.log(`${chalk.bold(APP_NAME)} - AI coding assistant with read, bash, edit, write tools\n\n${chalk.bold(\"Usage:\")}\n ${APP_NAME} [options] [@files...] [messages...]\n\n${chalk.bold(\"Commands:\")}\n ${APP_NAME} install <source> [-l] Install extension source and add to settings\n ${APP_NAME} remove <source> [-l] Remove extension source from settings\n ${APP_NAME} uninstall <source> [-l] Alias for remove\n ${APP_NAME} update [source|self|pi] Update hoocode and installed extensions\n ${APP_NAME} list List installed extensions from settings\n ${APP_NAME} config Open TUI to enable/disable package resources\n ${APP_NAME} resources List discovered skills, subagents, slash commands, and MCP servers\n ${APP_NAME} <command> --help Show help for install/remove/uninstall/update/list\n\n${chalk.bold(\"Options:\")}\n --provider <name> Provider name (default: google)\n --model <pattern> Model pattern or ID (supports \"provider/id\" and optional \":<thinking>\")\n --api-key <key> API key (defaults to env vars)\n --system-prompt <text> System prompt (default: coding assistant prompt)\n --mode <mode> Output mode: text (default), json, or rpc\n --print, -p Non-interactive mode: process prompt and exit\n --continue, -c Continue previous session\n --resume, -r Select a session to resume\n --session <path|id> Use specific session file or partial UUID\n --fork <path|id> Fork specific session file or partial UUID into a new session\n --session-dir <dir> Directory for session storage and lookup\n --no-session Don't save session (ephemeral)\n --team <url|auto> Bridge a hooteams server into the task panel's teams view\n (focus roles, nudge, attach, answer approval gates);\n \"auto\" finds .agents/teams/default.json\n or hooteams.config.json upward from cwd and spawns hooteams locally\n --models <patterns> Comma-separated model patterns for Ctrl+P cycling\n Supports globs (anthropic/*, *sonnet*) and fuzzy matching\n --no-tools, -nt Disable all tools by default (built-in and extension)\n --no-builtin-tools, -nbt Disable built-in tools by default but keep extension/custom tools enabled\n --tools, -t <tools> Comma-separated allowlist of tool names to enable\n Applies to built-in, extension, and custom tools\n --disallowed-tools <tools> Comma-separated denylist of tool names to disable\n (subtracted from the allowlist or default set)\n --max-turns <n> Hard cap on assistant turns; the agent is asked to wrap up near the\n cap and stopped at it (mainly used for spawned subagents)\n --enable-subagents Enable the subagent tool (delegate tasks to isolated agent loops)\n --warm-subagents Dispatch eligible subagents on reused warm RPC workers (experimental)\n --max-subagent-depth <n> Tree-wide subagent nesting cap (default 1 = no nesting). Overrides\n the \"maxSubagentDepth\" setting\n Can also be enabled via the \"enableSubagent\" setting\n --enable-todowrite Enable the TodoWrite tool (maintain a live todo list in the task panel)\n Can also be enabled via the \"enableTodoWrite\" setting\n --enable-webtools Enable the webfetch + websearch tools (network access, off by default)\n Can also be enabled via the \"enableWebTools\" setting\n Block hosts with a .webtoolsignore file (gitignore syntax)\n --enable-filetools Enable the DocRead + DocEdit + DocWrite document tools (off by default)\n Losslessly extract/edit XML, drawio, docx/xlsx/pptx, PDF via the filetools binary\n Can also be enabled via the \"enableFileTools\" setting\n --thinking <level> Set thinking level: off, minimal, low, medium, high, xhigh\n --extension, -e <path> Load an extension file (can be used multiple times)\n --no-extensions, -ne Disable extension discovery (explicit -e paths still work)\n --skill <path> Load a skill file or directory (can be used multiple times)\n --no-skills, -ns Disable skills discovery and loading\n --agent <path> Load an agent file or directory (can be used multiple times)\n --prompt-template <path> Load a prompt template / slash command file or directory (repeatable)\n --slash-command <path> Alias of --prompt-template (prompts and slash commands are one feature)\n --no-prompt-templates, -np Disable prompt template / slash command discovery (same as --no-slash-commands)\n --no-slash-commands, -nsc Disable prompt template / slash command discovery (same as --no-prompt-templates)\n --theme <path> Load a theme file or directory (can be used multiple times)\n --no-themes Disable theme discovery and loading\n --mode-path <dir> Add a directory to search for {name}/system.md mode files (can be used multiple times)\n --no-context-files, -nc Disable AGENTS.md and CLAUDE.md discovery and loading\n --export <file> Export session file to HTML and exit\n --list-models [search] List available models (with optional fuzzy search)\n --verbose Force verbose startup (overrides quietStartup setting)\n --offline Disable startup network operations (same as HOOCODE_OFFLINE=1)\n --ca-cert <path> Trust an extra PEM CA bundle for hoocode's own TLS traffic (provider\n calls, GitHub API, downloads). Additive to the bundled roots;\n verification stays ON. Also: HOOCODE_CA_CERT / NODE_EXTRA_CA_CERTS.\n Does not affect the webfetch/websearch binary.\n --use-system-ca Also trust the OS/system CA store (opt-in). Same as\n HOOCODE_USE_SYSTEM_CA=1\n --help, -h Show this help\n --version, -v Show version number\n\nExtensions can register additional flags (e.g., --plan from plan-mode extension).${extensionFlagsText}\n\n${chalk.bold(\"Examples:\")}\n # Interactive mode\n ${APP_NAME}\n\n # Interactive mode with initial prompt\n ${APP_NAME} \"List all .ts files in src/\"\n\n # Include files in initial message\n ${APP_NAME} @prompt.md @image.png \"What color is the sky?\"\n\n # Non-interactive mode (process and exit)\n ${APP_NAME} -p \"List all .ts files in src/\"\n\n # Multiple messages (interactive)\n ${APP_NAME} \"Read package.json\" \"What dependencies do we have?\"\n\n # Continue previous session\n ${APP_NAME} --continue \"What did we discuss?\"\n\n # Use different model\n ${APP_NAME} --provider openai --model gpt-4o-mini \"Help me refactor this code\"\n\n # Use model with provider prefix (no --provider needed)\n ${APP_NAME} --model openai/gpt-4o \"Help me refactor this code\"\n\n # Use model with thinking level shorthand\n ${APP_NAME} --model sonnet:high \"Solve this complex problem\"\n\n # Limit model cycling to specific models\n ${APP_NAME} --models claude-sonnet,claude-haiku,gpt-4o\n\n # Limit to a specific provider with glob pattern\n ${APP_NAME} --models \"github-copilot/*\"\n\n # Cycle models with fixed thinking levels\n ${APP_NAME} --models sonnet:high,haiku:low\n\n # Start with a specific thinking level\n ${APP_NAME} --thinking high \"Solve this complex problem\"\n\n # Read-only mode (no file modifications possible)\n ${APP_NAME} --tools read,grep,find,ls -p \"Review the code in src/\"\n\n # Export a session file to HTML\n ${APP_NAME} --export ~/${CONFIG_DIR_NAME}/agent/sessions/--path--/session.jsonl\n ${APP_NAME} --export session.jsonl output.html\n\n${chalk.bold(\"Environment Variables:\")}\n ANTHROPIC_API_KEY - Anthropic Claude API key\n ANTHROPIC_OAUTH_TOKEN - Anthropic OAuth token (alternative to API key)\n OPENAI_API_KEY - OpenAI GPT API key\n AZURE_OPENAI_API_KEY - Azure OpenAI API key\n AZURE_OPENAI_BASE_URL - Azure OpenAI/Cognitive Services base URL (e.g. https://{resource}.openai.azure.com)\n AZURE_OPENAI_RESOURCE_NAME - Azure OpenAI resource name (alternative to base URL)\n AZURE_OPENAI_API_VERSION - Azure OpenAI API version (default: v1)\n AZURE_OPENAI_DEPLOYMENT_NAME_MAP - Azure OpenAI model=deployment map (comma-separated)\n DEEPSEEK_API_KEY - DeepSeek API key\n GEMINI_API_KEY - Google Gemini API key\n GROQ_API_KEY - Groq API key\n CEREBRAS_API_KEY - Cerebras API key\n XAI_API_KEY - xAI Grok API key\n FIREWORKS_API_KEY - Fireworks API key\n TOGETHER_API_KEY - Together AI API key\n OPENROUTER_API_KEY - OpenRouter API key\n AI_GATEWAY_API_KEY - Vercel AI Gateway API key\n ZAI_API_KEY - ZAI API key\n MISTRAL_API_KEY - Mistral API key\n MINIMAX_API_KEY - MiniMax API key\n MOONSHOT_API_KEY - Moonshot AI API key\n OPENCODE_API_KEY - OpenCode Zen/OpenCode Go API key\n KIMI_API_KEY - Kimi For Coding API key\n CLOUDFLARE_API_KEY - Cloudflare API token (Workers AI and AI Gateway)\n CLOUDFLARE_ACCOUNT_ID - Cloudflare account id (required for both)\n CLOUDFLARE_GATEWAY_ID - Cloudflare AI Gateway slug (required for AI Gateway)\n XIAOMI_API_KEY - Xiaomi MiMo API key (api.xiaomimimo.com billing)\n XIAOMI_TOKEN_PLAN_CN_API_KEY - Xiaomi MiMo Token Plan API key (China region)\n XIAOMI_TOKEN_PLAN_AMS_API_KEY - Xiaomi MiMo Token Plan API key (Amsterdam region)\n XIAOMI_TOKEN_PLAN_SGP_API_KEY - Xiaomi MiMo Token Plan API key (Singapore region)\n NVIDIA_API_KEY - NVIDIA API key (integrate.api.nvidia.com)\n AWS_PROFILE - AWS profile for Amazon Bedrock\n AWS_ACCESS_KEY_ID - AWS access key for Amazon Bedrock\n AWS_SECRET_ACCESS_KEY - AWS secret key for Amazon Bedrock\n AWS_BEARER_TOKEN_BEDROCK - Bedrock API key (bearer token)\n AWS_REGION - AWS region for Amazon Bedrock (e.g., us-east-1)\n ${ENV_AGENT_DIR.padEnd(32)} - Config directory (default: ~/${CONFIG_DIR_NAME}/agent)\n ${ENV_SESSION_DIR.padEnd(32)} - Session storage directory (overridden by --session-dir)\n HOOCODE_PACKAGE_DIR - Override package directory (for Nix/Guix store paths). Legacy: PI_PACKAGE_DIR\n HOOCODE_OFFLINE - Disable startup network operations when set to 1/true/yes. Legacy: PI_OFFLINE\n HOOCODE_CA_CERT - Path to an extra PEM CA bundle to trust for hoocode's own TLS traffic\n (additive; verification stays on). Precedence: --ca-cert > this > NODE_EXTRA_CA_CERTS\n HOOCODE_USE_SYSTEM_CA - Also trust the OS/system CA store when set to 1/true/yes (same as --use-system-ca)\n NODE_EXTRA_CA_CERTS - Standard Node path to an extra PEM CA bundle (used as the lowest-precedence CA source)\n HOOCODE_WEBTOOLS_CA_CERT - Path to a PEM CA bundle forwarded to the webtools binary (webfetch/websearch) as --ca-cert\n HOOCODE_WEBTOOLS_INSECURE - Forward --insecure to the webtools binary (disables its TLS verification) when set to 1/true/yes\n HOOCODE_TELEMETRY - Override install telemetry when set to 1/true/yes or 0/false/no. Legacy: PI_TELEMETRY\n HOOCODE_SHARE_VIEWER_URL - Base URL for /share command (default: https://pi.dev/session/). Legacy: PI_SHARE_VIEWER_URL\n\n${chalk.bold(\"Built-in Tool Names:\")}\n read - Read file contents\n bash - Execute bash commands\n edit - Edit files with find/replace\n write - Write files (creates/overwrites)\n grep - Search file contents (read-only, off by default)\n find - Find files by glob pattern (read-only, off by default)\n ls - List directory contents (read-only, off by default)\n`);\n}\n"]}
package/dist/cli/args.js CHANGED
@@ -103,6 +103,9 @@ export function parseArgs(args) {
103
103
  else if (arg === "--enable-webtools") {
104
104
  result.enableWebTools = true;
105
105
  }
106
+ else if (arg === "--enable-filetools") {
107
+ result.enableFileTools = true;
108
+ }
106
109
  else if (arg === "--ca-cert" && i + 1 < args.length) {
107
110
  result.caCert = args[++i];
108
111
  }
@@ -296,6 +299,9 @@ ${chalk.bold("Options:")}
296
299
  --enable-webtools Enable the webfetch + websearch tools (network access, off by default)
297
300
  Can also be enabled via the "enableWebTools" setting
298
301
  Block hosts with a .webtoolsignore file (gitignore syntax)
302
+ --enable-filetools Enable the DocRead + DocEdit + DocWrite document tools (off by default)
303
+ Losslessly extract/edit XML, drawio, docx/xlsx/pptx, PDF via the filetools binary
304
+ Can also be enabled via the "enableFileTools" setting
299
305
  --thinking <level> Set thinking level: off, minimal, low, medium, high, xhigh
300
306
  --extension, -e <path> Load an extension file (can be used multiple times)
301
307
  --no-extensions, -ne Disable extension discovery (explicit -e paths still work)
@@ -1 +1 @@
1
- {"version":3,"file":"args.js","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * CLI argument parsing and help display\n */\n\nimport type { ThinkingLevel } from \"@kolisachint/hoocode-agent-core\";\nimport chalk from \"chalk\";\nimport { APP_NAME, CONFIG_DIR_NAME, ENV_AGENT_DIR, ENV_SESSION_DIR } from \"../config.js\";\nimport type { ExtensionFlag } from \"../core/extensions/types.js\";\n\nexport type Mode = \"text\" | \"json\" | \"rpc\";\n\nexport interface Args {\n\tprovider?: string;\n\tmodel?: string;\n\tapiKey?: string;\n\tsystemPrompt?: string;\n\tthinking?: ThinkingLevel;\n\tcontinue?: boolean;\n\tresume?: boolean;\n\thelp?: boolean;\n\tversion?: boolean;\n\tmode?: Mode;\n\tnoSession?: boolean;\n\t/** Internal: task id assigned by SubagentPool when this process is a spawned subagent. */\n\ttaskId?: string;\n\t/** Hard cap on assistant turns. Near the cap the agent is asked to wrap up; at the cap it is stopped. */\n\tmaxTurns?: number;\n\tsession?: string;\n\t/** Base URL of a hooteams server to bridge into the task panel's teams view, or \"auto\" to discover a config and spawn one locally. */\n\tteam?: string;\n\tfork?: string;\n\tsessionDir?: string;\n\tmodels?: string[];\n\ttools?: string[];\n\tdisallowedTools?: string[];\n\tnoTools?: boolean;\n\tnoBuiltinTools?: boolean;\n\tsubagent?: boolean;\n\t/** Dispatch eligible subagents on reused warm RPC workers (overrides the warmSubagents setting). */\n\twarmSubagents?: boolean;\n\t/** Tree-wide subagent nesting cap (overrides the maxSubagentDepth setting). */\n\tmaxSubagentDepth?: number;\n\t/** Internal: restricts which subagent types this process may delegate to. */\n\tdelegateAllow?: string[];\n\ttodoWrite?: boolean;\n\t/** Enable the webfetch + websearch tools (off by default). */\n\tenableWebTools?: boolean;\n\t/** Path to an explicit PEM CA bundle to trust additively for hoocode's own TLS traffic. */\n\tcaCert?: string;\n\t/** Trust the OS/system CA store additively (opt-in) for hoocode's own TLS traffic. */\n\tuseSystemCa?: boolean;\n\textensions?: string[];\n\tnoExtensions?: boolean;\n\tprint?: boolean;\n\texport?: string;\n\tnoSkills?: boolean;\n\tskills?: string[];\n\tagents?: string[];\n\tpromptTemplates?: string[];\n\tnoPromptTemplates?: boolean;\n\tslashCommands?: string[];\n\tnoSlashCommands?: boolean;\n\tthemes?: string[];\n\tnoThemes?: boolean;\n\tmodePaths?: string[];\n\tnoContextFiles?: boolean;\n\tlistModels?: string | true;\n\toffline?: boolean;\n\tverbose?: boolean;\n\tmessages: string[];\n\tfileArgs: string[];\n\t/** Unknown flags (potentially extension flags) - map of flag name to value */\n\tunknownFlags: Map<string, boolean | string>;\n\tdiagnostics: Array<{ type: \"warning\" | \"error\"; message: string }>;\n}\n\nconst VALID_THINKING_LEVELS = [\"off\", \"minimal\", \"low\", \"medium\", \"high\", \"xhigh\"] as const;\n\nexport function isValidThinkingLevel(level: string): level is ThinkingLevel {\n\treturn VALID_THINKING_LEVELS.includes(level as ThinkingLevel);\n}\n\nexport function parseArgs(args: string[]): Args {\n\tconst result: Args = {\n\t\tmessages: [],\n\t\tfileArgs: [],\n\t\tunknownFlags: new Map(),\n\t\tdiagnostics: [],\n\t};\n\n\tfor (let i = 0; i < args.length; i++) {\n\t\tconst arg = args[i];\n\n\t\tif (arg === \"--help\" || arg === \"-h\") {\n\t\t\tresult.help = true;\n\t\t} else if (arg === \"--version\" || arg === \"-v\") {\n\t\t\tresult.version = true;\n\t\t} else if (arg === \"--mode\" && i + 1 < args.length) {\n\t\t\tconst mode = args[++i];\n\t\t\tif (mode === \"text\" || mode === \"json\" || mode === \"rpc\") {\n\t\t\t\tresult.mode = mode;\n\t\t\t}\n\t\t} else if (arg === \"--continue\" || arg === \"-c\") {\n\t\t\tresult.continue = true;\n\t\t} else if (arg === \"--resume\" || arg === \"-r\") {\n\t\t\tresult.resume = true;\n\t\t} else if (arg === \"--provider\" && i + 1 < args.length) {\n\t\t\tresult.provider = args[++i];\n\t\t} else if (arg === \"--model\" && i + 1 < args.length) {\n\t\t\tresult.model = args[++i];\n\t\t} else if (arg === \"--api-key\" && i + 1 < args.length) {\n\t\t\tresult.apiKey = args[++i];\n\t\t} else if (arg === \"--system-prompt\" && i + 1 < args.length) {\n\t\t\tresult.systemPrompt = args[++i];\n\t\t} else if (arg === \"--no-session\") {\n\t\t\tresult.noSession = true;\n\t\t} else if (arg === \"--task-id\" && i + 1 < args.length) {\n\t\t\tresult.taskId = args[++i];\n\t\t} else if (arg === \"--max-turns\" && i + 1 < args.length) {\n\t\t\tconst n = Number.parseInt(args[++i], 10);\n\t\t\tif (Number.isInteger(n) && n > 0) {\n\t\t\t\tresult.maxTurns = n;\n\t\t\t}\n\t\t} else if (arg === \"--session\" && i + 1 < args.length) {\n\t\t\tresult.session = args[++i];\n\t\t} else if (arg === \"--team\" && i + 1 < args.length) {\n\t\t\tresult.team = args[++i];\n\t\t} else if (arg === \"--fork\" && i + 1 < args.length) {\n\t\t\tresult.fork = args[++i];\n\t\t} else if (arg === \"--session-dir\" && i + 1 < args.length) {\n\t\t\tresult.sessionDir = args[++i];\n\t\t} else if (arg === \"--models\" && i + 1 < args.length) {\n\t\t\tresult.models = args[++i].split(\",\").map((s) => s.trim());\n\t\t} else if (arg === \"--no-tools\" || arg === \"-nt\") {\n\t\t\tresult.noTools = true;\n\t\t} else if (arg === \"--no-builtin-tools\" || arg === \"-nbt\") {\n\t\t\tresult.noBuiltinTools = true;\n\t\t} else if (arg === \"--enable-subagents\") {\n\t\t\tresult.subagent = true;\n\t\t} else if (arg === \"--warm-subagents\") {\n\t\t\tresult.warmSubagents = true;\n\t\t} else if (arg === \"--max-subagent-depth\" && i + 1 < args.length) {\n\t\t\tconst n = Number.parseInt(args[++i], 10);\n\t\t\tif (Number.isInteger(n) && n >= 1) {\n\t\t\t\tresult.maxSubagentDepth = n;\n\t\t\t}\n\t\t} else if (arg === \"--delegate-allow\" && i + 1 < args.length) {\n\t\t\tresult.delegateAllow = args[++i]\n\t\t\t\t.split(\",\")\n\t\t\t\t.map((s) => s.trim())\n\t\t\t\t.filter((name) => name.length > 0);\n\t\t} else if (arg === \"--enable-todowrite\") {\n\t\t\tresult.todoWrite = true;\n\t\t} else if (arg === \"--enable-webtools\") {\n\t\t\tresult.enableWebTools = true;\n\t\t} else if (arg === \"--ca-cert\" && i + 1 < args.length) {\n\t\t\tresult.caCert = args[++i];\n\t\t} else if (arg === \"--use-system-ca\") {\n\t\t\tresult.useSystemCa = true;\n\t\t} else if ((arg === \"--tools\" || arg === \"-t\") && i + 1 < args.length) {\n\t\t\tresult.tools = args[++i]\n\t\t\t\t.split(\",\")\n\t\t\t\t.map((s) => s.trim())\n\t\t\t\t.filter((name) => name.length > 0);\n\t\t} else if (arg === \"--disallowed-tools\" && i + 1 < args.length) {\n\t\t\tresult.disallowedTools = args[++i]\n\t\t\t\t.split(\",\")\n\t\t\t\t.map((s) => s.trim())\n\t\t\t\t.filter((name) => name.length > 0);\n\t\t} else if (arg === \"--thinking\" && i + 1 < args.length) {\n\t\t\tconst level = args[++i];\n\t\t\tif (isValidThinkingLevel(level)) {\n\t\t\t\tresult.thinking = level;\n\t\t\t} else {\n\t\t\t\tresult.diagnostics.push({\n\t\t\t\t\ttype: \"warning\",\n\t\t\t\t\tmessage: `Invalid thinking level \"${level}\". Valid values: ${VALID_THINKING_LEVELS.join(\", \")}`,\n\t\t\t\t});\n\t\t\t}\n\t\t} else if (arg === \"--print\" || arg === \"-p\") {\n\t\t\tresult.print = true;\n\t\t\tconst next = args[i + 1];\n\t\t\tif (next !== undefined && !next.startsWith(\"@\") && (!next.startsWith(\"-\") || next.startsWith(\"---\"))) {\n\t\t\t\tresult.messages.push(next);\n\t\t\t\ti++;\n\t\t\t}\n\t\t} else if (arg === \"--export\" && i + 1 < args.length) {\n\t\t\tresult.export = args[++i];\n\t\t} else if ((arg === \"--extension\" || arg === \"-e\") && i + 1 < args.length) {\n\t\t\tresult.extensions = result.extensions ?? [];\n\t\t\tresult.extensions.push(args[++i]);\n\t\t} else if (arg === \"--no-extensions\" || arg === \"-ne\") {\n\t\t\tresult.noExtensions = true;\n\t\t} else if (arg === \"--skill\" && i + 1 < args.length) {\n\t\t\tresult.skills = result.skills ?? [];\n\t\t\tresult.skills.push(args[++i]);\n\t\t} else if (arg === \"--agent\" && i + 1 < args.length) {\n\t\t\tresult.agents = result.agents ?? [];\n\t\t\tresult.agents.push(args[++i]);\n\t\t} else if (arg === \"--prompt-template\" && i + 1 < args.length) {\n\t\t\tresult.promptTemplates = result.promptTemplates ?? [];\n\t\t\tresult.promptTemplates.push(args[++i]);\n\t\t} else if (arg === \"--slash-command\" && i + 1 < args.length) {\n\t\t\tresult.slashCommands = result.slashCommands ?? [];\n\t\t\tresult.slashCommands.push(args[++i]);\n\t\t} else if (arg === \"--theme\" && i + 1 < args.length) {\n\t\t\tresult.themes = result.themes ?? [];\n\t\t\tresult.themes.push(args[++i]);\n\t\t} else if (arg === \"--mode-path\" && i + 1 < args.length) {\n\t\t\tresult.modePaths = result.modePaths ?? [];\n\t\t\tresult.modePaths.push(args[++i]);\n\t\t} else if (arg === \"--no-skills\" || arg === \"-ns\") {\n\t\t\tresult.noSkills = true;\n\t\t} else if (arg === \"--no-prompt-templates\" || arg === \"-np\") {\n\t\t\tresult.noPromptTemplates = true;\n\t\t} else if (arg === \"--no-slash-commands\" || arg === \"-nsc\") {\n\t\t\tresult.noSlashCommands = true;\n\t\t} else if (arg === \"--no-themes\") {\n\t\t\tresult.noThemes = true;\n\t\t} else if (arg === \"--no-context-files\" || arg === \"-nc\") {\n\t\t\tresult.noContextFiles = true;\n\t\t} else if (arg === \"--list-models\") {\n\t\t\t// Check if next arg is a search pattern (not a flag or file arg)\n\t\t\tif (i + 1 < args.length && !args[i + 1].startsWith(\"-\") && !args[i + 1].startsWith(\"@\")) {\n\t\t\t\tresult.listModels = args[++i];\n\t\t\t} else {\n\t\t\t\tresult.listModels = true;\n\t\t\t}\n\t\t} else if (arg === \"--verbose\") {\n\t\t\tresult.verbose = true;\n\t\t} else if (arg === \"--offline\") {\n\t\t\tresult.offline = true;\n\t\t} else if (arg.startsWith(\"@\")) {\n\t\t\tresult.fileArgs.push(arg.slice(1)); // Remove @ prefix\n\t\t} else if (arg.startsWith(\"--\")) {\n\t\t\tconst eqIndex = arg.indexOf(\"=\");\n\t\t\tif (eqIndex !== -1) {\n\t\t\t\tresult.unknownFlags.set(arg.slice(2, eqIndex), arg.slice(eqIndex + 1));\n\t\t\t} else {\n\t\t\t\tconst flagName = arg.slice(2);\n\t\t\t\tconst next = args[i + 1];\n\t\t\t\tif (next !== undefined && !next.startsWith(\"-\") && !next.startsWith(\"@\")) {\n\t\t\t\t\tresult.unknownFlags.set(flagName, next);\n\t\t\t\t\ti++;\n\t\t\t\t} else {\n\t\t\t\t\tresult.unknownFlags.set(flagName, true);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (arg.startsWith(\"-\") && !arg.startsWith(\"--\")) {\n\t\t\tresult.diagnostics.push({ type: \"error\", message: `Unknown option: ${arg}` });\n\t\t} else if (!arg.startsWith(\"-\")) {\n\t\t\tresult.messages.push(arg);\n\t\t}\n\t}\n\n\treturn result;\n}\n\nexport function printHelp(extensionFlags?: ExtensionFlag[]): void {\n\tconst extensionFlagsText =\n\t\textensionFlags && extensionFlags.length > 0\n\t\t\t? `\\n${chalk.bold(\"Extension CLI Flags:\")}\\n${extensionFlags\n\t\t\t\t\t.map((flag) => {\n\t\t\t\t\t\tconst value = flag.type === \"string\" ? \" <value>\" : \"\";\n\t\t\t\t\t\tconst description = flag.description ?? `Registered by ${flag.extensionPath}`;\n\t\t\t\t\t\treturn ` --${flag.name}${value}`.padEnd(30) + description;\n\t\t\t\t\t})\n\t\t\t\t\t.join(\"\\n\")}\\n`\n\t\t\t: \"\";\n\tconsole.log(`${chalk.bold(APP_NAME)} - AI coding assistant with read, bash, edit, write tools\n\n${chalk.bold(\"Usage:\")}\n ${APP_NAME} [options] [@files...] [messages...]\n\n${chalk.bold(\"Commands:\")}\n ${APP_NAME} install <source> [-l] Install extension source and add to settings\n ${APP_NAME} remove <source> [-l] Remove extension source from settings\n ${APP_NAME} uninstall <source> [-l] Alias for remove\n ${APP_NAME} update [source|self|pi] Update hoocode and installed extensions\n ${APP_NAME} list List installed extensions from settings\n ${APP_NAME} config Open TUI to enable/disable package resources\n ${APP_NAME} resources List discovered skills, subagents, slash commands, and MCP servers\n ${APP_NAME} <command> --help Show help for install/remove/uninstall/update/list\n\n${chalk.bold(\"Options:\")}\n --provider <name> Provider name (default: google)\n --model <pattern> Model pattern or ID (supports \"provider/id\" and optional \":<thinking>\")\n --api-key <key> API key (defaults to env vars)\n --system-prompt <text> System prompt (default: coding assistant prompt)\n --mode <mode> Output mode: text (default), json, or rpc\n --print, -p Non-interactive mode: process prompt and exit\n --continue, -c Continue previous session\n --resume, -r Select a session to resume\n --session <path|id> Use specific session file or partial UUID\n --fork <path|id> Fork specific session file or partial UUID into a new session\n --session-dir <dir> Directory for session storage and lookup\n --no-session Don't save session (ephemeral)\n --team <url|auto> Bridge a hooteams server into the task panel's teams view\n (focus roles, nudge, attach, answer approval gates);\n \"auto\" finds .agents/teams/default.json\n or hooteams.config.json upward from cwd and spawns hooteams locally\n --models <patterns> Comma-separated model patterns for Ctrl+P cycling\n Supports globs (anthropic/*, *sonnet*) and fuzzy matching\n --no-tools, -nt Disable all tools by default (built-in and extension)\n --no-builtin-tools, -nbt Disable built-in tools by default but keep extension/custom tools enabled\n --tools, -t <tools> Comma-separated allowlist of tool names to enable\n Applies to built-in, extension, and custom tools\n --disallowed-tools <tools> Comma-separated denylist of tool names to disable\n (subtracted from the allowlist or default set)\n --max-turns <n> Hard cap on assistant turns; the agent is asked to wrap up near the\n cap and stopped at it (mainly used for spawned subagents)\n --enable-subagents Enable the subagent tool (delegate tasks to isolated agent loops)\n --warm-subagents Dispatch eligible subagents on reused warm RPC workers (experimental)\n --max-subagent-depth <n> Tree-wide subagent nesting cap (default 1 = no nesting). Overrides\n the \"maxSubagentDepth\" setting\n Can also be enabled via the \"enableSubagent\" setting\n --enable-todowrite Enable the TodoWrite tool (maintain a live todo list in the task panel)\n Can also be enabled via the \"enableTodoWrite\" setting\n --enable-webtools Enable the webfetch + websearch tools (network access, off by default)\n Can also be enabled via the \"enableWebTools\" setting\n Block hosts with a .webtoolsignore file (gitignore syntax)\n --thinking <level> Set thinking level: off, minimal, low, medium, high, xhigh\n --extension, -e <path> Load an extension file (can be used multiple times)\n --no-extensions, -ne Disable extension discovery (explicit -e paths still work)\n --skill <path> Load a skill file or directory (can be used multiple times)\n --no-skills, -ns Disable skills discovery and loading\n --agent <path> Load an agent file or directory (can be used multiple times)\n --prompt-template <path> Load a prompt template / slash command file or directory (repeatable)\n --slash-command <path> Alias of --prompt-template (prompts and slash commands are one feature)\n --no-prompt-templates, -np Disable prompt template / slash command discovery (same as --no-slash-commands)\n --no-slash-commands, -nsc Disable prompt template / slash command discovery (same as --no-prompt-templates)\n --theme <path> Load a theme file or directory (can be used multiple times)\n --no-themes Disable theme discovery and loading\n --mode-path <dir> Add a directory to search for {name}/system.md mode files (can be used multiple times)\n --no-context-files, -nc Disable AGENTS.md and CLAUDE.md discovery and loading\n --export <file> Export session file to HTML and exit\n --list-models [search] List available models (with optional fuzzy search)\n --verbose Force verbose startup (overrides quietStartup setting)\n --offline Disable startup network operations (same as HOOCODE_OFFLINE=1)\n --ca-cert <path> Trust an extra PEM CA bundle for hoocode's own TLS traffic (provider\n calls, GitHub API, downloads). Additive to the bundled roots;\n verification stays ON. Also: HOOCODE_CA_CERT / NODE_EXTRA_CA_CERTS.\n Does not affect the webfetch/websearch binary.\n --use-system-ca Also trust the OS/system CA store (opt-in). Same as\n HOOCODE_USE_SYSTEM_CA=1\n --help, -h Show this help\n --version, -v Show version number\n\nExtensions can register additional flags (e.g., --plan from plan-mode extension).${extensionFlagsText}\n\n${chalk.bold(\"Examples:\")}\n # Interactive mode\n ${APP_NAME}\n\n # Interactive mode with initial prompt\n ${APP_NAME} \"List all .ts files in src/\"\n\n # Include files in initial message\n ${APP_NAME} @prompt.md @image.png \"What color is the sky?\"\n\n # Non-interactive mode (process and exit)\n ${APP_NAME} -p \"List all .ts files in src/\"\n\n # Multiple messages (interactive)\n ${APP_NAME} \"Read package.json\" \"What dependencies do we have?\"\n\n # Continue previous session\n ${APP_NAME} --continue \"What did we discuss?\"\n\n # Use different model\n ${APP_NAME} --provider openai --model gpt-4o-mini \"Help me refactor this code\"\n\n # Use model with provider prefix (no --provider needed)\n ${APP_NAME} --model openai/gpt-4o \"Help me refactor this code\"\n\n # Use model with thinking level shorthand\n ${APP_NAME} --model sonnet:high \"Solve this complex problem\"\n\n # Limit model cycling to specific models\n ${APP_NAME} --models claude-sonnet,claude-haiku,gpt-4o\n\n # Limit to a specific provider with glob pattern\n ${APP_NAME} --models \"github-copilot/*\"\n\n # Cycle models with fixed thinking levels\n ${APP_NAME} --models sonnet:high,haiku:low\n\n # Start with a specific thinking level\n ${APP_NAME} --thinking high \"Solve this complex problem\"\n\n # Read-only mode (no file modifications possible)\n ${APP_NAME} --tools read,grep,find,ls -p \"Review the code in src/\"\n\n # Export a session file to HTML\n ${APP_NAME} --export ~/${CONFIG_DIR_NAME}/agent/sessions/--path--/session.jsonl\n ${APP_NAME} --export session.jsonl output.html\n\n${chalk.bold(\"Environment Variables:\")}\n ANTHROPIC_API_KEY - Anthropic Claude API key\n ANTHROPIC_OAUTH_TOKEN - Anthropic OAuth token (alternative to API key)\n OPENAI_API_KEY - OpenAI GPT API key\n AZURE_OPENAI_API_KEY - Azure OpenAI API key\n AZURE_OPENAI_BASE_URL - Azure OpenAI/Cognitive Services base URL (e.g. https://{resource}.openai.azure.com)\n AZURE_OPENAI_RESOURCE_NAME - Azure OpenAI resource name (alternative to base URL)\n AZURE_OPENAI_API_VERSION - Azure OpenAI API version (default: v1)\n AZURE_OPENAI_DEPLOYMENT_NAME_MAP - Azure OpenAI model=deployment map (comma-separated)\n DEEPSEEK_API_KEY - DeepSeek API key\n GEMINI_API_KEY - Google Gemini API key\n GROQ_API_KEY - Groq API key\n CEREBRAS_API_KEY - Cerebras API key\n XAI_API_KEY - xAI Grok API key\n FIREWORKS_API_KEY - Fireworks API key\n TOGETHER_API_KEY - Together AI API key\n OPENROUTER_API_KEY - OpenRouter API key\n AI_GATEWAY_API_KEY - Vercel AI Gateway API key\n ZAI_API_KEY - ZAI API key\n MISTRAL_API_KEY - Mistral API key\n MINIMAX_API_KEY - MiniMax API key\n MOONSHOT_API_KEY - Moonshot AI API key\n OPENCODE_API_KEY - OpenCode Zen/OpenCode Go API key\n KIMI_API_KEY - Kimi For Coding API key\n CLOUDFLARE_API_KEY - Cloudflare API token (Workers AI and AI Gateway)\n CLOUDFLARE_ACCOUNT_ID - Cloudflare account id (required for both)\n CLOUDFLARE_GATEWAY_ID - Cloudflare AI Gateway slug (required for AI Gateway)\n XIAOMI_API_KEY - Xiaomi MiMo API key (api.xiaomimimo.com billing)\n XIAOMI_TOKEN_PLAN_CN_API_KEY - Xiaomi MiMo Token Plan API key (China region)\n XIAOMI_TOKEN_PLAN_AMS_API_KEY - Xiaomi MiMo Token Plan API key (Amsterdam region)\n XIAOMI_TOKEN_PLAN_SGP_API_KEY - Xiaomi MiMo Token Plan API key (Singapore region)\n NVIDIA_API_KEY - NVIDIA API key (integrate.api.nvidia.com)\n AWS_PROFILE - AWS profile for Amazon Bedrock\n AWS_ACCESS_KEY_ID - AWS access key for Amazon Bedrock\n AWS_SECRET_ACCESS_KEY - AWS secret key for Amazon Bedrock\n AWS_BEARER_TOKEN_BEDROCK - Bedrock API key (bearer token)\n AWS_REGION - AWS region for Amazon Bedrock (e.g., us-east-1)\n ${ENV_AGENT_DIR.padEnd(32)} - Config directory (default: ~/${CONFIG_DIR_NAME}/agent)\n ${ENV_SESSION_DIR.padEnd(32)} - Session storage directory (overridden by --session-dir)\n HOOCODE_PACKAGE_DIR - Override package directory (for Nix/Guix store paths). Legacy: PI_PACKAGE_DIR\n HOOCODE_OFFLINE - Disable startup network operations when set to 1/true/yes. Legacy: PI_OFFLINE\n HOOCODE_CA_CERT - Path to an extra PEM CA bundle to trust for hoocode's own TLS traffic\n (additive; verification stays on). Precedence: --ca-cert > this > NODE_EXTRA_CA_CERTS\n HOOCODE_USE_SYSTEM_CA - Also trust the OS/system CA store when set to 1/true/yes (same as --use-system-ca)\n NODE_EXTRA_CA_CERTS - Standard Node path to an extra PEM CA bundle (used as the lowest-precedence CA source)\n HOOCODE_WEBTOOLS_CA_CERT - Path to a PEM CA bundle forwarded to the webtools binary (webfetch/websearch) as --ca-cert\n HOOCODE_WEBTOOLS_INSECURE - Forward --insecure to the webtools binary (disables its TLS verification) when set to 1/true/yes\n HOOCODE_TELEMETRY - Override install telemetry when set to 1/true/yes or 0/false/no. Legacy: PI_TELEMETRY\n HOOCODE_SHARE_VIEWER_URL - Base URL for /share command (default: https://pi.dev/session/). Legacy: PI_SHARE_VIEWER_URL\n\n${chalk.bold(\"Built-in Tool Names:\")}\n read - Read file contents\n bash - Execute bash commands\n edit - Edit files with find/replace\n write - Write files (creates/overwrites)\n grep - Search file contents (read-only, off by default)\n find - Find files by glob pattern (read-only, off by default)\n ls - List directory contents (read-only, off by default)\n`);\n}\n"]}
1
+ {"version":3,"file":"args.js","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * CLI argument parsing and help display\n */\n\nimport type { ThinkingLevel } from \"@kolisachint/hoocode-agent-core\";\nimport chalk from \"chalk\";\nimport { APP_NAME, CONFIG_DIR_NAME, ENV_AGENT_DIR, ENV_SESSION_DIR } from \"../config.js\";\nimport type { ExtensionFlag } from \"../core/extensions/types.js\";\n\nexport type Mode = \"text\" | \"json\" | \"rpc\";\n\nexport interface Args {\n\tprovider?: string;\n\tmodel?: string;\n\tapiKey?: string;\n\tsystemPrompt?: string;\n\tthinking?: ThinkingLevel;\n\tcontinue?: boolean;\n\tresume?: boolean;\n\thelp?: boolean;\n\tversion?: boolean;\n\tmode?: Mode;\n\tnoSession?: boolean;\n\t/** Internal: task id assigned by SubagentPool when this process is a spawned subagent. */\n\ttaskId?: string;\n\t/** Hard cap on assistant turns. Near the cap the agent is asked to wrap up; at the cap it is stopped. */\n\tmaxTurns?: number;\n\tsession?: string;\n\t/** Base URL of a hooteams server to bridge into the task panel's teams view, or \"auto\" to discover a config and spawn one locally. */\n\tteam?: string;\n\tfork?: string;\n\tsessionDir?: string;\n\tmodels?: string[];\n\ttools?: string[];\n\tdisallowedTools?: string[];\n\tnoTools?: boolean;\n\tnoBuiltinTools?: boolean;\n\tsubagent?: boolean;\n\t/** Dispatch eligible subagents on reused warm RPC workers (overrides the warmSubagents setting). */\n\twarmSubagents?: boolean;\n\t/** Tree-wide subagent nesting cap (overrides the maxSubagentDepth setting). */\n\tmaxSubagentDepth?: number;\n\t/** Internal: restricts which subagent types this process may delegate to. */\n\tdelegateAllow?: string[];\n\ttodoWrite?: boolean;\n\t/** Enable the webfetch + websearch tools (off by default). */\n\tenableWebTools?: boolean;\n\t/** Enable the DocRead + DocEdit + DocWrite document tools (off by default). */\n\tenableFileTools?: boolean;\n\t/** Path to an explicit PEM CA bundle to trust additively for hoocode's own TLS traffic. */\n\tcaCert?: string;\n\t/** Trust the OS/system CA store additively (opt-in) for hoocode's own TLS traffic. */\n\tuseSystemCa?: boolean;\n\textensions?: string[];\n\tnoExtensions?: boolean;\n\tprint?: boolean;\n\texport?: string;\n\tnoSkills?: boolean;\n\tskills?: string[];\n\tagents?: string[];\n\tpromptTemplates?: string[];\n\tnoPromptTemplates?: boolean;\n\tslashCommands?: string[];\n\tnoSlashCommands?: boolean;\n\tthemes?: string[];\n\tnoThemes?: boolean;\n\tmodePaths?: string[];\n\tnoContextFiles?: boolean;\n\tlistModels?: string | true;\n\toffline?: boolean;\n\tverbose?: boolean;\n\tmessages: string[];\n\tfileArgs: string[];\n\t/** Unknown flags (potentially extension flags) - map of flag name to value */\n\tunknownFlags: Map<string, boolean | string>;\n\tdiagnostics: Array<{ type: \"warning\" | \"error\"; message: string }>;\n}\n\nconst VALID_THINKING_LEVELS = [\"off\", \"minimal\", \"low\", \"medium\", \"high\", \"xhigh\"] as const;\n\nexport function isValidThinkingLevel(level: string): level is ThinkingLevel {\n\treturn VALID_THINKING_LEVELS.includes(level as ThinkingLevel);\n}\n\nexport function parseArgs(args: string[]): Args {\n\tconst result: Args = {\n\t\tmessages: [],\n\t\tfileArgs: [],\n\t\tunknownFlags: new Map(),\n\t\tdiagnostics: [],\n\t};\n\n\tfor (let i = 0; i < args.length; i++) {\n\t\tconst arg = args[i];\n\n\t\tif (arg === \"--help\" || arg === \"-h\") {\n\t\t\tresult.help = true;\n\t\t} else if (arg === \"--version\" || arg === \"-v\") {\n\t\t\tresult.version = true;\n\t\t} else if (arg === \"--mode\" && i + 1 < args.length) {\n\t\t\tconst mode = args[++i];\n\t\t\tif (mode === \"text\" || mode === \"json\" || mode === \"rpc\") {\n\t\t\t\tresult.mode = mode;\n\t\t\t}\n\t\t} else if (arg === \"--continue\" || arg === \"-c\") {\n\t\t\tresult.continue = true;\n\t\t} else if (arg === \"--resume\" || arg === \"-r\") {\n\t\t\tresult.resume = true;\n\t\t} else if (arg === \"--provider\" && i + 1 < args.length) {\n\t\t\tresult.provider = args[++i];\n\t\t} else if (arg === \"--model\" && i + 1 < args.length) {\n\t\t\tresult.model = args[++i];\n\t\t} else if (arg === \"--api-key\" && i + 1 < args.length) {\n\t\t\tresult.apiKey = args[++i];\n\t\t} else if (arg === \"--system-prompt\" && i + 1 < args.length) {\n\t\t\tresult.systemPrompt = args[++i];\n\t\t} else if (arg === \"--no-session\") {\n\t\t\tresult.noSession = true;\n\t\t} else if (arg === \"--task-id\" && i + 1 < args.length) {\n\t\t\tresult.taskId = args[++i];\n\t\t} else if (arg === \"--max-turns\" && i + 1 < args.length) {\n\t\t\tconst n = Number.parseInt(args[++i], 10);\n\t\t\tif (Number.isInteger(n) && n > 0) {\n\t\t\t\tresult.maxTurns = n;\n\t\t\t}\n\t\t} else if (arg === \"--session\" && i + 1 < args.length) {\n\t\t\tresult.session = args[++i];\n\t\t} else if (arg === \"--team\" && i + 1 < args.length) {\n\t\t\tresult.team = args[++i];\n\t\t} else if (arg === \"--fork\" && i + 1 < args.length) {\n\t\t\tresult.fork = args[++i];\n\t\t} else if (arg === \"--session-dir\" && i + 1 < args.length) {\n\t\t\tresult.sessionDir = args[++i];\n\t\t} else if (arg === \"--models\" && i + 1 < args.length) {\n\t\t\tresult.models = args[++i].split(\",\").map((s) => s.trim());\n\t\t} else if (arg === \"--no-tools\" || arg === \"-nt\") {\n\t\t\tresult.noTools = true;\n\t\t} else if (arg === \"--no-builtin-tools\" || arg === \"-nbt\") {\n\t\t\tresult.noBuiltinTools = true;\n\t\t} else if (arg === \"--enable-subagents\") {\n\t\t\tresult.subagent = true;\n\t\t} else if (arg === \"--warm-subagents\") {\n\t\t\tresult.warmSubagents = true;\n\t\t} else if (arg === \"--max-subagent-depth\" && i + 1 < args.length) {\n\t\t\tconst n = Number.parseInt(args[++i], 10);\n\t\t\tif (Number.isInteger(n) && n >= 1) {\n\t\t\t\tresult.maxSubagentDepth = n;\n\t\t\t}\n\t\t} else if (arg === \"--delegate-allow\" && i + 1 < args.length) {\n\t\t\tresult.delegateAllow = args[++i]\n\t\t\t\t.split(\",\")\n\t\t\t\t.map((s) => s.trim())\n\t\t\t\t.filter((name) => name.length > 0);\n\t\t} else if (arg === \"--enable-todowrite\") {\n\t\t\tresult.todoWrite = true;\n\t\t} else if (arg === \"--enable-webtools\") {\n\t\t\tresult.enableWebTools = true;\n\t\t} else if (arg === \"--enable-filetools\") {\n\t\t\tresult.enableFileTools = true;\n\t\t} else if (arg === \"--ca-cert\" && i + 1 < args.length) {\n\t\t\tresult.caCert = args[++i];\n\t\t} else if (arg === \"--use-system-ca\") {\n\t\t\tresult.useSystemCa = true;\n\t\t} else if ((arg === \"--tools\" || arg === \"-t\") && i + 1 < args.length) {\n\t\t\tresult.tools = args[++i]\n\t\t\t\t.split(\",\")\n\t\t\t\t.map((s) => s.trim())\n\t\t\t\t.filter((name) => name.length > 0);\n\t\t} else if (arg === \"--disallowed-tools\" && i + 1 < args.length) {\n\t\t\tresult.disallowedTools = args[++i]\n\t\t\t\t.split(\",\")\n\t\t\t\t.map((s) => s.trim())\n\t\t\t\t.filter((name) => name.length > 0);\n\t\t} else if (arg === \"--thinking\" && i + 1 < args.length) {\n\t\t\tconst level = args[++i];\n\t\t\tif (isValidThinkingLevel(level)) {\n\t\t\t\tresult.thinking = level;\n\t\t\t} else {\n\t\t\t\tresult.diagnostics.push({\n\t\t\t\t\ttype: \"warning\",\n\t\t\t\t\tmessage: `Invalid thinking level \"${level}\". Valid values: ${VALID_THINKING_LEVELS.join(\", \")}`,\n\t\t\t\t});\n\t\t\t}\n\t\t} else if (arg === \"--print\" || arg === \"-p\") {\n\t\t\tresult.print = true;\n\t\t\tconst next = args[i + 1];\n\t\t\tif (next !== undefined && !next.startsWith(\"@\") && (!next.startsWith(\"-\") || next.startsWith(\"---\"))) {\n\t\t\t\tresult.messages.push(next);\n\t\t\t\ti++;\n\t\t\t}\n\t\t} else if (arg === \"--export\" && i + 1 < args.length) {\n\t\t\tresult.export = args[++i];\n\t\t} else if ((arg === \"--extension\" || arg === \"-e\") && i + 1 < args.length) {\n\t\t\tresult.extensions = result.extensions ?? [];\n\t\t\tresult.extensions.push(args[++i]);\n\t\t} else if (arg === \"--no-extensions\" || arg === \"-ne\") {\n\t\t\tresult.noExtensions = true;\n\t\t} else if (arg === \"--skill\" && i + 1 < args.length) {\n\t\t\tresult.skills = result.skills ?? [];\n\t\t\tresult.skills.push(args[++i]);\n\t\t} else if (arg === \"--agent\" && i + 1 < args.length) {\n\t\t\tresult.agents = result.agents ?? [];\n\t\t\tresult.agents.push(args[++i]);\n\t\t} else if (arg === \"--prompt-template\" && i + 1 < args.length) {\n\t\t\tresult.promptTemplates = result.promptTemplates ?? [];\n\t\t\tresult.promptTemplates.push(args[++i]);\n\t\t} else if (arg === \"--slash-command\" && i + 1 < args.length) {\n\t\t\tresult.slashCommands = result.slashCommands ?? [];\n\t\t\tresult.slashCommands.push(args[++i]);\n\t\t} else if (arg === \"--theme\" && i + 1 < args.length) {\n\t\t\tresult.themes = result.themes ?? [];\n\t\t\tresult.themes.push(args[++i]);\n\t\t} else if (arg === \"--mode-path\" && i + 1 < args.length) {\n\t\t\tresult.modePaths = result.modePaths ?? [];\n\t\t\tresult.modePaths.push(args[++i]);\n\t\t} else if (arg === \"--no-skills\" || arg === \"-ns\") {\n\t\t\tresult.noSkills = true;\n\t\t} else if (arg === \"--no-prompt-templates\" || arg === \"-np\") {\n\t\t\tresult.noPromptTemplates = true;\n\t\t} else if (arg === \"--no-slash-commands\" || arg === \"-nsc\") {\n\t\t\tresult.noSlashCommands = true;\n\t\t} else if (arg === \"--no-themes\") {\n\t\t\tresult.noThemes = true;\n\t\t} else if (arg === \"--no-context-files\" || arg === \"-nc\") {\n\t\t\tresult.noContextFiles = true;\n\t\t} else if (arg === \"--list-models\") {\n\t\t\t// Check if next arg is a search pattern (not a flag or file arg)\n\t\t\tif (i + 1 < args.length && !args[i + 1].startsWith(\"-\") && !args[i + 1].startsWith(\"@\")) {\n\t\t\t\tresult.listModels = args[++i];\n\t\t\t} else {\n\t\t\t\tresult.listModels = true;\n\t\t\t}\n\t\t} else if (arg === \"--verbose\") {\n\t\t\tresult.verbose = true;\n\t\t} else if (arg === \"--offline\") {\n\t\t\tresult.offline = true;\n\t\t} else if (arg.startsWith(\"@\")) {\n\t\t\tresult.fileArgs.push(arg.slice(1)); // Remove @ prefix\n\t\t} else if (arg.startsWith(\"--\")) {\n\t\t\tconst eqIndex = arg.indexOf(\"=\");\n\t\t\tif (eqIndex !== -1) {\n\t\t\t\tresult.unknownFlags.set(arg.slice(2, eqIndex), arg.slice(eqIndex + 1));\n\t\t\t} else {\n\t\t\t\tconst flagName = arg.slice(2);\n\t\t\t\tconst next = args[i + 1];\n\t\t\t\tif (next !== undefined && !next.startsWith(\"-\") && !next.startsWith(\"@\")) {\n\t\t\t\t\tresult.unknownFlags.set(flagName, next);\n\t\t\t\t\ti++;\n\t\t\t\t} else {\n\t\t\t\t\tresult.unknownFlags.set(flagName, true);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (arg.startsWith(\"-\") && !arg.startsWith(\"--\")) {\n\t\t\tresult.diagnostics.push({ type: \"error\", message: `Unknown option: ${arg}` });\n\t\t} else if (!arg.startsWith(\"-\")) {\n\t\t\tresult.messages.push(arg);\n\t\t}\n\t}\n\n\treturn result;\n}\n\nexport function printHelp(extensionFlags?: ExtensionFlag[]): void {\n\tconst extensionFlagsText =\n\t\textensionFlags && extensionFlags.length > 0\n\t\t\t? `\\n${chalk.bold(\"Extension CLI Flags:\")}\\n${extensionFlags\n\t\t\t\t\t.map((flag) => {\n\t\t\t\t\t\tconst value = flag.type === \"string\" ? \" <value>\" : \"\";\n\t\t\t\t\t\tconst description = flag.description ?? `Registered by ${flag.extensionPath}`;\n\t\t\t\t\t\treturn ` --${flag.name}${value}`.padEnd(30) + description;\n\t\t\t\t\t})\n\t\t\t\t\t.join(\"\\n\")}\\n`\n\t\t\t: \"\";\n\tconsole.log(`${chalk.bold(APP_NAME)} - AI coding assistant with read, bash, edit, write tools\n\n${chalk.bold(\"Usage:\")}\n ${APP_NAME} [options] [@files...] [messages...]\n\n${chalk.bold(\"Commands:\")}\n ${APP_NAME} install <source> [-l] Install extension source and add to settings\n ${APP_NAME} remove <source> [-l] Remove extension source from settings\n ${APP_NAME} uninstall <source> [-l] Alias for remove\n ${APP_NAME} update [source|self|pi] Update hoocode and installed extensions\n ${APP_NAME} list List installed extensions from settings\n ${APP_NAME} config Open TUI to enable/disable package resources\n ${APP_NAME} resources List discovered skills, subagents, slash commands, and MCP servers\n ${APP_NAME} <command> --help Show help for install/remove/uninstall/update/list\n\n${chalk.bold(\"Options:\")}\n --provider <name> Provider name (default: google)\n --model <pattern> Model pattern or ID (supports \"provider/id\" and optional \":<thinking>\")\n --api-key <key> API key (defaults to env vars)\n --system-prompt <text> System prompt (default: coding assistant prompt)\n --mode <mode> Output mode: text (default), json, or rpc\n --print, -p Non-interactive mode: process prompt and exit\n --continue, -c Continue previous session\n --resume, -r Select a session to resume\n --session <path|id> Use specific session file or partial UUID\n --fork <path|id> Fork specific session file or partial UUID into a new session\n --session-dir <dir> Directory for session storage and lookup\n --no-session Don't save session (ephemeral)\n --team <url|auto> Bridge a hooteams server into the task panel's teams view\n (focus roles, nudge, attach, answer approval gates);\n \"auto\" finds .agents/teams/default.json\n or hooteams.config.json upward from cwd and spawns hooteams locally\n --models <patterns> Comma-separated model patterns for Ctrl+P cycling\n Supports globs (anthropic/*, *sonnet*) and fuzzy matching\n --no-tools, -nt Disable all tools by default (built-in and extension)\n --no-builtin-tools, -nbt Disable built-in tools by default but keep extension/custom tools enabled\n --tools, -t <tools> Comma-separated allowlist of tool names to enable\n Applies to built-in, extension, and custom tools\n --disallowed-tools <tools> Comma-separated denylist of tool names to disable\n (subtracted from the allowlist or default set)\n --max-turns <n> Hard cap on assistant turns; the agent is asked to wrap up near the\n cap and stopped at it (mainly used for spawned subagents)\n --enable-subagents Enable the subagent tool (delegate tasks to isolated agent loops)\n --warm-subagents Dispatch eligible subagents on reused warm RPC workers (experimental)\n --max-subagent-depth <n> Tree-wide subagent nesting cap (default 1 = no nesting). Overrides\n the \"maxSubagentDepth\" setting\n Can also be enabled via the \"enableSubagent\" setting\n --enable-todowrite Enable the TodoWrite tool (maintain a live todo list in the task panel)\n Can also be enabled via the \"enableTodoWrite\" setting\n --enable-webtools Enable the webfetch + websearch tools (network access, off by default)\n Can also be enabled via the \"enableWebTools\" setting\n Block hosts with a .webtoolsignore file (gitignore syntax)\n --enable-filetools Enable the DocRead + DocEdit + DocWrite document tools (off by default)\n Losslessly extract/edit XML, drawio, docx/xlsx/pptx, PDF via the filetools binary\n Can also be enabled via the \"enableFileTools\" setting\n --thinking <level> Set thinking level: off, minimal, low, medium, high, xhigh\n --extension, -e <path> Load an extension file (can be used multiple times)\n --no-extensions, -ne Disable extension discovery (explicit -e paths still work)\n --skill <path> Load a skill file or directory (can be used multiple times)\n --no-skills, -ns Disable skills discovery and loading\n --agent <path> Load an agent file or directory (can be used multiple times)\n --prompt-template <path> Load a prompt template / slash command file or directory (repeatable)\n --slash-command <path> Alias of --prompt-template (prompts and slash commands are one feature)\n --no-prompt-templates, -np Disable prompt template / slash command discovery (same as --no-slash-commands)\n --no-slash-commands, -nsc Disable prompt template / slash command discovery (same as --no-prompt-templates)\n --theme <path> Load a theme file or directory (can be used multiple times)\n --no-themes Disable theme discovery and loading\n --mode-path <dir> Add a directory to search for {name}/system.md mode files (can be used multiple times)\n --no-context-files, -nc Disable AGENTS.md and CLAUDE.md discovery and loading\n --export <file> Export session file to HTML and exit\n --list-models [search] List available models (with optional fuzzy search)\n --verbose Force verbose startup (overrides quietStartup setting)\n --offline Disable startup network operations (same as HOOCODE_OFFLINE=1)\n --ca-cert <path> Trust an extra PEM CA bundle for hoocode's own TLS traffic (provider\n calls, GitHub API, downloads). Additive to the bundled roots;\n verification stays ON. Also: HOOCODE_CA_CERT / NODE_EXTRA_CA_CERTS.\n Does not affect the webfetch/websearch binary.\n --use-system-ca Also trust the OS/system CA store (opt-in). Same as\n HOOCODE_USE_SYSTEM_CA=1\n --help, -h Show this help\n --version, -v Show version number\n\nExtensions can register additional flags (e.g., --plan from plan-mode extension).${extensionFlagsText}\n\n${chalk.bold(\"Examples:\")}\n # Interactive mode\n ${APP_NAME}\n\n # Interactive mode with initial prompt\n ${APP_NAME} \"List all .ts files in src/\"\n\n # Include files in initial message\n ${APP_NAME} @prompt.md @image.png \"What color is the sky?\"\n\n # Non-interactive mode (process and exit)\n ${APP_NAME} -p \"List all .ts files in src/\"\n\n # Multiple messages (interactive)\n ${APP_NAME} \"Read package.json\" \"What dependencies do we have?\"\n\n # Continue previous session\n ${APP_NAME} --continue \"What did we discuss?\"\n\n # Use different model\n ${APP_NAME} --provider openai --model gpt-4o-mini \"Help me refactor this code\"\n\n # Use model with provider prefix (no --provider needed)\n ${APP_NAME} --model openai/gpt-4o \"Help me refactor this code\"\n\n # Use model with thinking level shorthand\n ${APP_NAME} --model sonnet:high \"Solve this complex problem\"\n\n # Limit model cycling to specific models\n ${APP_NAME} --models claude-sonnet,claude-haiku,gpt-4o\n\n # Limit to a specific provider with glob pattern\n ${APP_NAME} --models \"github-copilot/*\"\n\n # Cycle models with fixed thinking levels\n ${APP_NAME} --models sonnet:high,haiku:low\n\n # Start with a specific thinking level\n ${APP_NAME} --thinking high \"Solve this complex problem\"\n\n # Read-only mode (no file modifications possible)\n ${APP_NAME} --tools read,grep,find,ls -p \"Review the code in src/\"\n\n # Export a session file to HTML\n ${APP_NAME} --export ~/${CONFIG_DIR_NAME}/agent/sessions/--path--/session.jsonl\n ${APP_NAME} --export session.jsonl output.html\n\n${chalk.bold(\"Environment Variables:\")}\n ANTHROPIC_API_KEY - Anthropic Claude API key\n ANTHROPIC_OAUTH_TOKEN - Anthropic OAuth token (alternative to API key)\n OPENAI_API_KEY - OpenAI GPT API key\n AZURE_OPENAI_API_KEY - Azure OpenAI API key\n AZURE_OPENAI_BASE_URL - Azure OpenAI/Cognitive Services base URL (e.g. https://{resource}.openai.azure.com)\n AZURE_OPENAI_RESOURCE_NAME - Azure OpenAI resource name (alternative to base URL)\n AZURE_OPENAI_API_VERSION - Azure OpenAI API version (default: v1)\n AZURE_OPENAI_DEPLOYMENT_NAME_MAP - Azure OpenAI model=deployment map (comma-separated)\n DEEPSEEK_API_KEY - DeepSeek API key\n GEMINI_API_KEY - Google Gemini API key\n GROQ_API_KEY - Groq API key\n CEREBRAS_API_KEY - Cerebras API key\n XAI_API_KEY - xAI Grok API key\n FIREWORKS_API_KEY - Fireworks API key\n TOGETHER_API_KEY - Together AI API key\n OPENROUTER_API_KEY - OpenRouter API key\n AI_GATEWAY_API_KEY - Vercel AI Gateway API key\n ZAI_API_KEY - ZAI API key\n MISTRAL_API_KEY - Mistral API key\n MINIMAX_API_KEY - MiniMax API key\n MOONSHOT_API_KEY - Moonshot AI API key\n OPENCODE_API_KEY - OpenCode Zen/OpenCode Go API key\n KIMI_API_KEY - Kimi For Coding API key\n CLOUDFLARE_API_KEY - Cloudflare API token (Workers AI and AI Gateway)\n CLOUDFLARE_ACCOUNT_ID - Cloudflare account id (required for both)\n CLOUDFLARE_GATEWAY_ID - Cloudflare AI Gateway slug (required for AI Gateway)\n XIAOMI_API_KEY - Xiaomi MiMo API key (api.xiaomimimo.com billing)\n XIAOMI_TOKEN_PLAN_CN_API_KEY - Xiaomi MiMo Token Plan API key (China region)\n XIAOMI_TOKEN_PLAN_AMS_API_KEY - Xiaomi MiMo Token Plan API key (Amsterdam region)\n XIAOMI_TOKEN_PLAN_SGP_API_KEY - Xiaomi MiMo Token Plan API key (Singapore region)\n NVIDIA_API_KEY - NVIDIA API key (integrate.api.nvidia.com)\n AWS_PROFILE - AWS profile for Amazon Bedrock\n AWS_ACCESS_KEY_ID - AWS access key for Amazon Bedrock\n AWS_SECRET_ACCESS_KEY - AWS secret key for Amazon Bedrock\n AWS_BEARER_TOKEN_BEDROCK - Bedrock API key (bearer token)\n AWS_REGION - AWS region for Amazon Bedrock (e.g., us-east-1)\n ${ENV_AGENT_DIR.padEnd(32)} - Config directory (default: ~/${CONFIG_DIR_NAME}/agent)\n ${ENV_SESSION_DIR.padEnd(32)} - Session storage directory (overridden by --session-dir)\n HOOCODE_PACKAGE_DIR - Override package directory (for Nix/Guix store paths). Legacy: PI_PACKAGE_DIR\n HOOCODE_OFFLINE - Disable startup network operations when set to 1/true/yes. Legacy: PI_OFFLINE\n HOOCODE_CA_CERT - Path to an extra PEM CA bundle to trust for hoocode's own TLS traffic\n (additive; verification stays on). Precedence: --ca-cert > this > NODE_EXTRA_CA_CERTS\n HOOCODE_USE_SYSTEM_CA - Also trust the OS/system CA store when set to 1/true/yes (same as --use-system-ca)\n NODE_EXTRA_CA_CERTS - Standard Node path to an extra PEM CA bundle (used as the lowest-precedence CA source)\n HOOCODE_WEBTOOLS_CA_CERT - Path to a PEM CA bundle forwarded to the webtools binary (webfetch/websearch) as --ca-cert\n HOOCODE_WEBTOOLS_INSECURE - Forward --insecure to the webtools binary (disables its TLS verification) when set to 1/true/yes\n HOOCODE_TELEMETRY - Override install telemetry when set to 1/true/yes or 0/false/no. Legacy: PI_TELEMETRY\n HOOCODE_SHARE_VIEWER_URL - Base URL for /share command (default: https://pi.dev/session/). Legacy: PI_SHARE_VIEWER_URL\n\n${chalk.bold(\"Built-in Tool Names:\")}\n read - Read file contents\n bash - Execute bash commands\n edit - Edit files with find/replace\n write - Write files (creates/overwrites)\n grep - Search file contents (read-only, off by default)\n find - Find files by glob pattern (read-only, off by default)\n ls - List directory contents (read-only, off by default)\n`);\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"agent-frontmatter.d.ts","sourceRoot":"","sources":["../../src/core/agent-frontmatter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAQ3D,gFAAgF;AAChF,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,aAAa,GAAG,gBAAgB,CAAC;AAE5F,wFAAwF;AACxF,eAAO,MAAM,aAAa,YAAY,CAAC;AAEvC;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,EAAE,SAAS,MAAM,EAU/C,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,cAAc,SAAS,CAAC;AACrC,eAAO,MAAM,oBAAoB,cAAc,CAAC;AAEhD;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAWhE,CAAC;AAEF,6DAA6D;AAC7D,MAAM,WAAW,gBAAgB;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+EAA+E;IAC/E,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC1B,qFAAqF;IACrF,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACpC,4DAA4D;IAC5D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wGAAwG;IACxG,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,EAAE,CAAC;IACvC;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACvB;AAED,gDAAgD;AAChD,MAAM,WAAW,eAAe;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,8DAA8D;IAC9D,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAC;IACf,iCAAiC;IACjC,MAAM,EAAE,WAAW,CAAC;IACpB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sDAAsD;IACtD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kGAAkG;IAClG,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,wFAAwF;IACxF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,8FAA8F;IAC9F,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,6EAA6E;IAC7E,IAAI,CAAC,EAAE,OAAO,CAAC;CACf;AAqDD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC7B,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,EACxB,QAAQ,CAAC,EAAE,MAAM,GACf;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,WAAW,EAAE,kBAAkB,EAAE,CAAA;CAAE,CA0BxD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAK5E;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CACnC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,GACxE;IAAE,KAAK,EAAE,eAAe,GAAG,IAAI,CAAC;IAAC,WAAW,EAAE,kBAAkB,EAAE,CAAA;CAAE,CA6ItE","sourcesContent":["/**\n * Agent frontmatter: schema, validation, and Claude Code compatibility shim.\n *\n * Agent definitions are Markdown files with YAML frontmatter, mirroring the\n * Claude Code subagent format so `.claude/agents/*.md` files import natively:\n *\n * ---\n * name: explore\n * description: When and why to use this agent (drives auto-delegation).\n * tools: Read, Grep, Glob, Bash # optional allowlist; omit = inherit all\n * model: sonnet # optional; sonnet|opus|haiku|inherit|pattern\n * ---\n * <system prompt body>\n *\n * The body becomes the subagent system prompt. Validation is non-fatal: we emit\n * diagnostics (warnings) and still load the agent when possible, matching the\n * behavior of skills.ts.\n */\n\nimport { basename } from \"path\";\nimport { parseFrontmatter } from \"../utils/frontmatter.js\";\nimport type { ResourceDiagnostic } from \"./diagnostics.js\";\n\n/** Max name length, aligned with skills. */\nconst MAX_NAME_LENGTH = 64;\n\n/** Max description length, aligned with skills. */\nconst MAX_DESCRIPTION_LENGTH = 1024;\n\n/** Where an agent definition came from. Used for precedence and diagnostics. */\nexport type AgentSource = \"builtin\" | \"user\" | \"project\" | \"claude-user\" | \"claude-project\";\n\n/** Sentinel meaning \"use the parent session's model\" (Claude Code `model: inherit`). */\nexport const MODEL_INHERIT = \"inherit\";\n\n/**\n * The built-in hoocode tools that an agent's `tools` allowlist is normalized\n * against; unknown tools are dropped with a diagnostic. Includes the opt-in web\n * tools (webfetch/websearch) so Claude Code's WebFetch/WebSearch map through.\n */\nexport const HOOCODE_TOOL_NAMES: readonly string[] = [\n\t\"bash\",\n\t\"edit\",\n\t\"find\",\n\t\"grep\",\n\t\"ls\",\n\t\"read\",\n\t\"webfetch\",\n\t\"websearch\",\n\t\"write\",\n];\n\n/**\n * Canonical registered names of the two opt-in tools. These are case-sensitive\n * identifiers the system prompt and tool gating match exactly, so downstream\n * callers should reference these constants instead of hardcoding the strings\n * (a mis-cased `\"task\"` silently disables the agents/skills prompt sections).\n */\nexport const TASK_TOOL_NAME = \"Task\";\nexport const TODO_WRITE_TOOL_NAME = \"TodoWrite\";\n\n/**\n * D7 — Claude Code compatibility shim.\n *\n * Maps Claude Code tool names (case-insensitive) to their hoocode equivalents.\n * Claude tools without a hoocode counterpart (MultiEdit, Task, TodoWrite,\n * NotebookEdit, MCP tools, ...) are intentionally absent and get dropped during\n * normalization.\n */\nexport const CLAUDE_TOOL_ALIASES: Readonly<Record<string, string>> = {\n\tread: \"read\",\n\twrite: \"write\",\n\tedit: \"edit\",\n\tbash: \"bash\",\n\tgrep: \"grep\",\n\tglob: \"find\",\n\tfind: \"find\",\n\tls: \"ls\",\n\twebfetch: \"webfetch\",\n\twebsearch: \"websearch\",\n};\n\n/** Raw frontmatter shape before validation/normalization. */\nexport interface AgentFrontmatter {\n\tname?: string;\n\tdescription?: string;\n\t/** Claude Code uses a comma-separated string; a YAML list is also accepted. */\n\ttools?: string | string[];\n\t/** Tools to subtract from the agent's set (allow + deny), Claude Code compatible. */\n\tdisallowedTools?: string | string[];\n\t/** sonnet | opus | haiku | inherit | a model id/pattern. */\n\tmodel?: string;\n\t/** hoocode extension (not part of the Claude Code format): turn cap. */\n\tmaxTurns?: number;\n\t/** Claude Code extension: run this agent detached (non-blocking) so the parent polls for its result. */\n\tbackground?: boolean;\n\t/**\n\t * hoocode extension: opt a agent into delegating via the Task tool (subject to the\n\t * tree-wide nesting cap). `true` = any subagent type; a comma-separated string or\n\t * YAML list = only those types. Opt-in per agent so the deliberate \"Task is not a\n\t * normal tool\" boundary stays intact for everyone else.\n\t */\n\tdelegate?: boolean | string | string[];\n\t/**\n\t * When true, this agent inherits the parent's full conversation (a fork) instead\n\t * of starting from a fresh context, reusing the parent's prompt cache.\n\t */\n\tfork?: boolean;\n\t[key: string]: unknown;\n}\n\n/** A validated, normalized agent definition. */\nexport interface AgentDefinition {\n\tname: string;\n\tdescription: string;\n\t/**\n\t * Resolved hoocode tool allowlist. `undefined` means \"inherit all parent\n\t * tools\" (Claude Code behavior when `tools` is omitted).\n\t */\n\ttools?: string[];\n\t/** Resolved denylist subtracted from the agent's tool set. */\n\tdisallowedTools?: string[];\n\t/**\n\t * Model alias/pattern, the `inherit` sentinel, or `undefined` for the\n\t * subagent default.\n\t */\n\tmodel?: string;\n\t/** System prompt body (frontmatter stripped). */\n\tprompt: string;\n\t/** Origin of this definition. */\n\tsource: AgentSource;\n\t/** Absolute path of the source file, when loaded from disk. */\n\tfilePath?: string;\n\t/** hoocode extension: optional per-agent turn cap. */\n\tmaxTurns?: number;\n\t/** When true, dispatch is non-blocking: the parent receives a handle and polls for the result. */\n\tbackground?: boolean;\n\t/** When true, this agent may delegate via the Task tool, subject to the nesting cap. */\n\tdelegate?: boolean;\n\t/** Restricts delegation to these subagent types (undefined = any when `delegate` is true). */\n\tdelegateTo?: string[];\n\t/** When true, the agent inherits the parent's full conversation (a fork). */\n\tfork?: boolean;\n}\n\nconst KNOWN_MODEL_ALIASES = new Set([\"sonnet\", \"opus\", \"haiku\", \"inherit\", \"fast\", \"standard\", \"capable\"]);\n\n/** Validate an agent name. Returns warning messages (empty when valid). */\nfunction validateName(name: string): string[] {\n\tconst errors: string[] = [];\n\tif (!name) {\n\t\terrors.push(\"name is required\");\n\t\treturn errors;\n\t}\n\tif (name.length > MAX_NAME_LENGTH) {\n\t\terrors.push(`name exceeds ${MAX_NAME_LENGTH} characters (${name.length})`);\n\t}\n\tif (!/^[a-z0-9-]+$/.test(name)) {\n\t\terrors.push(\"name contains invalid characters (must be lowercase a-z, 0-9, hyphens only)\");\n\t}\n\tif (name.startsWith(\"-\") || name.endsWith(\"-\")) {\n\t\terrors.push(\"name must not start or end with a hyphen\");\n\t}\n\tif (name.includes(\"--\")) {\n\t\terrors.push(\"name must not contain consecutive hyphens\");\n\t}\n\treturn errors;\n}\n\n/** Validate a description. Returns warning messages (empty when valid). */\nfunction validateDescription(description: string | undefined): string[] {\n\tconst errors: string[] = [];\n\tif (!description || description.trim() === \"\") {\n\t\terrors.push(\"description is required\");\n\t} else if (description.length > MAX_DESCRIPTION_LENGTH) {\n\t\terrors.push(`description exceeds ${MAX_DESCRIPTION_LENGTH} characters (${description.length})`);\n\t}\n\treturn errors;\n}\n\nfunction validateModel(value: string): string[] {\n\tconst trimmed = value.trim();\n\tif (!trimmed) return [];\n\tif (KNOWN_MODEL_ALIASES.has(trimmed)) return [];\n\tif (/^claude-/.test(trimmed)) return [];\n\treturn [\n\t\t`model \"${trimmed}\" is not a recognized alias (sonnet | opus | haiku | inherit | fast | standard | capable) or full model ID; the agent may not load correctly`,\n\t];\n}\n\n/** Split a `tools` frontmatter value (string or list) into raw token names. */\nfunction splitToolsValue(value: string | string[]): string[] {\n\tconst tokens = Array.isArray(value) ? value : value.split(\",\");\n\treturn tokens.map((t) => t.trim()).filter((t) => t.length > 0);\n}\n\n/**\n * Normalize a raw `tools` allowlist into hoocode tool names via the Claude Code\n * alias map. Returns the deduped, resolved list plus diagnostics for any tokens\n * that could not be mapped.\n *\n * Emits a warning when `value` is a YAML list rather than a comma-separated\n * string — the Claude Code standard format is `tools: read, bash` (string).\n */\nexport function normalizeTools(\n\tvalue: string | string[],\n\tfilePath?: string,\n): { tools: string[]; diagnostics: ResourceDiagnostic[] } {\n\tconst diagnostics: ResourceDiagnostic[] = [];\n\tif (Array.isArray(value)) {\n\t\tdiagnostics.push({\n\t\t\ttype: \"warning\",\n\t\t\tmessage:\n\t\t\t\t'tools: use a comma-separated string (\"tools: read, bash\") instead of a YAML list for Claude Code compatibility',\n\t\t\tpath: filePath,\n\t\t});\n\t}\n\tconst resolved: string[] = [];\n\tfor (const raw of splitToolsValue(value)) {\n\t\tconst mapped = CLAUDE_TOOL_ALIASES[raw.toLowerCase()];\n\t\tif (!mapped) {\n\t\t\tdiagnostics.push({\n\t\t\t\ttype: \"warning\",\n\t\t\t\tmessage: `tool \"${raw}\" has no hoocode equivalent and was dropped from the allowlist`,\n\t\t\t\tpath: filePath,\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\t\tif (!resolved.includes(mapped)) {\n\t\t\tresolved.push(mapped);\n\t\t}\n\t}\n\treturn { tools: resolved, diagnostics };\n}\n\n/**\n * Normalize a `model` frontmatter value. `inherit` is preserved as a sentinel;\n * any other non-empty string is passed through to the model resolver as-is\n * (so Claude aliases like `sonnet`/`opus`/`haiku` resolve via pattern match).\n */\nexport function normalizeModel(value: string | undefined): string | undefined {\n\tif (typeof value !== \"string\") return undefined;\n\tconst trimmed = value.trim();\n\tif (!trimmed) return undefined;\n\treturn trimmed;\n}\n\n/**\n * Parse and validate a single agent definition from raw Markdown content.\n *\n * `fallbackName` is used when frontmatter omits `name` (e.g. the filename, or\n * the embedded-template key). Returns `agent: null` only when the definition\n * is unusable (missing description). Other problems surface as diagnostics.\n */\nexport function parseAgentDefinition(\n\trawContent: string,\n\toptions: { source: AgentSource; filePath?: string; fallbackName?: string },\n): { agent: AgentDefinition | null; diagnostics: ResourceDiagnostic[] } {\n\tconst { source, filePath } = options;\n\tconst diagnostics: ResourceDiagnostic[] = [];\n\n\tlet frontmatter: AgentFrontmatter;\n\tlet body: string;\n\ttry {\n\t\tconst parsed = parseFrontmatter<AgentFrontmatter>(rawContent);\n\t\tfrontmatter = parsed.frontmatter;\n\t\tbody = parsed.body;\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : \"failed to parse agent frontmatter\";\n\t\tdiagnostics.push({ type: \"warning\", message, path: filePath });\n\t\treturn { agent: null, diagnostics };\n\t}\n\n\tconst fallbackName = options.fallbackName ?? (filePath ? basename(filePath, \".md\") : \"\");\n\tconst name = (frontmatter.name ?? fallbackName).trim();\n\n\tfor (const error of validateName(name)) {\n\t\tdiagnostics.push({ type: \"warning\", message: error, path: filePath });\n\t}\n\n\tconst description = typeof frontmatter.description === \"string\" ? frontmatter.description.trim() : \"\";\n\tfor (const error of validateDescription(description)) {\n\t\tdiagnostics.push({ type: \"warning\", message: error, path: filePath });\n\t}\n\n\t// Description is mandatory: it drives delegation. Without it the agent is unusable.\n\tif (!description) {\n\t\treturn { agent: null, diagnostics };\n\t}\n\t// A usable name is required as the registry key.\n\tif (!name || !/^[a-z0-9-]+$/.test(name)) {\n\t\treturn { agent: null, diagnostics };\n\t}\n\n\tlet tools: string[] | undefined;\n\tif (frontmatter.tools !== undefined) {\n\t\tconst normalized = normalizeTools(frontmatter.tools, filePath);\n\t\tdiagnostics.push(...normalized.diagnostics);\n\t\ttools = normalized.tools;\n\t}\n\n\tlet disallowedTools: string[] | undefined;\n\tif (frontmatter.disallowedTools !== undefined) {\n\t\tconst normalized = normalizeTools(frontmatter.disallowedTools, filePath);\n\t\tdiagnostics.push(...normalized.diagnostics);\n\t\tdisallowedTools = normalized.tools.length > 0 ? normalized.tools : undefined;\n\t}\n\n\tconst model = normalizeModel(frontmatter.model);\n\tif (model !== undefined) {\n\t\tfor (const error of validateModel(model)) {\n\t\t\tdiagnostics.push({ type: \"warning\", message: error, path: filePath });\n\t\t}\n\t}\n\n\tconst maxTurns =\n\t\ttypeof frontmatter.maxTurns === \"number\" && Number.isInteger(frontmatter.maxTurns) && frontmatter.maxTurns > 0\n\t\t\t? frontmatter.maxTurns\n\t\t\t: undefined;\n\n\tlet background: boolean | undefined;\n\tif (frontmatter.background !== undefined) {\n\t\tif (typeof frontmatter.background !== \"boolean\") {\n\t\t\tdiagnostics.push({\n\t\t\t\ttype: \"warning\",\n\t\t\t\tmessage: `background must be a boolean (true or false), got \"${frontmatter.background}\" — field ignored`,\n\t\t\t\tpath: filePath,\n\t\t\t});\n\t\t} else {\n\t\t\tbackground = frontmatter.background === true ? true : undefined;\n\t\t}\n\t}\n\n\t// `delegate` accepts a boolean (delegate to any agent) or a comma-separated\n\t// string / YAML list of agent type names (delegate only to those).\n\tlet fork: boolean | undefined;\n\tif (frontmatter.fork !== undefined) {\n\t\tif (typeof frontmatter.fork !== \"boolean\") {\n\t\t\tdiagnostics.push({\n\t\t\t\ttype: \"warning\",\n\t\t\t\tmessage: `fork must be a boolean (true or false), got \"${frontmatter.fork}\" — field ignored`,\n\t\t\t\tpath: filePath,\n\t\t\t});\n\t\t} else {\n\t\t\tfork = frontmatter.fork === true ? true : undefined;\n\t\t}\n\t}\n\n\tlet delegate: boolean | undefined;\n\tlet delegateTo: string[] | undefined;\n\tif (frontmatter.delegate !== undefined) {\n\t\tconst value = frontmatter.delegate;\n\t\tif (value === true) {\n\t\t\tdelegate = true;\n\t\t} else if (value === false) {\n\t\t\tdelegate = undefined;\n\t\t} else if (typeof value === \"string\" || Array.isArray(value)) {\n\t\t\tconst names = (Array.isArray(value) ? value.join(\",\") : value)\n\t\t\t\t.split(\",\")\n\t\t\t\t.map((s) => s.trim().toLowerCase())\n\t\t\t\t.filter((s) => /^[a-z0-9-]+$/.test(s));\n\t\t\tif (names.length > 0) {\n\t\t\t\tdelegate = true;\n\t\t\t\tdelegateTo = [...new Set(names)];\n\t\t\t} else {\n\t\t\t\tdiagnostics.push({\n\t\t\t\t\ttype: \"warning\",\n\t\t\t\t\tmessage: `delegate list \"${value}\" contained no valid agent names — field ignored`,\n\t\t\t\t\tpath: filePath,\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\tdiagnostics.push({\n\t\t\t\ttype: \"warning\",\n\t\t\t\tmessage: `delegate must be a boolean or a list of agent names, got \"${value}\" — field ignored`,\n\t\t\t\tpath: filePath,\n\t\t\t});\n\t\t}\n\t}\n\n\treturn {\n\t\tagent: {\n\t\t\tname,\n\t\t\tdescription,\n\t\t\ttools,\n\t\t\tdisallowedTools,\n\t\t\tmodel,\n\t\t\tprompt: body.trim(),\n\t\t\tsource,\n\t\t\tfilePath,\n\t\t\tmaxTurns,\n\t\t\tbackground,\n\t\t\tdelegate,\n\t\t\tdelegateTo,\n\t\t\tfork,\n\t\t},\n\t\tdiagnostics,\n\t};\n}\n"]}
1
+ {"version":3,"file":"agent-frontmatter.d.ts","sourceRoot":"","sources":["../../src/core/agent-frontmatter.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Agent frontmatter: schema, validation, and Claude Code compatibility shim.\n *\n * Agent definitions are Markdown files with YAML frontmatter, mirroring the\n * Claude Code subagent format so `.claude/agents/*.md` files import natively:\n *\n * ---\n * name: explore\n * description: When and why to use this agent (drives auto-delegation).\n * tools: Read, Grep, Glob, Bash # optional allowlist; omit = inherit all\n * model: sonnet # optional; sonnet|opus|haiku|inherit|pattern\n * ---\n * <system prompt body>\n *\n * The body becomes the subagent system prompt. Validation is non-fatal: we emit\n * diagnostics (warnings) and still load the agent when possible, matching the\n * behavior of skills.ts.\n */\n\nimport { basename } from \"path\";\nimport { parseFrontmatter } from \"../utils/frontmatter.js\";\nimport type { ResourceDiagnostic } from \"./diagnostics.js\";\n\n/** Max name length, aligned with skills. */\nconst MAX_NAME_LENGTH = 64;\n\n/** Max description length, aligned with skills. */\nconst MAX_DESCRIPTION_LENGTH = 1024;\n\n/** Where an agent definition came from. Used for precedence and diagnostics. */\nexport type AgentSource = \"builtin\" | \"user\" | \"project\" | \"claude-user\" | \"claude-project\";\n\n/** Sentinel meaning \"use the parent session's model\" (Claude Code `model: inherit`). */\nexport const MODEL_INHERIT = \"inherit\";\n\n/**\n * The built-in hoocode tools that an agent's `tools` allowlist is normalized\n * against; unknown tools are dropped with a diagnostic. Includes the opt-in web\n * tools (webfetch/websearch) so Claude Code's WebFetch/WebSearch map through.\n */\nexport const HOOCODE_TOOL_NAMES: readonly string[] = [\n\t\"bash\",\n\t\"edit\",\n\t\"find\",\n\t\"grep\",\n\t\"ls\",\n\t\"read\",\n\t\"webfetch\",\n\t\"websearch\",\n\t\"write\",\n\t\"DocRead\",\n\t\"DocEdit\",\n\t\"DocWrite\",\n];\n\n/**\n * Canonical registered names of the two opt-in tools. These are case-sensitive\n * identifiers the system prompt and tool gating match exactly, so downstream\n * callers should reference these constants instead of hardcoding the strings\n * (a mis-cased `\"task\"` silently disables the agents/skills prompt sections).\n */\nexport const TASK_TOOL_NAME = \"Task\";\nexport const TODO_WRITE_TOOL_NAME = \"TodoWrite\";\n\n/**\n * D7 — Claude Code compatibility shim.\n *\n * Maps Claude Code tool names (case-insensitive) to their hoocode equivalents.\n * Claude tools without a hoocode counterpart (MultiEdit, Task, TodoWrite,\n * NotebookEdit, MCP tools, ...) are intentionally absent and get dropped during\n * normalization.\n */\nexport const CLAUDE_TOOL_ALIASES: Readonly<Record<string, string>> = {\n\tread: \"read\",\n\twrite: \"write\",\n\tedit: \"edit\",\n\tbash: \"bash\",\n\tgrep: \"grep\",\n\tglob: \"find\",\n\tfind: \"find\",\n\tls: \"ls\",\n\twebfetch: \"webfetch\",\n\twebsearch: \"websearch\",\n};\n\n/** Raw frontmatter shape before validation/normalization. */\nexport interface AgentFrontmatter {\n\tname?: string;\n\tdescription?: string;\n\t/** Claude Code uses a comma-separated string; a YAML list is also accepted. */\n\ttools?: string | string[];\n\t/** Tools to subtract from the agent's set (allow + deny), Claude Code compatible. */\n\tdisallowedTools?: string | string[];\n\t/** sonnet | opus | haiku | inherit | a model id/pattern. */\n\tmodel?: string;\n\t/** hoocode extension (not part of the Claude Code format): turn cap. */\n\tmaxTurns?: number;\n\t/** Claude Code extension: run this agent detached (non-blocking) so the parent polls for its result. */\n\tbackground?: boolean;\n\t/**\n\t * hoocode extension: opt a agent into delegating via the Task tool (subject to the\n\t * tree-wide nesting cap). `true` = any subagent type; a comma-separated string or\n\t * YAML list = only those types. Opt-in per agent so the deliberate \"Task is not a\n\t * normal tool\" boundary stays intact for everyone else.\n\t */\n\tdelegate?: boolean | string | string[];\n\t/**\n\t * When true, this agent inherits the parent's full conversation (a fork) instead\n\t * of starting from a fresh context, reusing the parent's prompt cache.\n\t */\n\tfork?: boolean;\n\t[key: string]: unknown;\n}\n\n/** A validated, normalized agent definition. */\nexport interface AgentDefinition {\n\tname: string;\n\tdescription: string;\n\t/**\n\t * Resolved hoocode tool allowlist. `undefined` means \"inherit all parent\n\t * tools\" (Claude Code behavior when `tools` is omitted).\n\t */\n\ttools?: string[];\n\t/** Resolved denylist subtracted from the agent's tool set. */\n\tdisallowedTools?: string[];\n\t/**\n\t * Model alias/pattern, the `inherit` sentinel, or `undefined` for the\n\t * subagent default.\n\t */\n\tmodel?: string;\n\t/** System prompt body (frontmatter stripped). */\n\tprompt: string;\n\t/** Origin of this definition. */\n\tsource: AgentSource;\n\t/** Absolute path of the source file, when loaded from disk. */\n\tfilePath?: string;\n\t/** hoocode extension: optional per-agent turn cap. */\n\tmaxTurns?: number;\n\t/** When true, dispatch is non-blocking: the parent receives a handle and polls for the result. */\n\tbackground?: boolean;\n\t/** When true, this agent may delegate via the Task tool, subject to the nesting cap. */\n\tdelegate?: boolean;\n\t/** Restricts delegation to these subagent types (undefined = any when `delegate` is true). */\n\tdelegateTo?: string[];\n\t/** When true, the agent inherits the parent's full conversation (a fork). */\n\tfork?: boolean;\n}\n\nconst KNOWN_MODEL_ALIASES = new Set([\"sonnet\", \"opus\", \"haiku\", \"inherit\", \"fast\", \"standard\", \"capable\"]);\n\n/** Validate an agent name. Returns warning messages (empty when valid). */\nfunction validateName(name: string): string[] {\n\tconst errors: string[] = [];\n\tif (!name) {\n\t\terrors.push(\"name is required\");\n\t\treturn errors;\n\t}\n\tif (name.length > MAX_NAME_LENGTH) {\n\t\terrors.push(`name exceeds ${MAX_NAME_LENGTH} characters (${name.length})`);\n\t}\n\tif (!/^[a-z0-9-]+$/.test(name)) {\n\t\terrors.push(\"name contains invalid characters (must be lowercase a-z, 0-9, hyphens only)\");\n\t}\n\tif (name.startsWith(\"-\") || name.endsWith(\"-\")) {\n\t\terrors.push(\"name must not start or end with a hyphen\");\n\t}\n\tif (name.includes(\"--\")) {\n\t\terrors.push(\"name must not contain consecutive hyphens\");\n\t}\n\treturn errors;\n}\n\n/** Validate a description. Returns warning messages (empty when valid). */\nfunction validateDescription(description: string | undefined): string[] {\n\tconst errors: string[] = [];\n\tif (!description || description.trim() === \"\") {\n\t\terrors.push(\"description is required\");\n\t} else if (description.length > MAX_DESCRIPTION_LENGTH) {\n\t\terrors.push(`description exceeds ${MAX_DESCRIPTION_LENGTH} characters (${description.length})`);\n\t}\n\treturn errors;\n}\n\nfunction validateModel(value: string): string[] {\n\tconst trimmed = value.trim();\n\tif (!trimmed) return [];\n\tif (KNOWN_MODEL_ALIASES.has(trimmed)) return [];\n\tif (/^claude-/.test(trimmed)) return [];\n\treturn [\n\t\t`model \"${trimmed}\" is not a recognized alias (sonnet | opus | haiku | inherit | fast | standard | capable) or full model ID; the agent may not load correctly`,\n\t];\n}\n\n/** Split a `tools` frontmatter value (string or list) into raw token names. */\nfunction splitToolsValue(value: string | string[]): string[] {\n\tconst tokens = Array.isArray(value) ? value : value.split(\",\");\n\treturn tokens.map((t) => t.trim()).filter((t) => t.length > 0);\n}\n\n/**\n * Normalize a raw `tools` allowlist into hoocode tool names via the Claude Code\n * alias map. Returns the deduped, resolved list plus diagnostics for any tokens\n * that could not be mapped.\n *\n * Emits a warning when `value` is a YAML list rather than a comma-separated\n * string — the Claude Code standard format is `tools: read, bash` (string).\n */\nexport function normalizeTools(\n\tvalue: string | string[],\n\tfilePath?: string,\n): { tools: string[]; diagnostics: ResourceDiagnostic[] } {\n\tconst diagnostics: ResourceDiagnostic[] = [];\n\tif (Array.isArray(value)) {\n\t\tdiagnostics.push({\n\t\t\ttype: \"warning\",\n\t\t\tmessage:\n\t\t\t\t'tools: use a comma-separated string (\"tools: read, bash\") instead of a YAML list for Claude Code compatibility',\n\t\t\tpath: filePath,\n\t\t});\n\t}\n\tconst resolved: string[] = [];\n\tfor (const raw of splitToolsValue(value)) {\n\t\tconst mapped = CLAUDE_TOOL_ALIASES[raw.toLowerCase()];\n\t\tif (!mapped) {\n\t\t\tdiagnostics.push({\n\t\t\t\ttype: \"warning\",\n\t\t\t\tmessage: `tool \"${raw}\" has no hoocode equivalent and was dropped from the allowlist`,\n\t\t\t\tpath: filePath,\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\t\tif (!resolved.includes(mapped)) {\n\t\t\tresolved.push(mapped);\n\t\t}\n\t}\n\treturn { tools: resolved, diagnostics };\n}\n\n/**\n * Normalize a `model` frontmatter value. `inherit` is preserved as a sentinel;\n * any other non-empty string is passed through to the model resolver as-is\n * (so Claude aliases like `sonnet`/`opus`/`haiku` resolve via pattern match).\n */\nexport function normalizeModel(value: string | undefined): string | undefined {\n\tif (typeof value !== \"string\") return undefined;\n\tconst trimmed = value.trim();\n\tif (!trimmed) return undefined;\n\treturn trimmed;\n}\n\n/**\n * Parse and validate a single agent definition from raw Markdown content.\n *\n * `fallbackName` is used when frontmatter omits `name` (e.g. the filename, or\n * the embedded-template key). Returns `agent: null` only when the definition\n * is unusable (missing description). Other problems surface as diagnostics.\n */\nexport function parseAgentDefinition(\n\trawContent: string,\n\toptions: { source: AgentSource; filePath?: string; fallbackName?: string },\n): { agent: AgentDefinition | null; diagnostics: ResourceDiagnostic[] } {\n\tconst { source, filePath } = options;\n\tconst diagnostics: ResourceDiagnostic[] = [];\n\n\tlet frontmatter: AgentFrontmatter;\n\tlet body: string;\n\ttry {\n\t\tconst parsed = parseFrontmatter<AgentFrontmatter>(rawContent);\n\t\tfrontmatter = parsed.frontmatter;\n\t\tbody = parsed.body;\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : \"failed to parse agent frontmatter\";\n\t\tdiagnostics.push({ type: \"warning\", message, path: filePath });\n\t\treturn { agent: null, diagnostics };\n\t}\n\n\tconst fallbackName = options.fallbackName ?? (filePath ? basename(filePath, \".md\") : \"\");\n\tconst name = (frontmatter.name ?? fallbackName).trim();\n\n\tfor (const error of validateName(name)) {\n\t\tdiagnostics.push({ type: \"warning\", message: error, path: filePath });\n\t}\n\n\tconst description = typeof frontmatter.description === \"string\" ? frontmatter.description.trim() : \"\";\n\tfor (const error of validateDescription(description)) {\n\t\tdiagnostics.push({ type: \"warning\", message: error, path: filePath });\n\t}\n\n\t// Description is mandatory: it drives delegation. Without it the agent is unusable.\n\tif (!description) {\n\t\treturn { agent: null, diagnostics };\n\t}\n\t// A usable name is required as the registry key.\n\tif (!name || !/^[a-z0-9-]+$/.test(name)) {\n\t\treturn { agent: null, diagnostics };\n\t}\n\n\tlet tools: string[] | undefined;\n\tif (frontmatter.tools !== undefined) {\n\t\tconst normalized = normalizeTools(frontmatter.tools, filePath);\n\t\tdiagnostics.push(...normalized.diagnostics);\n\t\ttools = normalized.tools;\n\t}\n\n\tlet disallowedTools: string[] | undefined;\n\tif (frontmatter.disallowedTools !== undefined) {\n\t\tconst normalized = normalizeTools(frontmatter.disallowedTools, filePath);\n\t\tdiagnostics.push(...normalized.diagnostics);\n\t\tdisallowedTools = normalized.tools.length > 0 ? normalized.tools : undefined;\n\t}\n\n\tconst model = normalizeModel(frontmatter.model);\n\tif (model !== undefined) {\n\t\tfor (const error of validateModel(model)) {\n\t\t\tdiagnostics.push({ type: \"warning\", message: error, path: filePath });\n\t\t}\n\t}\n\n\tconst maxTurns =\n\t\ttypeof frontmatter.maxTurns === \"number\" && Number.isInteger(frontmatter.maxTurns) && frontmatter.maxTurns > 0\n\t\t\t? frontmatter.maxTurns\n\t\t\t: undefined;\n\n\tlet background: boolean | undefined;\n\tif (frontmatter.background !== undefined) {\n\t\tif (typeof frontmatter.background !== \"boolean\") {\n\t\t\tdiagnostics.push({\n\t\t\t\ttype: \"warning\",\n\t\t\t\tmessage: `background must be a boolean (true or false), got \"${frontmatter.background}\" — field ignored`,\n\t\t\t\tpath: filePath,\n\t\t\t});\n\t\t} else {\n\t\t\tbackground = frontmatter.background === true ? true : undefined;\n\t\t}\n\t}\n\n\t// `delegate` accepts a boolean (delegate to any agent) or a comma-separated\n\t// string / YAML list of agent type names (delegate only to those).\n\tlet fork: boolean | undefined;\n\tif (frontmatter.fork !== undefined) {\n\t\tif (typeof frontmatter.fork !== \"boolean\") {\n\t\t\tdiagnostics.push({\n\t\t\t\ttype: \"warning\",\n\t\t\t\tmessage: `fork must be a boolean (true or false), got \"${frontmatter.fork}\" — field ignored`,\n\t\t\t\tpath: filePath,\n\t\t\t});\n\t\t} else {\n\t\t\tfork = frontmatter.fork === true ? true : undefined;\n\t\t}\n\t}\n\n\tlet delegate: boolean | undefined;\n\tlet delegateTo: string[] | undefined;\n\tif (frontmatter.delegate !== undefined) {\n\t\tconst value = frontmatter.delegate;\n\t\tif (value === true) {\n\t\t\tdelegate = true;\n\t\t} else if (value === false) {\n\t\t\tdelegate = undefined;\n\t\t} else if (typeof value === \"string\" || Array.isArray(value)) {\n\t\t\tconst names = (Array.isArray(value) ? value.join(\",\") : value)\n\t\t\t\t.split(\",\")\n\t\t\t\t.map((s) => s.trim().toLowerCase())\n\t\t\t\t.filter((s) => /^[a-z0-9-]+$/.test(s));\n\t\t\tif (names.length > 0) {\n\t\t\t\tdelegate = true;\n\t\t\t\tdelegateTo = [...new Set(names)];\n\t\t\t} else {\n\t\t\t\tdiagnostics.push({\n\t\t\t\t\ttype: \"warning\",\n\t\t\t\t\tmessage: `delegate list \"${value}\" contained no valid agent names — field ignored`,\n\t\t\t\t\tpath: filePath,\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\tdiagnostics.push({\n\t\t\t\ttype: \"warning\",\n\t\t\t\tmessage: `delegate must be a boolean or a list of agent names, got \"${value}\" — field ignored`,\n\t\t\t\tpath: filePath,\n\t\t\t});\n\t\t}\n\t}\n\n\treturn {\n\t\tagent: {\n\t\t\tname,\n\t\t\tdescription,\n\t\t\ttools,\n\t\t\tdisallowedTools,\n\t\t\tmodel,\n\t\t\tprompt: body.trim(),\n\t\t\tsource,\n\t\t\tfilePath,\n\t\t\tmaxTurns,\n\t\t\tbackground,\n\t\t\tdelegate,\n\t\t\tdelegateTo,\n\t\t\tfork,\n\t\t},\n\t\tdiagnostics,\n\t};\n}\n"]}
@@ -39,6 +39,9 @@ export const HOOCODE_TOOL_NAMES = [
39
39
  "webfetch",
40
40
  "websearch",
41
41
  "write",
42
+ "DocRead",
43
+ "DocEdit",
44
+ "DocWrite",
42
45
  ];
43
46
  /**
44
47
  * Canonical registered names of the two opt-in tools. These are case-sensitive
@@ -1 +1 @@
1
- {"version":3,"file":"agent-frontmatter.js","sourceRoot":"","sources":["../../src/core/agent-frontmatter.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Agent frontmatter: schema, validation, and Claude Code compatibility shim.\n *\n * Agent definitions are Markdown files with YAML frontmatter, mirroring the\n * Claude Code subagent format so `.claude/agents/*.md` files import natively:\n *\n * ---\n * name: explore\n * description: When and why to use this agent (drives auto-delegation).\n * tools: Read, Grep, Glob, Bash # optional allowlist; omit = inherit all\n * model: sonnet # optional; sonnet|opus|haiku|inherit|pattern\n * ---\n * <system prompt body>\n *\n * The body becomes the subagent system prompt. Validation is non-fatal: we emit\n * diagnostics (warnings) and still load the agent when possible, matching the\n * behavior of skills.ts.\n */\n\nimport { basename } from \"path\";\nimport { parseFrontmatter } from \"../utils/frontmatter.js\";\nimport type { ResourceDiagnostic } from \"./diagnostics.js\";\n\n/** Max name length, aligned with skills. */\nconst MAX_NAME_LENGTH = 64;\n\n/** Max description length, aligned with skills. */\nconst MAX_DESCRIPTION_LENGTH = 1024;\n\n/** Where an agent definition came from. Used for precedence and diagnostics. */\nexport type AgentSource = \"builtin\" | \"user\" | \"project\" | \"claude-user\" | \"claude-project\";\n\n/** Sentinel meaning \"use the parent session's model\" (Claude Code `model: inherit`). */\nexport const MODEL_INHERIT = \"inherit\";\n\n/**\n * The built-in hoocode tools that an agent's `tools` allowlist is normalized\n * against; unknown tools are dropped with a diagnostic. Includes the opt-in web\n * tools (webfetch/websearch) so Claude Code's WebFetch/WebSearch map through.\n */\nexport const HOOCODE_TOOL_NAMES: readonly string[] = [\n\t\"bash\",\n\t\"edit\",\n\t\"find\",\n\t\"grep\",\n\t\"ls\",\n\t\"read\",\n\t\"webfetch\",\n\t\"websearch\",\n\t\"write\",\n];\n\n/**\n * Canonical registered names of the two opt-in tools. These are case-sensitive\n * identifiers the system prompt and tool gating match exactly, so downstream\n * callers should reference these constants instead of hardcoding the strings\n * (a mis-cased `\"task\"` silently disables the agents/skills prompt sections).\n */\nexport const TASK_TOOL_NAME = \"Task\";\nexport const TODO_WRITE_TOOL_NAME = \"TodoWrite\";\n\n/**\n * D7 — Claude Code compatibility shim.\n *\n * Maps Claude Code tool names (case-insensitive) to their hoocode equivalents.\n * Claude tools without a hoocode counterpart (MultiEdit, Task, TodoWrite,\n * NotebookEdit, MCP tools, ...) are intentionally absent and get dropped during\n * normalization.\n */\nexport const CLAUDE_TOOL_ALIASES: Readonly<Record<string, string>> = {\n\tread: \"read\",\n\twrite: \"write\",\n\tedit: \"edit\",\n\tbash: \"bash\",\n\tgrep: \"grep\",\n\tglob: \"find\",\n\tfind: \"find\",\n\tls: \"ls\",\n\twebfetch: \"webfetch\",\n\twebsearch: \"websearch\",\n};\n\n/** Raw frontmatter shape before validation/normalization. */\nexport interface AgentFrontmatter {\n\tname?: string;\n\tdescription?: string;\n\t/** Claude Code uses a comma-separated string; a YAML list is also accepted. */\n\ttools?: string | string[];\n\t/** Tools to subtract from the agent's set (allow + deny), Claude Code compatible. */\n\tdisallowedTools?: string | string[];\n\t/** sonnet | opus | haiku | inherit | a model id/pattern. */\n\tmodel?: string;\n\t/** hoocode extension (not part of the Claude Code format): turn cap. */\n\tmaxTurns?: number;\n\t/** Claude Code extension: run this agent detached (non-blocking) so the parent polls for its result. */\n\tbackground?: boolean;\n\t/**\n\t * hoocode extension: opt a agent into delegating via the Task tool (subject to the\n\t * tree-wide nesting cap). `true` = any subagent type; a comma-separated string or\n\t * YAML list = only those types. Opt-in per agent so the deliberate \"Task is not a\n\t * normal tool\" boundary stays intact for everyone else.\n\t */\n\tdelegate?: boolean | string | string[];\n\t/**\n\t * When true, this agent inherits the parent's full conversation (a fork) instead\n\t * of starting from a fresh context, reusing the parent's prompt cache.\n\t */\n\tfork?: boolean;\n\t[key: string]: unknown;\n}\n\n/** A validated, normalized agent definition. */\nexport interface AgentDefinition {\n\tname: string;\n\tdescription: string;\n\t/**\n\t * Resolved hoocode tool allowlist. `undefined` means \"inherit all parent\n\t * tools\" (Claude Code behavior when `tools` is omitted).\n\t */\n\ttools?: string[];\n\t/** Resolved denylist subtracted from the agent's tool set. */\n\tdisallowedTools?: string[];\n\t/**\n\t * Model alias/pattern, the `inherit` sentinel, or `undefined` for the\n\t * subagent default.\n\t */\n\tmodel?: string;\n\t/** System prompt body (frontmatter stripped). */\n\tprompt: string;\n\t/** Origin of this definition. */\n\tsource: AgentSource;\n\t/** Absolute path of the source file, when loaded from disk. */\n\tfilePath?: string;\n\t/** hoocode extension: optional per-agent turn cap. */\n\tmaxTurns?: number;\n\t/** When true, dispatch is non-blocking: the parent receives a handle and polls for the result. */\n\tbackground?: boolean;\n\t/** When true, this agent may delegate via the Task tool, subject to the nesting cap. */\n\tdelegate?: boolean;\n\t/** Restricts delegation to these subagent types (undefined = any when `delegate` is true). */\n\tdelegateTo?: string[];\n\t/** When true, the agent inherits the parent's full conversation (a fork). */\n\tfork?: boolean;\n}\n\nconst KNOWN_MODEL_ALIASES = new Set([\"sonnet\", \"opus\", \"haiku\", \"inherit\", \"fast\", \"standard\", \"capable\"]);\n\n/** Validate an agent name. Returns warning messages (empty when valid). */\nfunction validateName(name: string): string[] {\n\tconst errors: string[] = [];\n\tif (!name) {\n\t\terrors.push(\"name is required\");\n\t\treturn errors;\n\t}\n\tif (name.length > MAX_NAME_LENGTH) {\n\t\terrors.push(`name exceeds ${MAX_NAME_LENGTH} characters (${name.length})`);\n\t}\n\tif (!/^[a-z0-9-]+$/.test(name)) {\n\t\terrors.push(\"name contains invalid characters (must be lowercase a-z, 0-9, hyphens only)\");\n\t}\n\tif (name.startsWith(\"-\") || name.endsWith(\"-\")) {\n\t\terrors.push(\"name must not start or end with a hyphen\");\n\t}\n\tif (name.includes(\"--\")) {\n\t\terrors.push(\"name must not contain consecutive hyphens\");\n\t}\n\treturn errors;\n}\n\n/** Validate a description. Returns warning messages (empty when valid). */\nfunction validateDescription(description: string | undefined): string[] {\n\tconst errors: string[] = [];\n\tif (!description || description.trim() === \"\") {\n\t\terrors.push(\"description is required\");\n\t} else if (description.length > MAX_DESCRIPTION_LENGTH) {\n\t\terrors.push(`description exceeds ${MAX_DESCRIPTION_LENGTH} characters (${description.length})`);\n\t}\n\treturn errors;\n}\n\nfunction validateModel(value: string): string[] {\n\tconst trimmed = value.trim();\n\tif (!trimmed) return [];\n\tif (KNOWN_MODEL_ALIASES.has(trimmed)) return [];\n\tif (/^claude-/.test(trimmed)) return [];\n\treturn [\n\t\t`model \"${trimmed}\" is not a recognized alias (sonnet | opus | haiku | inherit | fast | standard | capable) or full model ID; the agent may not load correctly`,\n\t];\n}\n\n/** Split a `tools` frontmatter value (string or list) into raw token names. */\nfunction splitToolsValue(value: string | string[]): string[] {\n\tconst tokens = Array.isArray(value) ? value : value.split(\",\");\n\treturn tokens.map((t) => t.trim()).filter((t) => t.length > 0);\n}\n\n/**\n * Normalize a raw `tools` allowlist into hoocode tool names via the Claude Code\n * alias map. Returns the deduped, resolved list plus diagnostics for any tokens\n * that could not be mapped.\n *\n * Emits a warning when `value` is a YAML list rather than a comma-separated\n * string — the Claude Code standard format is `tools: read, bash` (string).\n */\nexport function normalizeTools(\n\tvalue: string | string[],\n\tfilePath?: string,\n): { tools: string[]; diagnostics: ResourceDiagnostic[] } {\n\tconst diagnostics: ResourceDiagnostic[] = [];\n\tif (Array.isArray(value)) {\n\t\tdiagnostics.push({\n\t\t\ttype: \"warning\",\n\t\t\tmessage:\n\t\t\t\t'tools: use a comma-separated string (\"tools: read, bash\") instead of a YAML list for Claude Code compatibility',\n\t\t\tpath: filePath,\n\t\t});\n\t}\n\tconst resolved: string[] = [];\n\tfor (const raw of splitToolsValue(value)) {\n\t\tconst mapped = CLAUDE_TOOL_ALIASES[raw.toLowerCase()];\n\t\tif (!mapped) {\n\t\t\tdiagnostics.push({\n\t\t\t\ttype: \"warning\",\n\t\t\t\tmessage: `tool \"${raw}\" has no hoocode equivalent and was dropped from the allowlist`,\n\t\t\t\tpath: filePath,\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\t\tif (!resolved.includes(mapped)) {\n\t\t\tresolved.push(mapped);\n\t\t}\n\t}\n\treturn { tools: resolved, diagnostics };\n}\n\n/**\n * Normalize a `model` frontmatter value. `inherit` is preserved as a sentinel;\n * any other non-empty string is passed through to the model resolver as-is\n * (so Claude aliases like `sonnet`/`opus`/`haiku` resolve via pattern match).\n */\nexport function normalizeModel(value: string | undefined): string | undefined {\n\tif (typeof value !== \"string\") return undefined;\n\tconst trimmed = value.trim();\n\tif (!trimmed) return undefined;\n\treturn trimmed;\n}\n\n/**\n * Parse and validate a single agent definition from raw Markdown content.\n *\n * `fallbackName` is used when frontmatter omits `name` (e.g. the filename, or\n * the embedded-template key). Returns `agent: null` only when the definition\n * is unusable (missing description). Other problems surface as diagnostics.\n */\nexport function parseAgentDefinition(\n\trawContent: string,\n\toptions: { source: AgentSource; filePath?: string; fallbackName?: string },\n): { agent: AgentDefinition | null; diagnostics: ResourceDiagnostic[] } {\n\tconst { source, filePath } = options;\n\tconst diagnostics: ResourceDiagnostic[] = [];\n\n\tlet frontmatter: AgentFrontmatter;\n\tlet body: string;\n\ttry {\n\t\tconst parsed = parseFrontmatter<AgentFrontmatter>(rawContent);\n\t\tfrontmatter = parsed.frontmatter;\n\t\tbody = parsed.body;\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : \"failed to parse agent frontmatter\";\n\t\tdiagnostics.push({ type: \"warning\", message, path: filePath });\n\t\treturn { agent: null, diagnostics };\n\t}\n\n\tconst fallbackName = options.fallbackName ?? (filePath ? basename(filePath, \".md\") : \"\");\n\tconst name = (frontmatter.name ?? fallbackName).trim();\n\n\tfor (const error of validateName(name)) {\n\t\tdiagnostics.push({ type: \"warning\", message: error, path: filePath });\n\t}\n\n\tconst description = typeof frontmatter.description === \"string\" ? frontmatter.description.trim() : \"\";\n\tfor (const error of validateDescription(description)) {\n\t\tdiagnostics.push({ type: \"warning\", message: error, path: filePath });\n\t}\n\n\t// Description is mandatory: it drives delegation. Without it the agent is unusable.\n\tif (!description) {\n\t\treturn { agent: null, diagnostics };\n\t}\n\t// A usable name is required as the registry key.\n\tif (!name || !/^[a-z0-9-]+$/.test(name)) {\n\t\treturn { agent: null, diagnostics };\n\t}\n\n\tlet tools: string[] | undefined;\n\tif (frontmatter.tools !== undefined) {\n\t\tconst normalized = normalizeTools(frontmatter.tools, filePath);\n\t\tdiagnostics.push(...normalized.diagnostics);\n\t\ttools = normalized.tools;\n\t}\n\n\tlet disallowedTools: string[] | undefined;\n\tif (frontmatter.disallowedTools !== undefined) {\n\t\tconst normalized = normalizeTools(frontmatter.disallowedTools, filePath);\n\t\tdiagnostics.push(...normalized.diagnostics);\n\t\tdisallowedTools = normalized.tools.length > 0 ? normalized.tools : undefined;\n\t}\n\n\tconst model = normalizeModel(frontmatter.model);\n\tif (model !== undefined) {\n\t\tfor (const error of validateModel(model)) {\n\t\t\tdiagnostics.push({ type: \"warning\", message: error, path: filePath });\n\t\t}\n\t}\n\n\tconst maxTurns =\n\t\ttypeof frontmatter.maxTurns === \"number\" && Number.isInteger(frontmatter.maxTurns) && frontmatter.maxTurns > 0\n\t\t\t? frontmatter.maxTurns\n\t\t\t: undefined;\n\n\tlet background: boolean | undefined;\n\tif (frontmatter.background !== undefined) {\n\t\tif (typeof frontmatter.background !== \"boolean\") {\n\t\t\tdiagnostics.push({\n\t\t\t\ttype: \"warning\",\n\t\t\t\tmessage: `background must be a boolean (true or false), got \"${frontmatter.background}\" — field ignored`,\n\t\t\t\tpath: filePath,\n\t\t\t});\n\t\t} else {\n\t\t\tbackground = frontmatter.background === true ? true : undefined;\n\t\t}\n\t}\n\n\t// `delegate` accepts a boolean (delegate to any agent) or a comma-separated\n\t// string / YAML list of agent type names (delegate only to those).\n\tlet fork: boolean | undefined;\n\tif (frontmatter.fork !== undefined) {\n\t\tif (typeof frontmatter.fork !== \"boolean\") {\n\t\t\tdiagnostics.push({\n\t\t\t\ttype: \"warning\",\n\t\t\t\tmessage: `fork must be a boolean (true or false), got \"${frontmatter.fork}\" — field ignored`,\n\t\t\t\tpath: filePath,\n\t\t\t});\n\t\t} else {\n\t\t\tfork = frontmatter.fork === true ? true : undefined;\n\t\t}\n\t}\n\n\tlet delegate: boolean | undefined;\n\tlet delegateTo: string[] | undefined;\n\tif (frontmatter.delegate !== undefined) {\n\t\tconst value = frontmatter.delegate;\n\t\tif (value === true) {\n\t\t\tdelegate = true;\n\t\t} else if (value === false) {\n\t\t\tdelegate = undefined;\n\t\t} else if (typeof value === \"string\" || Array.isArray(value)) {\n\t\t\tconst names = (Array.isArray(value) ? value.join(\",\") : value)\n\t\t\t\t.split(\",\")\n\t\t\t\t.map((s) => s.trim().toLowerCase())\n\t\t\t\t.filter((s) => /^[a-z0-9-]+$/.test(s));\n\t\t\tif (names.length > 0) {\n\t\t\t\tdelegate = true;\n\t\t\t\tdelegateTo = [...new Set(names)];\n\t\t\t} else {\n\t\t\t\tdiagnostics.push({\n\t\t\t\t\ttype: \"warning\",\n\t\t\t\t\tmessage: `delegate list \"${value}\" contained no valid agent names — field ignored`,\n\t\t\t\t\tpath: filePath,\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\tdiagnostics.push({\n\t\t\t\ttype: \"warning\",\n\t\t\t\tmessage: `delegate must be a boolean or a list of agent names, got \"${value}\" — field ignored`,\n\t\t\t\tpath: filePath,\n\t\t\t});\n\t\t}\n\t}\n\n\treturn {\n\t\tagent: {\n\t\t\tname,\n\t\t\tdescription,\n\t\t\ttools,\n\t\t\tdisallowedTools,\n\t\t\tmodel,\n\t\t\tprompt: body.trim(),\n\t\t\tsource,\n\t\t\tfilePath,\n\t\t\tmaxTurns,\n\t\t\tbackground,\n\t\t\tdelegate,\n\t\t\tdelegateTo,\n\t\t\tfork,\n\t\t},\n\t\tdiagnostics,\n\t};\n}\n"]}
1
+ {"version":3,"file":"agent-frontmatter.js","sourceRoot":"","sources":["../../src/core/agent-frontmatter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAChC,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAG3D,4CAA4C;AAC5C,MAAM,eAAe,GAAG,EAAE,CAAC;AAE3B,mDAAmD;AACnD,MAAM,sBAAsB,GAAG,IAAI,CAAC;AAKpC,wFAAwF;AACxF,MAAM,CAAC,MAAM,aAAa,GAAG,SAAS,CAAC;AAEvC;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAsB;IACpD,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,IAAI;IACJ,MAAM;IACN,UAAU;IACV,WAAW;IACX,OAAO;IACP,SAAS;IACT,SAAS;IACT,UAAU;CACV,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC;AACrC,MAAM,CAAC,MAAM,oBAAoB,GAAG,WAAW,CAAC;AAEhD;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAqC;IACpE,IAAI,EAAE,MAAM;IACZ,KAAK,EAAE,OAAO;IACd,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE,MAAM;IACZ,EAAE,EAAE,IAAI;IACR,QAAQ,EAAE,UAAU;IACpB,SAAS,EAAE,WAAW;CACtB,CAAC;AAiEF,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC,CAAC;AAE3G,2EAA2E;AAC3E,SAAS,YAAY,CAAC,IAAY,EAAY;IAC7C,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,CAAC,IAAI,EAAE,CAAC;QACX,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAChC,OAAO,MAAM,CAAC;IACf,CAAC;IACD,IAAI,IAAI,CAAC,MAAM,GAAG,eAAe,EAAE,CAAC;QACnC,MAAM,CAAC,IAAI,CAAC,gBAAgB,eAAe,gBAAgB,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;IAC5E,CAAC;IACD,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAChC,MAAM,CAAC,IAAI,CAAC,6EAA6E,CAAC,CAAC;IAC5F,CAAC;IACD,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAChD,MAAM,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC;IACzD,CAAC;IACD,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACzB,MAAM,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;IAC1D,CAAC;IACD,OAAO,MAAM,CAAC;AAAA,CACd;AAED,2EAA2E;AAC3E,SAAS,mBAAmB,CAAC,WAA+B,EAAY;IACvE,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,CAAC,WAAW,IAAI,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAC/C,MAAM,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;IACxC,CAAC;SAAM,IAAI,WAAW,CAAC,MAAM,GAAG,sBAAsB,EAAE,CAAC;QACxD,MAAM,CAAC,IAAI,CAAC,uBAAuB,sBAAsB,gBAAgB,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC;IACjG,CAAC;IACD,OAAO,MAAM,CAAC;AAAA,CACd;AAED,SAAS,aAAa,CAAC,KAAa,EAAY;IAC/C,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,CAAC;IACxB,IAAI,mBAAmB,CAAC,GAAG,CAAC,OAAO,CAAC;QAAE,OAAO,EAAE,CAAC;IAChD,IAAI,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,EAAE,CAAC;IACxC,OAAO;QACN,UAAU,OAAO,8IAA8I;KAC/J,CAAC;AAAA,CACF;AAED,+EAA+E;AAC/E,SAAS,eAAe,CAAC,KAAwB,EAAY;IAC5D,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/D,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AAAA,CAC/D;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAC7B,KAAwB,EACxB,QAAiB,EACwC;IACzD,MAAM,WAAW,GAAyB,EAAE,CAAC;IAC7C,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,WAAW,CAAC,IAAI,CAAC;YAChB,IAAI,EAAE,SAAS;YACf,OAAO,EACN,gHAAgH;YACjH,IAAI,EAAE,QAAQ;SACd,CAAC,CAAC;IACJ,CAAC;IACD,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,KAAK,MAAM,GAAG,IAAI,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1C,MAAM,MAAM,GAAG,mBAAmB,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;QACtD,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,WAAW,CAAC,IAAI,CAAC;gBAChB,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,SAAS,GAAG,gEAAgE;gBACrF,IAAI,EAAE,QAAQ;aACd,CAAC,CAAC;YACH,SAAS;QACV,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAChC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvB,CAAC;IACF,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;AAAA,CACxC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,KAAyB,EAAsB;IAC7E,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAChD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IAC/B,OAAO,OAAO,CAAC;AAAA,CACf;AAED;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CACnC,UAAkB,EAClB,OAA0E,EACH;IACvE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IACrC,MAAM,WAAW,GAAyB,EAAE,CAAC;IAE7C,IAAI,WAA6B,CAAC;IAClC,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACJ,MAAM,MAAM,GAAG,gBAAgB,CAAmB,UAAU,CAAC,CAAC;QAC9D,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;QACjC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;IACpB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,mCAAmC,CAAC;QAC7F,WAAW,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC/D,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;IACrC,CAAC;IAED,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACzF,MAAM,IAAI,GAAG,CAAC,WAAW,CAAC,IAAI,IAAI,YAAY,CAAC,CAAC,IAAI,EAAE,CAAC;IAEvD,KAAK,MAAM,KAAK,IAAI,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,WAAW,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;IACvE,CAAC;IAED,MAAM,WAAW,GAAG,OAAO,WAAW,CAAC,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACtG,KAAK,MAAM,KAAK,IAAI,mBAAmB,CAAC,WAAW,CAAC,EAAE,CAAC;QACtD,WAAW,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;IACvE,CAAC;IAED,oFAAoF;IACpF,IAAI,CAAC,WAAW,EAAE,CAAC;QAClB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;IACrC,CAAC;IACD,iDAAiD;IACjD,IAAI,CAAC,IAAI,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACzC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;IACrC,CAAC;IAED,IAAI,KAA2B,CAAC;IAChC,IAAI,WAAW,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QACrC,MAAM,UAAU,GAAG,cAAc,CAAC,WAAW,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QAC/D,WAAW,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;QAC5C,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC;IAC1B,CAAC;IAED,IAAI,eAAqC,CAAC;IAC1C,IAAI,WAAW,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;QAC/C,MAAM,UAAU,GAAG,cAAc,CAAC,WAAW,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC;QACzE,WAAW,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;QAC5C,eAAe,GAAG,UAAU,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAC9E,CAAC;IAED,MAAM,KAAK,GAAG,cAAc,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IAChD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACzB,KAAK,MAAM,KAAK,IAAI,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1C,WAAW,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;QACvE,CAAC;IACF,CAAC;IAED,MAAM,QAAQ,GACb,OAAO,WAAW,CAAC,QAAQ,KAAK,QAAQ,IAAI,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,WAAW,CAAC,QAAQ,GAAG,CAAC;QAC7G,CAAC,CAAC,WAAW,CAAC,QAAQ;QACtB,CAAC,CAAC,SAAS,CAAC;IAEd,IAAI,UAA+B,CAAC;IACpC,IAAI,WAAW,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QAC1C,IAAI,OAAO,WAAW,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YACjD,WAAW,CAAC,IAAI,CAAC;gBAChB,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,sDAAsD,WAAW,CAAC,UAAU,qBAAmB;gBACxG,IAAI,EAAE,QAAQ;aACd,CAAC,CAAC;QACJ,CAAC;aAAM,CAAC;YACP,UAAU,GAAG,WAAW,CAAC,UAAU,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;QACjE,CAAC;IACF,CAAC;IAED,4EAA4E;IAC5E,mEAAmE;IACnE,IAAI,IAAyB,CAAC;IAC9B,IAAI,WAAW,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QACpC,IAAI,OAAO,WAAW,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC3C,WAAW,CAAC,IAAI,CAAC;gBAChB,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,gDAAgD,WAAW,CAAC,IAAI,qBAAmB;gBAC5F,IAAI,EAAE,QAAQ;aACd,CAAC,CAAC;QACJ,CAAC;aAAM,CAAC;YACP,IAAI,GAAG,WAAW,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;QACrD,CAAC;IACF,CAAC;IAED,IAAI,QAA6B,CAAC;IAClC,IAAI,UAAgC,CAAC;IACrC,IAAI,WAAW,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,WAAW,CAAC,QAAQ,CAAC;QACnC,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACpB,QAAQ,GAAG,IAAI,CAAC;QACjB,CAAC;aAAM,IAAI,KAAK,KAAK,KAAK,EAAE,CAAC;YAC5B,QAAQ,GAAG,SAAS,CAAC;QACtB,CAAC;aAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9D,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;iBAC5D,KAAK,CAAC,GAAG,CAAC;iBACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;iBAClC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YACxC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACtB,QAAQ,GAAG,IAAI,CAAC;gBAChB,UAAU,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;YAClC,CAAC;iBAAM,CAAC;gBACP,WAAW,CAAC,IAAI,CAAC;oBAChB,IAAI,EAAE,SAAS;oBACf,OAAO,EAAE,kBAAkB,KAAK,oDAAkD;oBAClF,IAAI,EAAE,QAAQ;iBACd,CAAC,CAAC;YACJ,CAAC;QACF,CAAC;aAAM,CAAC;YACP,WAAW,CAAC,IAAI,CAAC;gBAChB,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,6DAA6D,KAAK,qBAAmB;gBAC9F,IAAI,EAAE,QAAQ;aACd,CAAC,CAAC;QACJ,CAAC;IACF,CAAC;IAED,OAAO;QACN,KAAK,EAAE;YACN,IAAI;YACJ,WAAW;YACX,KAAK;YACL,eAAe;YACf,KAAK;YACL,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE;YACnB,MAAM;YACN,QAAQ;YACR,QAAQ;YACR,UAAU;YACV,QAAQ;YACR,UAAU;YACV,IAAI;SACJ;QACD,WAAW;KACX,CAAC;AAAA,CACF","sourcesContent":["/**\n * Agent frontmatter: schema, validation, and Claude Code compatibility shim.\n *\n * Agent definitions are Markdown files with YAML frontmatter, mirroring the\n * Claude Code subagent format so `.claude/agents/*.md` files import natively:\n *\n * ---\n * name: explore\n * description: When and why to use this agent (drives auto-delegation).\n * tools: Read, Grep, Glob, Bash # optional allowlist; omit = inherit all\n * model: sonnet # optional; sonnet|opus|haiku|inherit|pattern\n * ---\n * <system prompt body>\n *\n * The body becomes the subagent system prompt. Validation is non-fatal: we emit\n * diagnostics (warnings) and still load the agent when possible, matching the\n * behavior of skills.ts.\n */\n\nimport { basename } from \"path\";\nimport { parseFrontmatter } from \"../utils/frontmatter.js\";\nimport type { ResourceDiagnostic } from \"./diagnostics.js\";\n\n/** Max name length, aligned with skills. */\nconst MAX_NAME_LENGTH = 64;\n\n/** Max description length, aligned with skills. */\nconst MAX_DESCRIPTION_LENGTH = 1024;\n\n/** Where an agent definition came from. Used for precedence and diagnostics. */\nexport type AgentSource = \"builtin\" | \"user\" | \"project\" | \"claude-user\" | \"claude-project\";\n\n/** Sentinel meaning \"use the parent session's model\" (Claude Code `model: inherit`). */\nexport const MODEL_INHERIT = \"inherit\";\n\n/**\n * The built-in hoocode tools that an agent's `tools` allowlist is normalized\n * against; unknown tools are dropped with a diagnostic. Includes the opt-in web\n * tools (webfetch/websearch) so Claude Code's WebFetch/WebSearch map through.\n */\nexport const HOOCODE_TOOL_NAMES: readonly string[] = [\n\t\"bash\",\n\t\"edit\",\n\t\"find\",\n\t\"grep\",\n\t\"ls\",\n\t\"read\",\n\t\"webfetch\",\n\t\"websearch\",\n\t\"write\",\n\t\"DocRead\",\n\t\"DocEdit\",\n\t\"DocWrite\",\n];\n\n/**\n * Canonical registered names of the two opt-in tools. These are case-sensitive\n * identifiers the system prompt and tool gating match exactly, so downstream\n * callers should reference these constants instead of hardcoding the strings\n * (a mis-cased `\"task\"` silently disables the agents/skills prompt sections).\n */\nexport const TASK_TOOL_NAME = \"Task\";\nexport const TODO_WRITE_TOOL_NAME = \"TodoWrite\";\n\n/**\n * D7 — Claude Code compatibility shim.\n *\n * Maps Claude Code tool names (case-insensitive) to their hoocode equivalents.\n * Claude tools without a hoocode counterpart (MultiEdit, Task, TodoWrite,\n * NotebookEdit, MCP tools, ...) are intentionally absent and get dropped during\n * normalization.\n */\nexport const CLAUDE_TOOL_ALIASES: Readonly<Record<string, string>> = {\n\tread: \"read\",\n\twrite: \"write\",\n\tedit: \"edit\",\n\tbash: \"bash\",\n\tgrep: \"grep\",\n\tglob: \"find\",\n\tfind: \"find\",\n\tls: \"ls\",\n\twebfetch: \"webfetch\",\n\twebsearch: \"websearch\",\n};\n\n/** Raw frontmatter shape before validation/normalization. */\nexport interface AgentFrontmatter {\n\tname?: string;\n\tdescription?: string;\n\t/** Claude Code uses a comma-separated string; a YAML list is also accepted. */\n\ttools?: string | string[];\n\t/** Tools to subtract from the agent's set (allow + deny), Claude Code compatible. */\n\tdisallowedTools?: string | string[];\n\t/** sonnet | opus | haiku | inherit | a model id/pattern. */\n\tmodel?: string;\n\t/** hoocode extension (not part of the Claude Code format): turn cap. */\n\tmaxTurns?: number;\n\t/** Claude Code extension: run this agent detached (non-blocking) so the parent polls for its result. */\n\tbackground?: boolean;\n\t/**\n\t * hoocode extension: opt a agent into delegating via the Task tool (subject to the\n\t * tree-wide nesting cap). `true` = any subagent type; a comma-separated string or\n\t * YAML list = only those types. Opt-in per agent so the deliberate \"Task is not a\n\t * normal tool\" boundary stays intact for everyone else.\n\t */\n\tdelegate?: boolean | string | string[];\n\t/**\n\t * When true, this agent inherits the parent's full conversation (a fork) instead\n\t * of starting from a fresh context, reusing the parent's prompt cache.\n\t */\n\tfork?: boolean;\n\t[key: string]: unknown;\n}\n\n/** A validated, normalized agent definition. */\nexport interface AgentDefinition {\n\tname: string;\n\tdescription: string;\n\t/**\n\t * Resolved hoocode tool allowlist. `undefined` means \"inherit all parent\n\t * tools\" (Claude Code behavior when `tools` is omitted).\n\t */\n\ttools?: string[];\n\t/** Resolved denylist subtracted from the agent's tool set. */\n\tdisallowedTools?: string[];\n\t/**\n\t * Model alias/pattern, the `inherit` sentinel, or `undefined` for the\n\t * subagent default.\n\t */\n\tmodel?: string;\n\t/** System prompt body (frontmatter stripped). */\n\tprompt: string;\n\t/** Origin of this definition. */\n\tsource: AgentSource;\n\t/** Absolute path of the source file, when loaded from disk. */\n\tfilePath?: string;\n\t/** hoocode extension: optional per-agent turn cap. */\n\tmaxTurns?: number;\n\t/** When true, dispatch is non-blocking: the parent receives a handle and polls for the result. */\n\tbackground?: boolean;\n\t/** When true, this agent may delegate via the Task tool, subject to the nesting cap. */\n\tdelegate?: boolean;\n\t/** Restricts delegation to these subagent types (undefined = any when `delegate` is true). */\n\tdelegateTo?: string[];\n\t/** When true, the agent inherits the parent's full conversation (a fork). */\n\tfork?: boolean;\n}\n\nconst KNOWN_MODEL_ALIASES = new Set([\"sonnet\", \"opus\", \"haiku\", \"inherit\", \"fast\", \"standard\", \"capable\"]);\n\n/** Validate an agent name. Returns warning messages (empty when valid). */\nfunction validateName(name: string): string[] {\n\tconst errors: string[] = [];\n\tif (!name) {\n\t\terrors.push(\"name is required\");\n\t\treturn errors;\n\t}\n\tif (name.length > MAX_NAME_LENGTH) {\n\t\terrors.push(`name exceeds ${MAX_NAME_LENGTH} characters (${name.length})`);\n\t}\n\tif (!/^[a-z0-9-]+$/.test(name)) {\n\t\terrors.push(\"name contains invalid characters (must be lowercase a-z, 0-9, hyphens only)\");\n\t}\n\tif (name.startsWith(\"-\") || name.endsWith(\"-\")) {\n\t\terrors.push(\"name must not start or end with a hyphen\");\n\t}\n\tif (name.includes(\"--\")) {\n\t\terrors.push(\"name must not contain consecutive hyphens\");\n\t}\n\treturn errors;\n}\n\n/** Validate a description. Returns warning messages (empty when valid). */\nfunction validateDescription(description: string | undefined): string[] {\n\tconst errors: string[] = [];\n\tif (!description || description.trim() === \"\") {\n\t\terrors.push(\"description is required\");\n\t} else if (description.length > MAX_DESCRIPTION_LENGTH) {\n\t\terrors.push(`description exceeds ${MAX_DESCRIPTION_LENGTH} characters (${description.length})`);\n\t}\n\treturn errors;\n}\n\nfunction validateModel(value: string): string[] {\n\tconst trimmed = value.trim();\n\tif (!trimmed) return [];\n\tif (KNOWN_MODEL_ALIASES.has(trimmed)) return [];\n\tif (/^claude-/.test(trimmed)) return [];\n\treturn [\n\t\t`model \"${trimmed}\" is not a recognized alias (sonnet | opus | haiku | inherit | fast | standard | capable) or full model ID; the agent may not load correctly`,\n\t];\n}\n\n/** Split a `tools` frontmatter value (string or list) into raw token names. */\nfunction splitToolsValue(value: string | string[]): string[] {\n\tconst tokens = Array.isArray(value) ? value : value.split(\",\");\n\treturn tokens.map((t) => t.trim()).filter((t) => t.length > 0);\n}\n\n/**\n * Normalize a raw `tools` allowlist into hoocode tool names via the Claude Code\n * alias map. Returns the deduped, resolved list plus diagnostics for any tokens\n * that could not be mapped.\n *\n * Emits a warning when `value` is a YAML list rather than a comma-separated\n * string — the Claude Code standard format is `tools: read, bash` (string).\n */\nexport function normalizeTools(\n\tvalue: string | string[],\n\tfilePath?: string,\n): { tools: string[]; diagnostics: ResourceDiagnostic[] } {\n\tconst diagnostics: ResourceDiagnostic[] = [];\n\tif (Array.isArray(value)) {\n\t\tdiagnostics.push({\n\t\t\ttype: \"warning\",\n\t\t\tmessage:\n\t\t\t\t'tools: use a comma-separated string (\"tools: read, bash\") instead of a YAML list for Claude Code compatibility',\n\t\t\tpath: filePath,\n\t\t});\n\t}\n\tconst resolved: string[] = [];\n\tfor (const raw of splitToolsValue(value)) {\n\t\tconst mapped = CLAUDE_TOOL_ALIASES[raw.toLowerCase()];\n\t\tif (!mapped) {\n\t\t\tdiagnostics.push({\n\t\t\t\ttype: \"warning\",\n\t\t\t\tmessage: `tool \"${raw}\" has no hoocode equivalent and was dropped from the allowlist`,\n\t\t\t\tpath: filePath,\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\t\tif (!resolved.includes(mapped)) {\n\t\t\tresolved.push(mapped);\n\t\t}\n\t}\n\treturn { tools: resolved, diagnostics };\n}\n\n/**\n * Normalize a `model` frontmatter value. `inherit` is preserved as a sentinel;\n * any other non-empty string is passed through to the model resolver as-is\n * (so Claude aliases like `sonnet`/`opus`/`haiku` resolve via pattern match).\n */\nexport function normalizeModel(value: string | undefined): string | undefined {\n\tif (typeof value !== \"string\") return undefined;\n\tconst trimmed = value.trim();\n\tif (!trimmed) return undefined;\n\treturn trimmed;\n}\n\n/**\n * Parse and validate a single agent definition from raw Markdown content.\n *\n * `fallbackName` is used when frontmatter omits `name` (e.g. the filename, or\n * the embedded-template key). Returns `agent: null` only when the definition\n * is unusable (missing description). Other problems surface as diagnostics.\n */\nexport function parseAgentDefinition(\n\trawContent: string,\n\toptions: { source: AgentSource; filePath?: string; fallbackName?: string },\n): { agent: AgentDefinition | null; diagnostics: ResourceDiagnostic[] } {\n\tconst { source, filePath } = options;\n\tconst diagnostics: ResourceDiagnostic[] = [];\n\n\tlet frontmatter: AgentFrontmatter;\n\tlet body: string;\n\ttry {\n\t\tconst parsed = parseFrontmatter<AgentFrontmatter>(rawContent);\n\t\tfrontmatter = parsed.frontmatter;\n\t\tbody = parsed.body;\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : \"failed to parse agent frontmatter\";\n\t\tdiagnostics.push({ type: \"warning\", message, path: filePath });\n\t\treturn { agent: null, diagnostics };\n\t}\n\n\tconst fallbackName = options.fallbackName ?? (filePath ? basename(filePath, \".md\") : \"\");\n\tconst name = (frontmatter.name ?? fallbackName).trim();\n\n\tfor (const error of validateName(name)) {\n\t\tdiagnostics.push({ type: \"warning\", message: error, path: filePath });\n\t}\n\n\tconst description = typeof frontmatter.description === \"string\" ? frontmatter.description.trim() : \"\";\n\tfor (const error of validateDescription(description)) {\n\t\tdiagnostics.push({ type: \"warning\", message: error, path: filePath });\n\t}\n\n\t// Description is mandatory: it drives delegation. Without it the agent is unusable.\n\tif (!description) {\n\t\treturn { agent: null, diagnostics };\n\t}\n\t// A usable name is required as the registry key.\n\tif (!name || !/^[a-z0-9-]+$/.test(name)) {\n\t\treturn { agent: null, diagnostics };\n\t}\n\n\tlet tools: string[] | undefined;\n\tif (frontmatter.tools !== undefined) {\n\t\tconst normalized = normalizeTools(frontmatter.tools, filePath);\n\t\tdiagnostics.push(...normalized.diagnostics);\n\t\ttools = normalized.tools;\n\t}\n\n\tlet disallowedTools: string[] | undefined;\n\tif (frontmatter.disallowedTools !== undefined) {\n\t\tconst normalized = normalizeTools(frontmatter.disallowedTools, filePath);\n\t\tdiagnostics.push(...normalized.diagnostics);\n\t\tdisallowedTools = normalized.tools.length > 0 ? normalized.tools : undefined;\n\t}\n\n\tconst model = normalizeModel(frontmatter.model);\n\tif (model !== undefined) {\n\t\tfor (const error of validateModel(model)) {\n\t\t\tdiagnostics.push({ type: \"warning\", message: error, path: filePath });\n\t\t}\n\t}\n\n\tconst maxTurns =\n\t\ttypeof frontmatter.maxTurns === \"number\" && Number.isInteger(frontmatter.maxTurns) && frontmatter.maxTurns > 0\n\t\t\t? frontmatter.maxTurns\n\t\t\t: undefined;\n\n\tlet background: boolean | undefined;\n\tif (frontmatter.background !== undefined) {\n\t\tif (typeof frontmatter.background !== \"boolean\") {\n\t\t\tdiagnostics.push({\n\t\t\t\ttype: \"warning\",\n\t\t\t\tmessage: `background must be a boolean (true or false), got \"${frontmatter.background}\" — field ignored`,\n\t\t\t\tpath: filePath,\n\t\t\t});\n\t\t} else {\n\t\t\tbackground = frontmatter.background === true ? true : undefined;\n\t\t}\n\t}\n\n\t// `delegate` accepts a boolean (delegate to any agent) or a comma-separated\n\t// string / YAML list of agent type names (delegate only to those).\n\tlet fork: boolean | undefined;\n\tif (frontmatter.fork !== undefined) {\n\t\tif (typeof frontmatter.fork !== \"boolean\") {\n\t\t\tdiagnostics.push({\n\t\t\t\ttype: \"warning\",\n\t\t\t\tmessage: `fork must be a boolean (true or false), got \"${frontmatter.fork}\" — field ignored`,\n\t\t\t\tpath: filePath,\n\t\t\t});\n\t\t} else {\n\t\t\tfork = frontmatter.fork === true ? true : undefined;\n\t\t}\n\t}\n\n\tlet delegate: boolean | undefined;\n\tlet delegateTo: string[] | undefined;\n\tif (frontmatter.delegate !== undefined) {\n\t\tconst value = frontmatter.delegate;\n\t\tif (value === true) {\n\t\t\tdelegate = true;\n\t\t} else if (value === false) {\n\t\t\tdelegate = undefined;\n\t\t} else if (typeof value === \"string\" || Array.isArray(value)) {\n\t\t\tconst names = (Array.isArray(value) ? value.join(\",\") : value)\n\t\t\t\t.split(\",\")\n\t\t\t\t.map((s) => s.trim().toLowerCase())\n\t\t\t\t.filter((s) => /^[a-z0-9-]+$/.test(s));\n\t\t\tif (names.length > 0) {\n\t\t\t\tdelegate = true;\n\t\t\t\tdelegateTo = [...new Set(names)];\n\t\t\t} else {\n\t\t\t\tdiagnostics.push({\n\t\t\t\t\ttype: \"warning\",\n\t\t\t\t\tmessage: `delegate list \"${value}\" contained no valid agent names — field ignored`,\n\t\t\t\t\tpath: filePath,\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\tdiagnostics.push({\n\t\t\t\ttype: \"warning\",\n\t\t\t\tmessage: `delegate must be a boolean or a list of agent names, got \"${value}\" — field ignored`,\n\t\t\t\tpath: filePath,\n\t\t\t});\n\t\t}\n\t}\n\n\treturn {\n\t\tagent: {\n\t\t\tname,\n\t\t\tdescription,\n\t\t\ttools,\n\t\t\tdisallowedTools,\n\t\t\tmodel,\n\t\t\tprompt: body.trim(),\n\t\t\tsource,\n\t\t\tfilePath,\n\t\t\tmaxTurns,\n\t\t\tbackground,\n\t\t\tdelegate,\n\t\t\tdelegateTo,\n\t\t\tfork,\n\t\t},\n\t\tdiagnostics,\n\t};\n}\n"]}
@@ -54,6 +54,7 @@ export interface CreateAgentSessionFromServicesOptions {
54
54
  noTools?: CreateAgentSessionOptions["noTools"];
55
55
  customTools?: ToolDefinition[];
56
56
  enableWebTools?: boolean;
57
+ enableFileTools?: boolean;
57
58
  }
58
59
  /**
59
60
  * Coherent cwd-bound runtime services for one effective session cwd.