minimal-agent 0.10.0 → 0.12.0

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 (573) hide show
  1. package/README.md +11 -3
  2. package/package.json +52 -5
  3. package/plugins/computer_use/.claude-plugin/plugin.json +6 -0
  4. package/plugins/computer_use/README.md +94 -0
  5. package/plugins/computer_use/app/_template.md +142 -0
  6. package/plugins/computer_use/app/chrome.md +165 -0
  7. package/plugins/computer_use/app/finder.md +76 -0
  8. package/plugins/computer_use/app/macos-system-settings.md +81 -0
  9. package/plugins/computer_use/app/microsoft-excel.md +80 -0
  10. package/plugins/computer_use/app/microsoft-powerpoint.md +80 -0
  11. package/plugins/computer_use/app/microsoft-word.md +79 -0
  12. package/plugins/computer_use/app/wechat.md +413 -0
  13. package/plugins/computer_use/app/weread.md +319 -0
  14. package/plugins/computer_use/commands/computeruse.md +25 -0
  15. package/plugins/computer_use/commands/cu.md +9 -0
  16. package/plugins/computer_use/plugin.js +26 -0
  17. package/plugins/computer_use/plugin.ts +30 -0
  18. package/plugins/computer_use/src/capture.js +90 -0
  19. package/plugins/computer_use/src/capture.ts +104 -0
  20. package/plugins/computer_use/src/commands.js +91 -0
  21. package/plugins/computer_use/src/commands.ts +103 -0
  22. package/plugins/computer_use/src/daemon.js +134 -0
  23. package/plugins/computer_use/src/daemon.ts +161 -0
  24. package/plugins/computer_use/src/manuals.js +135 -0
  25. package/plugins/computer_use/src/manuals.ts +159 -0
  26. package/plugins/computer_use/src/verify.js +168 -0
  27. package/plugins/computer_use/src/verify.ts +219 -0
  28. package/plugins/computer_use/test/commands.test.ts +73 -0
  29. package/plugins/cron-runner/plugin.ts +38 -0
  30. package/plugins/cron-runner/src/commands.ts +373 -0
  31. package/plugins/cron-runner/src/cronTime.ts +155 -0
  32. package/plugins/cron-runner/src/lock.ts +79 -0
  33. package/plugins/cron-runner/src/runs.ts +99 -0
  34. package/plugins/cron-runner/src/scheduleEngine.ts +76 -0
  35. package/plugins/cron-runner/src/scheduler.ts +376 -0
  36. package/plugins/cron-runner/src/schema.ts +139 -0
  37. package/plugins/cron-runner/src/service.ts +193 -0
  38. package/plugins/cron-runner/src/store.ts +333 -0
  39. package/plugins/cron-runner/src/types.ts +141 -0
  40. package/plugins/cron-runner/test/cronTime.test.ts +41 -0
  41. package/plugins/cron-runner/test/plugin-integration.test.ts +47 -0
  42. package/plugins/cron-runner/test/scheduleEngine.test.ts +41 -0
  43. package/plugins/cron-runner/test/service.test.ts +76 -0
  44. package/plugins/cron-runner/test/store-and-scheduler.test.ts +501 -0
  45. package/plugins/workflow-runner/plugin.js +56 -2
  46. package/plugins/workflow-runner/plugin.ts +113 -0
  47. package/plugins/workflow-runner/src/agentCommon.js +43 -4
  48. package/plugins/workflow-runner/src/agentCommon.ts +435 -0
  49. package/plugins/workflow-runner/src/controlFlow/branch.js +40 -0
  50. package/plugins/workflow-runner/src/controlFlow/branch.ts +46 -0
  51. package/plugins/workflow-runner/src/controlFlow/loop.js +211 -0
  52. package/plugins/workflow-runner/src/controlFlow/loop.ts +248 -0
  53. package/plugins/workflow-runner/src/controlFlow/pause.js +129 -0
  54. package/plugins/workflow-runner/src/controlFlow/pause.ts +141 -0
  55. package/plugins/workflow-runner/src/controlFlow/signal.js +21 -0
  56. package/plugins/workflow-runner/src/controlFlow/signal.ts +29 -0
  57. package/plugins/workflow-runner/src/controlFlow/types.js +18 -0
  58. package/plugins/workflow-runner/src/controlFlow/types.ts +63 -0
  59. package/plugins/workflow-runner/src/dslManifest.ts +127 -0
  60. package/plugins/workflow-runner/src/expressions.ts +622 -0
  61. package/plugins/workflow-runner/src/index.js +13 -4
  62. package/plugins/workflow-runner/src/index.ts +338 -0
  63. package/plugins/workflow-runner/src/jsonPayload.ts +84 -0
  64. package/plugins/workflow-runner/src/loader.js +23 -0
  65. package/plugins/workflow-runner/src/loader.ts +721 -0
  66. package/plugins/workflow-runner/src/multimodal.js +2 -1
  67. package/plugins/workflow-runner/src/multimodal.ts +64 -0
  68. package/plugins/workflow-runner/src/recovery.ts +149 -0
  69. package/plugins/workflow-runner/src/runner.js +75 -659
  70. package/plugins/workflow-runner/src/runner.ts +604 -0
  71. package/plugins/workflow-runner/src/stepExecutors/agent.ts +234 -0
  72. package/plugins/workflow-runner/src/stepExecutors/assert.ts +50 -0
  73. package/plugins/workflow-runner/src/stepExecutors/echo.js +31 -0
  74. package/plugins/workflow-runner/src/stepExecutors/echo.ts +38 -0
  75. package/plugins/workflow-runner/src/stepExecutors/llm.ts +133 -0
  76. package/plugins/workflow-runner/src/stepExecutors/set.js +49 -0
  77. package/plugins/workflow-runner/src/stepExecutors/set.ts +56 -0
  78. package/plugins/workflow-runner/src/stepExecutors/skill.js +5 -6
  79. package/plugins/workflow-runner/src/stepExecutors/skill.ts +140 -0
  80. package/plugins/workflow-runner/src/stepExecutors/tool.js +80 -8
  81. package/plugins/workflow-runner/src/stepExecutors/tool.ts +256 -0
  82. package/plugins/workflow-runner/src/stepExecutors/verify.ts +68 -0
  83. package/plugins/workflow-runner/src/stepPipeline.js +277 -0
  84. package/plugins/workflow-runner/src/stepPipeline.ts +366 -0
  85. package/plugins/workflow-runner/src/taskIdentity.ts +405 -0
  86. package/plugins/workflow-runner/src/toolRuntime.js +48 -0
  87. package/plugins/workflow-runner/src/toolRuntime.ts +64 -0
  88. package/plugins/workflow-runner/src/types.js +37 -1
  89. package/plugins/workflow-runner/src/types.ts +602 -0
  90. package/plugins/workflow-runner/src/workflowState.ts +733 -0
  91. package/plugins/workflow-runner/test/agent.test.ts +587 -0
  92. package/plugins/workflow-runner/test/agentLlmError.test.ts +373 -0
  93. package/plugins/workflow-runner/test/bashBlacklist.sweep.test.ts +65 -0
  94. package/plugins/workflow-runner/test/captureMisbind.test.ts +99 -0
  95. package/plugins/workflow-runner/test/cli.e2e.test.ts +147 -0
  96. package/plugins/workflow-runner/test/context-files.test.ts +320 -0
  97. package/plugins/workflow-runner/test/e2e.test.ts +370 -0
  98. package/plugins/workflow-runner/test/engineRobustness.test.ts +226 -0
  99. package/plugins/workflow-runner/test/expressions.test.ts +397 -0
  100. package/plugins/workflow-runner/test/foundation.test.ts +126 -0
  101. package/plugins/workflow-runner/test/graceful.test.ts +139 -0
  102. package/plugins/workflow-runner/test/greedyInputs.load.test.ts +47 -0
  103. package/plugins/workflow-runner/test/hostCapability.test.ts +108 -0
  104. package/plugins/workflow-runner/test/illustrate.load.test.ts +183 -0
  105. package/plugins/workflow-runner/test/jsonPayload.test.ts +83 -0
  106. package/plugins/workflow-runner/test/loader.test.ts +617 -0
  107. package/plugins/workflow-runner/test/maxTurnsRetryDelay.test.ts +33 -0
  108. package/plugins/workflow-runner/test/multimodal.test.ts +342 -0
  109. package/plugins/workflow-runner/test/output-schema.test.ts +213 -0
  110. package/plugins/workflow-runner/test/parseWorkflowArgs.test.ts +87 -0
  111. package/plugins/workflow-runner/test/pluginRunner.isolation.test.ts +269 -0
  112. package/plugins/workflow-runner/test/ppt.load.test.ts +1220 -0
  113. package/plugins/workflow-runner/test/ralphLoop.e2e.test.ts +220 -0
  114. package/plugins/workflow-runner/test/recovery.test.ts +265 -0
  115. package/plugins/workflow-runner/test/runner.test.ts +911 -0
  116. package/plugins/workflow-runner/test/runnerPreflight.test.ts +379 -0
  117. package/plugins/workflow-runner/test/skillTurnDone.test.ts +71 -0
  118. package/plugins/workflow-runner/test/stateLifecycle.test.ts +150 -0
  119. package/plugins/workflow-runner/test/stepPipeline.test.ts +114 -0
  120. package/plugins/workflow-runner/test/taskArbitration.test.ts +338 -0
  121. package/plugins/workflow-runner/test/taskIdentity.test.ts +237 -0
  122. package/plugins/workflow-runner/test/taskLifecycle.test.ts +270 -0
  123. package/plugins/workflow-runner/test/toolArtifactOverwrite.test.ts +221 -0
  124. package/plugins/workflow-runner/test/toolCapabilityBoundary.test.ts +29 -0
  125. package/plugins/workflow-runner/test/toolRuntimeIntegration.test.ts +168 -0
  126. package/plugins/workflow-runner/test/webppt.load.test.ts +250 -0
  127. package/plugins/workflow-runner/test/word.load.test.ts +208 -0
  128. package/plugins/workflow-runner/test/workflows.smoke.test.ts +76 -0
  129. package/plugins/workflow-runner/test/yamlGuardConditions.test.ts +207 -0
  130. package/skills/browser-automation/SKILL.md +9 -19
  131. package/skills/web-crawler/SKILL.md +9 -11
  132. package/src/askBridge.ts +249 -0
  133. package/src/bootstrap/cwdArg.js +10 -3
  134. package/src/bootstrap/cwdArg.ts +31 -0
  135. package/src/bootstrap/workingDir.ts +48 -0
  136. package/src/cli/args.js +70 -7
  137. package/src/cli/args.ts +146 -0
  138. package/src/cli/computerUse.js +185 -0
  139. package/src/cli/computerUse.ts +221 -0
  140. package/src/cli/configMenu.js +274 -202
  141. package/src/cli/configMenu.tsx +521 -0
  142. package/src/cli/memoryAccess.js +45 -0
  143. package/src/cli/memoryAccess.ts +53 -0
  144. package/src/cli/print.js +119 -5
  145. package/src/cli/print.ts +597 -0
  146. package/src/cli/quickModelSetup.js +60 -0
  147. package/src/cli/quickModelSetup.tsx +96 -0
  148. package/src/cli/streamJson.js +80 -4
  149. package/src/cli/streamJson.ts +433 -0
  150. package/src/cli/wizards/advisorWizard.js +1 -0
  151. package/src/cli/wizards/advisorWizard.tsx +195 -0
  152. package/src/cli/wizards/agentRuntimeWizard.js +84 -0
  153. package/src/cli/wizards/agentRuntimeWizard.tsx +134 -0
  154. package/src/cli/wizards/browserWizard.js +55 -0
  155. package/src/cli/wizards/browserWizard.tsx +77 -0
  156. package/src/cli/wizards/contextAdvisorWizard.js +84 -0
  157. package/src/cli/wizards/contextAdvisorWizard.tsx +124 -0
  158. package/src/cli/wizards/fieldForm.js +7 -4
  159. package/src/cli/wizards/fieldForm.tsx +250 -0
  160. package/src/cli/wizards/imageWizard.js +4 -5
  161. package/src/cli/wizards/imageWizard.tsx +96 -0
  162. package/src/cli/wizards/openRouterWizard.tsx +48 -0
  163. package/src/cli/wizards/providerPresets.js +1 -8
  164. package/src/cli/wizards/providerPresets.ts +106 -0
  165. package/src/cli/wizards/providerWizard.js +152 -205
  166. package/src/cli/wizards/providerWizard.tsx +266 -0
  167. package/src/cli/wizards/searchWizard.tsx +47 -0
  168. package/src/cli/wizards/ttsWizard.js +4 -3
  169. package/src/cli/wizards/ttsWizard.tsx +61 -0
  170. package/src/config/configDefaults.js +25 -0
  171. package/src/config/configDefaults.ts +33 -0
  172. package/src/config/configDiagnostics.js +117 -0
  173. package/src/config/configDiagnostics.ts +166 -0
  174. package/src/config/configFile.js +52 -32
  175. package/src/config/configFile.ts +633 -0
  176. package/src/config/configManagement.js +126 -0
  177. package/src/config/configManagement.ts +159 -0
  178. package/src/config/configService.js +66 -11
  179. package/src/config/configService.ts +554 -0
  180. package/src/config/numericLimits.js +61 -0
  181. package/src/config/numericLimits.ts +80 -0
  182. package/src/config.ts +109 -0
  183. package/src/context/agentHome.ts +11 -0
  184. package/src/context/archive.ts +144 -0
  185. package/src/context/budgetPlan.js +54 -0
  186. package/src/context/budgetPlan.ts +88 -0
  187. package/src/context/compact.js +179 -106
  188. package/src/context/compact.ts +584 -0
  189. package/src/context/contextBundle.js +119 -0
  190. package/src/context/contextBundle.ts +176 -0
  191. package/src/context/contextLock.ts +84 -0
  192. package/src/context/microCompactLite.ts +218 -0
  193. package/src/context/persistContext.ts +177 -0
  194. package/src/context/reactiveCompact.js +19 -4
  195. package/src/context/reactiveCompact.ts +240 -0
  196. package/src/context/recentDirs.ts +42 -0
  197. package/src/context/sessionPath.ts +206 -0
  198. package/src/context/sessionRegistry.js +8 -2
  199. package/src/context/sessionRegistry.ts +414 -0
  200. package/src/context/snipCompact.ts +163 -0
  201. package/src/context/tokenCounter.ts +106 -0
  202. package/src/context/workspaceIndex.js +2 -2
  203. package/src/context/workspaceIndex.ts +751 -0
  204. package/src/entry.compiled.tsx +20 -0
  205. package/src/harness/claimValidation.js +9 -0
  206. package/src/harness/claimValidation.ts +22 -0
  207. package/src/harness/evidenceLedger.js +92 -0
  208. package/src/harness/evidenceLedger.ts +96 -0
  209. package/src/harness/stallGuard.js +60 -0
  210. package/src/harness/stallGuard.ts +81 -0
  211. package/src/humanIntervention.js +129 -0
  212. package/src/humanIntervention.ts +216 -0
  213. package/src/infra/verification.ts +295 -0
  214. package/src/irreversible/rules.js +216 -0
  215. package/src/irreversible/rules.ts +261 -0
  216. package/src/llm/client.js +40 -3
  217. package/src/llm/client.ts +621 -0
  218. package/src/llm/promptCache.js +27 -0
  219. package/src/llm/promptCache.ts +41 -0
  220. package/src/llm/providers/anthropicFormat.js +41 -5
  221. package/src/llm/providers/anthropicFormat.ts +290 -0
  222. package/src/llm/providers/openaiFormat.js +186 -8
  223. package/src/llm/providers/openaiFormat.ts +428 -0
  224. package/src/loop.js +614 -63
  225. package/src/loop.ts +1454 -0
  226. package/src/main.js +67 -10
  227. package/src/main.tsx +344 -0
  228. package/src/memory/codec.js +204 -0
  229. package/src/memory/codec.ts +249 -0
  230. package/src/memory/constants.js +34 -0
  231. package/src/memory/constants.ts +50 -0
  232. package/src/memory/episodicMemory.js +684 -0
  233. package/src/memory/episodicMemory.ts +815 -0
  234. package/src/memory/fileStore.js +148 -0
  235. package/src/memory/fileStore.ts +184 -0
  236. package/src/memory/memoryService.js +570 -0
  237. package/src/memory/memoryService.ts +859 -0
  238. package/src/memory/migration.js +128 -0
  239. package/src/memory/migration.ts +160 -0
  240. package/src/memory/repository.js +789 -0
  241. package/src/memory/repository.ts +893 -0
  242. package/src/memory/retrieval.js +108 -0
  243. package/src/memory/retrieval.ts +145 -0
  244. package/src/memory/searchIndex.js +107 -0
  245. package/src/memory/searchIndex.ts +153 -0
  246. package/src/memory/topicView.js +82 -0
  247. package/src/memory/topicView.ts +95 -0
  248. package/src/memory/turnJournal.js +95 -0
  249. package/src/memory/turnJournal.ts +120 -0
  250. package/src/memory/types.js +2 -0
  251. package/src/memory/types.ts +186 -0
  252. package/src/messageQueue.ts +123 -0
  253. package/src/multimodal.js +128 -46
  254. package/src/multimodal.ts +349 -0
  255. package/src/plugin-sdk.js +21 -1
  256. package/src/plugin-sdk.ts +134 -0
  257. package/src/plugins/builtinPluginIds.js +47 -0
  258. package/src/plugins/builtinPluginIds.ts +51 -0
  259. package/src/plugins/builtinRegistry.ts +43 -0
  260. package/src/plugins/commandRouter.js +40 -26
  261. package/src/plugins/commandRouter.ts +261 -0
  262. package/src/plugins/hookEngine.ts +341 -0
  263. package/src/plugins/pluginApi.ts +133 -0
  264. package/src/plugins/pluginLifecycle.ts +34 -0
  265. package/src/plugins/pluginLoader.ts +147 -0
  266. package/src/plugins/pluginManifest.js +127 -0
  267. package/src/plugins/pluginManifest.ts +152 -0
  268. package/src/plugins/pluginRunner.js +47 -2
  269. package/src/plugins/pluginRunner.ts +207 -0
  270. package/src/plugins/transcript.ts +208 -0
  271. package/src/prompts/lint.js +169 -0
  272. package/src/prompts/lint.ts +220 -0
  273. package/src/prompts/pluginList.js +32 -16
  274. package/src/prompts/pluginList.ts +86 -0
  275. package/src/prompts/policyRegistry.js +318 -0
  276. package/src/prompts/policyRegistry.ts +358 -0
  277. package/src/prompts/projectInstructions.js +24 -0
  278. package/src/prompts/projectInstructions.ts +81 -0
  279. package/src/prompts/promptAssembly.js +311 -202
  280. package/src/prompts/promptAssembly.ts +510 -0
  281. package/src/prompts/skillList.js +106 -45
  282. package/src/prompts/skillList.ts +198 -0
  283. package/src/prompts/system.js +31 -6
  284. package/src/prompts/system.ts +81 -0
  285. package/src/runtime/agentRuntimeContext.js +53 -0
  286. package/src/runtime/agentRuntimeContext.ts +112 -0
  287. package/src/session/runAgentTurn.js +71 -12
  288. package/src/session/runAgentTurn.ts +181 -0
  289. package/src/session/runTurn.js +29 -0
  290. package/src/session/runTurn.ts +160 -0
  291. package/src/session/runtimeStore.js +149 -0
  292. package/src/session/runtimeStore.ts +197 -0
  293. package/src/session/sessionState.js +79 -3
  294. package/src/session/sessionState.ts +134 -0
  295. package/src/toolGate.ts +50 -0
  296. package/src/tools/advisor/advisor.js +76 -15
  297. package/src/tools/advisor/advisor.ts +512 -0
  298. package/src/tools/agent/agent.js +245 -29
  299. package/src/tools/agent/agent.ts +837 -0
  300. package/src/tools/agent/agentTaskService.js +60 -0
  301. package/src/tools/agent/agentTaskService.ts +113 -0
  302. package/src/tools/agent/agentTypes.js +20 -8
  303. package/src/tools/agent/agentTypes.ts +94 -0
  304. package/src/tools/agent/coordinator.ts +111 -0
  305. package/src/tools/agent/worktree.ts +296 -0
  306. package/src/tools/ask/ask.js +17 -0
  307. package/src/tools/ask/ask.ts +122 -0
  308. package/src/tools/bash/attachImage.js +223 -0
  309. package/src/tools/bash/attachImage.ts +281 -0
  310. package/src/tools/bash/bash.js +132 -14
  311. package/src/tools/bash/bash.ts +642 -0
  312. package/src/tools/bash/semantics.ts +103 -0
  313. package/src/tools/bash/warnings.js +17 -11
  314. package/src/tools/bash/warnings.ts +117 -0
  315. package/src/tools/capabilities.js +42 -0
  316. package/src/tools/capabilities.ts +69 -0
  317. package/src/tools/computeruse/accessibilityPermission.js +261 -0
  318. package/src/tools/computeruse/accessibilityPermission.ts +294 -0
  319. package/src/tools/computeruse/axSearch.js +96 -0
  320. package/src/tools/computeruse/axSearch.ts +120 -0
  321. package/src/tools/computeruse/axSnap.js +272 -0
  322. package/src/tools/computeruse/axSnap.ts +349 -0
  323. package/src/tools/computeruse/capabilityLabels.js +95 -0
  324. package/src/tools/computeruse/capabilityLabels.ts +115 -0
  325. package/src/tools/computeruse/computerUseService.js +2235 -0
  326. package/src/tools/computeruse/computerUseService.ts +2686 -0
  327. package/src/tools/computeruse/computeruse.js +2742 -0
  328. package/src/tools/computeruse/computeruse.ts +3265 -0
  329. package/src/tools/computeruse/diagnosticTrace.js +154 -0
  330. package/src/tools/computeruse/diagnosticTrace.ts +195 -0
  331. package/src/tools/computeruse/diagnostics.js +369 -0
  332. package/src/tools/computeruse/diagnostics.ts +453 -0
  333. package/src/tools/computeruse/grants.js +53 -0
  334. package/src/tools/computeruse/grants.ts +70 -0
  335. package/src/tools/computeruse/humanBoundary.js +159 -0
  336. package/src/tools/computeruse/humanBoundary.ts +199 -0
  337. package/src/tools/computeruse/intervention.js +77 -0
  338. package/src/tools/computeruse/intervention.ts +110 -0
  339. package/src/tools/computeruse/manualSchema.js +709 -0
  340. package/src/tools/computeruse/manualSchema.ts +916 -0
  341. package/src/tools/computeruse/observationImages.js +705 -0
  342. package/src/tools/computeruse/observationImages.ts +889 -0
  343. package/src/tools/computeruse/protocol.js +60 -0
  344. package/src/tools/computeruse/protocol.ts +515 -0
  345. package/src/tools/computeruse/telemetryLog.js +57 -0
  346. package/src/tools/computeruse/telemetryLog.ts +67 -0
  347. package/src/tools/computeruse/vision/appGuide.js +325 -0
  348. package/src/tools/computeruse/vision/appGuide.ts +482 -0
  349. package/src/tools/computeruse/vision/focus.js +291 -0
  350. package/src/tools/computeruse/vision/focus.ts +382 -0
  351. package/src/tools/computeruse/vision/frames.js +248 -0
  352. package/src/tools/computeruse/vision/frames.ts +329 -0
  353. package/src/tools/computeruse/vision/geometry.js +131 -0
  354. package/src/tools/computeruse/vision/geometry.ts +163 -0
  355. package/src/tools/computeruse/vision/imaging.js +201 -0
  356. package/src/tools/computeruse/vision/imaging.ts +281 -0
  357. package/src/tools/computeruse/vision/png.js +274 -0
  358. package/src/tools/computeruse/vision/png.ts +317 -0
  359. package/src/tools/computeruse/vision/raster.js +320 -0
  360. package/src/tools/computeruse/vision/raster.ts +408 -0
  361. package/src/tools/computeruse/vision/settle.js +131 -0
  362. package/src/tools/computeruse/vision/settle.ts +220 -0
  363. package/src/tools/computeruse/vision/telemetry.js +196 -0
  364. package/src/tools/computeruse/vision/telemetry.ts +241 -0
  365. package/src/tools/computeruse/visionOcr.js +115 -0
  366. package/src/tools/computeruse/visionOcr.ts +128 -0
  367. package/src/tools/computeruse/waitFor.js +237 -0
  368. package/src/tools/computeruse/waitFor.ts +291 -0
  369. package/src/tools/download/download.js +10 -6
  370. package/src/tools/download/download.ts +187 -0
  371. package/src/tools/edit/edit.js +30 -18
  372. package/src/tools/edit/edit.ts +349 -0
  373. package/src/tools/edit/multi-edit.js +25 -14
  374. package/src/tools/edit/multi-edit.ts +223 -0
  375. package/src/tools/effectiveToolSet.js +73 -0
  376. package/src/tools/effectiveToolSet.ts +91 -0
  377. package/src/tools/genimage/genimage.ts +257 -0
  378. package/src/tools/genspeech/genspeech.ts +83 -0
  379. package/src/tools/glob/glob.js +176 -29
  380. package/src/tools/glob/glob.ts +283 -0
  381. package/src/tools/grep/grep.js +61 -19
  382. package/src/tools/grep/grep.ts +239 -0
  383. package/src/tools/grep/rgPath.ts +206 -0
  384. package/src/tools/index.js +99 -5
  385. package/src/tools/index.ts +293 -0
  386. package/src/tools/lsp/config.js +113 -0
  387. package/src/tools/lsp/config.ts +113 -0
  388. package/src/tools/lsp/lsp.js +256 -0
  389. package/src/tools/lsp/lsp.ts +274 -0
  390. package/src/tools/lsp/service.js +303 -0
  391. package/src/tools/lsp/service.ts +296 -0
  392. package/src/tools/memory/memory.js +520 -0
  393. package/src/tools/memory/memory.ts +625 -0
  394. package/src/tools/memory/policy.js +53 -0
  395. package/src/tools/memory/policy.ts +72 -0
  396. package/src/tools/notebook/notebookEdit.js +114 -0
  397. package/src/tools/notebook/notebookEdit.ts +126 -0
  398. package/src/tools/powershell/powershell.js +210 -0
  399. package/src/tools/powershell/powershell.ts +239 -0
  400. package/src/tools/presentresult/presentresult.js +145 -0
  401. package/src/tools/presentresult/presentresult.ts +156 -0
  402. package/src/tools/read/read.js +371 -163
  403. package/src/tools/read/read.ts +558 -0
  404. package/src/tools/shared/diffSummary.js +44 -0
  405. package/src/tools/shared/diffSummary.ts +63 -0
  406. package/src/tools/shared/fileActivity.js +51 -0
  407. package/src/tools/shared/fileActivity.ts +66 -0
  408. package/src/tools/shared/fileMutationBus.js +13 -0
  409. package/src/tools/shared/fileMutationBus.ts +14 -0
  410. package/src/tools/shared/fileState.js +73 -65
  411. package/src/tools/shared/fileState.ts +145 -0
  412. package/src/tools/shared/fileUtils.js +81 -4
  413. package/src/tools/shared/fileUtils.ts +504 -0
  414. package/src/tools/shared/killTree.ts +50 -0
  415. package/src/tools/shared/permanentDeleteGuard.js +26 -0
  416. package/src/tools/shared/permanentDeleteGuard.ts +34 -0
  417. package/src/tools/shared/schemas.ts +20 -0
  418. package/src/tools/shared/toolOutputStore.js +97 -0
  419. package/src/tools/shared/toolOutputStore.ts +110 -0
  420. package/src/tools/skill/skill.js +86 -0
  421. package/src/tools/skill/skill.ts +94 -0
  422. package/src/tools/snip/snip.js +67 -0
  423. package/src/tools/snip/snip.ts +80 -0
  424. package/src/tools/tasks/backgroundTaskService.js +275 -0
  425. package/src/tools/tasks/backgroundTaskService.ts +369 -0
  426. package/src/tools/tasks/processEvidence.js +24 -0
  427. package/src/tools/tasks/processEvidence.ts +34 -0
  428. package/src/tools/tasks/taskManagement.js +163 -0
  429. package/src/tools/tasks/taskManagement.ts +180 -0
  430. package/src/tools/tasks/taskOutput.js +113 -0
  431. package/src/tools/tasks/taskOutput.ts +145 -0
  432. package/src/tools/tasks/taskStop.js +74 -0
  433. package/src/tools/tasks/taskStop.ts +99 -0
  434. package/src/tools/tasks/taskStore.js +46 -0
  435. package/src/tools/tasks/taskStore.ts +77 -0
  436. package/src/tools/terminal/terminalCapture.js +167 -0
  437. package/src/tools/terminal/terminalCapture.ts +179 -0
  438. package/src/tools/trash/trash.js +233 -0
  439. package/src/tools/trash/trash.ts +283 -0
  440. package/src/tools/types.js +1 -1
  441. package/src/tools/types.ts +24 -0
  442. package/src/tools/webbrowser/agentBrowserPath.ts +286 -0
  443. package/src/tools/webbrowser/browser.js +214 -11
  444. package/src/tools/webbrowser/browser.ts +293 -0
  445. package/src/tools/webbrowser/browserControl.js +153 -48
  446. package/src/tools/webbrowser/browserControl.ts +262 -0
  447. package/src/tools/webbrowser/browserDaemon.js +147 -39
  448. package/src/tools/webbrowser/browserDaemon.ts +270 -0
  449. package/src/tools/webbrowser/browserOutcome.js +273 -0
  450. package/src/tools/webbrowser/browserOutcome.ts +306 -0
  451. package/src/tools/webbrowser/browserRunRegistry.js +150 -0
  452. package/src/tools/webbrowser/browserRunRegistry.ts +179 -0
  453. package/src/tools/webbrowser/browserService.js +20 -6
  454. package/src/tools/webbrowser/browserService.ts +56 -0
  455. package/src/tools/webbrowser/browserStream.js +30 -1
  456. package/src/tools/webbrowser/browserStream.ts +216 -0
  457. package/src/tools/webbrowser/browserTabs.js +143 -0
  458. package/src/tools/webbrowser/browserTabs.ts +210 -0
  459. package/src/tools/webbrowser/webbrowser.js +831 -150
  460. package/src/tools/webbrowser/webbrowser.ts +1537 -0
  461. package/src/tools/webfetch/preapproved.ts +274 -0
  462. package/src/tools/webfetch/webfetch.js +24 -23
  463. package/src/tools/webfetch/webfetch.ts +383 -0
  464. package/src/tools/websearch/websearch.js +12 -11
  465. package/src/tools/websearch/websearch.ts +292 -0
  466. package/src/tools/worktree/sessionWorktree.js +128 -0
  467. package/src/tools/worktree/sessionWorktree.ts +158 -0
  468. package/src/tools/write/write.js +27 -44
  469. package/src/tools/write/write.ts +136 -0
  470. package/src/types.ts +960 -0
  471. package/src/ui/App.js +216 -12
  472. package/src/ui/App.tsx +879 -0
  473. package/src/ui/AskQuestion.tsx +300 -0
  474. package/src/ui/InputBox.js +77 -1
  475. package/src/ui/InputBox.tsx +567 -0
  476. package/src/ui/LiveArea.tsx +344 -0
  477. package/src/ui/MessageList.js +27 -6
  478. package/src/ui/MessageList.tsx +559 -0
  479. package/src/ui/ModelPicker.tsx +107 -0
  480. package/src/ui/QueuedMessagesBanner.tsx +51 -0
  481. package/src/ui/Root.js +6 -8
  482. package/src/ui/Root.tsx +100 -0
  483. package/src/ui/SessionPicker.tsx +169 -0
  484. package/src/ui/StatusLine.js +22 -1
  485. package/src/ui/StatusLine.tsx +145 -0
  486. package/src/ui/WorkspacePicker.tsx +84 -0
  487. package/src/ui/advisorCommand.js +54 -0
  488. package/src/ui/advisorCommand.ts +63 -0
  489. package/src/ui/computerCommand.js +19 -0
  490. package/src/ui/computerCommand.ts +35 -0
  491. package/src/ui/figures.ts +45 -0
  492. package/src/ui/hooks/askSlot.ts +112 -0
  493. package/src/ui/hooks/useChat.js +271 -7
  494. package/src/ui/hooks/useChat.ts +1578 -0
  495. package/src/ui/hooks/useInputHistory.ts +235 -0
  496. package/src/ui/hooks/usePasteHandler.ts +220 -0
  497. package/src/ui/hooks/useTerminalSize.ts +41 -0
  498. package/src/ui/hooks/useTextBuffer.ts +108 -0
  499. package/src/ui/hooks/useTokenUsage.ts +44 -0
  500. package/src/ui/liveViewport.ts +189 -0
  501. package/src/ui/markdown.ts +230 -0
  502. package/src/ui/textBuffer.ts +239 -0
  503. package/src/ui/theme.ts +35 -0
  504. package/src/utils/clipboardImage.js +358 -0
  505. package/src/utils/clipboardImage.ts +420 -0
  506. package/src/utils/debugLog.ts +50 -0
  507. package/src/utils/greenRoot.ts +35 -0
  508. package/src/utils/packageRoot.ts +40 -0
  509. package/src/utils/pathContains.js +28 -0
  510. package/src/utils/pathContains.ts +31 -0
  511. package/src/utils/resourcePaths.ts +71 -0
  512. package/src/utils/stripThink.ts +49 -0
  513. package/src/utils/zodToJson.ts +73 -0
  514. package/src/web/browserBridge.js +365 -66
  515. package/src/web/browserBridge.ts +672 -0
  516. package/src/web/protocol.ts +1804 -0
  517. package/vendor/computer-use/arm64-darwin/cu-helperd +0 -0
  518. package/workflows/ppt.yaml +13 -2
  519. package/workflows/wechat-reading-shots.yaml +315 -0
  520. package/workflows/word.yaml +11 -1
  521. package/skills/docx/scripts/office/helpers/__pycache__/__init__.cpython-314.pyc +0 -0
  522. package/skills/docx/scripts/office/helpers/__pycache__/merge_runs.cpython-314.pyc +0 -0
  523. package/skills/docx/scripts/office/helpers/__pycache__/simplify_redlines.cpython-314.pyc +0 -0
  524. package/skills/docx/scripts/office/validators/__pycache__/__init__.cpython-314.pyc +0 -0
  525. package/skills/docx/scripts/office/validators/__pycache__/base.cpython-314.pyc +0 -0
  526. package/skills/docx/scripts/office/validators/__pycache__/docx.cpython-314.pyc +0 -0
  527. package/skills/docx/scripts/office/validators/__pycache__/pptx.cpython-314.pyc +0 -0
  528. package/skills/docx/scripts/office/validators/__pycache__/redlining.cpython-314.pyc +0 -0
  529. package/skills/image-stats/scripts/__pycache__/image_stats.cpython-314.pyc +0 -0
  530. package/skills/image-stats/scripts/__pycache__/image_stats_test.cpython-314.pyc +0 -0
  531. package/skills/ui-design/scripts/__pycache__/assemble_material.cpython-314.pyc +0 -0
  532. package/skills/ui-design/scripts/__pycache__/assemble_material_test.cpython-314.pyc +0 -0
  533. package/skills/ui-design/scripts/__pycache__/chart_sanity_check.cpython-314.pyc +0 -0
  534. package/skills/ui-design/scripts/__pycache__/check_language_policy.cpython-314.pyc +0 -0
  535. package/skills/ui-design/scripts/__pycache__/check_ui_artifact.cpython-314.pyc +0 -0
  536. package/skills/ui-design/scripts/__pycache__/check_ui_artifact_pptx_test.cpython-314.pyc +0 -0
  537. package/skills/ui-design/scripts/__pycache__/deck_pages_check.cpython-314.pyc +0 -0
  538. package/skills/ui-design/scripts/__pycache__/deck_pages_check_test.cpython-314.pyc +0 -0
  539. package/skills/ui-design/scripts/__pycache__/deck_visual_style_check.cpython-314.pyc +0 -0
  540. package/skills/ui-design/scripts/__pycache__/deck_visual_style_check_test.cpython-314.pyc +0 -0
  541. package/skills/ui-design/scripts/__pycache__/design_budget_check.cpython-314.pyc +0 -0
  542. package/skills/ui-design/scripts/__pycache__/design_budget_check_test.cpython-314.pyc +0 -0
  543. package/skills/ui-design/scripts/__pycache__/design_repair_hints.cpython-314.pyc +0 -0
  544. package/skills/ui-design/scripts/__pycache__/design_repair_hints_test.cpython-314.pyc +0 -0
  545. package/skills/ui-design/scripts/__pycache__/design_style_check.cpython-314.pyc +0 -0
  546. package/skills/ui-design/scripts/__pycache__/design_style_check_test.cpython-314.pyc +0 -0
  547. package/skills/ui-design/scripts/__pycache__/draft_coverage_check.cpython-314.pyc +0 -0
  548. package/skills/ui-design/scripts/__pycache__/extract_source_assets.cpython-314.pyc +0 -0
  549. package/skills/ui-design/scripts/__pycache__/extract_source_assets_test.cpython-314.pyc +0 -0
  550. package/skills/ui-design/scripts/__pycache__/generated_image_review_collect.cpython-314.pyc +0 -0
  551. package/skills/ui-design/scripts/__pycache__/generated_image_review_collect_test.cpython-314.pyc +0 -0
  552. package/skills/ui-design/scripts/__pycache__/image_plan_lint.cpython-314.pyc +0 -0
  553. package/skills/ui-design/scripts/__pycache__/image_plan_lint_test.cpython-314.pyc +0 -0
  554. package/skills/ui-design/scripts/__pycache__/image_prompt_rewrite.cpython-314.pyc +0 -0
  555. package/skills/ui-design/scripts/__pycache__/image_prompt_rewrite_test.cpython-314.pyc +0 -0
  556. package/skills/ui-design/scripts/__pycache__/layout_balance.cpython-314.pyc +0 -0
  557. package/skills/ui-design/scripts/__pycache__/layout_balance_test.cpython-314.pyc +0 -0
  558. package/skills/ui-design/scripts/__pycache__/normalize_design_json.cpython-314.pyc +0 -0
  559. package/skills/ui-design/scripts/__pycache__/normalize_design_json_test.cpython-314.pyc +0 -0
  560. package/skills/ui-design/scripts/__pycache__/plan_source_layout.cpython-314.pyc +0 -0
  561. package/skills/ui-design/scripts/__pycache__/plan_source_layout_test.cpython-314.pyc +0 -0
  562. package/skills/ui-design/scripts/__pycache__/resolve_source_hint.cpython-314.pyc +0 -0
  563. package/skills/ui-design/scripts/__pycache__/resolve_source_hint_test.cpython-314.pyc +0 -0
  564. package/skills/ui-design/scripts/__pycache__/resolve_source_input.cpython-314.pyc +0 -0
  565. package/skills/ui-design/scripts/__pycache__/resolve_source_input_test.cpython-314.pyc +0 -0
  566. package/skills/ui-design/scripts/__pycache__/scaffold_ui_artifact.cpython-314.pyc +0 -0
  567. package/skills/ui-design/scripts/__pycache__/source_usage_check.cpython-314.pyc +0 -0
  568. package/skills/ui-design/scripts/__pycache__/source_usage_check_test.cpython-314.pyc +0 -0
  569. package/skills/ui-design/scripts/__pycache__/text_readability_pixel.cpython-314.pyc +0 -0
  570. package/skills/ui-design/scripts/__pycache__/visual_quality_gate.cpython-314.pyc +0 -0
  571. package/skills/ui-design/scripts/__pycache__/visual_quality_gate_test.cpython-314.pyc +0 -0
  572. /package/skills/ai-image/scripts/{generate_test.mjs → generate.selftest.mjs} +0 -0
  573. /package/skills/ai-image/scripts/{generate_from_plan_test.mjs → generate_from_plan.selftest.mjs} +0 -0
