@humain/terminal 0.0.3-beta.2 → 0.0.4-beta.1

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 (136) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/bun/cli.d.ts.map +1 -1
  3. package/dist/bun/cli.js +0 -1
  4. package/dist/bun/cli.js.map +1 -1
  5. package/dist/core/agent-session.d.ts.map +1 -1
  6. package/dist/core/agent-session.js +7 -1
  7. package/dist/core/agent-session.js.map +1 -1
  8. package/dist/core/sdk.d.ts.map +1 -1
  9. package/dist/core/sdk.js +1 -1
  10. package/dist/core/sdk.js.map +1 -1
  11. package/dist/core/session-manager.d.ts +4 -0
  12. package/dist/core/session-manager.d.ts.map +1 -1
  13. package/dist/core/session-manager.js +46 -22
  14. package/dist/core/session-manager.js.map +1 -1
  15. package/dist/core/tools/index.d.ts +2 -1
  16. package/dist/core/tools/index.d.ts.map +1 -1
  17. package/dist/core/tools/index.js +9 -1
  18. package/dist/core/tools/index.js.map +1 -1
  19. package/dist/core/tools/subagent.d.ts +82 -0
  20. package/dist/core/tools/subagent.d.ts.map +1 -0
  21. package/dist/core/tools/subagent.js +980 -0
  22. package/dist/core/tools/subagent.js.map +1 -0
  23. package/dist/humain/bedrock-provider/vendor/index.bundle.d.mts +3 -0
  24. package/dist/humain/bedrock-provider/vendor/index.bundle.mjs +1509 -0
  25. package/dist/humain/index.d.ts.map +1 -1
  26. package/dist/humain/index.js +3 -0
  27. package/dist/humain/index.js.map +1 -1
  28. package/dist/humain/mcp-adapter/vendor/CHANGELOG.md +36 -0
  29. package/dist/humain/mcp-adapter/vendor/README.md +47 -5
  30. package/dist/humain/mcp-adapter/vendor/cli.js +163 -1
  31. package/dist/humain/mcp-adapter/vendor/commands.ts +128 -22
  32. package/dist/humain/mcp-adapter/vendor/config.ts +25 -7
  33. package/dist/humain/mcp-adapter/vendor/direct-tools.ts +5 -4
  34. package/dist/humain/mcp-adapter/vendor/index.bundle.mjs +1663 -458
  35. package/dist/humain/mcp-adapter/vendor/index.ts +219 -32
  36. package/dist/humain/mcp-adapter/vendor/init.ts +36 -4
  37. package/dist/humain/mcp-adapter/vendor/lifecycle.ts +315 -24
  38. package/dist/humain/mcp-adapter/vendor/mcp-auth-flow.ts +39 -6
  39. package/dist/humain/mcp-adapter/vendor/mcp-bearer-store.ts +387 -0
  40. package/dist/humain/mcp-adapter/vendor/mcp-callback-server.ts +27 -3
  41. package/dist/humain/mcp-adapter/vendor/mcp-code.ts +4 -0
  42. package/dist/humain/mcp-adapter/vendor/mcp-panel.ts +42 -13
  43. package/dist/humain/mcp-adapter/vendor/metadata-cache.ts +32 -21
  44. package/dist/humain/mcp-adapter/vendor/package-mcp-loader.ts +168 -0
  45. package/dist/humain/mcp-adapter/vendor/package.json +179 -177
  46. package/dist/humain/mcp-adapter/vendor/proxy-modes.ts +5 -4
  47. package/dist/humain/mcp-adapter/vendor/request-headers-command.ts +31 -37
  48. package/dist/humain/mcp-adapter/vendor/search-ranking.ts +92 -22
  49. package/dist/humain/mcp-adapter/vendor/server-manager.ts +140 -2
  50. package/dist/humain/mcp-adapter/vendor/session-recovery.ts +7 -0
  51. package/dist/humain/mcp-adapter/vendor/tool-approval.ts +15 -2
  52. package/dist/humain/mcp-adapter/vendor/tool-result-renderer.ts +44 -4
  53. package/dist/humain/mcp-adapter/vendor/types.ts +2 -0
  54. package/dist/humain/mcp-adapter/vendor/ui-server.ts +18 -16
  55. package/dist/humain/mcp-adapter/vendor/utils.ts +70 -0
  56. package/dist/humain/web-access/vendor/anysearch.d.ts.map +1 -1
  57. package/dist/humain/web-access/vendor/anysearch.js +3 -2
  58. package/dist/humain/web-access/vendor/anysearch.js.map +1 -1
  59. package/dist/humain/web-access/vendor/brave.d.ts.map +1 -1
  60. package/dist/humain/web-access/vendor/brave.js +14 -4
  61. package/dist/humain/web-access/vendor/brave.js.map +1 -1
  62. package/dist/humain/web-access/vendor/curator-page.d.ts +3 -0
  63. package/dist/humain/web-access/vendor/curator-page.d.ts.map +1 -1
  64. package/dist/humain/web-access/vendor/curator-page.js +4 -1
  65. package/dist/humain/web-access/vendor/curator-page.js.map +1 -1
  66. package/dist/humain/web-access/vendor/curator-server.d.ts +3 -0
  67. package/dist/humain/web-access/vendor/curator-server.d.ts.map +1 -1
  68. package/dist/humain/web-access/vendor/curator-server.js +6 -0
  69. package/dist/humain/web-access/vendor/curator-server.js.map +1 -1
  70. package/dist/humain/web-access/vendor/exa.d.ts.map +1 -1
  71. package/dist/humain/web-access/vendor/exa.js +16 -7
  72. package/dist/humain/web-access/vendor/exa.js.map +1 -1
  73. package/dist/humain/web-access/vendor/extract.d.ts.map +1 -1
  74. package/dist/humain/web-access/vendor/extract.js +31 -3
  75. package/dist/humain/web-access/vendor/extract.js.map +1 -1
  76. package/dist/humain/web-access/vendor/gemini-search.d.ts +2 -2
  77. package/dist/humain/web-access/vendor/gemini-search.d.ts.map +1 -1
  78. package/dist/humain/web-access/vendor/gemini-search.js +25 -4
  79. package/dist/humain/web-access/vendor/gemini-search.js.map +1 -1
  80. package/dist/humain/web-access/vendor/index.d.ts.map +1 -1
  81. package/dist/humain/web-access/vendor/index.js +36 -49
  82. package/dist/humain/web-access/vendor/index.js.map +1 -1
  83. package/dist/humain/web-access/vendor/page-query.d.ts +1 -2
  84. package/dist/humain/web-access/vendor/page-query.d.ts.map +1 -1
  85. package/dist/humain/web-access/vendor/page-query.js +5 -2
  86. package/dist/humain/web-access/vendor/page-query.js.map +1 -1
  87. package/dist/humain/web-access/vendor/parallel-mcp.d.ts +10 -0
  88. package/dist/humain/web-access/vendor/parallel-mcp.d.ts.map +1 -0
  89. package/dist/humain/web-access/vendor/parallel-mcp.js +224 -0
  90. package/dist/humain/web-access/vendor/parallel-mcp.js.map +1 -0
  91. package/dist/humain/web-access/vendor/parallel.d.ts +1 -0
  92. package/dist/humain/web-access/vendor/parallel.d.ts.map +1 -1
  93. package/dist/humain/web-access/vendor/parallel.js +2 -2
  94. package/dist/humain/web-access/vendor/parallel.js.map +1 -1
  95. package/dist/humain/web-access/vendor/query-rewrite.d.ts +3 -0
  96. package/dist/humain/web-access/vendor/query-rewrite.d.ts.map +1 -0
  97. package/dist/humain/web-access/vendor/query-rewrite.js +42 -0
  98. package/dist/humain/web-access/vendor/query-rewrite.js.map +1 -0
  99. package/dist/humain/web-access/vendor/serper.d.ts +4 -0
  100. package/dist/humain/web-access/vendor/serper.d.ts.map +1 -0
  101. package/dist/humain/web-access/vendor/serper.js +206 -0
  102. package/dist/humain/web-access/vendor/serper.js.map +1 -0
  103. package/dist/humain/web-access/vendor/summary-model-scope.d.ts +5 -0
  104. package/dist/humain/web-access/vendor/summary-model-scope.d.ts.map +1 -1
  105. package/dist/humain/web-access/vendor/summary-model-scope.js +10 -5
  106. package/dist/humain/web-access/vendor/summary-model-scope.js.map +1 -1
  107. package/dist/humain/web-access/vendor/summary-review.d.ts.map +1 -1
  108. package/dist/humain/web-access/vendor/summary-review.js +40 -14
  109. package/dist/humain/web-access/vendor/summary-review.js.map +1 -1
  110. package/dist/humain/web-access/vendor/tavily.d.ts.map +1 -1
  111. package/dist/humain/web-access/vendor/tavily.js +14 -4
  112. package/dist/humain/web-access/vendor/tavily.js.map +1 -1
  113. package/dist/humain/web-access/vendor/utils.d.ts +10 -0
  114. package/dist/humain/web-access/vendor/utils.d.ts.map +1 -1
  115. package/dist/humain/web-access/vendor/utils.js +70 -0
  116. package/dist/humain/web-access/vendor/utils.js.map +1 -1
  117. package/dist/humain/web-access/vendor/valyu.d.ts +6 -0
  118. package/dist/humain/web-access/vendor/valyu.d.ts.map +1 -0
  119. package/dist/humain/web-access/vendor/valyu.js +194 -0
  120. package/dist/humain/web-access/vendor/valyu.js.map +1 -0
  121. package/docs/extensions.md +1 -1
  122. package/examples/extensions/README.md +1 -1
  123. package/examples/extensions/subagent/README.md +24 -147
  124. package/npm-shrinkwrap.json +7 -2
  125. package/package.json +7 -2
  126. package/src/humain/mcp-adapter/UPSTREAM.md +1 -1
  127. package/src/humain/mcp-adapter/upstream.json +3 -3
  128. package/src/humain/mcp-adapter/vendor/CHANGELOG.md +36 -0
  129. package/src/humain/web-access/UPSTREAM.md +1 -1
  130. package/src/humain/web-access/upstream.json +4 -4
  131. package/dist/bun/register-bedrock.d.ts +0 -2
  132. package/dist/bun/register-bedrock.d.ts.map +0 -1
  133. package/dist/bun/register-bedrock.js +0 -4
  134. package/dist/bun/register-bedrock.js.map +0 -1
  135. package/examples/extensions/subagent/agents.ts +0 -126
  136. package/examples/extensions/subagent/index.ts +0 -1015
