minimal-agent 0.13.0 → 0.15.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 (474) hide show
  1. package/README.md +6 -5
  2. package/package.json +60 -4
  3. package/plugins/computer_use/.claude-plugin/plugin.json +1 -1
  4. package/plugins/cron-runner/src/commands.js +4 -4
  5. package/plugins/cron-runner/src/commands.ts +4 -4
  6. package/plugins/workflow-runner/.claude-plugin/plugin.json +2 -2
  7. package/plugins/workflow-runner/commands/workflow.md +57 -90
  8. package/plugins/workflow-runner/commands/workflows.md +4 -4
  9. package/plugins/workflow-runner/plugin.js +24 -13
  10. package/plugins/workflow-runner/plugin.ts +28 -13
  11. package/plugins/workflow-runner/src/discovery.js +160 -0
  12. package/plugins/workflow-runner/src/discovery.ts +194 -0
  13. package/plugins/workflow-runner/src/goalAnchor.js +53 -0
  14. package/plugins/workflow-runner/src/goalAnchor.ts +59 -0
  15. package/plugins/workflow-runner/src/index.js +197 -206
  16. package/plugins/workflow-runner/src/index.ts +248 -249
  17. package/plugins/workflow-runner/src/inputCoercion.js +40 -0
  18. package/plugins/workflow-runner/src/inputCoercion.ts +43 -0
  19. package/plugins/workflow-runner/src/journal.js +224 -0
  20. package/plugins/workflow-runner/src/journal.ts +274 -0
  21. package/plugins/workflow-runner/src/jsonSchema.js +132 -0
  22. package/plugins/workflow-runner/src/jsonSchema.ts +162 -0
  23. package/plugins/workflow-runner/src/moduleResolution.js +64 -0
  24. package/plugins/workflow-runner/src/moduleResolution.ts +71 -0
  25. package/plugins/workflow-runner/src/resourceInputs.js +220 -0
  26. package/plugins/workflow-runner/src/resourceInputs.ts +300 -0
  27. package/plugins/workflow-runner/src/runner.js +400 -489
  28. package/plugins/workflow-runner/src/runner.ts +488 -560
  29. package/plugins/workflow-runner/src/runtime/config.js +46 -0
  30. package/plugins/workflow-runner/src/runtime/config.ts +69 -0
  31. package/plugins/workflow-runner/src/runtime/context.js +1304 -0
  32. package/plugins/workflow-runner/src/runtime/context.ts +1786 -0
  33. package/plugins/workflow-runner/src/runtime/exec.js +34 -0
  34. package/plugins/workflow-runner/src/runtime/exec.ts +53 -0
  35. package/plugins/workflow-runner/src/runtime/flow.js +8 -0
  36. package/plugins/workflow-runner/src/runtime/flow.ts +12 -0
  37. package/plugins/workflow-runner/src/runtime/fs.js +27 -0
  38. package/plugins/workflow-runner/src/runtime/fs.ts +41 -0
  39. package/plugins/workflow-runner/src/runtime/model.js +6 -0
  40. package/plugins/workflow-runner/src/runtime/model.ts +8 -0
  41. package/plugins/workflow-runner/src/runtime/output.js +7 -0
  42. package/plugins/workflow-runner/src/runtime/output.ts +21 -0
  43. package/plugins/workflow-runner/src/runtime/scheduler.js +141 -0
  44. package/plugins/workflow-runner/src/runtime/scheduler.ts +166 -0
  45. package/plugins/workflow-runner/src/runtime/state.js +16 -0
  46. package/plugins/workflow-runner/src/runtime/state.ts +19 -0
  47. package/plugins/workflow-runner/src/runtime/tools.js +3 -0
  48. package/plugins/workflow-runner/src/runtime/tools.ts +6 -0
  49. package/plugins/workflow-runner/src/sandbox.js +141 -0
  50. package/plugins/workflow-runner/src/sandbox.ts +182 -0
  51. package/plugins/workflow-runner/src/scriptGuard.d.mts +38 -0
  52. package/plugins/workflow-runner/src/scriptGuard.mjs +449 -0
  53. package/plugins/workflow-runner/src/taskIdentity.js +151 -307
  54. package/plugins/workflow-runner/src/taskIdentity.ts +207 -355
  55. package/plugins/workflow-runner/src/toolRuntime.js +29 -8
  56. package/plugins/workflow-runner/src/toolRuntime.ts +36 -11
  57. package/plugins/workflow-runner/src/types.js +7 -211
  58. package/plugins/workflow-runner/src/types.ts +154 -623
  59. package/plugins/workflow-runner/src/util.js +47 -0
  60. package/plugins/workflow-runner/src/util.ts +51 -0
  61. package/plugins/workflow-runner/src/workflowContext.js +20 -0
  62. package/plugins/workflow-runner/src/workflowContext.ts +58 -0
  63. package/plugins/workflow-runner/src/workflowDependencies.js +36 -0
  64. package/plugins/workflow-runner/src/workflowDependencies.ts +59 -0
  65. package/plugins/workflow-runner/src/workflowFingerprint.js +118 -0
  66. package/plugins/workflow-runner/src/workflowFingerprint.ts +122 -0
  67. package/plugins/workflow-runner/src/workflowState.js +474 -802
  68. package/plugins/workflow-runner/src/workflowState.ts +575 -970
  69. package/plugins/workflow-runner/test/api.test.ts +223 -0
  70. package/plugins/workflow-runner/test/apiCapabilities.test.ts +614 -0
  71. package/plugins/workflow-runner/test/apiConcurrencyGate.test.ts +104 -0
  72. package/plugins/workflow-runner/test/apiEcho.test.ts +210 -0
  73. package/plugins/workflow-runner/test/apiReadText.test.ts +178 -0
  74. package/plugins/workflow-runner/test/apiResourceLedger.test.ts +184 -0
  75. package/plugins/workflow-runner/test/childWorkflow.test.ts +304 -0
  76. package/plugins/workflow-runner/test/discovery.test.ts +234 -0
  77. package/plugins/workflow-runner/test/goalAnchor.test.ts +106 -0
  78. package/plugins/workflow-runner/test/goalController.test.ts +317 -0
  79. package/plugins/workflow-runner/test/journalLanes.test.ts +198 -0
  80. package/plugins/workflow-runner/test/listResources.test.ts +106 -0
  81. package/plugins/workflow-runner/test/resourceInputs.test.ts +294 -0
  82. package/plugins/workflow-runner/test/sandbox.test.ts +126 -0
  83. package/plugins/workflow-runner/test/scheduler.test.ts +70 -0
  84. package/plugins/workflow-runner/test/scriptGuard.test.ts +276 -0
  85. package/plugins/workflow-runner/test/skillDocSync.test.ts +78 -0
  86. package/plugins/workflow-runner/test/taskIdentity.test.ts +288 -179
  87. package/plugins/workflow-runner/test/workflowFingerprint.test.ts +106 -0
  88. package/plugins/workflow-runner/test/workflowState.test.ts +429 -0
  89. package/skills/pptx/examples/assets/cover-bg.svg +23 -0
  90. package/skills/pptx/examples/assets/icon-spark.svg +5 -0
  91. package/skills/ui-design/SKILL.md +5 -2
  92. package/skills/ui-design/references/layout-composition.md +1 -1
  93. package/skills/workflow-creator/SKILL.md +344 -0
  94. package/skills/workflow-creator/assets/template/workflow.mjs +48 -0
  95. package/skills/workflow-creator/references/api.md +216 -0
  96. package/skills/workflow-creator/references/migration.md +103 -0
  97. package/skills/workflow-creator/references/patterns.md +779 -0
  98. package/skills/workflow-creator/scripts/list-resources.mjs +205 -0
  99. package/skills/workflow-creator/scripts/scaffold.mjs +148 -0
  100. package/skills/workflow-creator/scripts/validate.mjs +275 -0
  101. package/skills/workflow-creator/scripts/workflow-creator.test.mjs +82 -0
  102. package/src/advisor/advisorCoordinator.js +536 -0
  103. package/src/advisor/advisorCoordinator.ts +693 -0
  104. package/src/cli/configMenu.tsx +0 -1
  105. package/src/cli/print.js +27 -6
  106. package/src/cli/print.ts +48 -4
  107. package/src/cli/quickModelSetup.js +12 -1
  108. package/src/cli/quickModelSetup.tsx +15 -3
  109. package/src/cli/streamJson.js +5 -6
  110. package/src/cli/streamJson.ts +8 -4
  111. package/src/cli/wizards/advisorWizard.js +4 -2
  112. package/src/cli/wizards/advisorWizard.tsx +8 -2
  113. package/src/cli/wizards/contextAdvisorWizard.js +5 -4
  114. package/src/cli/wizards/contextAdvisorWizard.tsx +7 -6
  115. package/src/cli/wizards/providerPresets.js +18 -8
  116. package/src/cli/wizards/providerPresets.ts +18 -8
  117. package/src/collaboration/taskFlow.js +115 -0
  118. package/src/collaboration/taskFlow.ts +169 -0
  119. package/src/config/configDefaults.js +41 -1
  120. package/src/config/configDefaults.ts +43 -1
  121. package/src/config/configDiagnostics.ts +2 -2
  122. package/src/config/configFile.js +40 -9
  123. package/src/config/configFile.ts +60 -11
  124. package/src/config/configService.js +419 -74
  125. package/src/config/configService.ts +703 -145
  126. package/src/config/numericLimits.js +22 -0
  127. package/src/config/numericLimits.ts +24 -0
  128. package/src/config.js +1 -0
  129. package/src/config.ts +3 -2
  130. package/src/context/budgetPlan.js +1 -1
  131. package/src/context/budgetPlan.ts +1 -1
  132. package/src/context/compact.js +7 -2
  133. package/src/context/compact.ts +9 -2
  134. package/src/context/microCompactLite.js +212 -13
  135. package/src/context/microCompactLite.ts +261 -12
  136. package/src/context/sessionRegistry.js +8 -1
  137. package/src/context/sessionRegistry.ts +18 -5
  138. package/src/context/toolResultArchive.js +72 -0
  139. package/src/context/toolResultArchive.ts +95 -0
  140. package/src/goal/errors.js +8 -0
  141. package/src/goal/errors.ts +18 -0
  142. package/src/goal/goalRuntime.js +344 -0
  143. package/src/goal/goalRuntime.ts +466 -0
  144. package/src/goal/goalStore.js +200 -0
  145. package/src/goal/goalStore.ts +219 -0
  146. package/src/goal/index.js +4 -0
  147. package/src/goal/index.ts +4 -0
  148. package/src/goal/statusMapping.js +71 -0
  149. package/src/goal/statusMapping.ts +95 -0
  150. package/src/goal/types.js +7 -0
  151. package/src/goal/types.ts +179 -0
  152. package/src/goal/workflowController.js +306 -0
  153. package/src/goal/workflowController.ts +360 -0
  154. package/src/harness/evidenceLedger.js +2 -0
  155. package/src/harness/evidenceLedger.ts +1 -0
  156. package/src/harness/stallGuard.js +9 -3
  157. package/src/harness/stallGuard.ts +7 -3
  158. package/src/images/imageResolver.js +161 -0
  159. package/src/images/imageResolver.ts +189 -0
  160. package/src/infra/verification.js +34 -5
  161. package/src/infra/verification.ts +39 -4
  162. package/src/llm/client.js +79 -21
  163. package/src/llm/client.ts +182 -35
  164. package/src/llm/gatewayClient.js +201 -0
  165. package/src/llm/gatewayClient.ts +299 -0
  166. package/src/llm/messageProvenance.js +46 -0
  167. package/src/llm/messageProvenance.ts +58 -0
  168. package/src/llm/modelProvider.js +1 -0
  169. package/src/llm/modelProvider.ts +22 -0
  170. package/src/llm/providers/anthropicFormat.js +108 -1
  171. package/src/llm/providers/anthropicFormat.ts +115 -4
  172. package/src/llm/providers/openaiFormat.js +9 -0
  173. package/src/llm/providers/openaiFormat.ts +12 -3
  174. package/src/loop.js +328 -55
  175. package/src/loop.ts +382 -58
  176. package/src/main.js +4 -1
  177. package/src/main.tsx +4 -1
  178. package/src/managedExecution/index.js +2 -0
  179. package/src/managedExecution/index.ts +2 -0
  180. package/src/managedExecution/registry.js +15 -0
  181. package/src/managedExecution/registry.ts +20 -0
  182. package/src/managedExecution/types.js +1 -0
  183. package/src/managedExecution/types.ts +86 -0
  184. package/src/modelRef.js +9 -0
  185. package/src/modelRef.ts +31 -0
  186. package/src/multimodal.js +14 -28
  187. package/src/multimodal.ts +17 -33
  188. package/src/net/lanDiscovery.js +65 -0
  189. package/src/net/lanDiscovery.ts +82 -0
  190. package/src/plugin-sdk.js +28 -3
  191. package/src/plugin-sdk.ts +39 -6
  192. package/src/plugins/pluginApi.ts +16 -1
  193. package/src/plugins/pluginLoader.js +4 -0
  194. package/src/plugins/pluginLoader.ts +6 -0
  195. package/src/plugins/pluginRunner.js +139 -7
  196. package/src/plugins/pluginRunner.ts +173 -9
  197. package/src/plugins/slashFallback.js +113 -0
  198. package/src/plugins/slashFallback.ts +137 -0
  199. package/src/prompts/policyRegistry.js +12 -32
  200. package/src/prompts/policyRegistry.ts +15 -32
  201. package/src/prompts/promptAssembly.js +103 -12
  202. package/src/prompts/promptAssembly.ts +114 -12
  203. package/src/prompts/skillList.js +21 -3
  204. package/src/prompts/skillList.ts +27 -2
  205. package/src/prompts/stableSystemPrompt.js +18 -0
  206. package/src/prompts/stableSystemPrompt.ts +33 -0
  207. package/src/runtime/agentRuntimeContext.js +8 -2
  208. package/src/runtime/agentRuntimeContext.ts +17 -4
  209. package/src/session/runAgentTurn.js +78 -12
  210. package/src/session/runAgentTurn.ts +105 -23
  211. package/src/session/runTurn.js +10 -9
  212. package/src/session/runTurn.ts +17 -8
  213. package/src/session/sessionState.ts +2 -0
  214. package/src/team/auth.js +186 -0
  215. package/src/team/auth.ts +298 -0
  216. package/src/team/cli.js +105 -0
  217. package/src/team/cli.ts +122 -0
  218. package/src/team/onlineToolContract.js +64 -0
  219. package/src/team/onlineToolContract.ts +109 -0
  220. package/src/team/toolPolicy.js +36 -0
  221. package/src/team/toolPolicy.ts +75 -0
  222. package/src/tools/advisor/advisor.js +115 -50
  223. package/src/tools/advisor/advisor.ts +124 -51
  224. package/src/tools/advisor/advisorDecision.js +71 -0
  225. package/src/tools/advisor/advisorDecision.ts +85 -0
  226. package/src/tools/agent/agent.js +18 -5
  227. package/src/tools/agent/agent.ts +21 -7
  228. package/src/tools/agent/agentControl.js +246 -0
  229. package/src/tools/agent/agentControl.ts +284 -0
  230. package/src/tools/agent/agentTaskService.js +40 -1
  231. package/src/tools/agent/agentTaskService.ts +44 -1
  232. package/src/tools/agent/agentTypes.js +14 -2
  233. package/src/tools/agent/agentTypes.ts +15 -2
  234. package/src/tools/applypatch/applyPatch.js +362 -0
  235. package/src/tools/applypatch/applyPatch.ts +428 -0
  236. package/src/tools/bash/bash.js +22 -15
  237. package/src/tools/bash/bash.ts +23 -17
  238. package/src/tools/capabilities.js +10 -5
  239. package/src/tools/capabilities.ts +10 -5
  240. package/src/tools/computeruse/computerIntent.js +32 -0
  241. package/src/tools/computeruse/computerIntent.ts +46 -0
  242. package/src/tools/computeruse/telemetryLog.js +12 -0
  243. package/src/tools/computeruse/telemetryLog.ts +16 -0
  244. package/src/tools/computeruse/vision/telemetry.js +1 -0
  245. package/src/tools/computeruse/vision/telemetry.ts +1 -0
  246. package/src/tools/effectiveToolSet.js +4 -0
  247. package/src/tools/effectiveToolSet.ts +4 -0
  248. package/src/tools/index.js +21 -2
  249. package/src/tools/index.ts +33 -2
  250. package/src/tools/presentresult/presentresult.js +6 -15
  251. package/src/tools/presentresult/presentresult.ts +6 -15
  252. package/src/tools/read/read.js +62 -9
  253. package/src/tools/read/read.ts +63 -9
  254. package/src/tools/shared/fileUtils.js +1 -2
  255. package/src/tools/shared/fileUtils.ts +1 -2
  256. package/src/tools/shared/toolOutputStore.js +23 -1
  257. package/src/tools/shared/toolOutputStore.ts +22 -1
  258. package/src/tools/skill/skill.js +9 -3
  259. package/src/tools/skill/skill.ts +8 -4
  260. package/src/tools/toolPromptGuides.js +125 -0
  261. package/src/tools/toolPromptGuides.ts +146 -0
  262. package/src/tools/webbrowser/agentBrowserPath.js +19 -9
  263. package/src/tools/webbrowser/agentBrowserPath.ts +70 -28
  264. package/src/tools/webbrowser/browser.js +27 -11
  265. package/src/tools/webbrowser/browser.ts +68 -24
  266. package/src/tools/webbrowser/browserAutomation.js +329 -0
  267. package/src/tools/webbrowser/browserAutomation.ts +467 -0
  268. package/src/tools/webbrowser/browserAxState.js +97 -0
  269. package/src/tools/webbrowser/browserAxState.ts +142 -0
  270. package/src/tools/webbrowser/browserBatch.js +1578 -0
  271. package/src/tools/webbrowser/browserBatch.ts +2382 -0
  272. package/src/tools/webbrowser/browserCdp.js +208 -0
  273. package/src/tools/webbrowser/browserCdp.ts +255 -0
  274. package/src/tools/webbrowser/browserConditions.js +24 -0
  275. package/src/tools/webbrowser/browserConditions.ts +45 -0
  276. package/src/tools/webbrowser/browserContent.js +281 -0
  277. package/src/tools/webbrowser/browserContent.ts +438 -0
  278. package/src/tools/webbrowser/browserControl.js +131 -34
  279. package/src/tools/webbrowser/browserControl.ts +210 -56
  280. package/src/tools/webbrowser/browserDaemon.js +22 -14
  281. package/src/tools/webbrowser/browserDaemon.ts +54 -21
  282. package/src/tools/webbrowser/browserFrames.js +47 -0
  283. package/src/tools/webbrowser/browserFrames.ts +54 -0
  284. package/src/tools/webbrowser/browserInteractionResolver.js +17 -0
  285. package/src/tools/webbrowser/browserInteractionResolver.ts +40 -0
  286. package/src/tools/webbrowser/browserLocator.js +140 -0
  287. package/src/tools/webbrowser/browserLocator.ts +194 -0
  288. package/src/tools/webbrowser/browserOutcome.js +10 -17
  289. package/src/tools/webbrowser/browserOutcome.ts +48 -31
  290. package/src/tools/webbrowser/browserRecovery.js +58 -0
  291. package/src/tools/webbrowser/browserRecovery.ts +83 -0
  292. package/src/tools/webbrowser/browserRunRegistry.js +35 -3
  293. package/src/tools/webbrowser/browserRunRegistry.ts +91 -15
  294. package/src/tools/webbrowser/browserService.js +28 -2
  295. package/src/tools/webbrowser/browserService.ts +49 -9
  296. package/src/tools/webbrowser/browserStream.js +132 -33
  297. package/src/tools/webbrowser/browserStream.ts +224 -50
  298. package/src/tools/webbrowser/browserTabs.js +48 -15
  299. package/src/tools/webbrowser/browserTabs.ts +178 -96
  300. package/src/tools/webbrowser/webbrowser.js +679 -144
  301. package/src/tools/webbrowser/webbrowser.ts +975 -236
  302. package/src/tools/webfetch/preapproved.js +0 -2
  303. package/src/tools/webfetch/preapproved.ts +0 -2
  304. package/src/tools/websearch/websearch.js +129 -8
  305. package/src/tools/websearch/websearch.ts +138 -6
  306. package/src/types.ts +459 -40
  307. package/src/ui/App.js +377 -58
  308. package/src/ui/App.tsx +576 -111
  309. package/src/ui/LiveArea.js +14 -8
  310. package/src/ui/LiveArea.tsx +14 -10
  311. package/src/ui/MessageList.js +63 -20
  312. package/src/ui/MessageList.tsx +101 -16
  313. package/src/ui/ModelPicker.js +7 -4
  314. package/src/ui/ModelPicker.tsx +55 -8
  315. package/src/ui/hooks/useChat.js +152 -163
  316. package/src/ui/hooks/useChat.ts +396 -334
  317. package/src/ui/loginCommand.js +56 -0
  318. package/src/ui/loginCommand.ts +63 -0
  319. package/src/ui/toolProgress.js +41 -0
  320. package/src/ui/toolProgress.ts +44 -0
  321. package/src/web/browserBridge.js +20 -2
  322. package/src/web/browserBridge.ts +20 -2
  323. package/src/web/protocol.ts +1897 -194
  324. package/workflows/adaptive-research/workflow.mjs +86 -0
  325. package/workflows/e2e-capabilities/workflow.mjs +102 -0
  326. package/workflows/e2e-llm/workflow.mjs +52 -0
  327. package/workflows/e2e-smoke/workflow.mjs +59 -0
  328. package/workflows/e2e-vision-schema/README.md +48 -0
  329. package/workflows/e2e-vision-schema/workflow.mjs +149 -0
  330. package/workflows/e2e-write-greet/workflow.mjs +37 -0
  331. package/workflows/file-census/README.md +14 -0
  332. package/workflows/file-census/scripts/.gitkeep +2 -0
  333. package/workflows/file-census/workflow.mjs +110 -0
  334. package/workflows/goal/README.md +166 -0
  335. package/workflows/goal/prompts/audit.md +57 -0
  336. package/workflows/goal/prompts/contract.md +56 -0
  337. package/workflows/goal/prompts/iterate.md +37 -0
  338. package/workflows/goal/workflow.mjs +501 -0
  339. package/workflows/illustrate/README.md +90 -0
  340. package/workflows/illustrate/assets/engines.json +20 -0
  341. package/workflows/illustrate/assets/extract-baidu.js +21 -0
  342. package/workflows/illustrate/assets/extract-bing.js +33 -0
  343. package/workflows/illustrate/assets/extract-google.js +31 -0
  344. package/workflows/illustrate/workflow.mjs +301 -0
  345. package/workflows/plan/workflow.mjs +389 -0
  346. package/workflows/question-crops/README.md +35 -0
  347. package/workflows/question-crops/prompts/inventory.md +23 -0
  348. package/workflows/question-crops/scripts/image-ops.mjs +305 -0
  349. package/workflows/question-crops/scripts/image-ops.test.mjs +95 -0
  350. package/workflows/question-crops/workflow.mjs +172 -0
  351. package/workflows/ralph-loop/workflow.mjs +162 -0
  352. package/workflows/research/README.md +74 -0
  353. package/workflows/research/prompts/s0-goal.md +43 -0
  354. package/workflows/research/prompts/s1-early-exit.md +22 -0
  355. package/workflows/research/prompts/s1-map.md +58 -0
  356. package/workflows/research/prompts/s2-options.md +53 -0
  357. package/workflows/research/prompts/s3-deep-dive.md +56 -0
  358. package/workflows/research/prompts/s4-verify.md +74 -0
  359. package/workflows/research/prompts/s5-synthesis.md +81 -0
  360. package/workflows/research/prompts/s5b-fill-gaps.md +32 -0
  361. package/workflows/research/prompts/s6-package.md +32 -0
  362. package/workflows/research/scripts/build-report.mjs +98 -0
  363. package/workflows/research/workflow.mjs +288 -0
  364. package/workflows/wechat-reading-shots/prompts/collect-params.md +16 -0
  365. package/workflows/wechat-reading-shots/prompts/evaluate.md +20 -0
  366. package/workflows/wechat-reading-shots/prompts/open-book.md +28 -0
  367. package/workflows/wechat-reading-shots/prompts/read-page.md +13 -0
  368. package/workflows/wechat-reading-shots/prompts/turn-batch.md +24 -0
  369. package/workflows/wechat-reading-shots/test/control-flow.test.ts +329 -0
  370. package/workflows/wechat-reading-shots/workflow.mjs +266 -0
  371. package/workflows/wrong-question-docx/README.md +55 -0
  372. package/workflows/wrong-question-docx/prompts/figure-qa.md +8 -0
  373. package/workflows/wrong-question-docx/prompts/transcribe.md +25 -0
  374. package/workflows/wrong-question-docx/scripts/workbook.mjs +857 -0
  375. package/workflows/wrong-question-docx/test/control-flow.test.ts +165 -0
  376. package/workflows/wrong-question-docx/test/workbook.test.mjs +303 -0
  377. package/workflows/wrong-question-docx/workflow.mjs +485 -0
  378. package/plugins/workflow-runner/src/agentCommon.js +0 -354
  379. package/plugins/workflow-runner/src/agentCommon.ts +0 -435
  380. package/plugins/workflow-runner/src/controlFlow/branch.js +0 -40
  381. package/plugins/workflow-runner/src/controlFlow/branch.ts +0 -46
  382. package/plugins/workflow-runner/src/controlFlow/loop.js +0 -211
  383. package/plugins/workflow-runner/src/controlFlow/loop.ts +0 -248
  384. package/plugins/workflow-runner/src/controlFlow/pause.js +0 -129
  385. package/plugins/workflow-runner/src/controlFlow/pause.ts +0 -141
  386. package/plugins/workflow-runner/src/controlFlow/signal.js +0 -21
  387. package/plugins/workflow-runner/src/controlFlow/signal.ts +0 -29
  388. package/plugins/workflow-runner/src/controlFlow/types.js +0 -18
  389. package/plugins/workflow-runner/src/controlFlow/types.ts +0 -63
  390. package/plugins/workflow-runner/src/dslManifest.js +0 -72
  391. package/plugins/workflow-runner/src/dslManifest.ts +0 -127
  392. package/plugins/workflow-runner/src/expressions.js +0 -639
  393. package/plugins/workflow-runner/src/expressions.ts +0 -640
  394. package/plugins/workflow-runner/src/loader.js +0 -573
  395. package/plugins/workflow-runner/src/loader.ts +0 -721
  396. package/plugins/workflow-runner/src/multimodal.js +0 -38
  397. package/plugins/workflow-runner/src/multimodal.ts +0 -64
  398. package/plugins/workflow-runner/src/recovery.js +0 -126
  399. package/plugins/workflow-runner/src/recovery.ts +0 -156
  400. package/plugins/workflow-runner/src/stepExecutors/agent.js +0 -173
  401. package/plugins/workflow-runner/src/stepExecutors/agent.ts +0 -234
  402. package/plugins/workflow-runner/src/stepExecutors/assert.js +0 -42
  403. package/plugins/workflow-runner/src/stepExecutors/assert.ts +0 -52
  404. package/plugins/workflow-runner/src/stepExecutors/echo.js +0 -31
  405. package/plugins/workflow-runner/src/stepExecutors/echo.ts +0 -38
  406. package/plugins/workflow-runner/src/stepExecutors/llm.js +0 -99
  407. package/plugins/workflow-runner/src/stepExecutors/llm.ts +0 -133
  408. package/plugins/workflow-runner/src/stepExecutors/set.js +0 -49
  409. package/plugins/workflow-runner/src/stepExecutors/set.ts +0 -56
  410. package/plugins/workflow-runner/src/stepExecutors/skill.js +0 -111
  411. package/plugins/workflow-runner/src/stepExecutors/skill.ts +0 -140
  412. package/plugins/workflow-runner/src/stepExecutors/tool.js +0 -227
  413. package/plugins/workflow-runner/src/stepExecutors/tool.ts +0 -274
  414. package/plugins/workflow-runner/src/stepExecutors/verify.js +0 -61
  415. package/plugins/workflow-runner/src/stepExecutors/verify.ts +0 -72
  416. package/plugins/workflow-runner/src/stepPipeline.js +0 -277
  417. package/plugins/workflow-runner/src/stepPipeline.ts +0 -366
  418. package/plugins/workflow-runner/test/agent.test.ts +0 -587
  419. package/plugins/workflow-runner/test/agentLlmError.test.ts +0 -373
  420. package/plugins/workflow-runner/test/bashBlacklist.sweep.test.ts +0 -65
  421. package/plugins/workflow-runner/test/captureMisbind.test.ts +0 -99
  422. package/plugins/workflow-runner/test/cli.e2e.test.ts +0 -167
  423. package/plugins/workflow-runner/test/context-files.test.ts +0 -320
  424. package/plugins/workflow-runner/test/e2e.test.ts +0 -370
  425. package/plugins/workflow-runner/test/e2eNewLayout.test.ts +0 -314
  426. package/plugins/workflow-runner/test/engineRobustness.test.ts +0 -234
  427. package/plugins/workflow-runner/test/expressions.test.ts +0 -439
  428. package/plugins/workflow-runner/test/foundation.test.ts +0 -126
  429. package/plugins/workflow-runner/test/graceful.test.ts +0 -139
  430. package/plugins/workflow-runner/test/greedyInputs.load.test.ts +0 -47
  431. package/plugins/workflow-runner/test/hostCapability.test.ts +0 -108
  432. package/plugins/workflow-runner/test/illustrate.load.test.ts +0 -183
  433. package/plugins/workflow-runner/test/jsonPayload.test.ts +0 -83
  434. package/plugins/workflow-runner/test/loader.test.ts +0 -617
  435. package/plugins/workflow-runner/test/maxTurnsRetryDelay.test.ts +0 -33
  436. package/plugins/workflow-runner/test/multimodal.test.ts +0 -342
  437. package/plugins/workflow-runner/test/output-schema.test.ts +0 -213
  438. package/plugins/workflow-runner/test/parseWorkflowArgs.test.ts +0 -106
  439. package/plugins/workflow-runner/test/pluginRunner.isolation.test.ts +0 -269
  440. package/plugins/workflow-runner/test/ppt.load.test.ts +0 -1220
  441. package/plugins/workflow-runner/test/ralphLoop.e2e.test.ts +0 -221
  442. package/plugins/workflow-runner/test/recovery.test.ts +0 -265
  443. package/plugins/workflow-runner/test/research.load.test.ts +0 -328
  444. package/plugins/workflow-runner/test/runner.test.ts +0 -911
  445. package/plugins/workflow-runner/test/runnerPreflight.test.ts +0 -436
  446. package/plugins/workflow-runner/test/skillTurnDone.test.ts +0 -71
  447. package/plugins/workflow-runner/test/stateLifecycle.test.ts +0 -198
  448. package/plugins/workflow-runner/test/stepPipeline.test.ts +0 -114
  449. package/plugins/workflow-runner/test/taskArbitration.test.ts +0 -354
  450. package/plugins/workflow-runner/test/taskLifecycle.test.ts +0 -324
  451. package/plugins/workflow-runner/test/toolArtifactOverwrite.test.ts +0 -221
  452. package/plugins/workflow-runner/test/toolCapabilityBoundary.test.ts +0 -29
  453. package/plugins/workflow-runner/test/toolRuntimeIntegration.test.ts +0 -168
  454. package/plugins/workflow-runner/test/webppt.load.test.ts +0 -250
  455. package/plugins/workflow-runner/test/word.load.test.ts +0 -208
  456. package/plugins/workflow-runner/test/workflows.smoke.test.ts +0 -76
  457. package/plugins/workflow-runner/test/yamlGuardConditions.test.ts +0 -207
  458. package/src/advisorState.js +0 -22
  459. package/src/cli/configWizard.js +0 -293
  460. package/src/tools/toolProgressBridge.js +0 -48
  461. package/workflows/adaptive-research.yaml +0 -50
  462. package/workflows/book-review-short.yaml +0 -125
  463. package/workflows/e2e-write-greet.yaml +0 -31
  464. package/workflows/illustrate.yaml +0 -227
  465. package/workflows/plan.yaml +0 -470
  466. package/workflows/ppt.yaml +0 -1670
  467. package/workflows/ralph-loop.yaml +0 -201
  468. package/workflows/research.yaml +0 -873
  469. package/workflows/schema.json +0 -176
  470. package/workflows/webppt.yaml +0 -496
  471. package/workflows/wechat-reading-shots.yaml +0 -315
  472. package/workflows/word.yaml +0 -720
  473. package/workflows/youtube-shorts.yaml +0 -202
  474. /package/workflows/{research.md → research/DESIGN.md} +0 -0
