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
package/src/main.js CHANGED
@@ -4,16 +4,18 @@ import { render } from 'ink';
4
4
  import { existsSync, mkdirSync } from 'node:fs';
5
5
  import { createRequire } from 'node:module';
6
6
  import { resolve } from 'node:path';
7
+ import { installTerminalCapture } from './tools/terminal/terminalCapture.js';
7
8
  const require = createRequire(import.meta.url);
8
9
  const pkg = (() => {
10
+ if (typeof __GREEN_BUILD_VERSION__ === 'string') {
11
+ return { version: __GREEN_BUILD_VERSION__ };
12
+ }
9
13
  try {
10
14
  return require('../package.json');
11
15
  }
12
16
  catch {
13
17
  return {
14
- version: typeof __GREEN_BUILD_VERSION__ === 'string'
15
- ? __GREEN_BUILD_VERSION__
16
- : '0.0.0',
18
+ version: '0.0.0',
17
19
  };
18
20
  }
19
21
  })();
@@ -25,19 +27,25 @@ import { clearContext, loadContext } from './context/persistContext.js';
25
27
  import { validateSessionId } from './context/sessionRegistry.js';
26
28
  import { workspaceIndexService } from './context/workspaceIndex.js';
27
29
  import { migrateLegacyContext, sessionFileFor } from './context/sessionPath.js';
28
- import { buildFullSystemPrompt } from './prompts/system.js';
30
+ import { buildBaseSystemPrompt } from './prompts/system.js';
31
+ import { resolveMemoryAccess } from './cli/memoryAccess.js';
29
32
  import { ALL_TOOLS } from './tools/index.js';
33
+ import { memoryToolAllowed } from './runtime/agentRuntimeContext.js';
30
34
  import { Root } from './ui/Root.js';
31
35
  import { runPrintMode } from './cli/print.js';
32
36
  import { runStreamJsonMode } from './cli/streamJson.js';
33
- import { extractFlagValue } from './cli/args.js';
37
+ import { extractFlagValue, normalizeArgs } from './cli/args.js';
38
+ import { resolveComputerUseMode, resolveComputerUseTraceDir } from './cli/computerUse.js';
34
39
  // re-export:对外保持「main.tsx 提供 extractFlagValue」的语义;实现住在 cli/args.ts,
35
40
  // 这样单测可零副作用 import(main.tsx 顶层 main() 自调用会启动整个 app,不可被测试 import)。
36
41
  export { extractFlagValue };