@@ -5,6 +5,7 @@ export { createFindTool, createFindToolDefinition, type FindOperations, type Fin
5
5
  export { createGrepTool, createGrepToolDefinition, type GrepOperations, type GrepToolDetails, type GrepToolInput, type GrepToolOptions, } from "./grep.ts";
6
6
  export { createLsTool, createLsToolDefinition, type LsOperations, type LsToolDetails, type LsToolInput, type LsToolOptions, } from "./ls.ts";
7
7
  export { createReadTool, createReadToolDefinition, type ReadOperations, type ReadToolDetails, type ReadToolInput, type ReadToolOptions, } from "./read.ts";
8
+ export { type AgentConfig, type AgentDiscoveryResult, type AgentScope, createSubagentTool, createSubagentToolDefinition, discoverAgents, SUBAGENT_DEPTH_ENV, type SubagentDetails, type SubagentSingleResult, type SubagentUsageStats, } from "./subagent.ts";
8
9
  export { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, formatSize, type TruncationOptions, type TruncationResult, truncateHead, truncateLine, truncateTail, } from "./truncate.ts";
9
10
  export { createWriteTool, createWriteToolDefinition, type WriteOperations, type WriteToolInput, type WriteToolOptions, } from "./write.ts";
10
11
  import type { AgentTool } from "@earendil-works/pi-agent-core";
@@ -18,7 +19,7 @@ import { type ReadToolOptions } from "./read.ts";
18
19
  import { type WriteToolOptions } from "./write.ts";
19
20
  export type Tool = AgentTool<any>;
20
21
  export type ToolDef = ToolDefinition<any, any>;
21
- export type ToolName = "read" | "bash" | "edit" | "write" | "grep" | "find" | "ls";
22
+ export type ToolName = "read" | "bash" | "edit" | "write" | "grep" | "find" | "ls" | "subagent";
22
23
  export declare const allToolNames: Set<ToolName>;
23
24
  export interface ToolsOptions {
24
25
  read?: ReadToolOptions;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/tools/index.ts"],"names":[],"mappings":"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","sourcesContent":["export {\n\ttype BashOperations,\n\ttype BashSpawnContext,\n\ttype BashSpawnHook,\n\ttype BashToolDetails,\n\ttype BashToolInput,\n\ttype BashToolOptions,\n\tcreateBashTool,\n\tcreateBashToolDefinition,\n\tcreateLocalBashOperations,\n} from \"./bash.ts\";\nexport {\n\tcreateEditTool,\n\tcreateEditToolDefinition,\n\ttype EditOperations,\n\ttype EditToolDetails,\n\ttype EditToolInput,\n\ttype EditToolOptions,\n} from \"./edit.ts\";\nexport { withFileMutationQueue } from \"./file-mutation-queue.ts\";\nexport {\n\tcreateFindTool,\n\tcreateFindToolDefinition,\n\ttype FindOperations,\n\ttype FindToolDetails,\n\ttype FindToolInput,\n\ttype FindToolOptions,\n} from \"./find.ts\";\nexport {\n\tcreateGrepTool,\n\tcreateGrepToolDefinition,\n\ttype GrepOperations,\n\ttype GrepToolDetails,\n\ttype GrepToolInput,\n\ttype GrepToolOptions,\n} from \"./grep.ts\";\nexport {\n\tcreateLsTool,\n\tcreateLsToolDefinition,\n\ttype LsOperations,\n\ttype LsToolDetails,\n\ttype LsToolInput,\n\ttype LsToolOptions,\n} from \"./ls.ts\";\nexport {\n\tcreateReadTool,\n\tcreateReadToolDefinition,\n\ttype ReadOperations,\n\ttype ReadToolDetails,\n\ttype ReadToolInput,\n\ttype ReadToolOptions,\n} from \"./read.ts\";\nexport {\n\tDEFAULT_MAX_BYTES,\n\tDEFAULT_MAX_LINES,\n\tformatSize,\n\ttype TruncationOptions,\n\ttype TruncationResult,\n\ttruncateHead,\n\ttruncateLine,\n\ttruncateTail,\n} from \"./truncate.ts\";\nexport {\n\tcreateWriteTool,\n\tcreateWriteToolDefinition,\n\ttype WriteOperations,\n\ttype WriteToolInput,\n\ttype WriteToolOptions,\n} from \"./write.ts\";\n\nimport type { AgentTool } from \"@earendil-works/pi-agent-core\";\nimport type { ToolDefinition } from \"../extensions/types.ts\";\nimport { type BashToolOptions, createBashTool, createBashToolDefinition } from \"./bash.ts\";\nimport { createEditTool, createEditToolDefinition, type EditToolOptions } from \"./edit.ts\";\nimport { createFindTool, createFindToolDefinition, type FindToolOptions } from \"./find.ts\";\nimport { createGrepTool, createGrepToolDefinition, type GrepToolOptions } from \"./grep.ts\";\nimport { createLsTool, createLsToolDefinition, type LsToolOptions } from \"./ls.ts\";\nimport { createReadTool, createReadToolDefinition, type ReadToolOptions } from \"./read.ts\";\nimport { createWriteTool, createWriteToolDefinition, type WriteToolOptions } from \"./write.ts\";\n\nexport type Tool = AgentTool<any>;\nexport type ToolDef = ToolDefinition<any, any>;\nexport type ToolName = \"read\" | \"bash\" | \"edit\" | \"write\" | \"grep\" | \"find\" | \"ls\";\nexport const allToolNames: Set<ToolName> = new Set([\"read\", \"bash\", \"edit\", \"write\", \"grep\", \"find\", \"ls\"]);\n\nexport interface ToolsOptions {\n\tread?: ReadToolOptions;\n\tbash?: BashToolOptions;\n\twrite?: WriteToolOptions;\n\tedit?: EditToolOptions;\n\tgrep?: GrepToolOptions;\n\tfind?: FindToolOptions;\n\tls?: LsToolOptions;\n}\n\nexport function createToolDefinition(toolName: ToolName, cwd: string, options?: ToolsOptions): ToolDef {\n\tswitch (toolName) {\n\t\tcase \"read\":\n\t\t\treturn createReadToolDefinition(cwd, options?.read);\n\t\tcase \"bash\":\n\t\t\treturn createBashToolDefinition(cwd, options?.bash);\n\t\tcase \"edit\":\n\t\t\treturn createEditToolDefinition(cwd, options?.edit);\n\t\tcase \"write\":\n\t\t\treturn createWriteToolDefinition(cwd, options?.write);\n\t\tcase \"grep\":\n\t\t\treturn createGrepToolDefinition(cwd, options?.grep);\n\t\tcase \"find\":\n\t\t\treturn createFindToolDefinition(cwd, options?.find);\n\t\tcase \"ls\":\n\t\t\treturn createLsToolDefinition(cwd, options?.ls);\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown tool name: ${toolName}`);\n\t}\n}\n\nexport function createTool(toolName: ToolName, cwd: string, options?: ToolsOptions): Tool {\n\tswitch (toolName) {\n\t\tcase \"read\":\n\t\t\treturn createReadTool(cwd, options?.read);\n\t\tcase \"bash\":\n\t\t\treturn createBashTool(cwd, options?.bash);\n\t\tcase \"edit\":\n\t\t\treturn createEditTool(cwd, options?.edit);\n\t\tcase \"write\":\n\t\t\treturn createWriteTool(cwd, options?.write);\n\t\tcase \"grep\":\n\t\t\treturn createGrepTool(cwd, options?.grep);\n\t\tcase \"find\":\n\t\t\treturn createFindTool(cwd, options?.find);\n\t\tcase \"ls\":\n\t\t\treturn createLsTool(cwd, options?.ls);\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown tool name: ${toolName}`);\n\t}\n}\n\nexport function createCodingToolDefinitions(cwd: string, options?: ToolsOptions): ToolDef[] {\n\treturn [\n\t\tcreateReadToolDefinition(cwd, options?.read),\n\t\tcreateBashToolDefinition(cwd, options?.bash),\n\t\tcreateEditToolDefinition(cwd, options?.edit),\n\t\tcreateWriteToolDefinition(cwd, options?.write),\n\t];\n}\n\nexport function createReadOnlyToolDefinitions(cwd: string, options?: ToolsOptions): ToolDef[] {\n\treturn [\n\t\tcreateReadToolDefinition(cwd, options?.read),\n\t\tcreateGrepToolDefinition(cwd, options?.grep),\n\t\tcreateFindToolDefinition(cwd, options?.find),\n\t\tcreateLsToolDefinition(cwd, options?.ls),\n\t];\n}\n\nexport function createAllToolDefinitions(cwd: string, options?: ToolsOptions): Record<ToolName, ToolDef> {\n\treturn {\n\t\tread: createReadToolDefinition(cwd, options?.read),\n\t\tbash: createBashToolDefinition(cwd, options?.bash),\n\t\tedit: createEditToolDefinition(cwd, options?.edit),\n\t\twrite: createWriteToolDefinition(cwd, options?.write),\n\t\tgrep: createGrepToolDefinition(cwd, options?.grep),\n\t\tfind: createFindToolDefinition(cwd, options?.find),\n\t\tls: createLsToolDefinition(cwd, options?.ls),\n\t};\n}\n\nexport function createCodingTools(cwd: string, options?: ToolsOptions): Tool[] {\n\treturn [\n\t\tcreateReadTool(cwd, options?.read),\n\t\tcreateBashTool(cwd, options?.bash),\n\t\tcreateEditTool(cwd, options?.edit),\n\t\tcreateWriteTool(cwd, options?.write),\n\t];\n}\n\nexport function createReadOnlyTools(cwd: string, options?: ToolsOptions): Tool[] {\n\treturn [\n\t\tcreateReadTool(cwd, options?.read),\n\t\tcreateGrepTool(cwd, options?.grep),\n\t\tcreateFindTool(cwd, options?.find),\n\t\tcreateLsTool(cwd, options?.ls),\n\t];\n}\n\nexport function createAllTools(cwd: string, options?: ToolsOptions): Record<ToolName, Tool> {\n\treturn {\n\t\tread: createReadTool(cwd, options?.read),\n\t\tbash: createBashTool(cwd, options?.bash),\n\t\tedit: createEditTool(cwd, options?.edit),\n\t\twrite: createWriteTool(cwd, options?.write),\n\t\tgrep: createGrepTool(cwd, options?.grep),\n\t\tfind: createFindTool(cwd, options?.find),\n\t\tls: createLsTool(cwd, options?.ls),\n\t};\n}\n"]}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/tools/index.ts"],"names":[],"mappings":"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","sourcesContent":["export {\n\ttype BashOperations,\n\ttype BashSpawnContext,\n\ttype BashSpawnHook,\n\ttype BashToolDetails,\n\ttype BashToolInput,\n\ttype BashToolOptions,\n\tcreateBashTool,\n\tcreateBashToolDefinition,\n\tcreateLocalBashOperations,\n} from \"./bash.ts\";\nexport {\n\tcreateEditTool,\n\tcreateEditToolDefinition,\n\ttype EditOperations,\n\ttype EditToolDetails,\n\ttype EditToolInput,\n\ttype EditToolOptions,\n} from \"./edit.ts\";\nexport { withFileMutationQueue } from \"./file-mutation-queue.ts\";\nexport {\n\tcreateFindTool,\n\tcreateFindToolDefinition,\n\ttype FindOperations,\n\ttype FindToolDetails,\n\ttype FindToolInput,\n\ttype FindToolOptions,\n} from \"./find.ts\";\nexport {\n\tcreateGrepTool,\n\tcreateGrepToolDefinition,\n\ttype GrepOperations,\n\ttype GrepToolDetails,\n\ttype GrepToolInput,\n\ttype GrepToolOptions,\n} from \"./grep.ts\";\nexport {\n\tcreateLsTool,\n\tcreateLsToolDefinition,\n\ttype LsOperations,\n\ttype LsToolDetails,\n\ttype LsToolInput,\n\ttype LsToolOptions,\n} from \"./ls.ts\";\nexport {\n\tcreateReadTool,\n\tcreateReadToolDefinition,\n\ttype ReadOperations,\n\ttype ReadToolDetails,\n\ttype ReadToolInput,\n\ttype ReadToolOptions,\n} from \"./read.ts\";\nexport {\n\ttype AgentConfig,\n\ttype AgentDiscoveryResult,\n\ttype AgentScope,\n\tcreateSubagentTool,\n\tcreateSubagentToolDefinition,\n\tdiscoverAgents,\n\tSUBAGENT_DEPTH_ENV,\n\ttype SubagentDetails,\n\ttype SubagentSingleResult,\n\ttype SubagentUsageStats,\n} from \"./subagent.ts\";\nexport {\n\tDEFAULT_MAX_BYTES,\n\tDEFAULT_MAX_LINES,\n\tformatSize,\n\ttype TruncationOptions,\n\ttype TruncationResult,\n\ttruncateHead,\n\ttruncateLine,\n\ttruncateTail,\n} from \"./truncate.ts\";\nexport {\n\tcreateWriteTool,\n\tcreateWriteToolDefinition,\n\ttype WriteOperations,\n\ttype WriteToolInput,\n\ttype WriteToolOptions,\n} from \"./write.ts\";\n\nimport type { AgentTool } from \"@earendil-works/pi-agent-core\";\nimport type { ToolDefinition } from \"../extensions/types.ts\";\nimport { type BashToolOptions, createBashTool, createBashToolDefinition } from \"./bash.ts\";\nimport { createEditTool, createEditToolDefinition, type EditToolOptions } from \"./edit.ts\";\nimport { createFindTool, createFindToolDefinition, type FindToolOptions } from \"./find.ts\";\nimport { createGrepTool, createGrepToolDefinition, type GrepToolOptions } from \"./grep.ts\";\nimport { createLsTool, createLsToolDefinition, type LsToolOptions } from \"./ls.ts\";\nimport { createReadTool, createReadToolDefinition, type ReadToolOptions } from \"./read.ts\";\nimport { createSubagentTool, createSubagentToolDefinition } from \"./subagent.ts\";\nimport { createWriteTool, createWriteToolDefinition, type WriteToolOptions } from \"./write.ts\";\n\nexport type Tool = AgentTool<any>;\nexport type ToolDef = ToolDefinition<any, any>;\nexport type ToolName = \"read\" | \"bash\" | \"edit\" | \"write\" | \"grep\" | \"find\" | \"ls\" | \"subagent\";\nexport const allToolNames: Set<ToolName> = new Set([\"read\", \"bash\", \"edit\", \"write\", \"grep\", \"find\", \"ls\", \"subagent\"]);\n\nexport interface ToolsOptions {\n\tread?: ReadToolOptions;\n\tbash?: BashToolOptions;\n\twrite?: WriteToolOptions;\n\tedit?: EditToolOptions;\n\tgrep?: GrepToolOptions;\n\tfind?: FindToolOptions;\n\tls?: LsToolOptions;\n}\n\nexport function createToolDefinition(toolName: ToolName, cwd: string, options?: ToolsOptions): ToolDef {\n\tswitch (toolName) {\n\t\tcase \"read\":\n\t\t\treturn createReadToolDefinition(cwd, options?.read);\n\t\tcase \"bash\":\n\t\t\treturn createBashToolDefinition(cwd, options?.bash);\n\t\tcase \"edit\":\n\t\t\treturn createEditToolDefinition(cwd, options?.edit);\n\t\tcase \"write\":\n\t\t\treturn createWriteToolDefinition(cwd, options?.write);\n\t\tcase \"grep\":\n\t\t\treturn createGrepToolDefinition(cwd, options?.grep);\n\t\tcase \"find\":\n\t\t\treturn createFindToolDefinition(cwd, options?.find);\n\t\tcase \"ls\":\n\t\t\treturn createLsToolDefinition(cwd, options?.ls);\n\t\tcase \"subagent\":\n\t\t\treturn createSubagentToolDefinition(cwd);\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown tool name: ${toolName}`);\n\t}\n}\n\nexport function createTool(toolName: ToolName, cwd: string, options?: ToolsOptions): Tool {\n\tswitch (toolName) {\n\t\tcase \"read\":\n\t\t\treturn createReadTool(cwd, options?.read);\n\t\tcase \"bash\":\n\t\t\treturn createBashTool(cwd, options?.bash);\n\t\tcase \"edit\":\n\t\t\treturn createEditTool(cwd, options?.edit);\n\t\tcase \"write\":\n\t\t\treturn createWriteTool(cwd, options?.write);\n\t\tcase \"grep\":\n\t\t\treturn createGrepTool(cwd, options?.grep);\n\t\tcase \"find\":\n\t\t\treturn createFindTool(cwd, options?.find);\n\t\tcase \"ls\":\n\t\t\treturn createLsTool(cwd, options?.ls);\n\t\tcase \"subagent\":\n\t\t\treturn createSubagentTool(cwd);\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown tool name: ${toolName}`);\n\t}\n}\n\nexport function createCodingToolDefinitions(cwd: string, options?: ToolsOptions): ToolDef[] {\n\treturn [\n\t\tcreateReadToolDefinition(cwd, options?.read),\n\t\tcreateBashToolDefinition(cwd, options?.bash),\n\t\tcreateEditToolDefinition(cwd, options?.edit),\n\t\tcreateWriteToolDefinition(cwd, options?.write),\n\t];\n}\n\nexport function createReadOnlyToolDefinitions(cwd: string, options?: ToolsOptions): ToolDef[] {\n\treturn [\n\t\tcreateReadToolDefinition(cwd, options?.read),\n\t\tcreateGrepToolDefinition(cwd, options?.grep),\n\t\tcreateFindToolDefinition(cwd, options?.find),\n\t\tcreateLsToolDefinition(cwd, options?.ls),\n\t];\n}\n\nexport function createAllToolDefinitions(cwd: string, options?: ToolsOptions): Record<ToolName, ToolDef> {\n\treturn {\n\t\tread: createReadToolDefinition(cwd, options?.read),\n\t\tbash: createBashToolDefinition(cwd, options?.bash),\n\t\tedit: createEditToolDefinition(cwd, options?.edit),\n\t\twrite: createWriteToolDefinition(cwd, options?.write),\n\t\tgrep: createGrepToolDefinition(cwd, options?.grep),\n\t\tfind: createFindToolDefinition(cwd, options?.find),\n\t\tls: createLsToolDefinition(cwd, options?.ls),\n\t\tsubagent: createSubagentToolDefinition(cwd),\n\t};\n}\n\nexport function createCodingTools(cwd: string, options?: ToolsOptions): Tool[] {\n\treturn [\n\t\tcreateReadTool(cwd, options?.read),\n\t\tcreateBashTool(cwd, options?.bash),\n\t\tcreateEditTool(cwd, options?.edit),\n\t\tcreateWriteTool(cwd, options?.write),\n\t];\n}\n\nexport function createReadOnlyTools(cwd: string, options?: ToolsOptions): Tool[] {\n\treturn [\n\t\tcreateReadTool(cwd, options?.read),\n\t\tcreateGrepTool(cwd, options?.grep),\n\t\tcreateFindTool(cwd, options?.find),\n\t\tcreateLsTool(cwd, options?.ls),\n\t];\n}\n\nexport function createAllTools(cwd: string, options?: ToolsOptions): Record<ToolName, Tool> {\n\treturn {\n\t\tread: createReadTool(cwd, options?.read),\n\t\tbash: createBashTool(cwd, options?.bash),\n\t\tedit: createEditTool(cwd, options?.edit),\n\t\twrite: createWriteTool(cwd, options?.write),\n\t\tgrep: createGrepTool(cwd, options?.grep),\n\t\tfind: createFindTool(cwd, options?.find),\n\t\tls: createLsTool(cwd, options?.ls),\n\t\tsubagent: createSubagentTool(cwd),\n\t};\n}\n"]}