@@ -3,14 +3,12 @@
3
3
  * src/tools/agent/agent.ts —— Agent 工具(fork 子 agent / 多 agent 并行)
4
4
  * ------------------------------------------------------------
5
5
  * 借鉴 Claude Code 官方 AgentTool/ForkAgent 的核心思想,按 minimal-agent
6
- * 内核架构做同步等效实现:
6
+ * 内核架构做可恢复的前台/后台等效实现:
7
7
  * - 官方 fork = 「隔离 context 嵌套跑同一主循环 + 摘要回传(完整历史不进
8
- * 父上下文)」。我们不需要它的后台任务队列/AsyncLocalStorage 身份追踪
9
- * (那是为 Ink UI 后台任务服务的)——本工具同步 await 一个嵌套 runQuery,
10
- * 声明 isConcurrencySafe:true 后,模型在同一轮发出 N 个 Agent 调用时,
11
- * loop.ts 现成的并行 worker 队列自动把它们并发执行。这就是并行的全部来源。
12
- * - 同轮混入任一非并发安全工具(如 Edit)会整轮退化串行——这是想要的安全
13
- * 语义(写操作与并行 fork 不该交错)。
8
+ * 父上下文)」。本工具在隔离 history 中嵌套运行同一主循环,并将私有历史、
9
+ * 进度和结果写入会话运行存储;前台、后台和重启后续接共用同一执行内核。
10
+ * - 同轮多个 Agent 调用仍由 loop.ts 的并行 worker 执行;write scopes 与可选
11
+ * worktree 负责隔离真正可并行的写任务。
14
12
  *