37
42
  async function main() {
38
43
  // ★ -d/--cwd:在锁定工作目录之前先建目录 + chdir,让后续逻辑全在 -d 下运行
39
44
  // 不存在则自动 mkdir -p;后续 initWorkingDir() 自然拿到新 cwd
40
- const args = process.argv.slice(2);
45
+ // normalizeArgs:先把 `--flag=value` 展开成空格式,之后所有解析(含下面的
46
+ // extractCwdArg、-p 分支的 extractFlagValue、print/streamJson 的 extractPromptArgs)
47
+ // 都只需处理一种写法。这是全进程唯一的 argv 入口,规范化放这里即全链路生效。
48
+ const args = normalizeArgs(process.argv.slice(2));
41
49
  const dirArg = extractCwdArg(args);
42
50
  if (dirArg) {
43
51
  const abs = resolve(dirArg);
@@ -137,8 +145,30 @@ async function main() {
137
145
  ` 2. 先直接运行 \`minimal-agent\`(TUI)在首次配置菜单里配好基座模型;菜单会写出 ~/.minimal-agent/config.json,之后 -p 模式自动复用\n\n`);
138
146
  process.exit(1);
139
147
  }
140
- const initialHistory = await buildInitialHistory(sessionFile);
148
+ // stream-json 的 stdin 是双工控制通道(宿主可回灌 ask_answer),所以它**能**交互提问;
149
+ // text/json 的 `-p` 不能——askBridge 会自动选推荐项兜底。提示词必须如实说明,
150
+ // 否则模型会以为可以停下来等用户选。
141
151
  const verbose = args.includes('--verbose') || args.includes('-v');
152
+ // 信任边界收敛在这一处:两个入口都不再自证「我是本机主人」(见 cli/memoryAccess.ts)。
153
+ let memoryAccess;
154
+ let computerUseMode;
155
+ let computerUseTraceDir;
156
+ try {
157
+ memoryAccess = resolveMemoryAccess(outputFormat, args);
158
+ computerUseMode = resolveComputerUseMode(args);
159
+ computerUseTraceDir = resolveComputerUseTraceDir(args);
160
+ }
161
+ catch (error) {
162
+ process.stderr.write(`参数错误:${error.message}\n`);
163
+ process.exitCode = 2;
164
+ return;
165
+ }
166
+ if (computerUseTraceDir) {
167
+ process.stderr.write(`Computer Use 诊断记录目录:${computerUseTraceDir}\n`);
168
+ }
169
+ const visibleTools = ALL_TOOLS.filter((tool) => memoryToolAllowed(tool.name, memoryAccess)
170
+ && (tool.name !== 'ComputerUse' || computerUseMode !== 'disabled'));
171
+ const initialHistory = await buildInitialHistory(sessionFile, visibleTools);
142
172
  // stream-json 走独立流式模式(webchat broker / 网关用);text/json 仍走原 runPrintMode(契约不变)。
143
173
  if (outputFormat === 'stream-json') {
144
174
  await runStreamJsonMode(provider, args, initialHistory, {
@@ -146,20 +176,32 @@ async function main() {
146
176
  compact: args.includes('--compact'),
147
177
  sessionFile,
148
178
  workspace: { cwd: getWorkingDir(), sessionId },
179
+ memoryAccess,
180
+ computerUseMode,
181
+ computerUseTraceDir,
149
182
  });
150
183
  return;
151
184
  }
152
185
  await runPrintMode(provider, args, initialHistory, {
153
186
  verbose, outputFormat, maxTurns, sessionFile,
154
187
  workspace: { cwd: getWorkingDir(), sessionId },
188
+ memoryAccess,
189
+ computerUseMode,
190
+ computerUseTraceDir,
155
191
  });
156
192
  return;
157
193
  }
158
194
  // TUI 交互模式:优先读 JSON 配置(home → exe 同级),没有再用 env 兜底;
159
195
  // 都没有则 Root 渲染首次配置菜单。
160
196
  const initialProvider = await loadProviderLayered();
197
+ const uninstallTerminalCapture = installTerminalCapture();
161
198
  const { waitUntilExit } = render(_jsx(Root, { initialProvider: initialProvider }));
162
- await waitUntilExit();
199
+ try {
200
+ await waitUntilExit();
201
+ }
202
+ finally {
203
+ uninstallTerminalCapture();
204
+ }
163
205
  }
164
206
  /**
165
207
  * 启动时构造 history:用当前 cwd / 工具的最新 system prompt,
@@ -172,8 +214,10 @@ async function main() {
172
214
  * @param sessionFile 显式会话文件路径(`-p`/stream-json 模式下由 `--session` 解析而来);
173
215
  * 缺省时走 `loadContext()` 的默认路径(= default session,向后兼容)。
174
216
  */
