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
@@ -0,0 +1,597 @@
1
+ /**
2
+ * ============================================================
3
+ * src/cli/print.ts —— CLI 非交互模式(-p / --print)
4
+ * ------------------------------------------------------------
5
+ * 不启动 Ink TUI,直接执行单次问答,最后落盘 history。
6
+ * 适合脚本集成、CI/CD、宿主程序(hermes/openclaw)spawn 调用。
7
+ *
8
+ * 两种输出格式(--output-format,默认 text):
9
+ * text —— 把最终回答原样打到 stdout(向后兼容,逐字节不变)
10
+ * json —— stdout 只输出**一行** JSON 结局契约,其它诊断全走 stderr
11
+ *
12
+ * v2 改进(对齐 kakadeai CLI 工程实践):
13
+ * 1. SIGINT 先保存 context 再退出(防丢失)
14
+ * 2. handleEvent 返回退出码,不直接 process.exit(单一职责)
15
+ * 3. EPIPE 保护:管道断开时静默退出不崩溃
16
+ * 4. stdin peek 超时:防止非 TTY 无管道时永久挂起
17
+ *
18
+ * 使用方式:
19
+ * minimal-agent -p "提示"
20
+ * echo "提示" | minimal-agent -p
21
+ * minimal-agent -p --verbose "提示"
22
+ * minimal-agent -p --output-format json "提示" # 结构化结局
23
+ * ============================================================
24
+ */
25
+
26
+ import { getContextPath, saveContext } from '../context/persistContext.js';
27
+ import { updateSessionMetadata } from '../context/sessionRegistry.js';
28
+ import { workspaceIndexService } from '../context/workspaceIndex.js';
29
+ import { normalizeImageDetail } from '../multimodal.js';
30
+ import type { DeliverableManifest, FileActivityMetadata, HarnessDiagnostics, ImageInputSpec, LoopEvent, Message, Provider } from '../types.js';
31
+ import { runWithPlugins } from '../plugins/pluginRunner.js';
32
+ import { buildBaseSystemPrompt, buildTransientPromptBundle } from '../prompts/system.js';
33
+ import { getOrCreateSessionState, sessionStateKey } from '../session/sessionState.js';
34
+ import { hydrateSessionWorktree } from '../tools/worktree/sessionWorktree.js';
35
+ import { ALL_TOOLS } from '../tools/index.js';
36
+ import { createPromptCacheContext } from '../llm/promptCache.js';
37
+ import {
38
+ createAgentRuntimeContext,
39
+ filterToolsForRuntime,
40
+ memoryContextFromRuntime,
41
+ } from '../runtime/agentRuntimeContext.js';
42
+ import type { ComputerUseCliMode } from './computerUse.js';
43
+ import { createCliComputerRun } from './computerUse.js';
44
+ import {
45
+ BOOLEAN_FLAGS,
46
+ VALUE_FLAGS,
47
+ extractFlagValue,
48
+ extractFlagValues,
49
+ normalizeArgs,
50
+ } from './args.js';
51
+
52
+ /**
53
+ * 本文件只处理框架通用 LoopEvent。插件私有事件(PluginEvent,type 为任意字符串)
54
+ * 一律走 default 静默忽略 —— 框架 UI 不认任何具体插件的事件词表。需要冒泡给用户的
55
+ * 非致命提示,插件应 yield 通用 `warning` 事件(已在 LoopEvent 内),而非私有事件。
56
+ */
57
+ type HandleableEvent = LoopEvent;
58
+
59
+ /** 输出格式:text(向后兼容,纯文本)/ json(结构化结局契约,一行 JSON)。 */
60
+ export type OutputFormat = 'text' | 'json';
61
+
62
+ interface PrintOptions {
63
+ verbose: boolean;
64
+ /** 输出格式;缺省 'text'(向后兼容)。 */
65
+ outputFormat?: OutputFormat;
66
+ /** 透传给 runQuery 的最大轮数;缺省走 loop 内默认(50)。 */
67
+ maxTurns?: number;
68
+ /**
69
+ * `--session <id>` 解析出的会话文件路径(main.tsx 算好传入)。
70
+ * 缺省时退回 `getContextPath()`(= default session),向后兼容。
71
+ *
72
+ * 必须和 initialHistory 的加载路径保持同一份解析结果——否则会出现
73
+ * "从 session A 读、写回 default"的读写分裂(load 用了 --session,
74
+ * save 却各自重新调用无参的 getContextPath())。
75
+ */
76
+ sessionFile?: string;
77
+ workspace?: { cwd: string; sessionId: string };
78
+ /** 本机长期记忆权限,由 main.tsx 按输出格式 + `--memory-access` 判定后传入(见 resolveMemoryAccess)。 */
79
+ memoryAccess?: import('../runtime/agentRuntimeContext.js').MemoryAccessInput;
80
+ /** 非交互 Computer Use 必须显式启用;缺省 disabled。 */
81
+ computerUseMode?: ComputerUseCliMode;
82
+ /** Explicit opt-in directory for chronological Computer Use diagnostics. */
83
+ computerUseTraceDir?: string;
84
+ }
85
+
86
+ /**
87
+ * json 模式的累积结局态。runPrintMode 创建一个,贯穿整个事件流:
88
+ * - buffer 累积 assistant 文本(= text 模式的 output.buffer)
89
+ * - numTurns assistant_message 事件计数(模型回合数)
90
+ * - stopReason 终结原因;turn_done→'end_turn',error→'error'/'max_turns',interrupted→'interrupted'
91
+ * - error 失败文案(成功为 null)
92
+ */
93
+ export interface PrintResult {
94
+ buffer: string;
95
+ numTurns: number;
96
+ stopReason: string | undefined;
97
+ error: string | null;
98
+ deliverables?: DeliverableManifest['files'];
99
+ warnings?: string[];
100
+ harnessDiagnostics?: HarnessDiagnostics;
101
+ }
102
+
103
+ /** handleEvent 返回的结构 */
104
+ interface HandleResult {
105
+ exitCode?: number;
106
+ }
107
+
108
+ /** stderr 显示工具结果时的截断阈值;超过即末尾加 "..." */
109
+ const TOOL_OUTPUT_PREVIEW_MAX = 200;
110
+
111
+ /** stdin 读取超时(ms),防止非 TTY + 无管道时永久挂起 */
112
+ const STDIN_TIMEOUT_MS = 3000;
113
+
114
+ /** 已告警过的未知事件类型(去重,避免高频插件私有事件刷屏 stderr)。 */
115
+ const warnedUnknownEventTypes = new Set<string>();
116
+
117
+ function warnUnknownEventType(type: unknown): void {
118
+ const t = typeof type === 'string' ? type : String(type);
119
+ if (warnedUnknownEventTypes.has(t)) return;
120
+ warnedUnknownEventTypes.add(t);
121
+ process.stderr.write(
122
+ `[minimal-agent] 忽略未识别事件类型 "${t}"(插件私有事件;若是 yield 时拼错的 LoopEvent type,请检查插件)\n`,
123
+ );
124
+ }
125
+
126
+ function handleEPIPE(stream: NodeJS.WriteStream): (err: NodeJS.ErrnoException) => void {
127
+ return (err) => {
128
+ if (err.code === 'EPIPE') stream.destroy();
129
+ };
130
+ }
131
+
132
+ export function truncateForDisplay(content: string, max = TOOL_OUTPUT_PREVIEW_MAX): string {
133
+ if (content.length <= max) return content;
134
+ return content.slice(0, max) + '...';
135
+ }
136
+
137
+ export function extractPromptArgs(args: string[]): string[] {
138
+ // flag 定义集中在 cli/args.ts(BOOLEAN_FLAGS / VALUE_FLAGS),这里只消费、不再各维护一份。
139
+ // 先 normalizeArgs 把 `--flag=value` 展开成空格式,否则整个 token 会被当成 prompt 文本
140
+ // 喂给模型(main.tsx 已在 argv 入口规范化过;这里重复调是给直接调用方兜底,幂等)。
141
+ const normalized = normalizeArgs(args);
142
+ const result: string[] = [];
143
+ for (let i = 0; i < normalized.length; i++) {
144
+ const a = normalized[i]!;
145
+ if (BOOLEAN_FLAGS.has(a)) continue;
146
+ if (VALUE_FLAGS.has(a)) {
147
+ i++; // 跳过带值标志紧跟的值(否则 --output-format 的值 json 会被当成 prompt 文本污染)
148
+ continue;
149
+ }
150
+ result.push(a);
151
+ }
152
+ return result;
153
+ }
154
+
155
+ export function extractImageOptions(args: string[]): {
156
+ imageInputs: ImageInputSpec[];
157
+ imageDetail: ImageInputSpec['detail'];
158
+ imageMaxLongSidePixel: number | undefined;
159
+ } {
160
+ const imageDetail = normalizeImageDetail(
161
+ extractFlagValue(args, ['--image-detail']),
162
+ );
163
+ const rawMaxLongSide = extractFlagValue(args, [
164
+ '--image-max-long-side-pixel',
165
+ ]);
166
+ const imageMaxLongSidePixel =
167
+ rawMaxLongSide !== undefined && Number.isFinite(Number(rawMaxLongSide))
168
+ ? Math.floor(Number(rawMaxLongSide))
169
+ : undefined;
170
+ const imageInputs = extractFlagValues(args, ['--image']).map((source) => ({
171
+ source,
172
+ detail: imageDetail,
173
+ maxLongSidePixel: imageMaxLongSidePixel,
174
+ }));
175
+ return { imageInputs, imageDetail, imageMaxLongSidePixel };
176
+ }
177
+
178
+ /**
179
+ * 输出 `-p --output-format json` 的结局契约(**一行** JSON 到 stdout)。
180
+ *
181
+ * ⚠️ 诚实声明:`ok=true` 只代表「Agent 正常跑完(stop_reason==='end_turn')——
182
+ * 未报错、未被中断、未撞最大轮数」,**不代表任务目标真的达成**。工具失败会被
183
+ * 吞回 LLM 让它自行重试,LLM 完全可能在没产出有效结果的情况下正常收尾、给出
184
+ * end_turn。调用方(宿主程序)若要判断「任务是否真做成」,必须额外校验 `result`
185
+ * 文本内容 / 产物文件,不能只看 ok。
186
+ *
187
+ * 字段语义:
188
+ * ok = (stop_reason === 'end_turn')
189
+ * result = 累积的 assistant 文本
190
+ * is_error = !ok
191
+ * stop_reason = end_turn | max_turns | stalled | error | interrupted | config_error
192
+ * num_turns = assistant_message 事件计数
193
+ * error = 失败文案(成功时 null)
194
+ * session_file(可选)= 当前对话落盘路径;拿得到才填,拿不到省略该键
195
+ *
196
+ * 导出供单测断言。
197
+ */
198
+ export function emitJsonResult(result: PrintResult, sessionFile?: string): void {
199
+ const stopReason = result.stopReason ?? 'error';
200
+ const ok = stopReason === 'end_turn';
201
+ const deliverables = result.deliverables ?? [];
202
+ const allVerified = deliverables.length > 0 && deliverables.every((file) => file.verification === 'passed');
203
+ const completionStatus = !ok
204
+ ? (stopReason === 'interrupted' ? 'interrupted' : 'failed')
205
+ : allVerified
206
+ ? 'verified'
207
+ : 'agent_completed';
208
+ const warnings = [
209
+ ...(result.warnings ?? []),
210
+ ...(ok && deliverables.some((file) => file.verification !== 'passed')
211
+ ? ['Agent 已正常结束,但部分产物尚未通过结构化验证。']
212
+ : []),
213
+ ];
214
+ console.log(
215
+ JSON.stringify({
216
+ ok,
217
+ result: result.buffer,
218
+ is_error: !ok,
219
+ stop_reason: stopReason,
220
+ num_turns: result.numTurns,
221
+ error: result.error,
222
+ completionStatus,
223
+ deliverables,
224
+ verification: allVerified ? 'passed' : deliverables.length > 0 ? 'not_run' : 'none',
225
+ warnings,
226
+ ...(result.harnessDiagnostics ? { harness: result.harnessDiagnostics } : {}),
227
+ ...(sessionFile ? { session_file: sessionFile } : {}),
228
+ }),
229
+ );
230
+ }
231
+
232
+ /**
233
+ * 尝试拿当前会话落盘路径(给 json 契约的 session_file 字段)。
234
+ * 取不到(异常等)返回 undefined,emitJsonResult 据此省略该键(契约允许)。
235
+ *
236
+ * override 有值时直接用它(`--session` 解析出的路径)——不重新调用无参的
237
+ * getContextPath(),否则会跟真正读写的文件不一致。
238
+ */
239
+ function trySessionFile(override?: string): string | undefined {
240
+ if (override) return override;
241
+ try {
242
+ return getContextPath();
243
+ } catch {
244
+ return undefined;
245
+ }
246
+ }
247
+
248
+ /**
249
+ * CLI 非交互模式:读取 prompt,执行 runQuery,最后落盘 history。
250
+ *
251
+ * - text 模式:流式 / 收尾把答案打到 stdout(逐字节兼容旧行为)
252
+ * - json 模式:stdout 只在退出时输出一行 JSON 结局契约(emitJsonResult)
253
+ */
254
+ export async function runPrintMode(
255
+ provider: Provider,
256
+ args: string[],
257
+ initialHistory: Message[],
258
+ options: PrintOptions,
259
+ ): Promise<void> {
260
+ // EPIPE 保护:管道断开时不崩溃(如 `bun -p "..." | head -1`)
261
+ process.stdout.on('error', handleEPIPE(process.stdout));
262
+ process.stderr.on('error', handleEPIPE(process.stderr));
263
+
264
+ const outputFormat: OutputFormat = options.outputFormat ?? 'text';
265
+ const isJson = outputFormat === 'json';
266
+ const imageOptions = extractImageOptions(args);
267
+
268
+ const promptArgs = extractPromptArgs(args);
269
+ let prompt: string;
270
+ if (promptArgs.length > 0) {
271
+ prompt = promptArgs.join(' ');
272
+ } else if (!process.stdin.isTTY) {
273
+ prompt = await readFromStdin();
274
+ } else {
275
+ console.error('错误: 请提供提示文本或使用管道输入');
276
+ process.exit(1);
277
+ }
278
+
279
+ if (!prompt.trim()) {
280
+ console.error('错误: 提示不能为空');
281
+ process.exit(1);
282
+ }
283
+ if (options.workspace) {
284
+ await updateSessionMetadata(options.workspace.cwd, options.workspace.sessionId, {
285
+ lastMessagePreview: prompt.trim(),
286
+ }).catch(() => {});
287
+ }
288
+
289
+ const abortController = new AbortController();
290
+ let interrupted = false;
291
+
292
+ const history = initialHistory;
293
+ // text 模式只关心 buffer;json 模式还要 numTurns / stopReason / error。
294
+ // 用同一个对象承载,handleEvent 按 outputFormat 决定写哪些字段。
295
+ const result: PrintResult = {
296
+ buffer: '',
297
+ numTurns: 0,
298
+ stopReason: undefined,
299
+ error: null,
300
+ };
301
+
302
+ // 收尾守卫:saveContext + (json) emit 只执行一次,所有退出路径 await 同一个
303
+ // promise 再 process.exit。
304
+ // 没有它的话:SIGINT 触发 abort 后,SIGINT handler 与 for-await 的 AbortError
305
+ // catch 会同时奔向收尾 → 双写 session 文件 + 往 stdout 打两行 JSON(破坏「一行契约」)。
306
+ // 用「缓存 promise」而非「布尔 once」是关键:后到的路径必须 await 到 emit 真正
307
+ // 完成再退出,否则可能抢先把进程杀掉、导致那一行 JSON 根本没发出。
308
+ let finalizePromise: Promise<void> | null = null;
309
+ function finalizeOnce(): Promise<void> {
310
+ if (!finalizePromise) {
311
+ finalizePromise = (async () => {
312
+ await saveContext(history, options.sessionFile);
313
+ if (isJson) emitJsonResult(result, trySessionFile(options.sessionFile));
314
+ })();
315
+ }
316
+ return finalizePromise;
317
+ }
318
+
319
+ process.on('SIGINT', () => {
320
+ if (interrupted) process.exit(130);
321
+ interrupted = true;
322
+ abortController.abort();
323
+ console.error('\n已中断');
324
+ // json 模式:SIGINT 也要给出结构化结局(stop_reason='interrupted')
325
+ if (isJson) result.stopReason = 'interrupted';
326
+ void finalizeOnce().finally(() => process.exit(130));
327
+ });
328
+
329
+ try {
330
+ const workspaceRoot = options.workspace?.cwd ?? process.cwd();
331
+ const workspace = await workspaceIndexService.findByPath(workspaceRoot).catch(() => null);
332
+ const sessionId = options.workspace?.sessionId ?? 'default';
333
+ const sessionState = getOrCreateSessionState(sessionStateKey({
334
+ surface: 'cli', workspaceId: workspace?.id,
335
+ cwd: workspace?.id ? undefined : workspaceRoot, sessionId,
336
+ }));
337
+ await hydrateSessionWorktree({ sessionState, workspaceId: workspace?.id, sessionId, cwd: workspaceRoot });
338
+ const cwd = sessionState.activeWorktree?.path ?? workspaceRoot;
339
+ const conversationKey = `workspace:${workspace?.id ?? workspaceRoot}:session:${sessionId}`;
340
+ const computerRun = options.computerUseMode && options.computerUseMode !== 'disabled'
341
+ ? createCliComputerRun({
342
+ mode: options.computerUseMode,
343
+ surface: 'cli',
344
+ conversationKey,
345
+ userInput: prompt,
346
+ allowedFileRoots: [cwd],
347
+ supervised: true,
348
+ diagnosticTraceDir: options.computerUseTraceDir,
349
+ })
350
+ : undefined;
351
+ const runtimeContext = createAgentRuntimeContext({
352
+ surface: 'cli',
353
+ profile: 'main',
354
+ cwd,
355
+ workspaceId: workspace?.id,
356
+ sessionId,
357
+ owner: options.memoryAccess === 'denied' ? 'untrusted' : 'local-owner',
358
+ memoryAccess: options.memoryAccess ?? 'read-only',
359
+ interactiveAsk: false,
360
+ computer: computerRun,
361
+ });
362
+ const turnTools = filterToolsForRuntime(ALL_TOOLS, runtimeContext);
363
+ const stablePrompt = await buildBaseSystemPrompt(cwd, turnTools);
364
+ if (history[0]?.role === 'system') history[0] = { ...history[0], content: stablePrompt };
365
+ else history.unshift({ role: 'system', content: stablePrompt });
366
+ const transientBundle = await buildTransientPromptBundle({
367
+ cwd,
368
+ tools: turnTools,
369
+ runtime: {
370
+ surface: 'cli',
371
+ cwd,
372
+ workspaceId: workspace?.id,
373
+ sessionId,
374
+ interactiveAsk: false,
375
+ memoryAccess: runtimeContext.memoryAccess,
376
+ currentUserInput: prompt,
377
+ },
378
+ }).catch(() => undefined);
379
+ for await (const event of runWithPlugins(prompt, {
380
+ provider,
381
+ history,
382
+ signal: abortController.signal,
383
+ maxTurns: options.maxTurns,
384
+ imageInputs: imageOptions.imageInputs,
385
+ parseInlineImages: true,
386
+ imageDetail: imageOptions.imageDetail,
387
+ imageMaxLongSidePixel: imageOptions.imageMaxLongSidePixel,
388
+ allowedTools: turnTools.map((tool) => tool.name),
389
+ runtimeContext,
390
+ sessionState,
391
+ ...(transientBundle ? { transientBundle } : {}),
392
+ promptCache: createPromptCacheContext(
393
+ `workspace:${workspace?.id ?? cwd}:session:${sessionId}`,
394
+ ),
395
+ memoryContext: memoryContextFromRuntime(runtimeContext),
396
+ ...(computerRun ? { computerRun } : {}),
397
+ })) {
398
+ // event 是 LoopEvent | PluginEvent;handleEvent 只认 LoopEvent,未识别的插件私有事件走 default 静默忽略
399
+ const handled = handleEvent(
400
+ event as HandleableEvent,
401
+ result,
402
+ options.verbose,
403
+ outputFormat,
404
+ );
405
+ if (handled.exitCode !== undefined) {
406
+ await finalizeOnce();
407
+ process.exit(handled.exitCode);
408
+ }
409
+ }
410
+ } catch (e) {
411
+ if ((e as Error).name === 'AbortError') {
412
+ if (isJson) result.stopReason = 'interrupted';
413
+ await finalizeOnce();
414
+ process.exit(130);
415
+ }
416
+ console.error(`\n未捕获异常: ${(e as Error).message}`);
417
+ if (isJson) {
418
+ // 未分类异常按 error 收尾(stopReason 仍为空 → emitJsonResult 兜底 'error')
419
+ result.error = result.error ?? (e as Error).message;
420
+ }
421
+ await finalizeOnce();
422
+ process.exit(1);
423
+ }
424
+
425
+ // 正常跑完(没触发任何 exitCode 退出点)也走同一个收尾(json 模式 emit 一行结局)。
426
+ await finalizeOnce();
427
+ }
428
+
429
+ /**
430
+ * 处理 runQuery yield 出来的 LoopEvent。
431
+ * 纯事件分发函数,返回 { exitCode? } 由调用方决定是否退出。
432
+ *
433
+ * @param result 累积态(buffer 始终累积;json 模式还会写 numTurns/stopReason/error)
434
+ * @param verbose 是否把工具/压缩诊断打到 stderr
435
+ * @param outputFormat 'text'(默认)逐字节兼容旧行为;'json' 时 stdout 静默(只在退出时由 emitJsonResult 输出)
436
+ *
437
+ * ⚠️ 向后兼容:旧调用方 `handleEvent(ev, output, verbose)` 三参不传 outputFormat,
438
+ * 默认 'text',行为与改前逐字节一致。
439
+ */
440
+ export function handleEvent(
441
+ event: HandleableEvent,
442
+ result: PrintResult,
443
+ verbose: boolean,
444
+ outputFormat: OutputFormat = 'text',
445
+ ): HandleResult {
446
+ const isJson = outputFormat === 'json';
447
+ switch (event.type) {
448
+ case 'text':
449
+ // text 模式:verbose 才流式写 stdout(与旧行为逐字节一致)。
450
+ // json 模式:绝不往 stdout 写任何东西(stdout 只允许最后那一行 JSON),仅累积 buffer。
451
+ if (verbose && !isJson) process.stdout.write(event.delta);
452
+ result.buffer += event.delta;
453
+ return {};
454
+
455
+ case 'assistant_message':
456
+ // 一轮 assistant 消息完整组装 → 回合计数 +1(json 契约的 num_turns)
457
+ result.numTurns++;
458
+ return {};
459
+
460
+ case 'tool_start':
461
+ if (verbose) {
462
+ process.stderr.write(`\n🔧 工具: ${event.toolName}(${event.argsPreview})\n`);
463
+ }
464
+ return {};
465
+
466
+ case 'tool_end':
467
+ if (event.ok && event.metadata?.kind === 'result_manifest') {
468
+ result.deliverables = event.metadata.manifest.files;
469
+ } else if (event.ok && event.metadata?.kind === 'file_activity') {
470
+ const metadata = event.metadata as FileActivityMetadata;
471
+ const current = new Map((result.deliverables ?? []).map((file) => [file.relativePath, file]));
472
+ for (const file of metadata.files) {
473
+ if (file.purpose !== 'deliverable') continue;
474
+ current.set(file.relativePath, {
475
+ relativePath: file.relativePath,
476
+ ...(file.sha256 ? { sha256: file.sha256 } : {}),
477
+ ...(file.mime ? { mime: file.mime } : {}),
478
+ sourceToolCallId: event.toolCallId,
479
+ verification: file.verification,
480
+ purpose: 'deliverable',
481
+ });
482
+ }
483
+ result.deliverables = [...current.values()];
484
+ }
485
+ if (verbose) {
486
+ process.stderr.write(
487
+ `${event.ok ? '✅' : '❌'} ${event.toolName}: ${truncateForDisplay(event.content)}\n`,
488
+ );
489
+ }
490
+ return {};
491
+
492
+ case 'harness_diagnostics':
493
+ result.harnessDiagnostics = event.diagnostics;
494
+ return {};
495
+
496
+ case 'compact_start':
497
+ if (verbose) process.stderr.write('\n📝 正在压缩上下文...\n');
498
+ return {};
499
+
500
+ case 'compact_done':
501
+ if (verbose) {
502
+ process.stderr.write(
503
+ `📝 压缩完成: ${event.before} → ${event.after} tokens\n`,
504
+ );
505
+ }
506
+ return {};
507
+
508
+ case 'warning':
509
+ // 通用非致命警告(如 workflow 多余参数、pause 被自动跳过等)始终走 stderr,
510
+ // 不受 verbose 控制 —— 这是用户必须看到的信号,避免静默丢弃语义被忽略。
511
+ process.stderr.write(`${event.message}\n`);
512
+ return {};
513
+
514
+ case 'turn_done':
515
+ // text 模式:非 verbose 时这里一次性把累积答案打到 stdout(旧行为,逐字节不变)。
516
+ // json 模式:只记 stopReason='end_turn',stdout 保持静默。
517
+ result.stopReason = 'end_turn';
518
+ if (!isJson && !verbose) console.log(result.buffer);
519
+ return {};
520
+
521
+ case 'error':
522
+ // compact_failed 是「非致命」信号:loop 压缩失败后会继续硬上(不 return),
523
+ // 这里**不退出**,只 stderr 警告 —— 对齐 loop 语义。
524
+ // (这同时修了一个旧瑕疵:之前 -p 收到该 error 会被误当致命退出。)
525
+ if (event.code === 'compact_failed') {
526
+ process.stderr.write(`${event.error}\n`);
527
+ return {};
528
+ }
529
+ // 其余 error 都是终结性的。
530
+ if (isJson) {
531
+ result.stopReason = event.code === 'max_turns'
532
+ ? 'max_turns'
533
+ : event.code === 'stalled'
534
+ ? 'stalled'
535
+ : 'error';
536
+ result.error = event.error;
537
+ // json 模式不在这里打 stdout/stderr;由外层 emitJsonResult 统一输出
538
+ return { exitCode: 1 };
539
+ }
540
+ // text 模式:保持旧行为(红字 stderr + exitCode 1)
541
+ console.error(`\n错误: ${event.error}`);
542
+ return { exitCode: 1 };
543
+
544
+ case 'interrupted':
545
+ // 用户中断:json 模式记 stop_reason;外层退出点(catch / for-await 收尾 / SIGINT)emit。
546
+ // text 模式无需特殊处理(与旧行为一致:静默忽略,靠 SIGINT handler 退出)。
547
+ if (isJson) result.stopReason = 'interrupted';
548
+ return {};
549
+
550
+ // 已知但 -p 模式无需呈现的框架事件:显式忽略,好让 default 只剩"真正未知"的插件私有事件。
551
+ case 'user_message_committed':
552
+ case 'tool_messages_committed':
553
+ case 'plugin_progress':
554
+ case 'reasoning':
555
+ case 'stage_change':
556
+ case 'context_usage':
557
+ return {};
558
+ default:
559
+ // 落到这里 = 插件私有事件(PluginEvent,type 任意字符串)。正常静默忽略;
560
+ // verbose 下打一行 stderr 帮插件作者发现 yield 了拼错的 type(如 tool_strat)。
561
+ if (verbose) warnUnknownEventType((event as { type?: unknown }).type);
562
+ return {};
563
+ }
564
+ }
565
+
566
+ function readFromStdin(): Promise<string> {
567
+ return new Promise((resolve) => {
568
+ let data = '';
569
+ let settled = false;
570
+
571
+ const timer = setTimeout(() => {
572
+ if (!settled) {
573
+ settled = true;
574
+ resolve('');
575
+ }
576
+ }, STDIN_TIMEOUT_MS);
577
+
578
+ process.stdin.setEncoding('utf8');
579
+
580
+ function onData(chunk: string): void {
581
+ data += chunk;
582
+ }
583
+
584
+ function onEnd(): void {
585
+ if (!settled) {
586
+ clearTimeout(timer);
587
+ settled = true;
588
+ resolve(data.trim());
589
+ }
590
+ }
591
+
592
+ process.stdin.on('data', onData);
593
+ process.stdin.on('end', onEnd);
594
+ });
595
+ }
596
+
597
+ export { readFromStdin };
@@ -0,0 +1,60 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text, useInput } from 'ink';
3
+ import { useEffect, useState } from 'react';
4
+ import { configService } from '../config/configService.js';
5
+ import { ProviderWizard } from './wizards/providerWizard.js';
6
+ export function QuickModelSetup({ onDone }) {
7
+ const [models, setModels] = useState(null);
8
+ const [index, setIndex] = useState(0);
9
+ const [adding, setAdding] = useState(false);
10
+ const [readOnly, setReadOnly] = useState(false);
11
+ const [message, setMessage] = useState(null);
12
+ useEffect(() => {
13
+ void configService.reload().then((snapshot) => {
14
+ setReadOnly(snapshot.readOnly);
15
+ setModels(snapshot.config?.models ?? []);
16
+ });
17
+ }, []);
18
+ useInput((input, key) => {
19
+ if (adding || !models)
20
+ return;
21
+ const usable = models.filter((model) => model.enabled && model.apiKey);
22
+ const length = usable.length + 1;
23
+ if (key.upArrow)
24
+ setIndex((value) => (value - 1 + length) % length);
25
+ else if (key.downArrow)
26
+ setIndex((value) => (value + 1) % length);
27
+ else if (key.return) {
28
+ if (index === usable.length)
29
+ setAdding(true);
30
+ else {
31
+ const selected = usable[index];
32
+ if (!selected)
33
+ return;
34
+ void configService
35
+ .savePatch({ baseModelId: selected.id })
36
+ .then(() => configService.provider())
37
+ .then((provider) => {
38
+ if (provider)
39
+ onDone(provider);
40
+ else
41
+ setMessage('该模型当前不可用,请编辑或添加模型');
42
+ })
43
+ .catch((error) => setMessage(error.message));
44
+ }
45
+ }
46
+ });
47
+ if (!models)
48
+ return _jsx(Text, { color: "gray", children: "\u6B63\u5728\u8BFB\u53D6\u914D\u7F6E..." });
49
+ if (readOnly)
50
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [_jsx(Text, { color: "yellow", bold: true, children: "\u5F53\u524D\u4E3A\u73AF\u5883\u53D8\u91CF\u53EA\u8BFB\u914D\u7F6E\uFF0C\u4F46\u6CA1\u6709\u53EF\u7528\u57FA\u5EA7\u6A21\u578B" }), _jsx(Text, { children: "\u8BF7\u68C0\u67E5 MINIMAL_AGENT_BASE_URL\u3001MINIMAL_AGENT_API_KEY \u548C MINIMAL_AGENT_MODEL\uFF0C\u7136\u540E\u91CD\u65B0\u542F\u52A8\u3002" })] }));
51
+ if (adding)
52
+ return (_jsx(ProviderWizard, { quick: true, setAsBase: true, onDone: () => {
53
+ void configService.provider().then((provider) => {
54
+ if (provider)
55
+ onDone(provider);
56
+ });
57
+ }, onCancel: () => setAdding(false) }));
58
+ const usable = models.filter((model) => model.enabled && model.apiKey);
59
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [_jsx(Text, { color: "cyan", bold: true, children: "\u6B22\u8FCE\u4F7F\u7528 minimal-agent" }), _jsx(Text, { children: "\u8BF7\u9009\u62E9\u4E00\u4E2A\u5DF2\u6709\u57FA\u5EA7\u6A21\u578B\uFF0C\u6216\u5FEB\u901F\u6DFB\u52A0\u6A21\u578B\u3002" }), _jsx(Text, { color: "gray", children: "\u914D\u7F6E\u5B8C\u6210\u540E\u53EF\u968F\u65F6\u8F93\u5165 /config \u8C03\u6574\u9AD8\u7EA7\u8BBE\u7F6E\u3002" }), _jsxs(Box, { flexDirection: "column", marginTop: 1, children: [usable.map((model, i) => (_jsxs(Text, { color: index === i ? 'cyan' : undefined, children: [index === i ? '> ' : ' ', model.displayName ?? model.model, ' ', _jsxs(Text, { color: "gray", children: ["(", model.model, ")"] })] }, model.id))), _jsxs(Text, { color: index === usable.length ? 'cyan' : undefined, children: [index === usable.length ? '> ' : ' ', "\uFF0B \u6DFB\u52A0\u6A21\u578B"] })] }), message && _jsx(Text, { color: "red", children: message })] }));
60
+ }