15
13
  * 已知限制(如实声明):
16
14
  * - 子 agent 的 LoopEvent 不外泄:-p / stream-json 宿主只看到本工具的一对
@@ -27,18 +25,23 @@
27
25
  * ============================================================
28
26
  */
29
27
  import { randomUUID } from 'node:crypto';
28
+ import { EventEmitter } from 'node:events';
29
+ import { access } from 'node:fs/promises';
30
30
  import { withAskSource } from '../../askBridge.js';
31
31
  import { isAbsolute, relative, resolve, sep } from 'node:path';
32
32
  import { z } from 'zod';
33
33
  import { getWorkingDir, withWorkingDir } from '../../bootstrap/workingDir.js';
34
+ import { derivePromptCacheContext } from '../../llm/promptCache.js';
34
35
  import { createSessionState } from '../../session/sessionState.js';
35
- import { assembleBasePrompt } from '../../prompts/promptAssembly.js';
36
+ import { assembleStablePrompt, buildTransientPromptBundle, } from '../../prompts/promptAssembly.js';
37
+ import { createAgentRuntimeContext, filterToolsForRuntime, } from '../../runtime/agentRuntimeContext.js';
36
38
  import { stripThinkBlocks } from '../../utils/stripThink.js';
37
39
  import { toToolParameters } from '../../utils/zodToJson.js';