175
- async function buildInitialHistory(sessionFile) {
176
- const content = await buildFullSystemPrompt(getWorkingDir(), ALL_TOOLS);
217
+ async function buildInitialHistory(sessionFile, tools = ALL_TOOLS) {
218
+ // 只放稳定层:易变的运行时状态由每回合的 transientContext 注入消息尾部,
219
+ // 保证 history[0] 逐字节稳定 → provider 前缀缓存可命中(见 prompts/system.ts)。
220
+ const content = await buildBaseSystemPrompt(getWorkingDir(), tools);
177
221
  const fresh = { role: 'system', content };
178
222
  const persisted = await loadContext(sessionFile);
179
223
  if (!persisted || persisted.length === 0)
@@ -200,6 +244,17 @@ minimal-agent - 轻量级 AI 编程助手
200
244
  (ok / result / stop_reason / num_turns / error);
201
245
  stream-json = 逐行 LoopEvent(webchat / 网关 broker 用)
202
246
  --max-turns <n> 最大工具循环轮数(防失控;缺省 50)
247
+ --memory-access <local-owner|read-write|read-only|denied>
248
+ 本机长期记忆权限。
249
+ 本机非交互 -p 模式缺省为 read-only;显式传
250
+ --memory-access local-owner(或 read-write)才允许写入。
251
+ 值拼错不会静默降级,会直接报错退出
252
+ --computer-use <observe|interactive>
253
+ 非交互模式默认禁用。observe 仅允许观察;interactive 开放基础
254
+ 键鼠,但剪贴板、文件投放和最终提交仍须在本次指令中明确提出
255
+ --computer-use-trace <dir>
256
+ 显式保存本次 Computer Use 的顺序事件与动作后截图,供问题复盘;
257
+ 目录含屏幕隐私数据,默认不开启
203
258
  --image <path|url> 附加图片(可重复;JPEG/PNG/GIF/WEBP,本地单图≤10MB)
204
259
  --image-detail <d> 图片细节级别:low / default / high(默认 default)
205
260
  --image-max-long-side-pixel <n>
@@ -209,6 +264,8 @@ minimal-agent - 轻量级 AI 编程助手
209
264
  --workspace-doctor 只读诊断全局工作区索引、Session 数量和孤立历史
210
265
  -h, --help 显示帮助信息
211
266
 
267
+ 所有带值标志两种写法等价:"--output-format json" 与 "--output-format=json"。
268
+
212
269
  会话记忆:
213
270
  按当前工作目录隔离,同一工作目录下可以有多个会话(session),
214
271
  自动加载 / 保存到 ~/.minimal-agent/sessions/<目录哈希>--<sessionId>.json
package/src/main.tsx ADDED
@@ -0,0 +1,344 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * ============================================================
4
+ * src/main.tsx —— minimal-agent 入口
5
+ * ------------------------------------------------------------
6
+ * shebang `#!/usr/bin/env node` 由 tsc 编译后保留到 src/main.js
7
+ * 作为 npm 包 bin。dev 跑 `bun run src/main.tsx` 时 Bun 忽略 shebang,
8
+ * 互不冲突。
9
+ * ------------------------------------------------------------
10
+ * 支持两种运行模式:
11
+ * - TUI 模式(默认):启动 Ink 对话框
12
+ * - CLI 模式(-p):非交互,一问一答后退出
13
+ *
14
+ * 跑法:
15
+ * bun run src/main.tsx
16
+ * bun run src/main.tsx -p "提示"
17
+ * echo "提示" | bun run src/main.tsx -p
18
+ *
19
+ * 快速排错:
20
+ * - "缺少必需的环境变量":检查 .env 文件是否配置正确
21
+ * - "rg: command not found":装 ripgrep(grep 工具用到)
22
+ * ============================================================
23
+ */
24
+
25
+ import React from 'react';
26
+ import { render } from 'ink';
27
+ import { existsSync, mkdirSync } from 'node:fs';
28
+ import { createRequire } from 'node:module';
29
+ import { resolve } from 'node:path';
30
+ import { installTerminalCapture } from './tools/terminal/terminalCapture.js';
31
+
32
+ const require = createRequire(import.meta.url);
33
+
34
+ // 版本号读取:绿色版优先采用编译期 define;dev/npm 才读取 package.json。
35
+ // Bun compile 的虚拟文件系统里 require('../package.json') 偶尔会“成功”解析到
36
+ // 非本包清单,不能依赖 throw 才使用注入值。
37
+ declare const __GREEN_BUILD_VERSION__: string | undefined;
38
+ const pkg: { version: string } = (() => {
39
+ if (typeof __GREEN_BUILD_VERSION__ === 'string') {
40
+ return { version: __GREEN_BUILD_VERSION__ };
41
+ }
42
+ try {
43
+ return require('../package.json') as { version: string };
44
+ } catch {
45
+ return {
46
+ version: '0.0.0',
47
+ };
48
+ }
49
+ })();
50
+
51
+ import { extractCwdArg } from './bootstrap/cwdArg.js';
52
+ import { initWorkingDir, getWorkingDir } from './bootstrap/workingDir.js';
53
+ import { ensureAgentBrowserOnPath } from './tools/webbrowser/agentBrowserPath.js';
54
+ import { applyToolKeysToEnv, loadProviderLayered } from './config.js';
55
+ import { clearContext, loadContext } from './context/persistContext.js';
56
+ import { validateSessionId } from './context/sessionRegistry.js';
57
+ import { workspaceIndexService } from './context/workspaceIndex.js';
58
+ import { migrateLegacyContext, sessionFileFor } from './context/sessionPath.js';
59
+ import { buildBaseSystemPrompt } from './prompts/system.js';
60
+ import { resolveMemoryAccess } from './cli/memoryAccess.js';
61
+ import { ALL_TOOLS } from './tools/index.js';
62
+ import { memoryToolAllowed } from './runtime/agentRuntimeContext.js';
63
+ import type { Message } from './types.js';
64
+ import { Root } from './ui/Root.js';
65
+ import { runPrintMode } from './cli/print.js';
66
+ import { runStreamJsonMode } from './cli/streamJson.js';
67
+ import { extractFlagValue, normalizeArgs } from './cli/args.js';
68
+ import { resolveComputerUseMode, resolveComputerUseTraceDir } from './cli/computerUse.js';
69
+
70
+ // re-export:对外保持「main.tsx 提供 extractFlagValue」的语义;实现住在 cli/args.ts,
71
+ // 这样单测可零副作用 import(main.tsx 顶层 main() 自调用会启动整个 app,不可被测试 import)。
72
+ export { extractFlagValue };
73
+
74
+ async function main(): Promise<void> {
75
+ // ★ -d/--cwd:在锁定工作目录之前先建目录 + chdir,让后续逻辑全在 -d 下运行
76
+ // 不存在则自动 mkdir -p;后续 initWorkingDir() 自然拿到新 cwd
77
+ // normalizeArgs:先把 `--flag=value` 展开成空格式,之后所有解析(含下面的
78
+ // extractCwdArg、-p 分支的 extractFlagValue、print/streamJson 的 extractPromptArgs)
79
+ // 都只需处理一种写法。这是全进程唯一的 argv 入口,规范化放这里即全链路生效。
80
+ const args = normalizeArgs(process.argv.slice(2));
81
+ const dirArg = extractCwdArg(args);
82
+ if (dirArg) {
83
+ const abs = resolve(dirArg);
84
+ if (!existsSync(abs)) {
85
+ mkdirSync(abs, { recursive: true });
86
+ }
87
+ process.chdir(abs);
88
+ }
89
+
90
+ // ★ 必须在所有其他逻辑之前——锁定工作目录,并迁移旧版 last-context.json
91
+ initWorkingDir();
92
+ await migrateLegacyContext(getWorkingDir());
93
+
94
+ // ★ 把 saved config 里的工具 key(如 TAVILY_API_KEY)注入 process.env。
95
+ // npm 全局安装跑 `node dist/main.js` 不会自动加载 .env,靠这一步把向导
96
+ // 收集到的 key 写回 env,否则 WebSearch 等工具 process.env.* 读不到。
97
+ await applyToolKeysToEnv();
98
+
99
+ // --help 优先显示
100
+ if (args.includes('-h') || args.includes('--help')) {
101
+ printHelp();
102
+ return;
103
+ }
104
+
105
+ // --version: 零依赖快速返回(对齐 kakadeai fast-path 设计)
106
+ if (args.includes('--version') || args.includes('-V')) {
107
+ console.log(`minimal-agent v${pkg.version}`);
108
+ return;
109
+ }
110
+
111
+ if (args.includes('--workspace-doctor')) {
112
+ const snapshot = await workspaceIndexService.snapshot();
113
+ console.log(`Workspace Index v${snapshot.version} · revision ${snapshot.revision}`);
114
+ for (const workspace of snapshot.workspaces) {
115
+ console.log(`${workspace.available ? '✓' : '○'} ${workspace.displayPath} · ${workspace.sessions.length} sessions`);
116
+ }
117
+ console.log(`可恢复/已过滤历史:${snapshot.recoverable.length}`);
118
+ return;
119
+ }
120
+
121
+ // --clear:清空当前工作目录的会话(归档 + 清空)后退出。供 webchat 的 /new 调用。
122
+ // 无需 provider;上面 -d/--cwd 已 chdir + initWorkingDir,clearContext() 作用于该目录。
123
+ if (args.includes('--clear')) {
124
+ await clearContext();
125
+ return;
126
+ }
127
+
128
+ // 内置 agent 浏览器:把已 vendored/绿色版同级的 agent-browser 目录前置进 PATH,
129
+ // 让 Bash 工具 / skill 脚本 / 工作流 bash 步也能直接调(tools/skills/工作流共用底座)。
130
+ // dev/npm 无 vendored 二进制时 no-op;不污染 stdout,-p json 契约安全。
131
+ await ensureAgentBrowserOnPath();
132
+
133
+ const isPrintMode = args.includes('-p') || args.includes('--print');
134
+
135
+ if (isPrintMode) {
136
+ // 先把输出格式解析出来——provider 缺失分支也要按 json 契约给信号。
137
+ // 只接受 'text' | 'json',其它值(含拼错)一律回落 'text'(向后兼容)。
138
+ const rawFormat = extractFlagValue(args, ['--output-format']);
139
+ // text(默认,逐字节向后兼容)/ json(一行结局契约)/ stream-json(逐行 LoopEvent,webchat broker 用)
140
+ const outputFormat: 'text' | 'json' | 'stream-json' =
141
+ rawFormat === 'json'
142
+ ? 'json'
143
+ : rawFormat === 'stream-json'
144
+ ? 'stream-json'
145
+ : 'text';
146
+ // --max-turns:parseInt,非法(NaN)→ undefined(走 loop 默认 50)
147
+ const rawMaxTurns = extractFlagValue(args, ['--max-turns']);
148
+ const parsedMaxTurns = rawMaxTurns !== undefined ? Number.parseInt(rawMaxTurns, 10) : Number.NaN;
149
+ const maxTurns = Number.isNaN(parsedMaxTurns) ? undefined : parsedMaxTurns;
150
+
151
+ // -s/--session <id>:选定同 cwd 下的哪个 session;缺省 'default'(向后兼容,
152
+ // 逐字节保持旧行为)。读、写必须用同一份解析结果——不能只让加载感知这个 flag,
153
+ // 落盘时各自重新计算,否则出现"从 session A 读、写回 default"的读写分裂。
154
+ let sessionId: string;
155
+ try {
156
+ sessionId = validateSessionId(extractFlagValue(args, ['-s', '--session']) ?? 'default');
157
+ } catch (error) {
158
+ console.error(`无效的 --session:${(error as Error).message}`);
159
+ process.exitCode = 2;
160
+ return;
161
+ }
162
+ await workspaceIndexService.register(getWorkingDir()).catch(() => {});
163
+ const sessionFile = sessionFileFor(getWorkingDir(), sessionId);
164
+
165
+ // CLI 非交互模式:先 env,再 ~/.minimal-agent/config.json fallback;都没就退出
166
+ // (宿主 spawn 子进程时通常没 export env,靠 TUI 向导写出的 config.json 持久化)
167
+ const provider = await loadProviderLayered();
168
+ if (!provider) {
169
+ // json 模式:先给宿主一行结构化信号(stop_reason='config_error'),再退出。
170
+ // 人类可读的中文提示仍走 stderr(json 契约只占 stdout 那一行)。
171
+ if (outputFormat === 'json') {
172
+ console.log(
173
+ JSON.stringify({
174
+ ok: false,
175
+ result: '',
176
+ is_error: true,
177
+ stop_reason: 'config_error',
178
+ num_turns: 0,
179
+ error: 'provider config not found',
180
+ }),
181
+ );
182
+ } else if (outputFormat === 'stream-json') {
183
+ // stream-json:吐一行 error 事件(webchat 前端识别为致命错误)
184
+ console.log(
185
+ JSON.stringify({ type: 'error', error: 'provider config not found', code: 'llm_error' }),
186
+ );
187
+ }
188
+ process.stderr.write(
189
+ `\n未找到 provider 配置。\n\n` +
190
+ `请二选一:\n` +
191
+ ` 1. 设置环境变量 MINIMAL_AGENT_BASE_URL / MINIMAL_AGENT_API_KEY / MINIMAL_AGENT_MODEL\n` +
192
+ ` 2. 先直接运行 \`minimal-agent\`(TUI)在首次配置菜单里配好基座模型;菜单会写出 ~/.minimal-agent/config.json,之后 -p 模式自动复用\n\n`,
193
+ );
194
+ process.exit(1);
195
+ }
196
+
197
+ // stream-json 的 stdin 是双工控制通道(宿主可回灌 ask_answer),所以它**能**交互提问;
198
+ // text/json 的 `-p` 不能——askBridge 会自动选推荐项兜底。提示词必须如实说明,
199
+ // 否则模型会以为可以停下来等用户选。
200
+ const verbose = args.includes('--verbose') || args.includes('-v');
201
+ // 信任边界收敛在这一处:两个入口都不再自证「我是本机主人」(见 cli/memoryAccess.ts)。
202
+ let memoryAccess: ReturnType<typeof resolveMemoryAccess>;
203
+ let computerUseMode: ReturnType<typeof resolveComputerUseMode>;
204
+ let computerUseTraceDir: ReturnType<typeof resolveComputerUseTraceDir>;
205
+ try {
206
+ memoryAccess = resolveMemoryAccess(outputFormat, args);
207
+ computerUseMode = resolveComputerUseMode(args);
208
+ computerUseTraceDir = resolveComputerUseTraceDir(args);
209
+ } catch (error) {
210
+ process.stderr.write(`参数错误:${(error as Error).message}\n`);
211
+ process.exitCode = 2;
212
+ return;
213
+ }
214
+ if (computerUseTraceDir) {
215
+ process.stderr.write(`Computer Use 诊断记录目录:${computerUseTraceDir}\n`);
216
+ }
217
+ const visibleTools = ALL_TOOLS.filter((tool) =>
218
+ memoryToolAllowed(tool.name, memoryAccess)
219
+ && (tool.name !== 'ComputerUse' || computerUseMode !== 'disabled'));
220
+ const initialHistory = await buildInitialHistory(sessionFile, visibleTools);
221
+ // stream-json 走独立流式模式(webchat broker / 网关用);text/json 仍走原 runPrintMode(契约不变)。
222
+ if (outputFormat === 'stream-json') {
223
+ await runStreamJsonMode(provider, args, initialHistory, {
224
+ maxTurns,
225
+ compact: args.includes('--compact'),
226
+ sessionFile,
227
+ workspace: { cwd: getWorkingDir(), sessionId },
228
+ memoryAccess,
229
+ computerUseMode,
230
+ computerUseTraceDir,
231
+ });
232
+ return;
233
+ }
234
+ await runPrintMode(provider, args, initialHistory, {
235
+ verbose, outputFormat, maxTurns, sessionFile,
236
+ workspace: { cwd: getWorkingDir(), sessionId },
237
+ memoryAccess,
238
+ computerUseMode,
239
+ computerUseTraceDir,
240
+ });
241
+ return;
242
+ }
243
+
244
+ // TUI 交互模式:优先读 JSON 配置(home → exe 同级),没有再用 env 兜底;
245
+ // 都没有则 Root 渲染首次配置菜单。
246
+ const initialProvider = await loadProviderLayered();
247
+ const uninstallTerminalCapture = installTerminalCapture();
248
+ const { waitUntilExit } = render(<Root initialProvider={initialProvider} />);
249
+ try {
250
+ await waitUntilExit();
251
+ } finally {
252
+ uninstallTerminalCapture();
253
+ }
254
+ }
255
+
256
+ /**
257
+ * 启动时构造 history:用当前 cwd / 工具的最新 system prompt,
258
+ * 后面接上 last-context.json 里上次保存的对话(如果有)。
259
+ *
260
+ * 总是用 fresh system prompt(即便 last-context.json 里也存了一份),
261
+ * 这样换 cwd 或工具后也不会沿用错的环境上下文。
262
+ */
263
+ /**
264
+ * @param sessionFile 显式会话文件路径(`-p`/stream-json 模式下由 `--session` 解析而来);
265
+ * 缺省时走 `loadContext()` 的默认路径(= default session,向后兼容)。
266
+ */
267
+ async function buildInitialHistory(
268
+ sessionFile?: string,
269
+ tools = ALL_TOOLS,
270
+ ): Promise<Message[]> {
271
+ // 只放稳定层:易变的运行时状态由每回合的 transientContext 注入消息尾部,
272
+ // 保证 history[0] 逐字节稳定 → provider 前缀缓存可命中(见 prompts/system.ts)。
273
+ const content = await buildBaseSystemPrompt(getWorkingDir(), tools);
274
+ const fresh: Message = { role: 'system', content };
275
+
276
+ const persisted = await loadContext(sessionFile);
277
+ if (!persisted || persisted.length === 0) return [fresh];
278
+ const rest = persisted[0]?.role === 'system' ? persisted.slice(1) : persisted;
279
+ return [fresh, ...rest];
280
+ }
281
+
282
+ function printHelp(): void {
283
+ console.log(`
284
+ minimal-agent - 轻量级 AI 编程助手
285
+
286
+ 用法:
287
+ minimal-agent [选项] [提示...]
288
+ echo "提示" | minimal-agent [选项]
289
+
290
+ 选项:
291
+ -p, --print 非交互模式,直接执行单次问答
292
+ -v, --verbose 显示详细输出(工具调用、压缩信息)
293
+ -d, --cwd <dir> 指定工作目录(不存在自动创建);启动时 chdir 到这里,
294
+ 上下文文件、工具相对路径、.env 加载都以此为基准
295
+ -s, --session <id> 选定同一工作目录下的哪个会话(缺省 'default');配合 TUI 的
296
+ /session /sessions /resume 是同一套内核会话,互不冲突
297
+ --output-format <fmt> text(默认)= 纯文本答案;json = 一行结局契约
298
+ (ok / result / stop_reason / num_turns / error);
299
+ stream-json = 逐行 LoopEvent(webchat / 网关 broker 用)
300
+ --max-turns <n> 最大工具循环轮数(防失控;缺省 50)
301
+ --memory-access <local-owner|read-write|read-only|denied>
302
+ 本机长期记忆权限。
303
+ 本机非交互 -p 模式缺省为 read-only;显式传
304
+ --memory-access local-owner(或 read-write)才允许写入。
305
+ 值拼错不会静默降级,会直接报错退出
306
+ --computer-use <observe|interactive>
307
+ 非交互模式默认禁用。observe 仅允许观察;interactive 开放基础
308
+ 键鼠,但剪贴板、文件投放和最终提交仍须在本次指令中明确提出
309
+ --computer-use-trace <dir>
310
+ 显式保存本次 Computer Use 的顺序事件与动作后截图,供问题复盘;
311
+ 目录含屏幕隐私数据,默认不开启
312
+ --image <path|url> 附加图片(可重复;JPEG/PNG/GIF/WEBP,本地单图≤10MB)
313
+ --image-detail <d> 图片细节级别:low / default / high(默认 default)
314
+ --image-max-long-side-pixel <n>
315
+ OpenAI 兼容图片参数:限制最长边像素
316
+ --clear 清空当前工作目录的会话(归档 + 清空)后退出
317
+ --compact 与 -p --output-format stream-json 连用:压缩当前会话
318
+ --workspace-doctor 只读诊断全局工作区索引、Session 数量和孤立历史
319
+ -h, --help 显示帮助信息
320
+
321
+ 所有带值标志两种写法等价:"--output-format json" 与 "--output-format=json"。
322
+
323
+ 会话记忆:
324
+ 按当前工作目录隔离,同一工作目录下可以有多个会话(session),
325
+ 自动加载 / 保存到 ~/.minimal-agent/sessions/<目录哈希>--<sessionId>.json
326
+ (不传 --session 时用 'default')。TUI 与 -p 共享同一套会话;
327
+ TUI 里用 /session /sessions /resume 列出并切换会话、/session new [标题] 新建;
328
+ -p 用 -s/--session <id> 选定;TUI 中输入 /new 仅清当前会话(不影响其它会话)
329
+
330
+ 示例:
331
+ minimal-agent -p "帮我写一个 hello world"
332
+ echo "解释代码" | minimal-agent -p
333
+ minimal-agent -p --verbose "运行测试并报告结果"
334
+ minimal-agent -p "处理资料" -d /tmp/job-123 # 工作目录隔离
335
+ minimal-agent -p --image ./ui.png "评价这个界面"
336
+ minimal-agent -p "@/tmp/a.png 请识别图片内容" # TUI / -p 均支持 @图片路径
337
+ minimal-agent -p --output-format json "做点事" # 宿主程序 spawn:一行 JSON 结局
338
+ `);
339
+ }
340
+
341
+ main().catch((e) => {
342
+ process.stderr.write(`\n未捕获异常:${(e as Error).message}\n${(e as Error).stack ?? ''}\n`);
343
+ process.exit(1);
344
+ });