@@ -5,6 +5,7 @@ export { createFindTool, createFindToolDefinition, } from "./find.js";
5
5
  export { createGrepTool, createGrepToolDefinition, } from "./grep.js";
6
6
  export { createLsTool, createLsToolDefinition, } from "./ls.js";
7
7
  export { createReadTool, createReadToolDefinition, } from "./read.js";
8
+ export { createSubagentTool, createSubagentToolDefinition, discoverAgents, SUBAGENT_DEPTH_ENV, } from "./subagent.js";
8
9
  export { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, formatSize, truncateHead, truncateLine, truncateTail, } from "./truncate.js";
9
10
  export { createWriteTool, createWriteToolDefinition, } from "./write.js";
10
11
  import { createBashTool, createBashToolDefinition } from "./bash.js";
@@ -13,8 +14,9 @@ import { createFindTool, createFindToolDefinition } from "./find.js";
13
14
  import { createGrepTool, createGrepToolDefinition } from "./grep.js";
14
15
  import { createLsTool, createLsToolDefinition } from "./ls.js";
15
16
  import { createReadTool, createReadToolDefinition } from "./read.js";
17
+ import { createSubagentTool, createSubagentToolDefinition } from "./subagent.js";
16
18
  import { createWriteTool, createWriteToolDefinition } from "./write.js";