38
40
  import { DEFAULT_MAX_RESULT_SIZE_CHARS } from '../types.js';
39
41
  import { SUBAGENT_EXCLUDED_TOOLS, resolveAgentType } from './agentTypes.js';
40
42
  import { acquireSubagentLease, normalizeWriteScopes } from './coordinator.js';
41
43
  import { commitWorktreeChanges, createAgentWorktree, hasWorktreeChanges, removeAgentWorktree, worktreeChangedFiles, worktreeDiffStat, } from './worktree.js';
44
+ import { appendAgentEvent, loadAgentRecord, saveAgentRecord } from './agentTaskService.js';
42
45
  let corePromise = null;
43
46
  /** 首次调用时才真正加载 loop/tools——此刻模块图早已初始化完毕,环安全。 */
44
47
  function loadCore() {
@@ -77,24 +80,27 @@ const inputSchema = z.object({
77
80
  .max(32)
78
81
  .optional()
79
82
  .describe('general 预计修改的工作目录相对路径。范围互不重叠时可并行;缺省时按整个工作目录串行。explore 不需要。'),
83
+ run_in_background: z.boolean().optional().describe('立即返回 agent_id,子任务在后台运行;用 TaskOutput/TaskStop 管理'),
84
+ resume_agent_id: z.string().regex(/^agent_[0-9a-f-]{36}$/i).optional().describe('继续当前会话中此前完成、中断或失败的 Agent 历史'),
80
85
  });
81
86
  const parameters = toToolParameters(inputSchema);
82
87
  // ---------------- 2. Description(给 LLM 看的工具说明) ----------------
83
88
  // 借鉴官方 AgentTool prompt 文案(任务书自包含 / 同轮并行 / 何时不用)。
84
- const description = `- Launches a stateless sub-agent with a fresh, isolated context to execute one self-contained subtask; returns only its final report text (its full working history never enters this conversation).
89
+ const description = `- Launches an isolated sub-agent for one self-contained task. Every run returns an agent_id; run_in_background=true continues without blocking, and resume_agent_id continues its persisted private history across user turns or an app restart.
85
90
  - The sub-agent CANNOT see this conversation. The \`prompt\` must be fully self-contained: background, exact file paths, what to look for / do, and the expected output format.
86
91
  - **To parallelize, emit multiple Agent calls in ONE assistant message** — they run concurrently. This is the main value of this tool.
92
+ - Background Agent progress/results are read with TaskOutput and stopped with TaskStop. Do not poll: TaskOutput(block=true) waits efficiently.
87
93
  - Use for: exploring/researching several independent areas of a codebase at once, parallel information gathering from multiple sources, independent analyses that will be synthesized afterwards, and (with agent_type:'general') genuinely parallelizable write/execute work.
88
94
  - Do NOT use for: single targeted lookups that one or two direct tool calls would answer (a fork starts cold and re-derives context — slower and costlier), or strictly sequential work. Only general execution agents may ask the user, and only when genuinely blocked.
89
95
  - agent_type: 'explore' (default) = strictly read-only research; 'general' = read-write execution. For direct writes, declare relative write_scopes; disjoint scopes may run concurrently, overlapping or omitted scopes are serialized.
90
- - isolation:'worktree' (general only): the sub-agent sees the repo's last COMMITTED state (uncommitted changes are invisible — commit first if it needs them). On completion its changes are auto-committed to a temp branch and the report tail tells you the branch name; review the diff, merge (e.g. \`git merge --squash <branch>\`), then clean up.
91
- - After sub-agents return you MUST synthesize: cross-check contradictions between reports, integrate into one conclusion — never just forward raw reports. A failed/timed-out fork is not a blocker: proceed with what you have and state the gap.`;
96
+ - isolation:'worktree' (general only): the sub-agent sees the repo's last COMMITTED state. Never commit the user's work merely to expose uncommitted changes; instead keep the task in the current workspace or make the task self-contained. On completion its changes are committed only to a temporary branch; review before applying it to the user's workspace.
97
+ - After sub-agents return you MUST synthesize: cross-check contradictions between reports, integrate into one conclusion — never just forward raw reports. A failed/timed-out fork is not a blocker: proceed with what you have and state the gap.
98
+ - Each sub-task result carries coveredFiles: the actual files/URLs the sub-agent read, extracted from its tool-call history (not self-reported). Before trusting a conclusion, audit its coveredFiles for gaps/overlaps — if coverage looks too thin for what it claims, treat that conclusion as low-confidence.`;
92
99
  // ---------------- 3. 子 agent 系统提示词(memoize,提示词缓存友好) ----------------
93
- /** 通用附加段:所有 agent_type 共享(拼在 assembleBasePrompt 之后)。 */
100
+ /** 任务回传契约。能力与权限已经由 assembleBasePrompt profile 精确注入。 */
94
101
  const SUBAGENT_COMMON_APPENDIX = `# 你是子 agent(fork 分身)
95
102
  你是主 agent 派生出的子 agent,正在执行一个自包含的子任务:
96
103
  - 你看不到主对话;任务书(用户消息)就是你的全部输入。
97
- - explore 子任务不能向用户提问;general 仅在缺少关键输入或高风险取舍时使用 AskUserQuestion,最多两次。
98
104
  - 你的**最后一条回复就是唯一回传主 agent 的报告**,必须自包含:结论 + 关键证据(文件路径/行号)+ 未尽事项。
99
105
  不要输出「我完成了」这类无信息量收尾,也不要在报告里向主 agent 提问——它不会回复你。`;
100
106
  /**
@@ -107,15 +113,18 @@ const SUBAGENT_COMMON_APPENDIX = `# 你是子 agent(fork 分身)
107
113
  const PROMPT_CACHE_TTL_MS = 60_000;
108
114
  const promptCache = new Map();
109
115
  async function buildSubSystemPrompt(cwd, def, allTools) {
110
- const key = `${cwd}::${def.type}`;
116
+ // Effective capabilities are part of prompt identity; a child must never
117
+ // reuse a cached parent-capability prompt (notably Desktop WebBrowser).
118
+ const key = `${cwd}::${def.type}::${allTools.map((tool) => tool.name).join(',')}`;
111
119
  const hit = promptCache.get(key);
112
120
  if (hit && Date.now() - hit.at < PROMPT_CACHE_TTL_MS)
113
121
  return hit.value;
114
122
  const allowedNames = def.resolveAllowedTools(allTools.map((t) => t.name));
115
123
  const subTools = allTools.filter((t) => allowedNames.includes(t.name));
116
- const base = await assembleBasePrompt({
124
+ const base = await assembleStablePrompt({
117
125
  cwd,
118
126
  tools: subTools,
127
+ profile: def.type === 'general' ? 'subagent-general' : 'subagent-explore',
119
128
  includeProjectInstructions: true, // 子 agent 在同一仓库干活,项目约定必须继承
120
129
  includePlugins: false, // 插件是宿主命令面,子 agent 不该被引去激活插件
121
130
  });
@@ -123,6 +132,52 @@ async function buildSubSystemPrompt(cwd, def, allTools) {
123
132
  promptCache.set(key, { value, at: Date.now() });
124
133
  return value;
125
134
  }
135
+ // ---------------- 3.5 覆盖度提取(客观,从工具调用历史推导) ----------------
136
+ /**
137
+ * 从子任务 history 中提取「实际读取/调研过的文件/目标」清单,
138
+ * 用于父 agent / 宿主做覆盖度自检,避免「以为覆盖了其实没覆盖」的幻觉。
139
+ */
140
+ export function extractCoveredFiles(history, startIdx) {
141
+ const seen = new Set();
142
+ for (let i = startIdx; i < history.length; i++) {
143
+ const msg = history[i];
144
+ if (msg.role !== 'assistant' || !msg.tool_calls)
145
+ continue;
146
+ for (const tc of msg.tool_calls) {
147
+ const name = tc.function.name;
148
+ let args;
149
+ try {
150
+ args = JSON.parse(tc.function.arguments);
151
+ }
152
+ catch {
153
+ continue;
154
+ }
155
+ if (!args)
156
+ continue;
157
+ if (name === 'Read' && typeof args.file_path === 'string') {
158
+ seen.add(args.file_path);
159
+ }
160
+ else if (name === 'Glob' && typeof args.pattern === 'string') {
161
+ seen.add(`glob:${args.pattern}`);
162
+ }
163
+ else if (name === 'Grep') {
164
+ const parts = ['grep:' + (typeof args.pattern === 'string' ? args.pattern : '?')];
165
+ if (typeof args.path === 'string')
166
+ parts.push(`path=${args.path}`);
167
+ if (typeof args.glob === 'string')
168
+ parts.push(`glob=${args.glob}`);
169
+ seen.add(parts.join(' '));
170
+ }
171
+ else if (name === 'WebFetch' && typeof args.url === 'string') {
172
+ seen.add(args.url);
173
+ }
174
+ else if (name === 'WebBrowser' && typeof args.url === 'string') {
175
+ seen.add(`browser:${args.url}`);
176
+ }
177
+ }
178
+ }
179
+ return [...seen].sort();
180
+ }
126
181
  function positiveInt(value) {
127
182
  const n = Number.parseInt(value ?? '', 10);
128
183
  return Number.isFinite(n) && n > 0 ? n : undefined;
@@ -186,10 +241,10 @@ export async function runAgentTask(input, signal, ctx, deps = {}) {
186
241
  // allowedTools 只裁「下发给模型的清单」;guardedExecute 是真正的硬防线(见下)。
187
242
  const allowedTools = def.resolveAllowedTools(ALL_TOOLS.map((t) => t.name));
188
243
  // ---- worktree 隔离(仅 general 显式要求时) ----
189
- let wt = null;
244
+ let wt = deps.existingWorktree ?? null;
190
245
  const isolation = input.isolation ?? ctx.subagentConfig?.defaultWriteIsolation ?? 'none';
191
- if (def.type === 'general' && isolation === 'worktree') {
192
- const created = await createAgentWorktree(`fork-${randomUUID().slice(0, 8)}`);
246
+ if (def.type === 'general' && isolation === 'worktree' && !wt) {
247
+ const created = await createAgentWorktree(`fork-${randomUUID().slice(0, 8)}`, ctx.cwd);
193
248
  if (!created.ok) {
194
249
  return {
195
250
  ok: false,
@@ -197,8 +252,9 @@ export async function runAgentTask(input, signal, ctx, deps = {}) {
197
252
  };
198
253
  }
199
254
  wt = created;
255
+ await deps.onWorktreeCreated?.(created);
200
256
  }
201
- const cwd = wt?.path ?? getWorkingDir();
257
+ const cwd = wt?.path ?? ctx.cwd ?? getWorkingDir();
202
258
  let writeScopes;
203
259
  try {
204
260
  writeScopes = def.type === 'general'
@@ -211,6 +267,38 @@ export async function runAgentTask(input, signal, ctx, deps = {}) {
211
267
  return { ok: false, error: error.message };
212
268
  }
213
269
  const rootScope = await normalizeWriteScopes(cwd, undefined);
270
+ const childMemoryAccess = ctx.memoryAccess === 'denied' || !ctx.memoryAccess
271
+ ? 'denied'
272
+ : 'read-only';
273
+ const childRuntime = createAgentRuntimeContext({
274
+ surface: 'subagent',
275
+ profile: def.type === 'general' ? 'subagent-general' : 'subagent-explore',
276
+ cwd,
277
+ workspaceId: ctx.workspaceId,
278
+ sessionId: ctx.sessionId,
279
+ owner: childMemoryAccess === 'denied' ? 'untrusted' : 'local-owner',
280
+ memoryAccess: childMemoryAccess,
281
+ interactiveAsk: def.type === 'general',
282
+ toolGate: ctx.toolGate,
283
+ });
284
+ const subTools = filterToolsForRuntime(ALL_TOOLS.filter((tool) => allowedTools.includes(tool.name)), childRuntime);
285
+ const subToolNames = subTools.map((tool) => tool.name);
286
+ const childTransientBundle = await buildTransientPromptBundle({
287
+ cwd,
288
+ tools: subTools,
289
+ profile: childRuntime.profile,
290
+ includeProjectInstructions: true,
291
+ includePlugins: false,
292
+ runtime: {
293
+ surface: 'subagent',
294
+ cwd,
295
+ workspaceId: ctx.workspaceId,
296
+ sessionId: ctx.sessionId,
297
+ interactiveAsk: childRuntime.interactiveAsk,
298
+ memoryAccess: childMemoryAccess,
299
+ currentUserInput: input.prompt,
300
+ },
301
+ }).catch(() => undefined);
214
302
  let lastPublishAt = 0;
215
303
  const label = input.description;
216
304
  const publish = (line, detail, force = false) => {
@@ -221,8 +309,8 @@ export async function runAgentTask(input, signal, ctx, deps = {}) {
221
309
  ctx.reportProgress?.(line, detail);
222
310
  };
223
311
  // ---- 子 history:一条 system(压缩按 role 定位,必须存在)+ runQuery 自己 push 任务书 ----
224
- const history = [
225
- { role: 'system', content: await buildSubSystemPrompt(cwd, def, ALL_TOOLS) },
312
+ const history = deps.initialHistory?.length ? [...deps.initialHistory] : [
313
+ { role: 'system', content: await buildSubSystemPrompt(cwd, def, subTools) },
226
314
  ];
227
315
  const historyLenBefore = history.length;
228
316
  const maxConcurrent = positiveInt(process.env.AGENT_TOOL_MAX_CONCURRENT) ?? ctx.subagentConfig?.maxConcurrent ?? 3;
@@ -353,20 +441,22 @@ export async function runAgentTask(input, signal, ctx, deps = {}) {
353
441
  publish('正在分析任务', { kind: 'subagent', phase: 'analyzing' }, true);
354
442
  const events = runQuery(input.prompt, {
355
443
  provider: ctx.provider,
444
+ runtimeContext: childRuntime,
356
445
  history,
357
446
  maxTurns,
358
- allowedTools,
447
+ allowedTools: subToolNames,
359
448
  signal: combinedSignal,
360
449
  sessionState: createSessionState(), // 独立会话态,不与主循环/其他分身串扰
361
450
  toolGate: ctx.toolGate, // 继承主循环审批策略(不给可写子 agent 开审批后门)
362
451
  chat: deps.chat,
363
452
  executeTool: guardedExecute,
364
- // 受监督宿主(Desktop)下把「监督位」透传给子 agent:子 agent 的浏览器 challenge(验证码/登录)
365
- // 仍可由用户在可见浏览器里处理,与主 agent 行为一致;非监督(CLI/-p/TUI)不传 → 子 agent 同样
366
- // 非阻塞、绝不挂起。conversationKey 留空以维持子 agent「不认领独立标签页」的既有行为。
367
- ...(ctx.browserRun?.supervised
368
- ? { browserRun: { conversationKey: '', runId: randomUUID(), supervised: true } }
369
- : {}),
453
+ memoryContext: {
454
+ access: childMemoryAccess,
455
+ workspaceId: ctx.workspaceId,
456
+ sessionId: ctx.sessionId,
457
+ },
458
+ transientBundle: childTransientBundle,
459
+ promptCache: derivePromptCacheContext(ctx.promptCache, `subagent:${ctx.toolCallId ?? input.description}`),
370
460
  // 不传 transientContext:任务书必须自包含,父回合的瞬时上下文不该隐式泄入
371
461
  });
372
462
  for await (const ev of events) {
@@ -445,6 +535,7 @@ export async function runAgentTask(input, signal, ctx, deps = {}) {
445
535
  finally {
446
536
  stopTimeout();
447
537
  releaseLease?.();
538
+ await deps.captureHistory?.(history);
448
539
  }
449
540
  // ---- 结局映射(直接查 signal 状态,不依赖事件旗标) ----
450
541
  if (ownerCancelController.signal.aborted) {
@@ -505,6 +596,8 @@ export async function runAgentTask(input, signal, ctx, deps = {}) {
505
596
  changedFiles.add(path);
506
597
  report += await finalizeWorktree(wt, label);
507
598
  }
599
+ // 覆盖度提取(客观,从 tool call 历史推导)——在截断之前,不受报告长度影响。
600
+ const coveredFiles = extractCoveredFiles(history, historyLenBefore);
508
601
  if (report.length > DEFAULT_MAX_RESULT_SIZE_CHARS) {
509
602
  report =
510
603
  report.slice(0, DEFAULT_MAX_RESULT_SIZE_CHARS) +
@@ -523,6 +616,7 @@ export async function runAgentTask(input, signal, ctx, deps = {}) {
523
616
  failedToolCalls: toolFail,
524
617
  durationMs: Date.now() - startedAt,
525
618
  changedFiles: [...changedFiles].sort(),
619
+ coveredFiles,
526
620
  ...(wt && changedFiles.size > 0 ? {
527
621
  worktree: {
528
622
  id: wt.branch.replace(/^agent\//, ''),
@@ -538,6 +632,128 @@ export async function runAgentTask(input, signal, ctx, deps = {}) {
538
632
  async function call(input, signal) {
539
633
  return runAgentTask(input, signal, {});
540
634
  }
635
+ export async function runManagedAgentTask(input, signal, ctx, deps = {}) {
636
+ if (!ctx.sessionState)
637
+ return runAgentTask(input, signal, ctx);
638
+ const id = input.resume_agent_id ?? `agent_${randomUUID()}`;
639
+ let initialHistory;
640
+ let resumedWorktree;
641
+ let coreInput = { ...input, run_in_background: undefined, resume_agent_id: undefined };
642
+ if (input.resume_agent_id) {
643
+ const live = ctx.sessionState.agentTasks.tasks.get(id);
644
+ if (live?.status === 'running')
645
+ return { ok: false, error: `Agent ${id} 正在运行,不能并发恢复` };
646
+ const saved = await loadAgentRecord(ctx, id);
647
+ if (!saved)
648
+ return { ok: false, error: `找不到可恢复 Agent:${id}` };
649
+ initialHistory = saved.history;
650
+ resumedWorktree = saved.worktree && await access(saved.worktree.path)
651
+ .then(() => saved.worktree)
652
+ .catch(() => undefined);
653
+ coreInput = {
654
+ ...saved.input,
655
+ prompt: input.prompt,
656
+ description: input.description || saved.description,
657
+ run_in_background: undefined,
658
+ resume_agent_id: undefined,
659
+ };
660
+ }
661
+ const abort = new AbortController();
662
+ const combined = signal ? AbortSignal.any([signal, abort.signal]) : abort.signal;
663
+ let settle;
664
+ const completion = new Promise((resolvePromise) => { settle = resolvePromise; });
665
+ const task = {
666
+ id,
667
+ status: 'running',
668
+ description: coreInput.description,
669
+ input: coreInput,
670
+ createdAt: Date.now(),
671
+ updatedAt: Date.now(),
672
+ abort,
673
+ completion,
674
+ events: new EventEmitter(),
675
+ };
676
+ ctx.sessionState.agentTasks.tasks.set(id, task);
677
+ await saveAgentRecord(ctx, task);
678
+ await appendAgentEvent(ctx, id, { phase: 'started', resumed: Boolean(input.resume_agent_id) });
679
+ const run = async () => {
680
+ let captured = initialHistory;
681
+ let lastPersistedProgressAt = 0;
682
+ const managedContext = {
683
+ ...ctx,
684
+ reportProgress: (line, detail) => {
685
+ ctx.reportProgress?.(line, detail);
686
+ task.progress = line;
687
+ task.events.emit('change');
688
+ if (Date.now() - lastPersistedProgressAt >= 1_000) {
689
+ lastPersistedProgressAt = Date.now();
690
+ void saveAgentRecord(ctx, task).catch(() => undefined);
691
+ void appendAgentEvent(ctx, id, { phase: 'progress', message: line })
692
+ .catch(() => undefined);
693
+ }
694
+ },
695
+ };
696
+ try {
697
+ const result = await runAgentTask(coreInput, combined, managedContext, {
698
+ ...deps,
699
+ initialHistory,
700
+ existingWorktree: resumedWorktree,
701
+ onWorktreeCreated: async (worktree) => {
702
+ task.worktree = worktree;
703
+ await saveAgentRecord(ctx, task);
704
+ },
705
+ captureHistory: (history) => { captured = [...history]; },
706
+ });
707
+ task.result = result;
708
+ task.history = captured;
709
+ task.status = abort.signal.aborted ? 'stopped' : result.ok ? 'completed' : 'failed';
710
+ if (task.worktree && !await access(task.worktree.path).then(() => true).catch(() => false)) {
711
+ task.worktree = undefined;
712
+ }
713
+ task.updatedAt = Date.now();
714
+ await saveAgentRecord(ctx, task);
715
+ await appendAgentEvent(ctx, id, { phase: task.status, ok: result.ok });
716
+ return result;
717
+ }
718
+ catch (error) {
719
+ task.status = abort.signal.aborted ? 'stopped' : 'failed';
720
+ task.result = { ok: false, error: error.message };
721
+ task.history = captured;
722
+ task.updatedAt = Date.now();
723
+ await saveAgentRecord(ctx, task).catch(() => undefined);
724
+ await appendAgentEvent(ctx, id, { phase: task.status, error: error.message })
725
+ .catch(() => undefined);
726
+ return task.result;
727
+ }
728
+ finally {
729
+ task.events.emit('change');
730
+ settle();
731
+ }
732
+ };
733
+ if (input.run_in_background) {
734
+ void run();
735
+ return {
736
+ ok: true,
737
+ content: `后台 Agent 已启动。agent_id=${id}\n使用 TaskOutput 获取进度/结果,TaskStop 停止。`,
738
+ metadata: {
739
+ kind: 'agent', agentId: id, status: 'running',
740
+ agentType: input.agent_type ?? 'explore', description: input.description,
741
+ isolation: input.isolation ?? 'none', turns: 0, toolCalls: 0,
742
+ failedToolCalls: 0, durationMs: 0, changedFiles: [],
743
+ },
744
+ };
745
+ }
746
+ const result = await run();
747
+ if (result.ok && result.metadata?.kind === 'agent') {
748
+ result.metadata.agentId = id;
749
+ result.metadata.status = 'completed';
750
+ result.content = `agent_id=${id}\n${result.content}`;
751
+ }
752
+ else if (!result.ok) {
753
+ result.error = `agent_id=${id}\n${result.error}`;
754
+ }
755
+ return result;
756
+ }
541
757
  // ---------------- 5. 导出 ----------------
542
758
  export const agentTool = {
543
759
  name: 'Agent',
@@ -551,5 +767,5 @@ export const agentTool = {
551
767
  maxResultSizeChars: DEFAULT_MAX_RESULT_SIZE_CHARS,
552
768
  interruptBehavior: () => 'block',
553
769
  call,
554
- callWithContext: runAgentTask,
770
+ callWithContext: runManagedAgentTask,
555
771
  };