@@ -152,7 +152,7 @@ export function applyLineEnding(content: string, ending: LineEndingType): string
152
152
 
153
153
  // 上游 D:\code\kakadeai\constants\files.ts:5-112 BINARY_EXTENSIONS Set 的裁剪版:
154
154
  // 故意剔除 .log / .csv / .tsv / .dat / .data / .lock —— 这些经常被人当文本读。
155
- // 保留纯二进制:图片 / 文档 / 可执行 / 编译产物 / 压缩包 / 多媒体 / 字体 / 数据库 / wasm。
155
+ // 保留纯二进制:图片 / 文档 / 可执行 / 编译产物 / 压缩包 / 多媒体 / 字体 / wasm。
156
156
  export const BINARY_EXTENSIONS = new Set<string>([
157
157
  '.png', '.jpg', '.jpeg', '.gif', '.webp', '.bmp', '.ico', '.tiff', '.tif',
158
158
  '.pdf', '.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx',
@@ -161,7 +161,6 @@ export const BINARY_EXTENSIONS = new Set<string>([
161
161
  '.zip', '.tar', '.gz', '.bz2', '.7z', '.rar', '.iso',
162
162
  '.mp3', '.mp4', '.mov', '.avi', '.mkv', '.wav', '.flac', '.ogg',
163
163
  '.ttf', '.otf', '.woff', '.woff2',
164
- '.sqlite', '.sqlite3', '.db',
165
164
  '.psd', '.ai', '.bin', '.wasm',
166
165
  ]);
167
166
 
@@ -15,6 +15,10 @@ export class ToolOutputStore {
15
15
  diskBytes = 0;
16
16
  bytes = 0;
17
17
  complete = true;
18
+ /** finish() 已调用:hash 已 digest,此后不能再 update(见 append 头注)。 */
19
+ sealed = false;
20
+ /** finish() 的结果缓存 —— digest 只能算一次,二次调用必须拿到同一份。 */
21
+ settled;
18
22
  path;
19
23
  constructor(identity) {
20
24
  const dir = join(sessionRuntimeDir(identity), 'outputs');
@@ -22,6 +26,18 @@ export class ToolOutputStore {
22
26
  this.path = join(dir, `procout_${randomUUID()}.log`);
23
27
  }
24
28
  append(source, value) {
29
+ // ⚠️ finish() 之后到达的迟到数据:**绝不能抛**。
30
+ //
31
+ // `bash.ts` 的 spawnRunner 按 `'exit'` 结算(不能等 `'close'`,否则被 daemon
32
+ // 继承的 pipe 会把它拖成无限挂),代价就是 exit 之后仍可能有 chunk 到达。
33
+ // 那时 hash 已经 digest 过,`hash.update()` 会抛 ERR_CRYPTO_HASH_FINALIZED,
34
+ // 而这个抛错发生在 stdout 的 'data' 回调里 —— 没有任何人接得住。
35
+ //
36
+ // 正确做法是如实记成不完整(数据确实没被算进已报出的结果),然后安静返回。
37
+ if (this.sealed) {
38
+ this.complete = false;
39
+ return true;
40
+ }
25
41
  const raw = Buffer.from(value);
26
42
  if (this.bytes >= MAX_BYTES) {
27
43
  this.complete = false;
@@ -70,6 +86,11 @@ export class ToolOutputStore {
70
86
  this.stream?.once('drain', callback);
71
87
  }
72
88
  async finish() {
89
+ // 幂等:digest 只能算一次。二次调用返回同一份快照,但 `complete` 取最新值 ——
90
+ // 如果之间来过迟到数据,调用方有权知道这份输出其实不完整了。
91
+ if (this.settled)
92
+ return { ...this.settled, complete: this.complete };
93
+ this.sealed = true;
73
94
  if (this.stream) {
74
95
  try {
75
96
  await new Promise((resolve, reject) => {
@@ -85,7 +106,7 @@ export class ToolOutputStore {
85
106
  const preview = (head, tail) => this.stream && tail && !head.endsWith(tail)
86
107
  ? `${head}\n... [middle stored on disk] ...\n${tail}`
87
108
  : head;
88
- return {
109
+ this.settled = {
89
110
  stdout: preview(this.stdout, this.stdoutTail),
90
111
  stderr: preview(this.stderr, this.stderrTail),
91
112
  ...(this.stream ? { path: this.path } : {}),
@@ -93,5 +114,6 @@ export class ToolOutputStore {
93
114
  sha256: this.stream ? this.diskHash.digest('hex') : this.hash.digest('hex'),
94
115
  complete: this.complete,
95
116
  };
117
+ return this.settled;
96
118
  }
97
119
  }
@@ -32,6 +32,10 @@ export class ToolOutputStore {
32
32
  private diskBytes = 0;
33
33
  private bytes = 0;
34
34
  private complete = true;
35
+ /** finish() 已调用:hash 已 digest,此后不能再 update(见 append 头注)。 */
36
+ private sealed = false;
37
+ /** finish() 的结果缓存 —— digest 只能算一次,二次调用必须拿到同一份。 */
38
+ private settled?: StoredOutput;
35
39
  readonly path: string;
36
40
  constructor(identity: RuntimeIdentity) {
37
41
  const dir = join(sessionRuntimeDir(identity), 'outputs');
@@ -39,6 +43,18 @@ export class ToolOutputStore {
39
43
  this.path = join(dir, `procout_${randomUUID()}.log`);
40
44
  }
41
45
  append(source: 'stdout' | 'stderr', value: Buffer | string): boolean {
46
+ // ⚠️ finish() 之后到达的迟到数据:**绝不能抛**。
47
+ //
48
+ // `bash.ts` 的 spawnRunner 按 `'exit'` 结算(不能等 `'close'`,否则被 daemon
49
+ // 继承的 pipe 会把它拖成无限挂),代价就是 exit 之后仍可能有 chunk 到达。
50
+ // 那时 hash 已经 digest 过,`hash.update()` 会抛 ERR_CRYPTO_HASH_FINALIZED,
51
+ // 而这个抛错发生在 stdout 的 'data' 回调里 —— 没有任何人接得住。
52
+ //
53
+ // 正确做法是如实记成不完整(数据确实没被算进已报出的结果),然后安静返回。
54
+ if (this.sealed) {
55
+ this.complete = false;
56
+ return true;
57
+ }
42
58
  const raw = Buffer.from(value);
43
59
  if (this.bytes >= MAX_BYTES) {
44
60
  this.complete = false;
@@ -83,6 +99,10 @@ export class ToolOutputStore {
83
99
  this.stream?.once('drain', callback);
84
100
  }
85
101
  async finish(): Promise<StoredOutput> {
102
+ // 幂等:digest 只能算一次。二次调用返回同一份快照,但 `complete` 取最新值 ——
103
+ // 如果之间来过迟到数据,调用方有权知道这份输出其实不完整了。
104
+ if (this.settled) return { ...this.settled, complete: this.complete };
105
+ this.sealed = true;
86
106
  if (this.stream) {
87
107
  try {
88
108
  await new Promise<void>((resolve, reject) => {
@@ -98,7 +118,7 @@ export class ToolOutputStore {
98
118
  this.stream && tail && !head.endsWith(tail)
99
119
  ? `${head}\n... [middle stored on disk] ...\n${tail}`
100
120
  : head;
101
- return {
121
+ this.settled = {
102
122
  stdout: preview(this.stdout, this.stdoutTail),
103
123
  stderr: preview(this.stderr, this.stderrTail),
104
124
  ...(this.stream ? { path: this.path } : {}),
@@ -106,5 +126,6 @@ export class ToolOutputStore {
106
126
  sha256: this.stream ? this.diskHash!.digest('hex') : this.hash.digest('hex'),
107
127
  complete: this.complete,
108
128
  };
129
+ return this.settled;
109
130
  }
110
131
  }
@@ -15,9 +15,9 @@ const schema = z.object({
15
15
  arguments: z.string().max(20_000).optional(),
16
16
  });
17
17
  const activated = new Map();
18
- async function candidates(name, cwd) {
18
+ async function candidates(name, context) {
19
19
  const exact = [];
20
- for (const root of getResourceSearchPaths('skills', import.meta.url, cwd)) {
20
+ for (const root of getResourceSearchPaths('skills', import.meta.url, context.cwd)) {
21
21
  let entries;
22
22
  try {
23
23
  entries = await readdir(root, { withFileTypes: true });
@@ -35,6 +35,12 @@ async function candidates(name, cwd) {
35
35
  const metadata = frontmatter
36
36
  ? parseYaml(frontmatter[1])
37
37
  : undefined;
38
+ const modes = Array.isArray(metadata?.metadata?.modes) ? metadata.metadata.modes : [];
39
+ const surfaces = Array.isArray(metadata?.metadata?.surfaces) ? metadata.metadata.surfaces : [];
40
+ if (modes.length > 0 && !modes.includes(context.conversationMode ?? 'private'))
41
+ continue;
42
+ if (surfaces.length > 0 && !surfaces.includes(context.surface))
43
+ continue;
38
44
  const declared = typeof metadata?.name === 'string' ? metadata.name.trim() : undefined;
39
45
  if (entry.name === name || declared === name)
40
46
  exact.push(path);
@@ -45,7 +51,7 @@ async function candidates(name, cwd) {
45
51
  return [...new Set(exact)];
46
52
  }
47
53
  async function call(input, context) {
48
- const found = await candidates(input.name, context.cwd);
54
+ const found = await candidates(input.name, context);
49
55
  if (!found.length)
50
56
  return { ok: false, error: `没有找到名称精确匹配的 Skill:${input.name}` };
51
57
  // Search roots are ordered: project skill intentionally overrides the bundled skill.
@@ -20,9 +20,9 @@ const schema = z.object({
20
20
  type Input = z.infer<typeof schema>;
21
21
  const activated = new Map<string, string>();
22
22
 
23
- async function candidates(name: string, cwd?: string): Promise<string[]> {
23
+ async function candidates(name: string, context: ToolCallContext): Promise<string[]> {
24
24
  const exact: string[] = [];
25
- for (const root of getResourceSearchPaths('skills', import.meta.url, cwd)) {
25
+ for (const root of getResourceSearchPaths('skills', import.meta.url, context.cwd)) {
26
26
  let entries;
27
27
  try {
28
28
  entries = await readdir(root, { withFileTypes: true });
@@ -36,8 +36,12 @@ async function candidates(name: string, cwd?: string): Promise<string[]> {
36
36
  const text = await readFile(path, 'utf8');
37
37
  const frontmatter = text.match(/^---\r?\n([\s\S]*?)\r?\n---/);
38
38
  const metadata = frontmatter
39
- ? (parseYaml(frontmatter[1]!) as { name?: unknown })
39
+ ? (parseYaml(frontmatter[1]!) as { name?: unknown; metadata?: { modes?: unknown; surfaces?: unknown } })
40
40
  : undefined;
41
+ const modes = Array.isArray(metadata?.metadata?.modes) ? metadata.metadata.modes : [];
42
+ const surfaces = Array.isArray(metadata?.metadata?.surfaces) ? metadata.metadata.surfaces : [];
43
+ if (modes.length > 0 && !modes.includes(context.conversationMode ?? 'private')) continue;
44
+ if (surfaces.length > 0 && !surfaces.includes(context.surface)) continue;
41
45
  const declared =
42
46
  typeof metadata?.name === 'string' ? metadata.name.trim() : undefined;
43
47
  if (entry.name === name || declared === name) exact.push(path);
@@ -51,7 +55,7 @@ async function call(
51
55
  input: Input,
52
56
  context: ToolCallContext,
53
57
  ): Promise<ToolResult> {
54
- const found = await candidates(input.name, context.cwd);
58
+ const found = await candidates(input.name, context);
55
59
  if (!found.length)
56
60
  return { ok: false, error: `没有找到名称精确匹配的 Skill:${input.name}` };
57
61
  // Search roots are ordered: project skill intentionally overrides the bundled skill.
@@ -0,0 +1,125 @@
1
+ import { bashShellNotice } from './bash/bash.js';
2
+ import { COMPUTER_USE_TOOL_ACTIONS } from './computeruse/protocol.js';
3
+ export const TOOL_CATEGORY_LABELS = {
4
+ files: '文件与代码',
5
+ shell: 'Shell 与后台任务',
6
+ web: 'Web 与浏览器',
7
+ desktop: '桌面自动化',
8
+ agents: 'Agent、任务与协作',
9
+ memory: '记忆、Skill 与顾问',
10
+ media: '媒体与成果交付',
11
+ };
12
+ const g = (category, useWhen, method, avoidWhen, priority = 'normal') => ({ category, useWhen, method, ...(avoidWhen ? { avoidWhen } : {}), priority });
13
+ /** Single source of truth for built-in tool selection and first-step guidance. */
14
+ export const BUILTIN_TOOL_PROMPT_GUIDES = {
15
+ Read: g('files', '读取已知本机文本、图片、Notebook 或 PDF', '按明确路径和必要范围读取', '通过桌面图片查看器重新打开静态图片', 'preferred'),
16
+ Edit: g('files', '精确替换既有文件中的一处内容', '先 Read 最新内容,再提供唯一 old/new 文本', '不要用于创建文件或大范围机械改写'),
17
+ MultiEdit: g('files', '同一文件需要多处有序精确替换', '先 Read,一次提交互不冲突的 edits', '跨文件修改使用 ApplyPatch'),
18
+ Write: g('files', '创建新文件或完整覆盖明确的小文件', '写入完整最终内容并随后验证', '修改既有文件优先 Edit/ApplyPatch'),
19
+ NotebookEdit: g('files', '按 cell 修改 Jupyter Notebook', '按 cell id 或位置做插入、替换、删除', '不要把 ipynb 当普通 JSON 整体改写'),
20
+ Glob: g('files', '按路径模式查找候选文件', '使用尽量具体的 glob,再 Read 命中项', '已知精确路径时直接 Read'),
21
+ Grep: g('files', '搜索字面量或正则文本', '限制目录和文件类型,再读取命中上下文', '定义、引用和类型关系优先 LSP'),
22
+ LSP: g('files', '获取代码的语义关系和诊断', '定位后读取相关源码确认', '不要把 LSP 摘要当作文件正文'),
23
+ ApplyPatch: g('files', '以统一 diff 原子修改一个或多个文件', '提交标准补丁并处理精确失败位置', '简单单点替换可用 Edit', 'preferred'),
24
+ Trash: g('files', '可恢复地删除文件或清理 Git 未跟踪项', '先确认目标,再移入回收站', '不要用 shell 永久删除代替'),
25
+ Snip: g('files', '截取或压缩当前上下文中的冗长内容', '只移除可恢复或不再需要的片段', '不要删掉当前任务所需证据'),
26
+ Bash: g('shell', '运行构建、测试、Git、安装及确需 shell 的命令', '执行后检查退出状态和输出', '文件读取编辑优先专用工具'),
27
+ PowerShell: g('shell', '运行 Windows 原生脚本和管理命令', '使用结构化参数并检查退出状态', '非 Windows 或普通文件操作不要使用'),
28
+ TaskOutput: g('shell', '读取后台任务增量输出或等待完成', '持有 task_id 后阻塞等待新输出', '高频轮询'),
29
+ TaskStop: g('shell', '停止不再需要或失控的后台任务', '传入准确 task_id 并确认终止结果', '任务仍有价值时不要提前停止'),
30
+ TerminalCapture: g('shell', '查看当前 TUI 终端屏幕状态', '仅在需要屏幕呈现而非命令输出时截取', '项目命令输出用 Bash/TaskOutput'),
31
+ WebSearch: g('web', '发现来源、查询当前信息或做多来源核实', '用短查询和明确时间范围,再打开高价值来源', '已知 URL 正文直接用 WebFetch', 'preferred'),
32
+ WebFetch: g('web', '读取已知 URL 的静态正文', '抓取正文后核对来源与发布时间', '需要登录态、点击或动态交互时用 WebBrowser'),
33
+ WebBrowser: g('web', '操作登录态网页、动态页面、表单或做网页视觉验收', '先观察,单步操作,再验证页面状态', '普通搜索、静态阅读和原生应用不要使用'),
34
+ BrowserBatch: g('web', '同一标签内执行可预期的多步网页流程', '一次提交有条件、失败即停的 steps,并取最终快照', '探索性或单步操作使用 WebBrowser'),
35
+ BrowserCDP: g('web', '需要现有浏览器工具未覆盖的原始 CDP 能力', '发送精确方法并按事件序列读取结果', '常规网页自动化优先 WebBrowser/BrowserBatch', 'last-resort'),
36
+ Download: g('web', '把已知 URL 的原始资源保存到本机', '给出目标路径并校验下载结果', '只阅读正文时用 WebFetch'),
37
+ ComputerUse: g('desktop', '用户明确要求观察或操作原生应用、系统窗口或桌面界面', '观察当前界面,执行一个动作,再验证结果', '文件、静态图片、Shell 和网页任务优先专用工具', 'last-resort'),
38
+ Agent: g('agents', '派生独立且边界清晰的子任务', '给出自包含任务书并在返回后核验整合', '不要拆分琐碎或强顺序工作'),
39
+ AgentMessage: g('agents', '向运行中的子 Agent 补充非触发消息', '按稳定 agent id 发送必要上下文', '需要追加新工作使用 AgentFollowup'),
40
+ AgentList: g('agents', '查看子 Agent 状态和稳定 ID', '按任务路径列出后选择目标', '已知目标 ID 时无需调用'),
41
+ AgentWait: g('agents', '等待指定子 Agent 进展或结果', '优先长等待,收到更新后再整合', '忙轮询'),
42
+ AgentInterrupt: g('agents', '当前子任务方向错误或必须立即停止', '按稳定 ID 中断并保留已有结果', '可用补充指令修正时优先 AgentFollowup'),
43
+ AgentFollowup: g('agents', '给既有子 Agent 追加任务并触发继续运行', '发送范围明确的后续任务', '仅传递信息使用 AgentMessage'),
44
+ TaskCreate: g('agents', '建立跨阶段、有依赖或需验收的正式任务', '写清目标、范围和验收标准', '简单问答和单步工作不建任务'),
45
+ TaskGet: g('agents', '读取一个正式任务的详情', '用稳定 task id 获取最新状态', '需要总览时使用 TaskList'),
46
+ TaskUpdate: g('agents', '更新正式任务状态、依赖或交付信息', '基于真实进展更新并保留因果关系', '未验证完成时不要标记完成'),
47
+ TaskList: g('agents', '查看当前会话任务图和阻塞关系', '先识别可执行项再行动', '已知单个 task id 时用 TaskGet'),
48
+ AskUserQuestion: g('agents', '关键输入无法推断或存在影响方向的真实选择', '一次提出少量互斥选项并给出推荐', '可安全推断或能继续调查时不要打断用户'),
49
+ EnterWorktree: g('agents', '为主任务创建隔离工作区', '创建后记录工作树基线', '只读调查或无需隔离时不要使用'),
50
+ ExitWorktree: g('agents', '收口当前隔离工作树', '核对 diff 后选择 apply、keep 或 discard', '未检查成果前不要丢弃'),
51
+ RecallMemory: g('memory', '当前回答依赖跨会话稳定偏好、决定或背景', '按主题召回并核对证据', '当前消息已足够时不要装饰性召回'),
52
+ RememberMemory: g('memory', '用户明确给出长期有效事实、偏好或决定', '保存原话证据和适用范围', '必须有用户明确依据'),
53
+ UpdateMemory: g('memory', '当前用户陈述纠正一条已有记忆', '先 Recall 定位版本,再完整替换', '不要创建冲突副本'),
54
+ ListMemories: g('memory', '用户要查看已保存记忆或需要管理总览', '按范围列出后再决定操作', '正常任务无需全量列出'),
55
+ ForgetMemory: g('memory', '用户明确要求忘记某条记忆', '定位准确 ID 后删除', '不得主动清理'),
56
+ SetPersona: g('memory', '用户明确要求改变长期角色或协作风格', '写入清晰、稳定的人格要求', '一次性语气请求不要持久化'),
57
+ ClearPersona: g('memory', '用户明确要求恢复默认角色或风格', '清除持久 Persona 并说明下回合生效', '不要自行重置'),
58
+ ConfirmMemory: g('memory', '用户重新确认已有同一事实', '更新目标记录的确认状态', '内容变化时使用 UpdateMemory'),
59
+ ReviewMemories: g('memory', '检查到期或待复核的记忆', '列出需要确认的记录', '不要自动删除'),
60
+ SearchConversations: g('memory', '用户提到之前、上次或既有方案', '用少量内容关键词检索', '不要提交整段问题或元词'),
61
+ Skill: g('memory', '加载已安装的专门工作流程', '按精确名称读取并遵循 SKILL.md', '没有匹配 Skill 时不要调用'),
62
+ Advisor: g('memory', '方案定型、高风险、执行不收敛或交付前需要独立复核', '提供目标、证据和分歧点,再核验建议', '不要把顾问当事实来源或权限授予者'),
63
+ AdvisorDecision: g('memory', '已收到 Advisor 建议,需要记录采纳结论', '按证据记录 accept、partial 或 reject', '未咨询 Advisor 时不要调用'),
64
+ GenerateImage: g('media', '用户要求生成或编辑图片', '给出成品目标和输出位置并检查结果', '分析已有图片不使用'),
65
+ GenerateSpeech: g('media', '用户要求生成语音或音频', '提供文本、声音要求和输出位置', '普通文字回答不使用'),
66
+ PresentResult: g('media', '向用户正式交付生成或修改后的文件', '提交真实最终文件并附简短说明', '只提交面向用户的最终产物', 'preferred'),
67
+ };
68
+ // ⚠️ 覆写会整体替换 tool.description 发给模型的内容——只准放"压缩后仍然完整"的
69
+ // 摘要,不能是与原描述脱节的一句话简介。两类内容绝不能在压缩时被静默丢弃:
70
+ // ① 运行时探测结果(Bash 的 shell 方言警告——机器不同结果不同,覆写必须调用
71
+ // 源头的探测函数重新拼接)——K1 事故(win32 无 bash 时 description 仍声称
72
+ // bash 可用,模型写出的 `mkdir -p` 必挂)的复现路径。
73
+ // ② 从唯一真值动态生成、或带安全相关行为引导的内容(ComputerUse 的动作枚举
74
+ // 来自 `COMPUTER_USE_TOOL_ACTIONS`,WebBrowser 的"坐标点击只是没有选择器
75
+ // 时的兜底、不是默认路径")——一刀切替换成静态简介曾经真的把这两类内容
76
+ // 压没了,`test/computerUseActionDispatch.test.ts`、
77
+ // `test/computerUseRepeat.test.ts`、`test/webbrowserPointer.test.ts` 三个
78
+ // 测试就是从这次真实回归里补的,锁住"压缩后仍要包含这些内容"而不是简单地
79
+ // 锁住某个具体的压缩产物。
80
+ export const CONTRACT_DESCRIPTION_OVERRIDES = {
81
+ ComputerUse: () => `调用宿主原生桌面自动化协议观察或操作原生应用/系统窗口;仅在宿主按当前用户意图动态暴露时可用。` +
82
+ `动作:${COMPUTER_USE_TOOL_ACTIONS.join('、')}。` +
83
+ `遍历可滚动区域(长列表/文档/邮件/diff)优先用 repeat 参数一轮内连续翻页,到边界自动停且如实报告停在第几次,不要每翻一页都单独调用一次。`,
84
+ WebBrowser: '调用受监督真实浏览器执行单步导航、观察或 DOM 交互;定位优先级 @eN 快照引用 > CSS 选择器 > 坐标——坐标点击只是选择器确实拿不到时的兜底,不是默认路径。',
85
+ BrowserBatch: '在同一受监督浏览器标签和锁内执行一组结构化网页步骤。',
86
+ Bash: () => {
87
+ const base = '在当前工作目录启动一个 shell 命令,返回输出或后台任务标识。';
88
+ const notice = bashShellNotice();
89
+ return notice ? `${base}\n\n${notice}` : base;
90
+ },
91
+ Advisor: '向无工具权限的顾问模型请求一次结构化第二意见。',
92
+ // 通用兜底截断逻辑会在 280 字符处硬切原始 description,此前把"partial/reject
93
+ // 必须列出被拒绝的意见点并给出一手证据"这条唯一的自然语言说明整句吞掉(schema
94
+ // 的 superRefine 仍会强制校验字段,但模型看不到为什么)。用覆写绕开截断。
95
+ AdvisorDecision: '记录主 Agent 在一次成功的 Advisor 咨询后对其意见作出的证据判断。' +
96
+ '应在恢复被暂缓的写入、不可逆操作或最终交付之前调用。' +
97
+ '顾问只是第二意见,不是权威结论——判断必须基于代码、测试或用户约束等一手证据,不能默认采纳顾问结论。' +
98
+ '选择 partial 或 reject 时必须明确列出被拒绝的意见点(rejectedPoints)并说明支持该判断的一手证据;' +
99
+ '未经过一次成功的 Advisor 咨询时不要调用本工具。',
100
+ Agent: '启动一个具有明确任务书和隔离边界的子 Agent。',
101
+ };
102
+ function compactContractDescription(tool) {
103
+ const override = CONTRACT_DESCRIPTION_OVERRIDES[tool.name];
104
+ if (override)
105
+ return typeof override === 'function' ? override() : override;
106
+ const raw = typeof tool.description === 'function' ? tool.description() : tool.description;
107
+ return raw.split('\n').map((line) => line.trim()).find(Boolean)?.slice(0, 280)
108
+ ?? `${tool.name} 工具调用契约。`;
109
+ }
110
+ export function attachBuiltinPromptGuides(tools) {
111
+ return tools.map((tool) => {
112
+ const promptGuide = BUILTIN_TOOL_PROMPT_GUIDES[tool.name];
113
+ return promptGuide
114
+ ? Object.assign(tool, {
115
+ promptGuide,
116
+ description: compactContractDescription(tool),
117
+ })
118
+ : tool;
119
+ });
120
+ }
121
+ export function fallbackPromptGuide(tool) {
122
+ const description = typeof tool.description === 'function' ? tool.description() : tool.description;
123
+ const first = description.split(/(?<=[。.!?])\s+|\n/, 1)[0]?.trim() || `调用 ${tool.name}`;
124
+ return g('agents', first, '按工具参数契约调用并核对结构化结果');
125
+ }
@@ -0,0 +1,146 @@
1
+ import type { Tool, ToolCategory, ToolPromptGuide } from '../types.js';
2
+ import { bashShellNotice } from './bash/bash.js';
3
+ import { COMPUTER_USE_TOOL_ACTIONS } from './computeruse/protocol.js';
4
+
5
+ export const TOOL_CATEGORY_LABELS: Record<ToolCategory, string> = {
6
+ files: '文件与代码',
7
+ shell: 'Shell 与后台任务',
8
+ web: 'Web 与浏览器',
9
+ desktop: '桌面自动化',
10
+ agents: 'Agent、任务与协作',
11
+ memory: '记忆、Skill 与顾问',
12
+ media: '媒体与成果交付',
13
+ };
14
+
15
+ const g = (
16
+ category: ToolCategory,
17
+ useWhen: string,
18
+ method: string,
19
+ avoidWhen?: string,
20
+ priority: ToolPromptGuide['priority'] = 'normal',
21
+ ): ToolPromptGuide => ({ category, useWhen, method, ...(avoidWhen ? { avoidWhen } : {}), priority });
22
+
23
+ /** Single source of truth for built-in tool selection and first-step guidance. */
24
+ export const BUILTIN_TOOL_PROMPT_GUIDES: Readonly<Record<string, ToolPromptGuide>> = {
25
+ Read: g('files', '读取已知本机文本、图片、Notebook 或 PDF', '按明确路径和必要范围读取', '通过桌面图片查看器重新打开静态图片', 'preferred'),
26
+ Edit: g('files', '精确替换既有文件中的一处内容', '先 Read 最新内容,再提供唯一 old/new 文本', '不要用于创建文件或大范围机械改写'),
27
+ MultiEdit: g('files', '同一文件需要多处有序精确替换', '先 Read,一次提交互不冲突的 edits', '跨文件修改使用 ApplyPatch'),
28
+ Write: g('files', '创建新文件或完整覆盖明确的小文件', '写入完整最终内容并随后验证', '修改既有文件优先 Edit/ApplyPatch'),
29
+ NotebookEdit: g('files', '按 cell 修改 Jupyter Notebook', '按 cell id 或位置做插入、替换、删除', '不要把 ipynb 当普通 JSON 整体改写'),
30
+ Glob: g('files', '按路径模式查找候选文件', '使用尽量具体的 glob,再 Read 命中项', '已知精确路径时直接 Read'),
31
+ Grep: g('files', '搜索字面量或正则文本', '限制目录和文件类型,再读取命中上下文', '定义、引用和类型关系优先 LSP'),
32
+ LSP: g('files', '获取代码的语义关系和诊断', '定位后读取相关源码确认', '不要把 LSP 摘要当作文件正文'),
33
+ ApplyPatch: g('files', '以统一 diff 原子修改一个或多个文件', '提交标准补丁并处理精确失败位置', '简单单点替换可用 Edit', 'preferred'),
34
+ Trash: g('files', '可恢复地删除文件或清理 Git 未跟踪项', '先确认目标,再移入回收站', '不要用 shell 永久删除代替'),
35
+ Snip: g('files', '截取或压缩当前上下文中的冗长内容', '只移除可恢复或不再需要的片段', '不要删掉当前任务所需证据'),
36
+
37
+ Bash: g('shell', '运行构建、测试、Git、安装及确需 shell 的命令', '执行后检查退出状态和输出', '文件读取编辑优先专用工具'),
38
+ PowerShell: g('shell', '运行 Windows 原生脚本和管理命令', '使用结构化参数并检查退出状态', '非 Windows 或普通文件操作不要使用'),
39
+ TaskOutput: g('shell', '读取后台任务增量输出或等待完成', '持有 task_id 后阻塞等待新输出', '高频轮询'),
40
+ TaskStop: g('shell', '停止不再需要或失控的后台任务', '传入准确 task_id 并确认终止结果', '任务仍有价值时不要提前停止'),
41
+ TerminalCapture: g('shell', '查看当前 TUI 终端屏幕状态', '仅在需要屏幕呈现而非命令输出时截取', '项目命令输出用 Bash/TaskOutput'),
42
+
43
+ WebSearch: g('web', '发现来源、查询当前信息或做多来源核实', '用短查询和明确时间范围,再打开高价值来源', '已知 URL 正文直接用 WebFetch', 'preferred'),
44
+ WebFetch: g('web', '读取已知 URL 的静态正文', '抓取正文后核对来源与发布时间', '需要登录态、点击或动态交互时用 WebBrowser'),
45
+ WebBrowser: g('web', '操作登录态网页、动态页面、表单或做网页视觉验收', '先观察,单步操作,再验证页面状态', '普通搜索、静态阅读和原生应用不要使用'),
46
+ BrowserBatch: g('web', '同一标签内执行可预期的多步网页流程', '一次提交有条件、失败即停的 steps,并取最终快照', '探索性或单步操作使用 WebBrowser'),
47
+ BrowserCDP: g('web', '需要现有浏览器工具未覆盖的原始 CDP 能力', '发送精确方法并按事件序列读取结果', '常规网页自动化优先 WebBrowser/BrowserBatch', 'last-resort'),
48
+ Download: g('web', '把已知 URL 的原始资源保存到本机', '给出目标路径并校验下载结果', '只阅读正文时用 WebFetch'),
49
+
50
+ ComputerUse: g('desktop', '用户明确要求观察或操作原生应用、系统窗口或桌面界面', '观察当前界面,执行一个动作,再验证结果', '文件、静态图片、Shell 和网页任务优先专用工具', 'last-resort'),
51
+
52
+ Agent: g('agents', '派生独立且边界清晰的子任务', '给出自包含任务书并在返回后核验整合', '不要拆分琐碎或强顺序工作'),
53
+ AgentMessage: g('agents', '向运行中的子 Agent 补充非触发消息', '按稳定 agent id 发送必要上下文', '需要追加新工作使用 AgentFollowup'),
54
+ AgentList: g('agents', '查看子 Agent 状态和稳定 ID', '按任务路径列出后选择目标', '已知目标 ID 时无需调用'),
55
+ AgentWait: g('agents', '等待指定子 Agent 进展或结果', '优先长等待,收到更新后再整合', '忙轮询'),
56
+ AgentInterrupt: g('agents', '当前子任务方向错误或必须立即停止', '按稳定 ID 中断并保留已有结果', '可用补充指令修正时优先 AgentFollowup'),
57
+ AgentFollowup: g('agents', '给既有子 Agent 追加任务并触发继续运行', '发送范围明确的后续任务', '仅传递信息使用 AgentMessage'),
58
+ TaskCreate: g('agents', '建立跨阶段、有依赖或需验收的正式任务', '写清目标、范围和验收标准', '简单问答和单步工作不建任务'),
59
+ TaskGet: g('agents', '读取一个正式任务的详情', '用稳定 task id 获取最新状态', '需要总览时使用 TaskList'),
60
+ TaskUpdate: g('agents', '更新正式任务状态、依赖或交付信息', '基于真实进展更新并保留因果关系', '未验证完成时不要标记完成'),
61
+ TaskList: g('agents', '查看当前会话任务图和阻塞关系', '先识别可执行项再行动', '已知单个 task id 时用 TaskGet'),
62
+ AskUserQuestion: g('agents', '关键输入无法推断或存在影响方向的真实选择', '一次提出少量互斥选项并给出推荐', '可安全推断或能继续调查时不要打断用户'),
63
+ EnterWorktree: g('agents', '为主任务创建隔离工作区', '创建后记录工作树基线', '只读调查或无需隔离时不要使用'),
64
+ ExitWorktree: g('agents', '收口当前隔离工作树', '核对 diff 后选择 apply、keep 或 discard', '未检查成果前不要丢弃'),
65
+
66
+ RecallMemory: g('memory', '当前回答依赖跨会话稳定偏好、决定或背景', '按主题召回并核对证据', '当前消息已足够时不要装饰性召回'),
67
+ RememberMemory: g('memory', '用户明确给出长期有效事实、偏好或决定', '保存原话证据和适用范围', '必须有用户明确依据'),
68
+ UpdateMemory: g('memory', '当前用户陈述纠正一条已有记忆', '先 Recall 定位版本,再完整替换', '不要创建冲突副本'),
69
+ ListMemories: g('memory', '用户要查看已保存记忆或需要管理总览', '按范围列出后再决定操作', '正常任务无需全量列出'),
70
+ ForgetMemory: g('memory', '用户明确要求忘记某条记忆', '定位准确 ID 后删除', '不得主动清理'),
71
+ SetPersona: g('memory', '用户明确要求改变长期角色或协作风格', '写入清晰、稳定的人格要求', '一次性语气请求不要持久化'),
72
+ ClearPersona: g('memory', '用户明确要求恢复默认角色或风格', '清除持久 Persona 并说明下回合生效', '不要自行重置'),
73
+ ConfirmMemory: g('memory', '用户重新确认已有同一事实', '更新目标记录的确认状态', '内容变化时使用 UpdateMemory'),
74
+ ReviewMemories: g('memory', '检查到期或待复核的记忆', '列出需要确认的记录', '不要自动删除'),
75
+ SearchConversations: g('memory', '用户提到之前、上次或既有方案', '用少量内容关键词检索', '不要提交整段问题或元词'),
76
+ Skill: g('memory', '加载已安装的专门工作流程', '按精确名称读取并遵循 SKILL.md', '没有匹配 Skill 时不要调用'),
77
+ Advisor: g('memory', '方案定型、高风险、执行不收敛或交付前需要独立复核', '提供目标、证据和分歧点,再核验建议', '不要把顾问当事实来源或权限授予者'),
78
+ AdvisorDecision: g('memory', '已收到 Advisor 建议,需要记录采纳结论', '按证据记录 accept、partial 或 reject', '未咨询 Advisor 时不要调用'),
79
+
80
+ GenerateImage: g('media', '用户要求生成或编辑图片', '给出成品目标和输出位置并检查结果', '分析已有图片不使用'),
81
+ GenerateSpeech: g('media', '用户要求生成语音或音频', '提供文本、声音要求和输出位置', '普通文字回答不使用'),
82
+ PresentResult: g('media', '向用户正式交付生成或修改后的文件', '提交真实最终文件并附简短说明', '只提交面向用户的最终产物', 'preferred'),
83
+ };
84
+
85
+ // ⚠️ 覆写会整体替换 tool.description 发给模型的内容——只准放"压缩后仍然完整"的
86
+ // 摘要,不能是与原描述脱节的一句话简介。两类内容绝不能在压缩时被静默丢弃:
87
+ // ① 运行时探测结果(Bash 的 shell 方言警告——机器不同结果不同,覆写必须调用
88
+ // 源头的探测函数重新拼接)——K1 事故(win32 无 bash 时 description 仍声称
89
+ // bash 可用,模型写出的 `mkdir -p` 必挂)的复现路径。
90
+ // ② 从唯一真值动态生成、或带安全相关行为引导的内容(ComputerUse 的动作枚举
91
+ // 来自 `COMPUTER_USE_TOOL_ACTIONS`,WebBrowser 的"坐标点击只是没有选择器
92
+ // 时的兜底、不是默认路径")——一刀切替换成静态简介曾经真的把这两类内容
93
+ // 压没了,`test/computerUseActionDispatch.test.ts`、
94
+ // `test/computerUseRepeat.test.ts`、`test/webbrowserPointer.test.ts` 三个
95
+ // 测试就是从这次真实回归里补的,锁住"压缩后仍要包含这些内容"而不是简单地
96
+ // 锁住某个具体的压缩产物。
97
+ export const CONTRACT_DESCRIPTION_OVERRIDES: Readonly<Record<string, string | (() => string)>> = {
98
+ ComputerUse: () =>
99
+ `调用宿主原生桌面自动化协议观察或操作原生应用/系统窗口;仅在宿主按当前用户意图动态暴露时可用。` +
100
+ `动作:${COMPUTER_USE_TOOL_ACTIONS.join('、')}。` +
101
+ `遍历可滚动区域(长列表/文档/邮件/diff)优先用 repeat 参数一轮内连续翻页,到边界自动停且如实报告停在第几次,不要每翻一页都单独调用一次。`,
102
+ WebBrowser: '调用受监督真实浏览器执行单步导航、观察或 DOM 交互;定位优先级 @eN 快照引用 > CSS 选择器 > 坐标——坐标点击只是选择器确实拿不到时的兜底,不是默认路径。',
103
+ BrowserBatch: '在同一受监督浏览器标签和锁内执行一组结构化网页步骤。',
104
+ Bash: () => {
105
+ const base = '在当前工作目录启动一个 shell 命令,返回输出或后台任务标识。';
106
+ const notice = bashShellNotice();
107
+ return notice ? `${base}\n\n${notice}` : base;
108
+ },
109
+ Advisor: '向无工具权限的顾问模型请求一次结构化第二意见。',
110
+ // 通用兜底截断逻辑会在 280 字符处硬切原始 description,此前把"partial/reject
111
+ // 必须列出被拒绝的意见点并给出一手证据"这条唯一的自然语言说明整句吞掉(schema
112
+ // 的 superRefine 仍会强制校验字段,但模型看不到为什么)。用覆写绕开截断。
113
+ AdvisorDecision:
114
+ '记录主 Agent 在一次成功的 Advisor 咨询后对其意见作出的证据判断。' +
115
+ '应在恢复被暂缓的写入、不可逆操作或最终交付之前调用。' +
116
+ '顾问只是第二意见,不是权威结论——判断必须基于代码、测试或用户约束等一手证据,不能默认采纳顾问结论。' +
117
+ '选择 partial 或 reject 时必须明确列出被拒绝的意见点(rejectedPoints)并说明支持该判断的一手证据;' +
118
+ '未经过一次成功的 Advisor 咨询时不要调用本工具。',
119
+ Agent: '启动一个具有明确任务书和隔离边界的子 Agent。',
120
+ };
121
+
122
+ function compactContractDescription(tool: Tool): string {
123
+ const override = CONTRACT_DESCRIPTION_OVERRIDES[tool.name];
124
+ if (override) return typeof override === 'function' ? override() : override;
125
+ const raw = typeof tool.description === 'function' ? tool.description() : tool.description;
126
+ return raw.split('\n').map((line) => line.trim()).find(Boolean)?.slice(0, 280)
127
+ ?? `${tool.name} 工具调用契约。`;
128
+ }
129
+
130
+ export function attachBuiltinPromptGuides<T extends Tool>(tools: readonly T[]): T[] {
131
+ return tools.map((tool) => {
132
+ const promptGuide = BUILTIN_TOOL_PROMPT_GUIDES[tool.name];
133
+ return promptGuide
134
+ ? Object.assign(tool, {
135
+ promptGuide,
136
+ description: compactContractDescription(tool),
137
+ })
138
+ : tool;
139
+ });
140
+ }
141
+
142
+ export function fallbackPromptGuide(tool: Tool): ToolPromptGuide {
143
+ const description = typeof tool.description === 'function' ? tool.description() : tool.description;
144
+ const first = description.split(/(?<=[。.!?])\s+|\n/, 1)[0]?.trim() || `调用 ${tool.name}`;
145
+ return g('agents', first, '按工具参数契约调用并核对结构化结果');
146
+ }
@@ -37,9 +37,9 @@
37
37
  import { spawn } from 'node:child_process';
38
38
  import { chmodSync, existsSync } from 'node:fs';
39
39
  import { dirname, isAbsolute, resolve, win32 } from 'node:path';
40
+ import { sanitizeCredentialEnv } from '../../config/configService.js';
40
41
  import { execSiblingDir } from '../../utils/greenRoot.js';
41
42
  import { findPackageRoot } from '../../utils/packageRoot.js';
42
- import { sanitizeCredentialEnv } from '../../config/configService.js';
43
43
  function realDeps() {
44
44
  return {
45
45
  env: process.env,
@@ -138,7 +138,9 @@ export async function detectAgentBrowser(deps) {
138
138
  */
139
139
  export function resolveBundledChromium(deps = realDeps()) {
140
140
  const sub = subdir(deps);
141
- const roots = [resolve(deps.siblingDir(), 'vendor', 'chromium', sub)];
141
+ const roots = [
142
+ resolve(deps.siblingDir(), 'vendor', 'chromium', sub),
143
+ ];
142
144
  const root = deps.packageRoot();
143
145
  if (root)
144
146
  roots.push(resolve(root, 'vendor', 'chromium', sub));
@@ -159,8 +161,8 @@ export function resolveBundledChromium(deps = realDeps()) {
159
161
  * the user's normal Chrome profile or attempting fingerprint evasion.
160
162
  */
161
163
  export function resolveSystemBrowser(deps = realDeps()) {
162
- const explicit = deps.env.MINIMAL_AGENT_BROWSER_EXECUTABLE_PATH
163
- ?? deps.env.AGENT_BROWSER_EXECUTABLE_PATH;
164
+ const explicit = deps.env.MINIMAL_AGENT_BROWSER_EXECUTABLE_PATH ??
165
+ deps.env.AGENT_BROWSER_EXECUTABLE_PATH;
164
166
  if (explicit && deps.exists(explicit))
165
167
  return explicit;
166
168
  const home = deps.env.HOME ?? deps.env.USERPROFILE ?? '';
@@ -169,13 +171,21 @@ export function resolveSystemBrowser(deps = realDeps()) {
169
171
  '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
170
172
  '/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge',
171
173
  '/Applications/Chromium.app/Contents/MacOS/Chromium',
172
- home ? resolve(home, 'Applications/Google Chrome.app/Contents/MacOS/Google Chrome') : '',
174
+ home
175
+ ? resolve(home, 'Applications/Google Chrome.app/Contents/MacOS/Google Chrome')
176
+ : '',
173
177
  ]
174
178
  : deps.platform === 'win32'
175
179
  ? [
176
- deps.env.PROGRAMFILES ? resolve(deps.env.PROGRAMFILES, 'Google/Chrome/Application/chrome.exe') : '',
177
- deps.env['PROGRAMFILES(X86)'] ? resolve(deps.env['PROGRAMFILES(X86)'], 'Microsoft/Edge/Application/msedge.exe') : '',
178
- deps.env.LOCALAPPDATA ? resolve(deps.env.LOCALAPPDATA, 'Google/Chrome/Application/chrome.exe') : '',
180
+ deps.env.PROGRAMFILES
181
+ ? resolve(deps.env.PROGRAMFILES, 'Google/Chrome/Application/chrome.exe')
182
+ : '',
183
+ deps.env['PROGRAMFILES(X86)']
184
+ ? resolve(deps.env['PROGRAMFILES(X86)'], 'Microsoft/Edge/Application/msedge.exe')
185
+ : '',
186
+ deps.env.LOCALAPPDATA
187
+ ? resolve(deps.env.LOCALAPPDATA, 'Google/Chrome/Application/chrome.exe')
188
+ : '',
179
189
  ]
180
190
  : [
181
191
  '/usr/bin/google-chrome-stable',
@@ -184,7 +194,7 @@ export function resolveSystemBrowser(deps = realDeps()) {
184
194
  '/usr/bin/chromium',
185
195
  '/usr/bin/chromium-browser',
186
196
  ];
187
- return candidates.find((candidate) => candidate && deps.exists(candidate)) ?? null;
197
+ return (candidates.find((candidate) => candidate && deps.exists(candidate)) ?? null);
188
198
  }
189
199
  /** vendor 子目录名 = <arch>-<platform>(对齐 rgPath.ts / build-green.ts 的 vendor 约定)。 */
190
200
  function subdir(deps) {