17
- export const allToolNames = new Set(["read", "bash", "edit", "write", "grep", "find", "ls"]);
19
+ export const allToolNames = new Set(["read", "bash", "edit", "write", "grep", "find", "ls", "subagent"]);
18
20
  export function createToolDefinition(toolName, cwd, options) {
19
21
  switch (toolName) {
20
22
  case "read":
@@ -31,6 +33,8 @@ export function createToolDefinition(toolName, cwd, options) {
31
33
  return createFindToolDefinition(cwd, options?.find);
32
34
  case "ls":
33
35
  return createLsToolDefinition(cwd, options?.ls);
36
+ case "subagent":
37
+ return createSubagentToolDefinition(cwd);
34
38
  default:
35
39
  throw new Error(`Unknown tool name: ${toolName}`);
36
40
  }
@@ -51,6 +55,8 @@ export function createTool(toolName, cwd, options) {
51
55
  return createFindTool(cwd, options?.find);
52
56
  case "ls":
53
57
  return createLsTool(cwd, options?.ls);
58
+ case "subagent":
59
+ return createSubagentTool(cwd);
54
60
  default:
55
61
  throw new Error(`Unknown tool name: ${toolName}`);
56
62
  }
@@ -80,6 +86,7 @@ export function createAllToolDefinitions(cwd, options) {
80
86
  grep: createGrepToolDefinition(cwd, options?.grep),
81
87
  find: createFindToolDefinition(cwd, options?.find),
82
88
  ls: createLsToolDefinition(cwd, options?.ls),
89
+ subagent: createSubagentToolDefinition(cwd),
83
90
  };
84
91
  }
85
92
  export function createCodingTools(cwd, options) {
@@ -107,6 +114,7 @@ export function createAllTools(cwd, options) {
107
114
  grep: createGrepTool(cwd, options?.grep),
108
115
  find: createFindTool(cwd, options?.find),
109
116
  ls: createLsTool(cwd, options?.ls),
117
+ subagent: createSubagentTool(cwd),
110
118
  };
111
119
  }
112
120
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/tools/index.ts"],"names":[],"mappings":"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","sourcesContent":["export {\n\ttype BashOperations,\n\ttype BashSpawnContext,\n\ttype BashSpawnHook,\n\ttype BashToolDetails,\n\ttype BashToolInput,\n\ttype BashToolOptions,\n\tcreateBashTool,\n\tcreateBashToolDefinition,\n\tcreateLocalBashOperations,\n} from \"./bash.ts\";\nexport {\n\tcreateEditTool,\n\tcreateEditToolDefinition,\n\ttype EditOperations,\n\ttype EditToolDetails,\n\ttype EditToolInput,\n\ttype EditToolOptions,\n} from \"./edit.ts\";\nexport { withFileMutationQueue } from \"./file-mutation-queue.ts\";\nexport {\n\tcreateFindTool,\n\tcreateFindToolDefinition,\n\ttype FindOperations,\n\ttype FindToolDetails,\n\ttype FindToolInput,\n\ttype FindToolOptions,\n} from \"./find.ts\";\nexport {\n\tcreateGrepTool,\n\tcreateGrepToolDefinition,\n\ttype GrepOperations,\n\ttype GrepToolDetails,\n\ttype GrepToolInput,\n\ttype GrepToolOptions,\n} from \"./grep.ts\";\nexport {\n\tcreateLsTool,\n\tcreateLsToolDefinition,\n\ttype LsOperations,\n\ttype LsToolDetails,\n\ttype LsToolInput,\n\ttype LsToolOptions,\n} from \"./ls.ts\";\nexport {\n\tcreateReadTool,\n\tcreateReadToolDefinition,\n\ttype ReadOperations,\n\ttype ReadToolDetails,\n\ttype ReadToolInput,\n\ttype ReadToolOptions,\n} from \"./read.ts\";\nexport {\n\tDEFAULT_MAX_BYTES,\n\tDEFAULT_MAX_LINES,\n\tformatSize,\n\ttype TruncationOptions,\n\ttype TruncationResult,\n\ttruncateHead,\n\ttruncateLine,\n\ttruncateTail,\n} from \"./truncate.ts\";\nexport {\n\tcreateWriteTool,\n\tcreateWriteToolDefinition,\n\ttype WriteOperations,\n\ttype WriteToolInput,\n\ttype WriteToolOptions,\n} from \"./write.ts\";\n\nimport type { AgentTool } from \"@earendil-works/pi-agent-core\";\nimport type { ToolDefinition } from \"../extensions/types.ts\";\nimport { type BashToolOptions, createBashTool, createBashToolDefinition } from \"./bash.ts\";\nimport { createEditTool, createEditToolDefinition, type EditToolOptions } from \"./edit.ts\";\nimport { createFindTool, createFindToolDefinition, type FindToolOptions } from \"./find.ts\";\nimport { createGrepTool, createGrepToolDefinition, type GrepToolOptions } from \"./grep.ts\";\nimport { createLsTool, createLsToolDefinition, type LsToolOptions } from \"./ls.ts\";\nimport { createReadTool, createReadToolDefinition, type ReadToolOptions } from \"./read.ts\";\nimport { createWriteTool, createWriteToolDefinition, type WriteToolOptions } from \"./write.ts\";\n\nexport type Tool = AgentTool<any>;\nexport type ToolDef = ToolDefinition<any, any>;\nexport type ToolName = \"read\" | \"bash\" | \"edit\" | \"write\" | \"grep\" | \"find\" | \"ls\";\nexport const allToolNames: Set<ToolName> = new Set([\"read\", \"bash\", \"edit\", \"write\", \"grep\", \"find\", \"ls\"]);\n\nexport interface ToolsOptions {\n\tread?: ReadToolOptions;\n\tbash?: BashToolOptions;\n\twrite?: WriteToolOptions;\n\tedit?: EditToolOptions;\n\tgrep?: GrepToolOptions;\n\tfind?: FindToolOptions;\n\tls?: LsToolOptions;\n}\n\nexport function createToolDefinition(toolName: ToolName, cwd: string, options?: ToolsOptions): ToolDef {\n\tswitch (toolName) {\n\t\tcase \"read\":\n\t\t\treturn createReadToolDefinition(cwd, options?.read);\n\t\tcase \"bash\":\n\t\t\treturn createBashToolDefinition(cwd, options?.bash);\n\t\tcase \"edit\":\n\t\t\treturn createEditToolDefinition(cwd, options?.edit);\n\t\tcase \"write\":\n\t\t\treturn createWriteToolDefinition(cwd, options?.write);\n\t\tcase \"grep\":\n\t\t\treturn createGrepToolDefinition(cwd, options?.grep);\n\t\tcase \"find\":\n\t\t\treturn createFindToolDefinition(cwd, options?.find);\n\t\tcase \"ls\":\n\t\t\treturn createLsToolDefinition(cwd, options?.ls);\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown tool name: ${toolName}`);\n\t}\n}\n\nexport function createTool(toolName: ToolName, cwd: string, options?: ToolsOptions): Tool {\n\tswitch (toolName) {\n\t\tcase \"read\":\n\t\t\treturn createReadTool(cwd, options?.read);\n\t\tcase \"bash\":\n\t\t\treturn createBashTool(cwd, options?.bash);\n\t\tcase \"edit\":\n\t\t\treturn createEditTool(cwd, options?.edit);\n\t\tcase \"write\":\n\t\t\treturn createWriteTool(cwd, options?.write);\n\t\tcase \"grep\":\n\t\t\treturn createGrepTool(cwd, options?.grep);\n\t\tcase \"find\":\n\t\t\treturn createFindTool(cwd, options?.find);\n\t\tcase \"ls\":\n\t\t\treturn createLsTool(cwd, options?.ls);\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown tool name: ${toolName}`);\n\t}\n}\n\nexport function createCodingToolDefinitions(cwd: string, options?: ToolsOptions): ToolDef[] {\n\treturn [\n\t\tcreateReadToolDefinition(cwd, options?.read),\n\t\tcreateBashToolDefinition(cwd, options?.bash),\n\t\tcreateEditToolDefinition(cwd, options?.edit),\n\t\tcreateWriteToolDefinition(cwd, options?.write),\n\t];\n}\n\nexport function createReadOnlyToolDefinitions(cwd: string, options?: ToolsOptions): ToolDef[] {\n\treturn [\n\t\tcreateReadToolDefinition(cwd, options?.read),\n\t\tcreateGrepToolDefinition(cwd, options?.grep),\n\t\tcreateFindToolDefinition(cwd, options?.find),\n\t\tcreateLsToolDefinition(cwd, options?.ls),\n\t];\n}\n\nexport function createAllToolDefinitions(cwd: string, options?: ToolsOptions): Record<ToolName, ToolDef> {\n\treturn {\n\t\tread: createReadToolDefinition(cwd, options?.read),\n\t\tbash: createBashToolDefinition(cwd, options?.bash),\n\t\tedit: createEditToolDefinition(cwd, options?.edit),\n\t\twrite: createWriteToolDefinition(cwd, options?.write),\n\t\tgrep: createGrepToolDefinition(cwd, options?.grep),\n\t\tfind: createFindToolDefinition(cwd, options?.find),\n\t\tls: createLsToolDefinition(cwd, options?.ls),\n\t};\n}\n\nexport function createCodingTools(cwd: string, options?: ToolsOptions): Tool[] {\n\treturn [\n\t\tcreateReadTool(cwd, options?.read),\n\t\tcreateBashTool(cwd, options?.bash),\n\t\tcreateEditTool(cwd, options?.edit),\n\t\tcreateWriteTool(cwd, options?.write),\n\t];\n}\n\nexport function createReadOnlyTools(cwd: string, options?: ToolsOptions): Tool[] {\n\treturn [\n\t\tcreateReadTool(cwd, options?.read),\n\t\tcreateGrepTool(cwd, options?.grep),\n\t\tcreateFindTool(cwd, options?.find),\n\t\tcreateLsTool(cwd, options?.ls),\n\t];\n}\n\nexport function createAllTools(cwd: string, options?: ToolsOptions): Record<ToolName, Tool> {\n\treturn {\n\t\tread: createReadTool(cwd, options?.read),\n\t\tbash: createBashTool(cwd, options?.bash),\n\t\tedit: createEditTool(cwd, options?.edit),\n\t\twrite: createWriteTool(cwd, options?.write),\n\t\tgrep: createGrepTool(cwd, options?.grep),\n\t\tfind: createFindTool(cwd, options?.find),\n\t\tls: createLsTool(cwd, options?.ls),\n\t};\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/tools/index.ts"],"names":[],"mappings":"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","sourcesContent":["export {\n\ttype BashOperations,\n\ttype BashSpawnContext,\n\ttype BashSpawnHook,\n\ttype BashToolDetails,\n\ttype BashToolInput,\n\ttype BashToolOptions,\n\tcreateBashTool,\n\tcreateBashToolDefinition,\n\tcreateLocalBashOperations,\n} from \"./bash.ts\";\nexport {\n\tcreateEditTool,\n\tcreateEditToolDefinition,\n\ttype EditOperations,\n\ttype EditToolDetails,\n\ttype EditToolInput,\n\ttype EditToolOptions,\n} from \"./edit.ts\";\nexport { withFileMutationQueue } from \"./file-mutation-queue.ts\";\nexport {\n\tcreateFindTool,\n\tcreateFindToolDefinition,\n\ttype FindOperations,\n\ttype FindToolDetails,\n\ttype FindToolInput,\n\ttype FindToolOptions,\n} from \"./find.ts\";\nexport {\n\tcreateGrepTool,\n\tcreateGrepToolDefinition,\n\ttype GrepOperations,\n\ttype GrepToolDetails,\n\ttype GrepToolInput,\n\ttype GrepToolOptions,\n} from \"./grep.ts\";\nexport {\n\tcreateLsTool,\n\tcreateLsToolDefinition,\n\ttype LsOperations,\n\ttype LsToolDetails,\n\ttype LsToolInput,\n\ttype LsToolOptions,\n} from \"./ls.ts\";\nexport {\n\tcreateReadTool,\n\tcreateReadToolDefinition,\n\ttype ReadOperations,\n\ttype ReadToolDetails,\n\ttype ReadToolInput,\n\ttype ReadToolOptions,\n} from \"./read.ts\";\nexport {\n\ttype AgentConfig,\n\ttype AgentDiscoveryResult,\n\ttype AgentScope,\n\tcreateSubagentTool,\n\tcreateSubagentToolDefinition,\n\tdiscoverAgents,\n\tSUBAGENT_DEPTH_ENV,\n\ttype SubagentDetails,\n\ttype SubagentSingleResult,\n\ttype SubagentUsageStats,\n} from \"./subagent.ts\";\nexport {\n\tDEFAULT_MAX_BYTES,\n\tDEFAULT_MAX_LINES,\n\tformatSize,\n\ttype TruncationOptions,\n\ttype TruncationResult,\n\ttruncateHead,\n\ttruncateLine,\n\ttruncateTail,\n} from \"./truncate.ts\";\nexport {\n\tcreateWriteTool,\n\tcreateWriteToolDefinition,\n\ttype WriteOperations,\n\ttype WriteToolInput,\n\ttype WriteToolOptions,\n} from \"./write.ts\";\n\nimport type { AgentTool } from \"@earendil-works/pi-agent-core\";\nimport type { ToolDefinition } from \"../extensions/types.ts\";\nimport { type BashToolOptions, createBashTool, createBashToolDefinition } from \"./bash.ts\";\nimport { createEditTool, createEditToolDefinition, type EditToolOptions } from \"./edit.ts\";\nimport { createFindTool, createFindToolDefinition, type FindToolOptions } from \"./find.ts\";\nimport { createGrepTool, createGrepToolDefinition, type GrepToolOptions } from \"./grep.ts\";\nimport { createLsTool, createLsToolDefinition, type LsToolOptions } from \"./ls.ts\";\nimport { createReadTool, createReadToolDefinition, type ReadToolOptions } from \"./read.ts\";\nimport { createSubagentTool, createSubagentToolDefinition } from \"./subagent.ts\";\nimport { createWriteTool, createWriteToolDefinition, type WriteToolOptions } from \"./write.ts\";\n\nexport type Tool = AgentTool<any>;\nexport type ToolDef = ToolDefinition<any, any>;\nexport type ToolName = \"read\" | \"bash\" | \"edit\" | \"write\" | \"grep\" | \"find\" | \"ls\" | \"subagent\";\nexport const allToolNames: Set<ToolName> = new Set([\"read\", \"bash\", \"edit\", \"write\", \"grep\", \"find\", \"ls\", \"subagent\"]);\n\nexport interface ToolsOptions {\n\tread?: ReadToolOptions;\n\tbash?: BashToolOptions;\n\twrite?: WriteToolOptions;\n\tedit?: EditToolOptions;\n\tgrep?: GrepToolOptions;\n\tfind?: FindToolOptions;\n\tls?: LsToolOptions;\n}\n\nexport function createToolDefinition(toolName: ToolName, cwd: string, options?: ToolsOptions): ToolDef {\n\tswitch (toolName) {\n\t\tcase \"read\":\n\t\t\treturn createReadToolDefinition(cwd, options?.read);\n\t\tcase \"bash\":\n\t\t\treturn createBashToolDefinition(cwd, options?.bash);\n\t\tcase \"edit\":\n\t\t\treturn createEditToolDefinition(cwd, options?.edit);\n\t\tcase \"write\":\n\t\t\treturn createWriteToolDefinition(cwd, options?.write);\n\t\tcase \"grep\":\n\t\t\treturn createGrepToolDefinition(cwd, options?.grep);\n\t\tcase \"find\":\n\t\t\treturn createFindToolDefinition(cwd, options?.find);\n\t\tcase \"ls\":\n\t\t\treturn createLsToolDefinition(cwd, options?.ls);\n\t\tcase \"subagent\":\n\t\t\treturn createSubagentToolDefinition(cwd);\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown tool name: ${toolName}`);\n\t}\n}\n\nexport function createTool(toolName: ToolName, cwd: string, options?: ToolsOptions): Tool {\n\tswitch (toolName) {\n\t\tcase \"read\":\n\t\t\treturn createReadTool(cwd, options?.read);\n\t\tcase \"bash\":\n\t\t\treturn createBashTool(cwd, options?.bash);\n\t\tcase \"edit\":\n\t\t\treturn createEditTool(cwd, options?.edit);\n\t\tcase \"write\":\n\t\t\treturn createWriteTool(cwd, options?.write);\n\t\tcase \"grep\":\n\t\t\treturn createGrepTool(cwd, options?.grep);\n\t\tcase \"find\":\n\t\t\treturn createFindTool(cwd, options?.find);\n\t\tcase \"ls\":\n\t\t\treturn createLsTool(cwd, options?.ls);\n\t\tcase \"subagent\":\n\t\t\treturn createSubagentTool(cwd);\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown tool name: ${toolName}`);\n\t}\n}\n\nexport function createCodingToolDefinitions(cwd: string, options?: ToolsOptions): ToolDef[] {\n\treturn [\n\t\tcreateReadToolDefinition(cwd, options?.read),\n\t\tcreateBashToolDefinition(cwd, options?.bash),\n\t\tcreateEditToolDefinition(cwd, options?.edit),\n\t\tcreateWriteToolDefinition(cwd, options?.write),\n\t];\n}\n\nexport function createReadOnlyToolDefinitions(cwd: string, options?: ToolsOptions): ToolDef[] {\n\treturn [\n\t\tcreateReadToolDefinition(cwd, options?.read),\n\t\tcreateGrepToolDefinition(cwd, options?.grep),\n\t\tcreateFindToolDefinition(cwd, options?.find),\n\t\tcreateLsToolDefinition(cwd, options?.ls),\n\t];\n}\n\nexport function createAllToolDefinitions(cwd: string, options?: ToolsOptions): Record<ToolName, ToolDef> {\n\treturn {\n\t\tread: createReadToolDefinition(cwd, options?.read),\n\t\tbash: createBashToolDefinition(cwd, options?.bash),\n\t\tedit: createEditToolDefinition(cwd, options?.edit),\n\t\twrite: createWriteToolDefinition(cwd, options?.write),\n\t\tgrep: createGrepToolDefinition(cwd, options?.grep),\n\t\tfind: createFindToolDefinition(cwd, options?.find),\n\t\tls: createLsToolDefinition(cwd, options?.ls),\n\t\tsubagent: createSubagentToolDefinition(cwd),\n\t};\n}\n\nexport function createCodingTools(cwd: string, options?: ToolsOptions): Tool[] {\n\treturn [\n\t\tcreateReadTool(cwd, options?.read),\n\t\tcreateBashTool(cwd, options?.bash),\n\t\tcreateEditTool(cwd, options?.edit),\n\t\tcreateWriteTool(cwd, options?.write),\n\t];\n}\n\nexport function createReadOnlyTools(cwd: string, options?: ToolsOptions): Tool[] {\n\treturn [\n\t\tcreateReadTool(cwd, options?.read),\n\t\tcreateGrepTool(cwd, options?.grep),\n\t\tcreateFindTool(cwd, options?.find),\n\t\tcreateLsTool(cwd, options?.ls),\n\t];\n}\n\nexport function createAllTools(cwd: string, options?: ToolsOptions): Record<ToolName, Tool> {\n\treturn {\n\t\tread: createReadTool(cwd, options?.read),\n\t\tbash: createBashTool(cwd, options?.bash),\n\t\tedit: createEditTool(cwd, options?.edit),\n\t\twrite: createWriteTool(cwd, options?.write),\n\t\tgrep: createGrepTool(cwd, options?.grep),\n\t\tfind: createFindTool(cwd, options?.find),\n\t\tls: createLsTool(cwd, options?.ls),\n\t\tsubagent: createSubagentTool(cwd),\n\t};\n}\n"]}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Subagent Tool - Delegate tasks to specialized agents
3
+ *
4
+ * Spawns a separate humain-terminal process for each subagent invocation,
5
+ * giving it an isolated context window.
6
+ *
7
+ * Supports three modes:
8
+ * - Single: { agent: "name", task: "..." }
9
+ * - Parallel: { tasks: [{ agent: "name", task: "..." }, ...] }
10
+ * - Chain: { chain: [{ agent: "name", task: "... {previous} ..." }, ...] }
11
+ *
12
+ * Uses JSON mode to capture structured output from subagents.
13
+ */
14
+ import type { Message } from "@earendil-works/pi-ai";
15
+ import { Type } from "typebox";
16
+ import type { ToolDefinition } from "../extensions/types.ts";
17
+ /** Children must not delegate further: depth 0 = top-level agent, depth >= 1 = subagent. */
18
+ export declare const SUBAGENT_DEPTH_ENV = "HUMAIN_TERMINAL_SUBAGENT_DEPTH";
19
+ export type AgentScope = "user" | "project" | "both";
20
+ export interface AgentConfig {
21
+ name: string;
22
+ description: string;
23
+ tools?: string[];
24
+ model?: string;
25
+ systemPrompt: string;
26
+ source: "user" | "project";
27
+ filePath: string;
28
+ }
29
+ export interface AgentDiscoveryResult {
30
+ agents: AgentConfig[];
31
+ projectAgentsDir: string | null;
32
+ }
33
+ export declare function discoverAgents(cwd: string, scope: AgentScope): AgentDiscoveryResult;
34
+ export interface SubagentUsageStats {
35
+ input: number;
36
+ output: number;
37
+ cacheRead: number;
38
+ cacheWrite: number;
39
+ cost: number;
40
+ contextTokens: number;
41
+ turns: number;
42
+ }
43
+ export interface SubagentSingleResult {
44
+ agent: string;
45
+ agentSource: "user" | "project" | "unknown";
46
+ task: string;
47
+ exitCode: number;
48
+ messages: Message[];
49
+ stderr: string;
50
+ usage: SubagentUsageStats;
51
+ model?: string;
52
+ stopReason?: string;
53
+ errorMessage?: string;
54
+ step?: number;
55
+ }
56
+ export interface SubagentDetails {
57
+ mode: "single" | "parallel" | "chain";
58
+ agentScope: AgentScope;
59
+ projectAgentsDir: string | null;
60
+ results: SubagentSingleResult[];
61
+ }
62
+ declare const SubagentParams: Type.TObject<{
63
+ agent: Type.TOptional<Type.TString>;
64
+ task: Type.TOptional<Type.TString>;
65
+ tasks: Type.TOptional<Type.TArray<Type.TObject<{
66
+ agent: Type.TString;
67
+ task: Type.TString;
68
+ cwd: Type.TOptional<Type.TString>;
69
+ }>>>;
70
+ chain: Type.TOptional<Type.TArray<Type.TObject<{
71
+ agent: Type.TString;
72
+ task: Type.TString;
73
+ cwd: Type.TOptional<Type.TString>;
74
+ }>>>;
75
+ agentScope: Type.TOptional<Type.TUnsafe<"both" | "project" | "user">>;
76
+ confirmProjectAgents: Type.TOptional<Type.TBoolean>;
77
+ cwd: Type.TOptional<Type.TString>;
78
+ }>;
79
+ export declare function createSubagentToolDefinition(cwd: string): ToolDefinition<typeof SubagentParams, SubagentDetails>;
80
+ export declare function createSubagentTool(cwd: string): import("@earendil-works/pi-agent-core").AgentTool<any, SubagentDetails>;
81
+ export {};
82
+ //# sourceMappingURL=subagent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subagent.d.ts","sourceRoot":"","sources":["../../../src/core/tools/subagent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAOH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAGrD,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAI/B,OAAO,KAAK,EAAoB,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAU/E,4FAA4F;AAC5F,eAAO,MAAM,kBAAkB,mCAAmC,CAAC;AAUnE,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC;AAErD,MAAM,WAAW,WAAW;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACpC,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAyED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,oBAAoB,CAmBnF;AAoGD,MAAM,WAAW,kBAAkB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,oBAAoB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,kBAAkB,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,eAAe;IAC/B,IAAI,EAAE,QAAQ,GAAG,UAAU,GAAG,OAAO,CAAC;IACtC,UAAU,EAAE,UAAU,CAAC;IACvB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,OAAO,EAAE,oBAAoB,EAAE,CAAC;CAChC;AA4RD,QAAA,MAAM,cAAc;;;;;;;;;;;;;;;;EAUlB,CAAC;AAEH,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAAC,OAAO,cAAc,EAAE,eAAe,CAAC,CA+mBhH;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,2EAE7C","sourcesContent":["/**\n * Subagent Tool - Delegate tasks to specialized agents\n *\n * Spawns a separate humain-terminal process for each subagent invocation,\n * giving it an isolated context window.\n *\n * Supports three modes:\n * - Single: { agent: \"name\", task: \"...\" }\n * - Parallel: { tasks: [{ agent: \"name\", task: \"...\" }, ...] }\n * - Chain: { chain: [{ agent: \"name\", task: \"... {previous} ...\" }, ...] }\n *\n * Uses JSON mode to capture structured output from subagents.\n */\n\nimport { spawn } from \"node:child_process\";\nimport * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport type { AgentToolResult } from \"@earendil-works/pi-agent-core\";\nimport type { Message } from \"@earendil-works/pi-ai\";\nimport { StringEnum } from \"@earendil-works/pi-ai\";\nimport { Container, Markdown, Spacer, Text } from \"@earendil-works/pi-tui\";\nimport { Type } from \"typebox\";\nimport { CONFIG_DIR_NAME, getAgentDir } from \"../../config.ts\";\nimport { getMarkdownTheme, type Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport { parseFrontmatter } from \"../../utils/frontmatter.ts\";\nimport type { ExtensionContext, ToolDefinition } from \"../extensions/types.ts\";\nimport { withFileMutationQueue } from \"./file-mutation-queue.ts\";\nimport { shortenPath } from \"./render-utils.ts\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.ts\";\n\nconst MAX_PARALLEL_TASKS = 8;\nconst MAX_CONCURRENCY = 4;\nconst COLLAPSED_ITEM_COUNT = 10;\nconst PER_TASK_OUTPUT_CAP = 50 * 1024;\n\n/** Children must not delegate further: depth 0 = top-level agent, depth >= 1 = subagent. */\nexport const SUBAGENT_DEPTH_ENV = \"HUMAIN_TERMINAL_SUBAGENT_DEPTH\";\nconst MAX_SUBAGENT_DEPTH = 1;\n\nfunction currentSubagentDepth(): number {\n\tconst raw = Number(process.env[SUBAGENT_DEPTH_ENV] ?? \"0\");\n\treturn Number.isFinite(raw) && raw > 0 ? Math.floor(raw) : 0;\n}\n\n// --- Agent discovery ---\n\nexport type AgentScope = \"user\" | \"project\" | \"both\";\n\nexport interface AgentConfig {\n\tname: string;\n\tdescription: string;\n\ttools?: string[];\n\tmodel?: string;\n\tsystemPrompt: string;\n\tsource: \"user\" | \"project\";\n\tfilePath: string;\n}\n\nexport interface AgentDiscoveryResult {\n\tagents: AgentConfig[];\n\tprojectAgentsDir: string | null;\n}\n\nfunction loadAgentsFromDir(dir: string, source: \"user\" | \"project\"): AgentConfig[] {\n\tconst agents: AgentConfig[] = [];\n\n\tif (!fs.existsSync(dir)) {\n\t\treturn agents;\n\t}\n\n\tlet entries: fs.Dirent[];\n\ttry {\n\t\tentries = fs.readdirSync(dir, { withFileTypes: true });\n\t} catch {\n\t\treturn agents;\n\t}\n\n\tfor (const entry of entries) {\n\t\tif (!entry.name.endsWith(\".md\")) continue;\n\t\tif (!entry.isFile() && !entry.isSymbolicLink()) continue;\n\n\t\tconst filePath = path.join(dir, entry.name);\n\t\tlet content: string;\n\t\ttry {\n\t\t\tcontent = fs.readFileSync(filePath, \"utf-8\");\n\t\t} catch {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst { frontmatter, body } = parseFrontmatter<Record<string, string>>(content);\n\n\t\tif (!frontmatter.name || !frontmatter.description) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst tools = frontmatter.tools\n\t\t\t?.split(\",\")\n\t\t\t.map((t: string) => t.trim())\n\t\t\t.filter(Boolean);\n\n\t\tagents.push({\n\t\t\tname: frontmatter.name,\n\t\t\tdescription: frontmatter.description,\n\t\t\ttools: tools && tools.length > 0 ? tools : undefined,\n\t\t\tmodel: frontmatter.model,\n\t\t\tsystemPrompt: body,\n\t\t\tsource,\n\t\t\tfilePath,\n\t\t});\n\t}\n\n\treturn agents;\n}\n\nfunction isDirectory(p: string): boolean {\n\ttry {\n\t\treturn fs.statSync(p).isDirectory();\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction findNearestProjectAgentsDir(cwd: string): string | null {\n\tlet currentDir = cwd;\n\twhile (true) {\n\t\tconst candidate = path.join(currentDir, CONFIG_DIR_NAME, \"agents\");\n\t\tif (isDirectory(candidate)) return candidate;\n\n\t\tconst parentDir = path.dirname(currentDir);\n\t\tif (parentDir === currentDir) return null;\n\t\tcurrentDir = parentDir;\n\t}\n}\n\nexport function discoverAgents(cwd: string, scope: AgentScope): AgentDiscoveryResult {\n\tconst userDir = path.join(getAgentDir(), \"agents\");\n\tconst projectAgentsDir = findNearestProjectAgentsDir(cwd);\n\n\tconst userAgents = scope === \"project\" ? [] : loadAgentsFromDir(userDir, \"user\");\n\tconst projectAgents = scope === \"user\" || !projectAgentsDir ? [] : loadAgentsFromDir(projectAgentsDir, \"project\");\n\n\tconst agentMap = new Map<string, AgentConfig>();\n\n\tif (scope === \"both\") {\n\t\tfor (const agent of userAgents) agentMap.set(agent.name, agent);\n\t\tfor (const agent of projectAgents) agentMap.set(agent.name, agent);\n\t} else if (scope === \"user\") {\n\t\tfor (const agent of userAgents) agentMap.set(agent.name, agent);\n\t} else {\n\t\tfor (const agent of projectAgents) agentMap.set(agent.name, agent);\n\t}\n\n\treturn { agents: Array.from(agentMap.values()), projectAgentsDir };\n}\n\n// --- Formatting helpers ---\n\nfunction formatTokens(count: number): string {\n\tif (count < 1000) return count.toString();\n\tif (count < 10000) return `${(count / 1000).toFixed(1)}k`;\n\tif (count < 1000000) return `${Math.round(count / 1000)}k`;\n\treturn `${(count / 1000000).toFixed(1)}M`;\n}\n\nfunction formatUsageStats(\n\tusage: {\n\t\tinput: number;\n\t\toutput: number;\n\t\tcacheRead: number;\n\t\tcacheWrite: number;\n\t\tcost: number;\n\t\tcontextTokens?: number;\n\t\tturns?: number;\n\t},\n\tmodel?: string,\n): string {\n\tconst parts: string[] = [];\n\tif (usage.turns) parts.push(`${usage.turns} turn${usage.turns > 1 ? \"s\" : \"\"}`);\n\tif (usage.input) parts.push(`↑${formatTokens(usage.input)}`);\n\tif (usage.output) parts.push(`↓${formatTokens(usage.output)}`);\n\tif (usage.cacheRead) parts.push(`R${formatTokens(usage.cacheRead)}`);\n\tif (usage.cacheWrite) parts.push(`W${formatTokens(usage.cacheWrite)}`);\n\tif (usage.cost) parts.push(`$${usage.cost.toFixed(4)}`);\n\tif (usage.contextTokens && usage.contextTokens > 0) {\n\t\tparts.push(`ctx:${formatTokens(usage.contextTokens)}`);\n\t}\n\tif (model) parts.push(model);\n\treturn parts.join(\" \");\n}\n\nfunction formatToolCall(\n\ttoolName: string,\n\targs: Record<string, unknown>,\n\tthemeFg: (color: any, text: string) => string,\n): string {\n\tswitch (toolName) {\n\t\tcase \"bash\": {\n\t\t\tconst command = (args.command as string) || \"...\";\n\t\t\tconst preview = command.length > 60 ? `${command.slice(0, 60)}...` : command;\n\t\t\treturn themeFg(\"muted\", \"$ \") + themeFg(\"toolOutput\", preview);\n\t\t}\n\t\tcase \"read\": {\n\t\t\tconst rawPath = (args.file_path || args.path || \"...\") as string;\n\t\t\tconst filePath = shortenPath(rawPath);\n\t\t\tconst offset = args.offset as number | undefined;\n\t\t\tconst limit = args.limit as number | undefined;\n\t\t\tlet text = themeFg(\"accent\", filePath);\n\t\t\tif (offset !== undefined || limit !== undefined) {\n\t\t\t\tconst startLine = offset ?? 1;\n\t\t\t\tconst endLine = limit !== undefined ? startLine + limit - 1 : \"\";\n\t\t\t\ttext += themeFg(\"warning\", `:${startLine}${endLine ? `-${endLine}` : \"\"}`);\n\t\t\t}\n\t\t\treturn themeFg(\"muted\", \"read \") + text;\n\t\t}\n\t\tcase \"write\": {\n\t\t\tconst rawPath = (args.file_path || args.path || \"...\") as string;\n\t\t\tconst filePath = shortenPath(rawPath);\n\t\t\tconst content = (args.content || \"\") as string;\n\t\t\tconst lines = content.split(\"\\n\").length;\n\t\t\tlet text = themeFg(\"muted\", \"write \") + themeFg(\"accent\", filePath);\n\t\t\tif (lines > 1) text += themeFg(\"dim\", ` (${lines} lines)`);\n\t\t\treturn text;\n\t\t}\n\t\tcase \"edit\": {\n\t\t\tconst rawPath = (args.file_path || args.path || \"...\") as string;\n\t\t\treturn themeFg(\"muted\", \"edit \") + themeFg(\"accent\", shortenPath(rawPath));\n\t\t}\n\t\tcase \"ls\": {\n\t\t\tconst rawPath = (args.path || \".\") as string;\n\t\t\treturn themeFg(\"muted\", \"ls \") + themeFg(\"accent\", shortenPath(rawPath));\n\t\t}\n\t\tcase \"find\": {\n\t\t\tconst pattern = (args.pattern || \"*\") as string;\n\t\t\tconst rawPath = (args.path || \".\") as string;\n\t\t\treturn themeFg(\"muted\", \"find \") + themeFg(\"accent\", pattern) + themeFg(\"dim\", ` in ${shortenPath(rawPath)}`);\n\t\t}\n\t\tcase \"grep\": {\n\t\t\tconst pattern = (args.pattern || \"\") as string;\n\t\t\tconst rawPath = (args.path || \".\") as string;\n\t\t\treturn (\n\t\t\t\tthemeFg(\"muted\", \"grep \") +\n\t\t\t\tthemeFg(\"accent\", `/${pattern}/`) +\n\t\t\t\tthemeFg(\"dim\", ` in ${shortenPath(rawPath)}`)\n\t\t\t);\n\t\t}\n\t\tdefault: {\n\t\t\tconst argsStr = JSON.stringify(args);\n\t\t\tconst preview = argsStr.length > 50 ? `${argsStr.slice(0, 50)}...` : argsStr;\n\t\t\treturn themeFg(\"accent\", toolName) + themeFg(\"dim\", ` ${preview}`);\n\t\t}\n\t}\n}\n\nexport interface SubagentUsageStats {\n\tinput: number;\n\toutput: number;\n\tcacheRead: number;\n\tcacheWrite: number;\n\tcost: number;\n\tcontextTokens: number;\n\tturns: number;\n}\n\nexport interface SubagentSingleResult {\n\tagent: string;\n\tagentSource: \"user\" | \"project\" | \"unknown\";\n\ttask: string;\n\texitCode: number;\n\tmessages: Message[];\n\tstderr: string;\n\tusage: SubagentUsageStats;\n\tmodel?: string;\n\tstopReason?: string;\n\terrorMessage?: string;\n\tstep?: number;\n}\n\nexport interface SubagentDetails {\n\tmode: \"single\" | \"parallel\" | \"chain\";\n\tagentScope: AgentScope;\n\tprojectAgentsDir: string | null;\n\tresults: SubagentSingleResult[];\n}\n\nfunction getFinalOutput(messages: Message[]): string {\n\tfor (let i = messages.length - 1; i >= 0; i--) {\n\t\tconst msg = messages[i];\n\t\tif (msg.role === \"assistant\") {\n\t\t\tfor (const part of msg.content) {\n\t\t\t\tif (part.type === \"text\") return part.text;\n\t\t\t}\n\t\t}\n\t}\n\treturn \"\";\n}\n\nfunction isFailedResult(result: SubagentSingleResult): boolean {\n\treturn result.exitCode !== 0 || result.stopReason === \"error\" || result.stopReason === \"aborted\";\n}\n\nfunction getResultOutput(result: SubagentSingleResult): string {\n\tif (isFailedResult(result)) {\n\t\treturn result.errorMessage || result.stderr || getFinalOutput(result.messages) || \"(no output)\";\n\t}\n\treturn getFinalOutput(result.messages) || \"(no output)\";\n}\n\nfunction truncateParallelOutput(output: string): string {\n\tconst byteLength = Buffer.byteLength(output, \"utf8\");\n\tif (byteLength <= PER_TASK_OUTPUT_CAP) return output;\n\n\tlet truncated = output.slice(0, PER_TASK_OUTPUT_CAP);\n\twhile (Buffer.byteLength(truncated, \"utf8\") > PER_TASK_OUTPUT_CAP) {\n\t\ttruncated = truncated.slice(0, -1);\n\t}\n\treturn `${truncated}\\n\\n[Output truncated: ${byteLength - Buffer.byteLength(truncated, \"utf8\")} bytes omitted. Full output preserved in tool details.]`;\n}\n\ntype DisplayItem = { type: \"text\"; text: string } | { type: \"toolCall\"; name: string; args: Record<string, any> };\n\nfunction getDisplayItems(messages: Message[]): DisplayItem[] {\n\tconst items: DisplayItem[] = [];\n\tfor (const msg of messages) {\n\t\tif (msg.role === \"assistant\") {\n\t\t\tfor (const part of msg.content) {\n\t\t\t\tif (part.type === \"text\") items.push({ type: \"text\", text: part.text });\n\t\t\t\telse if (part.type === \"toolCall\") items.push({ type: \"toolCall\", name: part.name, args: part.arguments });\n\t\t\t}\n\t\t}\n\t}\n\treturn items;\n}\n\nasync function mapWithConcurrencyLimit<TIn, TOut>(\n\titems: TIn[],\n\tconcurrency: number,\n\tfn: (item: TIn, index: number) => Promise<TOut>,\n\tsignal?: AbortSignal,\n): Promise<TOut[]> {\n\tif (items.length === 0) return [];\n\tconst limit = Math.max(1, Math.min(concurrency, items.length));\n\tconst results: TOut[] = new Array(items.length);\n\tlet nextIndex = 0;\n\tconst workers = new Array(limit).fill(null).map(async () => {\n\t\twhile (true) {\n\t\t\t// Don't spawn doomed children for tasks still queued after an abort.\n\t\t\tif (signal?.aborted) throw new Error(\"Subagent was aborted\");\n\t\t\tconst current = nextIndex++;\n\t\t\tif (current >= items.length) return;\n\t\t\tresults[current] = await fn(items[current], current);\n\t\t}\n\t});\n\tawait Promise.all(workers);\n\treturn results;\n}\n\nasync function writePromptToTempFile(agentName: string, prompt: string): Promise<{ dir: string; filePath: string }> {\n\tconst tmpDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), \"humain-subagent-\"));\n\tconst safeName = agentName.replace(/[^\\w.-]+/g, \"_\");\n\tconst filePath = path.join(tmpDir, `prompt-${safeName}.md`);\n\tawait withFileMutationQueue(filePath, async () => {\n\t\tawait fs.promises.writeFile(filePath, prompt, { encoding: \"utf-8\", mode: 0o600 });\n\t});\n\treturn { dir: tmpDir, filePath };\n}\n\nfunction getCliInvocation(args: string[]): { command: string; args: string[] } {\n\tconst currentScript = process.argv[1];\n\tconst isBunVirtualScript = currentScript?.startsWith(\"/$bunfs/root/\");\n\tif (currentScript && !isBunVirtualScript && fs.existsSync(currentScript)) {\n\t\treturn { command: process.execPath, args: [currentScript, ...args] };\n\t}\n\n\tconst execName = path.basename(process.execPath).toLowerCase();\n\tconst isGenericRuntime = /^(node|bun)(\\.exe)?$/.test(execName);\n\tif (!isGenericRuntime) {\n\t\treturn { command: process.execPath, args };\n\t}\n\n\treturn { command: \"humain-terminal\", args };\n}\n\ntype OnUpdateCallback = (partial: AgentToolResult<SubagentDetails>) => void;\n\nasync function runSingleAgent(\n\tdefaultCwd: string,\n\tagents: AgentConfig[],\n\tagentName: string,\n\ttask: string,\n\tcwd: string | undefined,\n\tstep: number | undefined,\n\tsignal: AbortSignal | undefined,\n\tonUpdate: OnUpdateCallback | undefined,\n\tmakeDetails: (results: SubagentSingleResult[]) => SubagentDetails,\n): Promise<SubagentSingleResult> {\n\tconst agent = agents.find((a) => a.name === agentName);\n\n\tif (!agent) {\n\t\tconst available = agents.map((a) => `\"${a.name}\"`).join(\", \") || \"none\";\n\t\treturn {\n\t\t\tagent: agentName,\n\t\t\tagentSource: \"unknown\",\n\t\t\ttask,\n\t\t\texitCode: 1,\n\t\t\tmessages: [],\n\t\t\tstderr: `Unknown agent: \"${agentName}\". Available agents: ${available}.`,\n\t\t\tusage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0, contextTokens: 0, turns: 0 },\n\t\t\tstep,\n\t\t};\n\t}\n\n\tconst args: string[] = [\"--mode\", \"json\", \"-p\", \"--no-session\"];\n\tif (agent.model) args.push(\"--model\", agent.model);\n\tif (agent.tools && agent.tools.length > 0) args.push(\"--tools\", agent.tools.join(\",\"));\n\n\tlet tmpPromptDir: string | null = null;\n\tlet tmpPromptPath: string | null = null;\n\n\tconst currentResult: SubagentSingleResult = {\n\t\tagent: agentName,\n\t\tagentSource: agent.source,\n\t\ttask,\n\t\texitCode: 0,\n\t\tmessages: [],\n\t\tstderr: \"\",\n\t\tusage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0, contextTokens: 0, turns: 0 },\n\t\tmodel: agent.model,\n\t\tstep,\n\t};\n\n\tconst emitUpdate = () => {\n\t\tif (onUpdate) {\n\t\t\tonUpdate({\n\t\t\t\tcontent: [{ type: \"text\", text: getFinalOutput(currentResult.messages) || \"(running...)\" }],\n\t\t\t\tdetails: makeDetails([currentResult]),\n\t\t\t});\n\t\t}\n\t};\n\n\ttry {\n\t\tif (agent.systemPrompt.trim()) {\n\t\t\tconst tmp = await writePromptToTempFile(agent.name, agent.systemPrompt);\n\t\t\ttmpPromptDir = tmp.dir;\n\t\t\ttmpPromptPath = tmp.filePath;\n\t\t\targs.push(\"--append-system-prompt\", tmpPromptPath);\n\t\t}\n\n\t\targs.push(`Task: ${task}`);\n\t\tlet wasAborted = false;\n\n\t\tconst exitCode = await new Promise<number>((resolve) => {\n\t\t\tconst invocation = getCliInvocation(args);\n\t\t\tconst proc = spawn(invocation.command, invocation.args, {\n\t\t\t\tcwd: cwd ?? defaultCwd,\n\t\t\t\tshell: false,\n\t\t\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t\t\t\tenv: { ...process.env, [SUBAGENT_DEPTH_ENV]: String(currentSubagentDepth() + 1) },\n\t\t\t});\n\t\t\tlet buffer = \"\";\n\n\t\t\tconst processLine = (line: string) => {\n\t\t\t\tif (!line.trim()) return;\n\t\t\t\tlet event: any;\n\t\t\t\ttry {\n\t\t\t\t\tevent = JSON.parse(line);\n\t\t\t\t} catch {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (event.type === \"message_end\" && event.message) {\n\t\t\t\t\tconst msg = event.message as Message;\n\t\t\t\t\tcurrentResult.messages.push(msg);\n\n\t\t\t\t\tif (msg.role === \"assistant\") {\n\t\t\t\t\t\tcurrentResult.usage.turns++;\n\t\t\t\t\t\tconst usage = msg.usage;\n\t\t\t\t\t\tif (usage) {\n\t\t\t\t\t\t\tcurrentResult.usage.input += usage.input || 0;\n\t\t\t\t\t\t\tcurrentResult.usage.output += usage.output || 0;\n\t\t\t\t\t\t\tcurrentResult.usage.cacheRead += usage.cacheRead || 0;\n\t\t\t\t\t\t\tcurrentResult.usage.cacheWrite += usage.cacheWrite || 0;\n\t\t\t\t\t\t\tcurrentResult.usage.cost += usage.cost?.total || 0;\n\t\t\t\t\t\t\tcurrentResult.usage.contextTokens = usage.totalTokens || 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!currentResult.model && msg.model) currentResult.model = msg.model;\n\t\t\t\t\t\tif (msg.stopReason) currentResult.stopReason = msg.stopReason;\n\t\t\t\t\t\tif (msg.errorMessage) currentResult.errorMessage = msg.errorMessage;\n\t\t\t\t\t}\n\t\t\t\t\temitUpdate();\n\t\t\t\t}\n\n\t\t\t\tif (event.type === \"tool_result_end\" && event.message) {\n\t\t\t\t\tcurrentResult.messages.push(event.message as Message);\n\t\t\t\t\temitUpdate();\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tproc.stdout.on(\"data\", (data) => {\n\t\t\t\tbuffer += data.toString();\n\t\t\t\tconst lines = buffer.split(\"\\n\");\n\t\t\t\tbuffer = lines.pop() || \"\";\n\t\t\t\tfor (const line of lines) processLine(line);\n\t\t\t});\n\n\t\t\tproc.stderr.on(\"data\", (data) => {\n\t\t\t\tcurrentResult.stderr += data.toString();\n\t\t\t});\n\n\t\t\tproc.on(\"close\", (code) => {\n\t\t\t\tif (buffer.trim()) processLine(buffer);\n\t\t\t\tresolve(code ?? 0);\n\t\t\t});\n\n\t\t\tproc.on(\"error\", () => {\n\t\t\t\tresolve(1);\n\t\t\t});\n\n\t\t\tif (signal) {\n\t\t\t\tconst killProc = () => {\n\t\t\t\t\twasAborted = true;\n\t\t\t\t\tproc.kill(\"SIGTERM\");\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tif (!proc.killed) proc.kill(\"SIGKILL\");\n\t\t\t\t\t}, 5000);\n\t\t\t\t};\n\t\t\t\tif (signal.aborted) killProc();\n\t\t\t\telse signal.addEventListener(\"abort\", killProc, { once: true });\n\t\t\t}\n\t\t});\n\n\t\tcurrentResult.exitCode = exitCode;\n\t\tif (wasAborted) throw new Error(\"Subagent was aborted\");\n\t\treturn currentResult;\n\t} finally {\n\t\tif (tmpPromptPath)\n\t\t\ttry {\n\t\t\t\tfs.unlinkSync(tmpPromptPath);\n\t\t\t} catch {\n\t\t\t\t/* ignore */\n\t\t\t}\n\t\tif (tmpPromptDir)\n\t\t\ttry {\n\t\t\t\tfs.rmdirSync(tmpPromptDir);\n\t\t\t} catch {\n\t\t\t\t/* ignore */\n\t\t\t}\n\t}\n}\n\nconst TaskItem = Type.Object({\n\tagent: Type.String({ description: \"Name of the agent to invoke\" }),\n\ttask: Type.String({ description: \"Task to delegate to the agent\" }),\n\tcwd: Type.Optional(Type.String({ description: \"Working directory for the agent process\" })),\n});\n\nconst ChainItem = Type.Object({\n\tagent: Type.String({ description: \"Name of the agent to invoke\" }),\n\ttask: Type.String({ description: \"Task with optional {previous} placeholder for prior output\" }),\n\tcwd: Type.Optional(Type.String({ description: \"Working directory for the agent process\" })),\n});\n\nconst AgentScopeSchema = StringEnum([\"user\", \"project\", \"both\"] as const, {\n\tdescription: 'Which agent directories to use. Default: \"user\". Use \"both\" to include project-local agents.',\n\tdefault: \"user\",\n});\n\nconst SubagentParams = Type.Object({\n\tagent: Type.Optional(Type.String({ description: \"Name of the agent to invoke (for single mode)\" })),\n\ttask: Type.Optional(Type.String({ description: \"Task to delegate (for single mode)\" })),\n\ttasks: Type.Optional(Type.Array(TaskItem, { description: \"Array of {agent, task} for parallel execution\" })),\n\tchain: Type.Optional(Type.Array(ChainItem, { description: \"Array of {agent, task} for sequential execution\" })),\n\tagentScope: Type.Optional(AgentScopeSchema),\n\tconfirmProjectAgents: Type.Optional(\n\t\tType.Boolean({ description: \"Prompt before running project-local agents. Default: true.\", default: true }),\n\t),\n\tcwd: Type.Optional(Type.String({ description: \"Working directory for the agent process (single mode)\" })),\n});\n\nexport function createSubagentToolDefinition(cwd: string): ToolDefinition<typeof SubagentParams, SubagentDetails> {\n\treturn {\n\t\tname: \"subagent\",\n\t\tlabel: \"Subagent\",\n\t\tdescription: [\n\t\t\t\"Delegate tasks to specialized subagents with isolated context.\",\n\t\t\t\"Modes: single (agent + task), parallel (tasks array), chain (sequential with {previous} placeholder).\",\n\t\t\t`Default agent scope is \"user\" (from ${path.join(getAgentDir(), \"agents\")}).`,\n\t\t\t`To enable project-local agents in ${CONFIG_DIR_NAME}/agents, set agentScope: \"both\" (or \"project\").`,\n\t\t].join(\" \"),\n\t\tpromptSnippet:\n\t\t\t\"subagent: delegate work to isolated subagents — single task, parallel batch (tasks array), or sequential chain with {previous} placeholder\",\n\t\tpromptGuidelines: [\n\t\t\t\"Use subagent to fan out independent work in parallel (tasks array) or run multi-step pipelines (chain). Subagents run with isolated context and cannot delegate further.\",\n\t\t],\n\t\tparameters: SubagentParams,\n\n\t\tasync execute(_toolCallId, params, signal, onUpdate, ctx: ExtensionContext) {\n\t\t\tconst agentScope: AgentScope = params.agentScope ?? \"user\";\n\t\t\tconst defaultCwd = ctx?.cwd ?? cwd;\n\t\t\tconst discovery = discoverAgents(defaultCwd, agentScope);\n\t\t\tconst agents = discovery.agents;\n\t\t\tconst confirmProjectAgents = params.confirmProjectAgents ?? true;\n\n\t\t\t// Every requested child must appear in details.results, even when\n\t\t\t// nothing ran: external consumers fan out per-child bookkeeping from\n\t\t\t// the tool args and reconcile it against results by index.\n\t\t\tconst requestedChildren = (): Array<{ agent: string; task?: string; step?: number }> => {\n\t\t\t\tif (params.tasks && params.tasks.length > 0)\n\t\t\t\t\treturn params.tasks.map((t) => ({ agent: t.agent, task: t.task }));\n\t\t\t\tif (params.chain && params.chain.length > 0)\n\t\t\t\t\treturn params.chain.map((s, i) => ({ agent: s.agent, task: s.task, step: i + 1 }));\n\t\t\t\tif (params.agent) return [{ agent: params.agent, task: params.task }];\n\t\t\t\treturn [];\n\t\t\t};\n\t\t\tconst stubResult = (\n\t\t\t\tchild: { agent: string; task?: string; step?: number },\n\t\t\t\terrorMessage: string,\n\t\t\t): SubagentSingleResult => ({\n\t\t\t\tagent: child.agent,\n\t\t\t\tagentSource: \"unknown\",\n\t\t\t\ttask: child.task ?? \"\",\n\t\t\t\texitCode: 1,\n\t\t\t\tmessages: [],\n\t\t\t\tstderr: \"\",\n\t\t\t\tusage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0, contextTokens: 0, turns: 0 },\n\t\t\t\terrorMessage,\n\t\t\t\tstep: child.step,\n\t\t\t});\n\t\t\tconst stubAllChildren = (errorMessage: string): SubagentSingleResult[] =>\n\t\t\t\trequestedChildren().map((child) => stubResult(child, errorMessage));\n\n\t\t\tconst makeDetails =\n\t\t\t\t(mode: \"single\" | \"parallel\" | \"chain\") =>\n\t\t\t\t(results: SubagentSingleResult[]): SubagentDetails => ({\n\t\t\t\t\tmode,\n\t\t\t\t\tagentScope,\n\t\t\t\t\tprojectAgentsDir: discovery.projectAgentsDir,\n\t\t\t\t\tresults,\n\t\t\t\t});\n\n\t\t\tif (currentSubagentDepth() >= MAX_SUBAGENT_DEPTH) {\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\ttext: \"Nested delegation is not allowed: this process is already a subagent. Complete the task directly.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tdetails: makeDetails(\"single\")([]),\n\t\t\t\t\tisError: true,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst hasChain = (params.chain?.length ?? 0) > 0;\n\t\t\tconst hasTasks = (params.tasks?.length ?? 0) > 0;\n\t\t\tconst hasSingle = Boolean(params.agent && params.task);\n\t\t\tconst modeCount = Number(hasChain) + Number(hasTasks) + Number(hasSingle);\n\n\t\t\tif (modeCount !== 1) {\n\t\t\t\tconst available = agents.map((a) => `${a.name} (${a.source})`).join(\", \") || \"none\";\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\ttext: `Invalid parameters. Provide exactly one mode.\\nAvailable agents: ${available}`,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tdetails: makeDetails(\"single\")(\n\t\t\t\t\t\tstubAllChildren(\"not run: invalid parameters (provide exactly one mode)\"),\n\t\t\t\t\t),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif ((agentScope === \"project\" || agentScope === \"both\") && confirmProjectAgents && ctx?.hasUI) {\n\t\t\t\tconst requestedAgentNames = new Set<string>();\n\t\t\t\tif (params.chain) for (const step of params.chain) requestedAgentNames.add(step.agent);\n\t\t\t\tif (params.tasks) for (const t of params.tasks) requestedAgentNames.add(t.agent);\n\t\t\t\tif (params.agent) requestedAgentNames.add(params.agent);\n\n\t\t\t\tconst projectAgentsRequested = Array.from(requestedAgentNames)\n\t\t\t\t\t.map((name) => agents.find((a) => a.name === name))\n\t\t\t\t\t.filter((a): a is AgentConfig => a?.source === \"project\");\n\n\t\t\t\tif (projectAgentsRequested.length > 0) {\n\t\t\t\t\tconst names = projectAgentsRequested.map((a) => a.name).join(\", \");\n\t\t\t\t\tconst dir = discovery.projectAgentsDir ?? \"(unknown)\";\n\t\t\t\t\tconst ok = await ctx.ui.confirm(\n\t\t\t\t\t\t\"Run project-local agents?\",\n\t\t\t\t\t\t`Agents: ${names}\\nSource: ${dir}\\n\\nProject agents are repo-controlled. Only continue for trusted repositories.`,\n\t\t\t\t\t);\n\t\t\t\t\tif (!ok)\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tcontent: [{ type: \"text\", text: \"Canceled: project-local agents not approved.\" }],\n\t\t\t\t\t\t\tdetails: makeDetails(hasChain ? \"chain\" : hasTasks ? \"parallel\" : \"single\")(\n\t\t\t\t\t\t\t\tstubAllChildren(\"canceled: project-local agents not approved\"),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\tisError: true,\n\t\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (params.chain && params.chain.length > 0) {\n\t\t\t\tconst results: SubagentSingleResult[] = [];\n\t\t\t\tlet previousOutput = \"\";\n\n\t\t\t\tfor (let i = 0; i < params.chain.length; i++) {\n\t\t\t\t\tconst step = params.chain[i];\n\t\t\t\t\tconst taskWithContext = step.task.replace(/\\{previous\\}/g, previousOutput);\n\n\t\t\t\t\t// Create update callback that includes all previous results\n\t\t\t\t\tconst chainUpdate: OnUpdateCallback | undefined = onUpdate\n\t\t\t\t\t\t? (partial) => {\n\t\t\t\t\t\t\t\t// Combine completed results with current streaming result\n\t\t\t\t\t\t\t\tconst currentResult = partial.details?.results[0];\n\t\t\t\t\t\t\t\tif (currentResult) {\n\t\t\t\t\t\t\t\t\tconst allResults = [...results, currentResult];\n\t\t\t\t\t\t\t\t\tonUpdate({\n\t\t\t\t\t\t\t\t\t\tcontent: partial.content,\n\t\t\t\t\t\t\t\t\t\tdetails: makeDetails(\"chain\")(allResults),\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: undefined;\n\n\t\t\t\t\tconst result = await runSingleAgent(\n\t\t\t\t\t\tdefaultCwd,\n\t\t\t\t\t\tagents,\n\t\t\t\t\t\tstep.agent,\n\t\t\t\t\t\ttaskWithContext,\n\t\t\t\t\t\tstep.cwd,\n\t\t\t\t\t\ti + 1,\n\t\t\t\t\t\tsignal,\n\t\t\t\t\t\tchainUpdate,\n\t\t\t\t\t\tmakeDetails(\"chain\"),\n\t\t\t\t\t);\n\t\t\t\t\tresults.push(result);\n\n\t\t\t\t\tconst isError = isFailedResult(result);\n\t\t\t\t\tif (isError) {\n\t\t\t\t\t\tconst errorMsg = getResultOutput(result);\n\t\t\t\t\t\tconst skipped = params.chain\n\t\t\t\t\t\t\t.slice(i + 1)\n\t\t\t\t\t\t\t.map((s, offset) =>\n\t\t\t\t\t\t\t\tstubResult(\n\t\t\t\t\t\t\t\t\t{ agent: s.agent, task: s.task, step: i + 2 + offset },\n\t\t\t\t\t\t\t\t\t`not run: chain stopped at step ${i + 1}`,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tcontent: [{ type: \"text\", text: `Chain stopped at step ${i + 1} (${step.agent}): ${errorMsg}` }],\n\t\t\t\t\t\t\tdetails: makeDetails(\"chain\")([...results, ...skipped]),\n\t\t\t\t\t\t\tisError: true,\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\tpreviousOutput = getFinalOutput(result.messages);\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [{ type: \"text\", text: getFinalOutput(results[results.length - 1].messages) || \"(no output)\" }],\n\t\t\t\t\tdetails: makeDetails(\"chain\")(results),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif (params.tasks && params.tasks.length > 0) {\n\t\t\t\tif (params.tasks.length > MAX_PARALLEL_TASKS)\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\ttext: `Too many parallel tasks (${params.tasks.length}). Max is ${MAX_PARALLEL_TASKS}.`,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t\tdetails: makeDetails(\"parallel\")(\n\t\t\t\t\t\t\tstubAllChildren(`not run: too many parallel tasks (max ${MAX_PARALLEL_TASKS})`),\n\t\t\t\t\t\t),\n\t\t\t\t\t\tisError: true,\n\t\t\t\t\t};\n\n\t\t\t\t// Track all results for streaming updates\n\t\t\t\tconst allResults: SubagentSingleResult[] = new Array(params.tasks.length);\n\n\t\t\t\t// Initialize placeholder results\n\t\t\t\tfor (let i = 0; i < params.tasks.length; i++) {\n\t\t\t\t\tallResults[i] = {\n\t\t\t\t\t\tagent: params.tasks[i].agent,\n\t\t\t\t\t\tagentSource: \"unknown\",\n\t\t\t\t\t\ttask: params.tasks[i].task,\n\t\t\t\t\t\texitCode: -1, // -1 = still running\n\t\t\t\t\t\tmessages: [],\n\t\t\t\t\t\tstderr: \"\",\n\t\t\t\t\t\tusage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0, contextTokens: 0, turns: 0 },\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tconst emitParallelUpdate = () => {\n\t\t\t\t\tif (onUpdate) {\n\t\t\t\t\t\tconst running = allResults.filter((r) => r.exitCode === -1).length;\n\t\t\t\t\t\tconst done = allResults.filter((r) => r.exitCode !== -1).length;\n\t\t\t\t\t\tonUpdate({\n\t\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t\t{ type: \"text\", text: `Parallel: ${done}/${allResults.length} done, ${running} running...` },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\tdetails: makeDetails(\"parallel\")([...allResults]),\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\tconst results = await mapWithConcurrencyLimit(\n\t\t\t\t\tparams.tasks,\n\t\t\t\t\tMAX_CONCURRENCY,\n\t\t\t\t\tasync (t, index) => {\n\t\t\t\t\t\tconst result = await runSingleAgent(\n\t\t\t\t\t\t\tdefaultCwd,\n\t\t\t\t\t\t\tagents,\n\t\t\t\t\t\t\tt.agent,\n\t\t\t\t\t\t\tt.task,\n\t\t\t\t\t\t\tt.cwd,\n\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\tsignal,\n\t\t\t\t\t\t\t// Per-task update callback\n\t\t\t\t\t\t\t(partial) => {\n\t\t\t\t\t\t\t\tif (partial.details?.results[0]) {\n\t\t\t\t\t\t\t\t\tallResults[index] = partial.details.results[0];\n\t\t\t\t\t\t\t\t\temitParallelUpdate();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tmakeDetails(\"parallel\"),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tallResults[index] = result;\n\t\t\t\t\t\temitParallelUpdate();\n\t\t\t\t\t\treturn result;\n\t\t\t\t\t},\n\t\t\t\t\tsignal,\n\t\t\t\t);\n\n\t\t\t\tconst successCount = results.filter((r) => !isFailedResult(r)).length;\n\t\t\t\tconst summaries = results.map((r) => {\n\t\t\t\t\tconst output = truncateParallelOutput(getResultOutput(r));\n\t\t\t\t\tconst status = isFailedResult(r)\n\t\t\t\t\t\t? `failed${r.stopReason && r.stopReason !== \"end\" ? ` (${r.stopReason})` : \"\"}`\n\t\t\t\t\t\t: \"completed\";\n\t\t\t\t\treturn `### [${r.agent}] ${status}\\n\\n${output}`;\n\t\t\t\t});\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\ttext: `Parallel: ${successCount}/${results.length} succeeded\\n\\n${summaries.join(\"\\n\\n---\\n\\n\")}`,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tdetails: makeDetails(\"parallel\")(results),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif (params.agent && params.task) {\n\t\t\t\tconst result = await runSingleAgent(\n\t\t\t\t\tdefaultCwd,\n\t\t\t\t\tagents,\n\t\t\t\t\tparams.agent,\n\t\t\t\t\tparams.task,\n\t\t\t\t\tparams.cwd,\n\t\t\t\t\tundefined,\n\t\t\t\t\tsignal,\n\t\t\t\t\tonUpdate,\n\t\t\t\t\tmakeDetails(\"single\"),\n\t\t\t\t);\n\t\t\t\tconst isError = isFailedResult(result);\n\t\t\t\tif (isError) {\n\t\t\t\t\tconst errorMsg = getResultOutput(result);\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [{ type: \"text\", text: `Agent ${result.stopReason || \"failed\"}: ${errorMsg}` }],\n\t\t\t\t\t\tdetails: makeDetails(\"single\")([result]),\n\t\t\t\t\t\tisError: true,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [{ type: \"text\", text: getFinalOutput(result.messages) || \"(no output)\" }],\n\t\t\t\t\tdetails: makeDetails(\"single\")([result]),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst available = agents.map((a) => `${a.name} (${a.source})`).join(\", \") || \"none\";\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: \"text\", text: `Invalid parameters. Available agents: ${available}` }],\n\t\t\t\tdetails: makeDetails(\"single\")([]),\n\t\t\t};\n\t\t},\n\n\t\trenderCall(args, theme: Theme, _context) {\n\t\t\tconst scope: AgentScope = args.agentScope ?? \"user\";\n\t\t\tif (args.chain && args.chain.length > 0) {\n\t\t\t\tlet text =\n\t\t\t\t\ttheme.fg(\"toolTitle\", theme.bold(\"subagent \")) +\n\t\t\t\t\ttheme.fg(\"accent\", `chain (${args.chain.length} steps)`) +\n\t\t\t\t\ttheme.fg(\"muted\", ` [${scope}]`);\n\t\t\t\tfor (let i = 0; i < Math.min(args.chain.length, 3); i++) {\n\t\t\t\t\tconst step = args.chain[i];\n\t\t\t\t\t// Clean up {previous} placeholder for display\n\t\t\t\t\tconst cleanTask = step.task.replace(/\\{previous\\}/g, \"\").trim();\n\t\t\t\t\tconst preview = cleanTask.length > 40 ? `${cleanTask.slice(0, 40)}...` : cleanTask;\n\t\t\t\t\ttext +=\n\t\t\t\t\t\t\"\\n \" +\n\t\t\t\t\t\ttheme.fg(\"muted\", `${i + 1}.`) +\n\t\t\t\t\t\t\" \" +\n\t\t\t\t\t\ttheme.fg(\"accent\", step.agent) +\n\t\t\t\t\t\ttheme.fg(\"dim\", ` ${preview}`);\n\t\t\t\t}\n\t\t\t\tif (args.chain.length > 3) text += `\\n ${theme.fg(\"muted\", `... +${args.chain.length - 3} more`)}`;\n\t\t\t\treturn new Text(text, 0, 0);\n\t\t\t}\n\t\t\tif (args.tasks && args.tasks.length > 0) {\n\t\t\t\tlet text =\n\t\t\t\t\ttheme.fg(\"toolTitle\", theme.bold(\"subagent \")) +\n\t\t\t\t\ttheme.fg(\"accent\", `parallel (${args.tasks.length} tasks)`) +\n\t\t\t\t\ttheme.fg(\"muted\", ` [${scope}]`);\n\t\t\t\tfor (const t of args.tasks.slice(0, 3)) {\n\t\t\t\t\tconst preview = t.task.length > 40 ? `${t.task.slice(0, 40)}...` : t.task;\n\t\t\t\t\ttext += `\\n ${theme.fg(\"accent\", t.agent)}${theme.fg(\"dim\", ` ${preview}`)}`;\n\t\t\t\t}\n\t\t\t\tif (args.tasks.length > 3) text += `\\n ${theme.fg(\"muted\", `... +${args.tasks.length - 3} more`)}`;\n\t\t\t\treturn new Text(text, 0, 0);\n\t\t\t}\n\t\t\tconst agentName = args.agent || \"...\";\n\t\t\tconst preview = args.task ? (args.task.length > 60 ? `${args.task.slice(0, 60)}...` : args.task) : \"...\";\n\t\t\tlet text =\n\t\t\t\ttheme.fg(\"toolTitle\", theme.bold(\"subagent \")) +\n\t\t\t\ttheme.fg(\"accent\", agentName) +\n\t\t\t\ttheme.fg(\"muted\", ` [${scope}]`);\n\t\t\ttext += `\\n ${theme.fg(\"dim\", preview)}`;\n\t\t\treturn new Text(text, 0, 0);\n\t\t},\n\n\t\trenderResult(result, { expanded }, theme: Theme, _context) {\n\t\t\tconst details = result.details as SubagentDetails | undefined;\n\t\t\tif (!details || details.results.length === 0) {\n\t\t\t\tconst text = result.content[0];\n\t\t\t\treturn new Text(text?.type === \"text\" ? text.text : \"(no output)\", 0, 0);\n\t\t\t}\n\n\t\t\tconst mdTheme = getMarkdownTheme();\n\n\t\t\tconst renderDisplayItems = (items: DisplayItem[], limit?: number) => {\n\t\t\t\tconst toShow = limit ? items.slice(-limit) : items;\n\t\t\t\tconst skipped = limit && items.length > limit ? items.length - limit : 0;\n\t\t\t\tlet text = \"\";\n\t\t\t\tif (skipped > 0) text += theme.fg(\"muted\", `... ${skipped} earlier items\\n`);\n\t\t\t\tfor (const item of toShow) {\n\t\t\t\t\tif (item.type === \"text\") {\n\t\t\t\t\t\tconst preview = expanded ? item.text : item.text.split(\"\\n\").slice(0, 3).join(\"\\n\");\n\t\t\t\t\t\ttext += `${theme.fg(\"toolOutput\", preview)}\\n`;\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttext += `${theme.fg(\"muted\", \"→ \") + formatToolCall(item.name, item.args, theme.fg.bind(theme))}\\n`;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn text.trimEnd();\n\t\t\t};\n\n\t\t\tif (details.mode === \"single\" && details.results.length === 1) {\n\t\t\t\tconst r = details.results[0];\n\t\t\t\tconst isError = isFailedResult(r);\n\t\t\t\tconst icon = isError ? theme.fg(\"error\", \"✗\") : theme.fg(\"success\", \"✓\");\n\t\t\t\tconst displayItems = getDisplayItems(r.messages);\n\t\t\t\tconst finalOutput = getFinalOutput(r.messages);\n\n\t\t\t\tif (expanded) {\n\t\t\t\t\tconst container = new Container();\n\t\t\t\t\tlet header = `${icon} ${theme.fg(\"toolTitle\", theme.bold(r.agent))}${theme.fg(\"muted\", ` (${r.agentSource})`)}`;\n\t\t\t\t\tif (isError && r.stopReason) header += ` ${theme.fg(\"error\", `[${r.stopReason}]`)}`;\n\t\t\t\t\tcontainer.addChild(new Text(header, 0, 0));\n\t\t\t\t\tif (isError && r.errorMessage)\n\t\t\t\t\t\tcontainer.addChild(new Text(theme.fg(\"error\", `Error: ${r.errorMessage}`), 0, 0));\n\t\t\t\t\tcontainer.addChild(new Spacer(1));\n\t\t\t\t\tcontainer.addChild(new Text(theme.fg(\"muted\", \"─── Task ───\"), 0, 0));\n\t\t\t\t\tcontainer.addChild(new Text(theme.fg(\"dim\", r.task), 0, 0));\n\t\t\t\t\tcontainer.addChild(new Spacer(1));\n\t\t\t\t\tcontainer.addChild(new Text(theme.fg(\"muted\", \"─── Output ───\"), 0, 0));\n\t\t\t\t\tif (displayItems.length === 0 && !finalOutput) {\n\t\t\t\t\t\tcontainer.addChild(new Text(theme.fg(\"muted\", \"(no output)\"), 0, 0));\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfor (const item of displayItems) {\n\t\t\t\t\t\t\tif (item.type === \"toolCall\")\n\t\t\t\t\t\t\t\tcontainer.addChild(\n\t\t\t\t\t\t\t\t\tnew Text(\n\t\t\t\t\t\t\t\t\t\ttheme.fg(\"muted\", \"→ \") + formatToolCall(item.name, item.args, theme.fg.bind(theme)),\n\t\t\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (finalOutput) {\n\t\t\t\t\t\t\tcontainer.addChild(new Spacer(1));\n\t\t\t\t\t\t\tcontainer.addChild(new Markdown(finalOutput.trim(), 0, 0, mdTheme));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tconst usageStr = formatUsageStats(r.usage, r.model);\n\t\t\t\t\tif (usageStr) {\n\t\t\t\t\t\tcontainer.addChild(new Spacer(1));\n\t\t\t\t\t\tcontainer.addChild(new Text(theme.fg(\"dim\", usageStr), 0, 0));\n\t\t\t\t\t}\n\t\t\t\t\treturn container;\n\t\t\t\t}\n\n\t\t\t\tlet text = `${icon} ${theme.fg(\"toolTitle\", theme.bold(r.agent))}${theme.fg(\"muted\", ` (${r.agentSource})`)}`;\n\t\t\t\tif (isError && r.stopReason) text += ` ${theme.fg(\"error\", `[${r.stopReason}]`)}`;\n\t\t\t\tif (isError && r.errorMessage) text += `\\n${theme.fg(\"error\", `Error: ${r.errorMessage}`)}`;\n\t\t\t\telse if (displayItems.length === 0) text += `\\n${theme.fg(\"muted\", \"(no output)\")}`;\n\t\t\t\telse {\n\t\t\t\t\ttext += `\\n${renderDisplayItems(displayItems, COLLAPSED_ITEM_COUNT)}`;\n\t\t\t\t\tif (displayItems.length > COLLAPSED_ITEM_COUNT) text += `\\n${theme.fg(\"muted\", \"(Ctrl+O to expand)\")}`;\n\t\t\t\t}\n\t\t\t\tconst usageStr = formatUsageStats(r.usage, r.model);\n\t\t\t\tif (usageStr) text += `\\n${theme.fg(\"dim\", usageStr)}`;\n\t\t\t\treturn new Text(text, 0, 0);\n\t\t\t}\n\n\t\t\tconst aggregateUsage = (results: SubagentSingleResult[]) => {\n\t\t\t\tconst total = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0, turns: 0 };\n\t\t\t\tfor (const r of results) {\n\t\t\t\t\ttotal.input += r.usage.input;\n\t\t\t\t\ttotal.output += r.usage.output;\n\t\t\t\t\ttotal.cacheRead += r.usage.cacheRead;\n\t\t\t\t\ttotal.cacheWrite += r.usage.cacheWrite;\n\t\t\t\t\ttotal.cost += r.usage.cost;\n\t\t\t\t\ttotal.turns += r.usage.turns;\n\t\t\t\t}\n\t\t\t\treturn total;\n\t\t\t};\n\n\t\t\tif (details.mode === \"chain\") {\n\t\t\t\tconst successCount = details.results.filter((r) => r.exitCode === 0).length;\n\t\t\t\tconst icon = successCount === details.results.length ? theme.fg(\"success\", \"✓\") : theme.fg(\"error\", \"✗\");\n\n\t\t\t\tif (expanded) {\n\t\t\t\t\tconst container = new Container();\n\t\t\t\t\tcontainer.addChild(\n\t\t\t\t\t\tnew Text(\n\t\t\t\t\t\t\ticon +\n\t\t\t\t\t\t\t\t\" \" +\n\t\t\t\t\t\t\t\ttheme.fg(\"toolTitle\", theme.bold(\"chain \")) +\n\t\t\t\t\t\t\t\ttheme.fg(\"accent\", `${successCount}/${details.results.length} steps`),\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\n\t\t\t\t\tfor (const r of details.results) {\n\t\t\t\t\t\tconst rIcon = r.exitCode === 0 ? theme.fg(\"success\", \"✓\") : theme.fg(\"error\", \"✗\");\n\t\t\t\t\t\tconst displayItems = getDisplayItems(r.messages);\n\t\t\t\t\t\tconst finalOutput = getFinalOutput(r.messages);\n\n\t\t\t\t\t\tcontainer.addChild(new Spacer(1));\n\t\t\t\t\t\tcontainer.addChild(\n\t\t\t\t\t\t\tnew Text(\n\t\t\t\t\t\t\t\t`${theme.fg(\"muted\", `─── Step ${r.step}: `) + theme.fg(\"accent\", r.agent)} ${rIcon}`,\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tcontainer.addChild(new Text(theme.fg(\"muted\", \"Task: \") + theme.fg(\"dim\", r.task), 0, 0));\n\n\t\t\t\t\t\t// Show tool calls\n\t\t\t\t\t\tfor (const item of displayItems) {\n\t\t\t\t\t\t\tif (item.type === \"toolCall\") {\n\t\t\t\t\t\t\t\tcontainer.addChild(\n\t\t\t\t\t\t\t\t\tnew Text(\n\t\t\t\t\t\t\t\t\t\ttheme.fg(\"muted\", \"→ \") + formatToolCall(item.name, item.args, theme.fg.bind(theme)),\n\t\t\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Show final output as markdown\n\t\t\t\t\t\tif (finalOutput) {\n\t\t\t\t\t\t\tcontainer.addChild(new Spacer(1));\n\t\t\t\t\t\t\tcontainer.addChild(new Markdown(finalOutput.trim(), 0, 0, mdTheme));\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst stepUsage = formatUsageStats(r.usage, r.model);\n\t\t\t\t\t\tif (stepUsage) container.addChild(new Text(theme.fg(\"dim\", stepUsage), 0, 0));\n\t\t\t\t\t}\n\n\t\t\t\t\tconst usageStr = formatUsageStats(aggregateUsage(details.results));\n\t\t\t\t\tif (usageStr) {\n\t\t\t\t\t\tcontainer.addChild(new Spacer(1));\n\t\t\t\t\t\tcontainer.addChild(new Text(theme.fg(\"dim\", `Total: ${usageStr}`), 0, 0));\n\t\t\t\t\t}\n\t\t\t\t\treturn container;\n\t\t\t\t}\n\n\t\t\t\t// Collapsed view\n\t\t\t\tlet text =\n\t\t\t\t\ticon +\n\t\t\t\t\t\" \" +\n\t\t\t\t\ttheme.fg(\"toolTitle\", theme.bold(\"chain \")) +\n\t\t\t\t\ttheme.fg(\"accent\", `${successCount}/${details.results.length} steps`);\n\t\t\t\tfor (const r of details.results) {\n\t\t\t\t\tconst rIcon = r.exitCode === 0 ? theme.fg(\"success\", \"✓\") : theme.fg(\"error\", \"✗\");\n\t\t\t\t\tconst displayItems = getDisplayItems(r.messages);\n\t\t\t\t\ttext += `\\n\\n${theme.fg(\"muted\", `─── Step ${r.step}: `)}${theme.fg(\"accent\", r.agent)} ${rIcon}`;\n\t\t\t\t\tif (displayItems.length === 0) text += `\\n${theme.fg(\"muted\", \"(no output)\")}`;\n\t\t\t\t\telse text += `\\n${renderDisplayItems(displayItems, 5)}`;\n\t\t\t\t}\n\t\t\t\tconst usageStr = formatUsageStats(aggregateUsage(details.results));\n\t\t\t\tif (usageStr) text += `\\n\\n${theme.fg(\"dim\", `Total: ${usageStr}`)}`;\n\t\t\t\ttext += `\\n${theme.fg(\"muted\", \"(Ctrl+O to expand)\")}`;\n\t\t\t\treturn new Text(text, 0, 0);\n\t\t\t}\n\n\t\t\tif (details.mode === \"parallel\") {\n\t\t\t\tconst running = details.results.filter((r) => r.exitCode === -1).length;\n\t\t\t\tconst successCount = details.results.filter((r) => r.exitCode !== -1 && !isFailedResult(r)).length;\n\t\t\t\tconst failCount = details.results.filter((r) => r.exitCode !== -1 && isFailedResult(r)).length;\n\t\t\t\tconst isRunning = running > 0;\n\t\t\t\tconst icon = isRunning\n\t\t\t\t\t? theme.fg(\"warning\", \"⏳\")\n\t\t\t\t\t: failCount > 0\n\t\t\t\t\t\t? theme.fg(\"warning\", \"◐\")\n\t\t\t\t\t\t: theme.fg(\"success\", \"✓\");\n\t\t\t\tconst status = isRunning\n\t\t\t\t\t? `${successCount + failCount}/${details.results.length} done, ${running} running`\n\t\t\t\t\t: `${successCount}/${details.results.length} tasks`;\n\n\t\t\t\tif (expanded && !isRunning) {\n\t\t\t\t\tconst container = new Container();\n\t\t\t\t\tcontainer.addChild(\n\t\t\t\t\t\tnew Text(\n\t\t\t\t\t\t\t`${icon} ${theme.fg(\"toolTitle\", theme.bold(\"parallel \"))}${theme.fg(\"accent\", status)}`,\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\n\t\t\t\t\tfor (const r of details.results) {\n\t\t\t\t\t\tconst rIcon = isFailedResult(r) ? theme.fg(\"error\", \"✗\") : theme.fg(\"success\", \"✓\");\n\t\t\t\t\t\tconst displayItems = getDisplayItems(r.messages);\n\t\t\t\t\t\tconst finalOutput = getFinalOutput(r.messages);\n\n\t\t\t\t\t\tcontainer.addChild(new Spacer(1));\n\t\t\t\t\t\tcontainer.addChild(\n\t\t\t\t\t\t\tnew Text(`${theme.fg(\"muted\", \"─── \") + theme.fg(\"accent\", r.agent)} ${rIcon}`, 0, 0),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tcontainer.addChild(new Text(theme.fg(\"muted\", \"Task: \") + theme.fg(\"dim\", r.task), 0, 0));\n\n\t\t\t\t\t\t// Show tool calls\n\t\t\t\t\t\tfor (const item of displayItems) {\n\t\t\t\t\t\t\tif (item.type === \"toolCall\") {\n\t\t\t\t\t\t\t\tcontainer.addChild(\n\t\t\t\t\t\t\t\t\tnew Text(\n\t\t\t\t\t\t\t\t\t\ttheme.fg(\"muted\", \"→ \") + formatToolCall(item.name, item.args, theme.fg.bind(theme)),\n\t\t\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Show final output as markdown\n\t\t\t\t\t\tif (finalOutput) {\n\t\t\t\t\t\t\tcontainer.addChild(new Spacer(1));\n\t\t\t\t\t\t\tcontainer.addChild(new Markdown(finalOutput.trim(), 0, 0, mdTheme));\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst taskUsage = formatUsageStats(r.usage, r.model);\n\t\t\t\t\t\tif (taskUsage) container.addChild(new Text(theme.fg(\"dim\", taskUsage), 0, 0));\n\t\t\t\t\t}\n\n\t\t\t\t\tconst usageStr = formatUsageStats(aggregateUsage(details.results));\n\t\t\t\t\tif (usageStr) {\n\t\t\t\t\t\tcontainer.addChild(new Spacer(1));\n\t\t\t\t\t\tcontainer.addChild(new Text(theme.fg(\"dim\", `Total: ${usageStr}`), 0, 0));\n\t\t\t\t\t}\n\t\t\t\t\treturn container;\n\t\t\t\t}\n\n\t\t\t\t// Collapsed view (or still running)\n\t\t\t\tlet text = `${icon} ${theme.fg(\"toolTitle\", theme.bold(\"parallel \"))}${theme.fg(\"accent\", status)}`;\n\t\t\t\tfor (const r of details.results) {\n\t\t\t\t\tconst rIcon =\n\t\t\t\t\t\tr.exitCode === -1\n\t\t\t\t\t\t\t? theme.fg(\"warning\", \"⏳\")\n\t\t\t\t\t\t\t: isFailedResult(r)\n\t\t\t\t\t\t\t\t? theme.fg(\"error\", \"✗\")\n\t\t\t\t\t\t\t\t: theme.fg(\"success\", \"✓\");\n\t\t\t\t\tconst displayItems = getDisplayItems(r.messages);\n\t\t\t\t\ttext += `\\n\\n${theme.fg(\"muted\", \"─── \")}${theme.fg(\"accent\", r.agent)} ${rIcon}`;\n\t\t\t\t\tif (displayItems.length === 0)\n\t\t\t\t\t\ttext += `\\n${theme.fg(\"muted\", r.exitCode === -1 ? \"(running...)\" : \"(no output)\")}`;\n\t\t\t\t\telse text += `\\n${renderDisplayItems(displayItems, 5)}`;\n\t\t\t\t}\n\t\t\t\tif (!isRunning) {\n\t\t\t\t\tconst usageStr = formatUsageStats(aggregateUsage(details.results));\n\t\t\t\t\tif (usageStr) text += `\\n\\n${theme.fg(\"dim\", `Total: ${usageStr}`)}`;\n\t\t\t\t}\n\t\t\t\tif (!expanded) text += `\\n${theme.fg(\"muted\", \"(Ctrl+O to expand)\")}`;\n\t\t\t\treturn new Text(text, 0, 0);\n\t\t\t}\n\n\t\t\tconst text = result.content[0];\n\t\t\treturn new Text(text?.type === \"text\" ? text.text : \"(no output)\", 0, 0);\n\t\t},\n\t};\n}\n\nexport function createSubagentTool(cwd: string) {\n\treturn wrapToolDefinition(createSubagentToolDefinition(cwd));\n}\n"]}