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,294 @@
1
+ import { execSync } from 'node:child_process';
2
+
3
+ /**
4
+ * macOS 权限引导工具。
5
+ *
6
+ * 设计参考:UI-TARS-desktop/apps/ui-tars/src/main/utils/systemPermissions.ts
7
+ *
8
+ * 核心原则:
9
+ * 1. 实际调用系统 API(CGEventPost / CGDisplayCreateImage)的是 cu-helperd 守护进程,
10
+ * 因此 macOS TCC 权限数据库中记录的是 cu-helperd 二进制的权限状态。
11
+ * 2. 系统原生权限弹窗(AXIsProcessTrustedWithOptions / CGRequestScreenCaptureAccess)
12
+ * 由 cu-helperd 在首次需要时自动触发,但这种弹窗有局限性:
13
+ * - 只在权限状态为 "not determined" 时弹出一次
14
+ * - 用户如果点了"拒绝",之后不会再弹,必须手动去系统设置
15
+ * - 从后台进程触发弹窗有时会被其他窗口遮挡
16
+ * 3. 因此本模块的核心策略是:**主动探测 + 自动打开设置 + 明确文字引导**,
17
+ * 参考 UI-TARS 的 openSystemPreferences() 做法,不管什么状态,只要权限缺失
18
+ * 就直接打开系统设置页面,让用户一目了然该勾选什么。
19
+ */
20
+
21
+ /**
22
+ * 打开 macOS 系统设置 → 隐私与安全性 → 辅助功能 页面。
23
+ */
24
+ export function openAccessibilitySettings(): void {
25
+ if (process.platform !== 'darwin') return;
26
+ try {
27
+ execSync(
28
+ 'open "x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility"',
29
+ { stdio: 'ignore', timeout: 5000 },
30
+ );
31
+ } catch {
32
+ // fallback:如果系统设置URL scheme失效,尝试直接打开系统设置应用
33
+ try { execSync('open "x-apple.systempreferences:"', { stdio: 'ignore', timeout: 5000 }); } catch {}
34
+ }
35
+ }
36
+
37
+ /**
38
+ * 打开 macOS 系统设置 → 隐私与安全性 → 屏幕录制 页面。
39
+ */
40
+ export function openScreenCaptureSettings(): void {
41
+ if (process.platform !== 'darwin') return;
42
+ try {
43
+ execSync(
44
+ 'open "x-apple.systempreferences:com.apple.preference.security?Privacy_ScreenCapture"',
45
+ { stdio: 'ignore', timeout: 5000 },
46
+ );
47
+ } catch {
48
+ try { execSync('open "x-apple.systempreferences:"', { stdio: 'ignore', timeout: 5000 }); } catch {}
49
+ }
50
+ }
51
+
52
+ /**
53
+ * 检测当前是否运行在一个 .app bundle 内部(即 Tauri/Electron 打包后的生产环境)。
54
+ */
55
+ export function isRunningInAppBundle(): boolean {
56
+ if (process.platform !== 'darwin') return false;
57
+ return process.execPath.includes('.app/Contents/MacOS/');
58
+ }
59
+
60
+ /**
61
+ * 获取权限引导信息中应该告诉用户查找哪个应用名。
62
+ *
63
+ * **只有两种情况**,因为实际调用系统 API 的进程只有两种:
64
+ * · 打包进 .app 时,TCC 记的是宿主 App → 让用户找 "KakadeAI"
65
+ * · 其余(CLI / dev)由 cu-helperd 守护进程调用 → 让用户找 "cu-helperd"
66
+ *
67
+ * 这里曾有第三种「终端应用名(Terminal/iTerm/Warp…)」分支,服务于已移除的
68
+ * nut-js transport —— 它在主进程内直接调 CGEvent,于是 TCC 记的是终端。
69
+ * nut-js 移除后那条分支恒为误导(会让用户去给终端授权,而真正需要授权的是
70
+ * cu-helperd),所以一并删除。
71
+ */
72
+ export function getPermissionTargetName(): string {
73
+ return isRunningInAppBundle() ? 'KakadeAI' : 'cu-helperd';
74
+ }
75
+
76
+ /**
77
+ * 权限状态(与 cu-helperd protocol 中的 PermissionState 对齐)。
78
+ */
79
+ export type MacPermissionState = 'granted' | 'not_determined' | 'denied';
80
+
81
+ export interface PermissionCheckResult {
82
+ accessibility: MacPermissionState;
83
+ screenCapture: MacPermissionState;
84
+ /** 是否有缺失的权限需要用户授权 */
85
+ hasMissingPermissions: boolean;
86
+ /** 缺失的权限列表描述 */
87
+ missingPermissions: Array<'accessibility' | 'screenCapture'>;
88
+ /**
89
+ * 这次**查询本身**失败了(守护进程报错、认证失败、响应形状不认识)。
90
+ *
91
+ * 与「查到了、结果是没授权」是两件完全不同的事,必须分开:前者要修的是我们自己,
92
+ * 后者才该去引导用户点系统设置。混为一谈的代价是真实发生过的 —— 见
93
+ * `parsePermissionResponse` 的注释。
94
+ */
95
+ queryFailed: boolean;
96
+ }
97
+
98
+ /**
99
+ * 解析 cu-helperd 返回的 permissions 响应,生成标准化的检查结果。
100
+ * 支持多种响应格式:
101
+ * - 原生 wire 格式:{ response: { Ok: { accessibility, screenCapture } } }
102
+ * - 高层 service 格式:{ ok: true, data: { accessibility, screenCapture } }
103
+ * - 纯数据格式:{ accessibility, screenCapture }
104
+ */
105
+ const PERMISSION_STATES = new Set(['granted', 'denied', 'not_determined']);
106
+
107
+ /**
108
+ * ⚠️ **「查不到」绝不能当成「没授权」。**
109
+ *
110
+ * 这里以前从任意形状的响应里挖 `accessibility` / `screenCapture`,挖不到就默认
111
+ * `not_determined`,于是**错误信封被当成了权限答案**:守护进程返回
112
+ * `{response:{Err:{code:'authentication_failed'}}}`,两个字段自然都不存在,函数愉快地
113
+ * 报告「两个权限都缺失」,调用方打印一整屏「请去系统设置授权」。
114
+ *
115
+ * 而它确实一直在返回这个错误 —— `probePermissions` 把 32 字节的二进制配对令牌按
116
+ * utf8 读,HMAC 必然对不上。也就是说这个自检**从未成功过一次**,却始终显得像是在工作。
117
+ * 真实代价:用户被反复引去检查根本没问题的系统设置,而真正的故障在完全不同的地方;
118
+ * 排查中先后错怪了 cdhash、用户的授权配置和另一处改动。
119
+ *
120
+ * 修法不是把那次读改对就完了 —— 那只堵住一个诱因。判据本身必须能表达「我不知道」。
121
+ */
122
+ export function parsePermissionResponse(permResp: any): PermissionCheckResult {
123
+ const unknown = (): PermissionCheckResult => ({
124
+ accessibility: 'not_determined',
125
+ screenCapture: 'not_determined',
126
+ // 查询失败时**不**声称有权限缺失:那会把用户引向系统设置,而问题不在那儿。
127
+ hasMissingPermissions: false,
128
+ missingPermissions: [],
129
+ queryFailed: true,
130
+ });
131
+
132
+ // 明确的错误信封:直接判定为「查询失败」,不去它身上找权限字段。
133
+ if (permResp?.response?.Err || permResp?.ok === false) return unknown();
134
+
135
+ let perms: any = permResp;
136
+ if (permResp?.response?.Ok) {
137
+ perms = permResp.response.Ok; // 原生 wire 格式
138
+ } else if (permResp?.ok && permResp?.data) {
139
+ perms = permResp.data; // 高层 service 格式(diagnostics/request 返回)
140
+ }
141
+
142
+ // 两个字段**都**认不出来 = 这根本不是一份权限响应,而不是「两个权限都没授权」。
143
+ const knownAccessibility = PERMISSION_STATES.has(perms?.accessibility);
144
+ const knownScreenCapture = PERMISSION_STATES.has(perms?.screenCapture);
145
+ if (!knownAccessibility && !knownScreenCapture) return unknown();
146
+
147
+ const accessibility: MacPermissionState = knownAccessibility
148
+ ? perms.accessibility
149
+ : 'not_determined';
150
+ const screenCapture: MacPermissionState = knownScreenCapture
151
+ ? perms.screenCapture
152
+ : 'not_determined';
153
+
154
+ const missingPermissions: Array<'accessibility' | 'screenCapture'> = [];
155
+ if (accessibility !== 'granted') missingPermissions.push('accessibility');
156
+ if (screenCapture !== 'granted') missingPermissions.push('screenCapture');
157
+ return {
158
+ accessibility,
159
+ screenCapture,
160
+ hasMissingPermissions: missingPermissions.length > 0,
161
+ missingPermissions,
162
+ queryFailed: false,
163
+ };
164
+ }
165
+
166
+ /**
167
+ * 打印醒目的权限缺失提示,并自动打开系统设置。
168
+ * 参考 UI-TARS 的 wrapWithWarning + openSystemPreferences 模式。
169
+ *
170
+ * 引导文案遵循三层结构:
171
+ * 1. 为什么需要这些权限(让用户理解价值,减少抵触)
172
+ * 2. 具体要做什么(分步骤、目标明确)
173
+ * 3. 遇到问题怎么办(找不到应用、已勾选仍不行等常见坑)
174
+ */
175
+ export function showPermissionGuidance(result: PermissionCheckResult): void {
176
+ if (process.platform !== 'darwin') return;
177
+ if (!result.hasMissingPermissions) return;
178
+
179
+ const targetName = getPermissionTargetName();
180
+ const lines: string[] = [];
181
+ const inAppBundle = isRunningInAppBundle();
182
+
183
+ lines.push('');
184
+ lines.push('╔════════════════════════════════════════════════════════════════╗');
185
+ lines.push('║ ⚠️ 需要授予 macOS 系统权限才能使用「电脑操控」功能 ║');
186
+ lines.push('╚════════════════════════════════════════════════════════════════╝');
187
+ lines.push('');
188
+
189
+ // 第 1 层:需要什么权限、为什么需要
190
+ lines.push('—— 需要授予的权限 ——');
191
+ lines.push('');
192
+ if (result.missingPermissions.includes('accessibility')) {
193
+ lines.push(' 🖱️ 辅助功能(Accessibility)');
194
+ lines.push(' 用途:控制鼠标移动/点击、模拟键盘输入、拖拽操作');
195
+ lines.push(' 没有它:AI 无法操作你的鼠标和键盘');
196
+ lines.push('');
197
+ }
198
+ if (result.missingPermissions.includes('screenCapture')) {
199
+ lines.push(' 📷 屏幕录制(Screen Recording)');
200
+ lines.push(' 用途:读取屏幕画面,让 AI "看到" 你当前的界面');
201
+ lines.push(' 没有它:AI 看不到屏幕,无法判断该点哪里、该做什么');
202
+ lines.push('');
203
+ }
204
+
205
+ lines.push('👉 已为你自动打开「系统设置 → 隐私与安全性」对应页面');
206
+ lines.push('');
207
+
208
+ // 第 2 层:具体操作步骤
209
+ lines.push('—— 授权步骤(只需 4 步,约 30 秒)——');
210
+ lines.push('');
211
+
212
+ const permLabels: string[] = [];
213
+ if (result.missingPermissions.includes('accessibility')) permLabels.push('辅助功能');
214
+ if (result.missingPermissions.includes('screenCapture')) permLabels.push('屏幕录制');
215
+
216
+ lines.push(` 1. 在系统设置中,依次点击「隐私与安全性」→「${permLabels[0]}」`);
217
+ if (permLabels.length > 1) {
218
+ lines.push(` (两个权限都需要授权,授权完一个再切换到另一个)`);
219
+ }
220
+ lines.push(' 2. 点击左下角 🔒 锁形图标,输入开机密码解锁');
221
+ lines.push(` 3. 在右侧应用列表中找到「${targetName}」,打开它的开关`);
222
+
223
+ if (!inAppBundle) {
224
+ lines.push(' ⓘ 这里要授权的是 cu-helperd(守护进程),不是你的终端 ——');
225
+ lines.push(' 真正调用系统 API 的是它,所以 macOS 记录的也是它的权限。');
226
+ }
227
+
228
+ lines.push(' 4. 完成后回到这里,继续让 AI 操作即可');
229
+ lines.push('');
230
+
231
+ // 第 3 层:常见问题 / 排错
232
+ lines.push('—— 常见问题 ——');
233
+ lines.push('');
234
+ lines.push(' Q: 列表里找不到「' + targetName + '」怎么办?');
235
+ lines.push(' A: 点击列表下方的 ➕ 按钮,手动添加' + targetName);
236
+ if (!inAppBundle) {
237
+ lines.push(' (cu-helperd 随包位于 vendor/computer-use/<arch>-<plat>/ 目录下;');
238
+ lines.push(' 源码构建时在 computer-use-native/target/release/)');
239
+ lines.push(' 也可以先让 AI 执行一次操作,cu-helperd 会主动弹出系统授权请求。');
240
+ }
241
+ lines.push('');
242
+ lines.push(' Q: 已经勾选了,但还是提示权限不足?');
243
+ lines.push(' A: 把开关先关掉再重新打开一次,macOS 有时需要重新确认。');
244
+ lines.push(' 如果仍然不行,重启应用后再试。');
245
+ lines.push('');
246
+ lines.push(' Q: 这些权限安全吗?会不会泄露隐私?');
247
+ lines.push(' A: 权限只在本地使用,屏幕画面和操作都不会上传到任何服务器。');
248
+ lines.push(' AI 模型只接收截图用于分析操作,不做存储。');
249
+ lines.push('');
250
+
251
+ // 输出到 stderr,确保在 TUI/CLI 中都能看到
252
+ for (const line of lines) {
253
+ process.stderr.write(line + '\n');
254
+ }
255
+
256
+ // 自动打开对应的设置页面(优先屏幕录制,因为最直观)
257
+ if (result.missingPermissions.includes('screenCapture')) {
258
+ try {
259
+ openScreenCaptureSettings();
260
+ } catch {
261
+ process.stderr.write(' ⚠️ 未能自动打开系统设置,请手动打开:系统设置 → 隐私与安全性 → 屏幕录制\n');
262
+ }
263
+ }
264
+ if (result.missingPermissions.includes('accessibility')) {
265
+ try {
266
+ openAccessibilitySettings();
267
+ } catch {
268
+ process.stderr.write(' ⚠️ 未能自动打开系统设置,请手动打开:系统设置 → 隐私与安全性 → 辅助功能\n');
269
+ }
270
+ }
271
+ }
272
+
273
+ /**
274
+ * 一次性完成权限检查:解析响应、打印引导、打开设置。
275
+ * 返回 true 表示权限齐全可以继续,false 表示需要用户授权。
276
+ */
277
+ export function ensureMacPermissions(permResp: any): boolean {
278
+ if (process.platform !== 'darwin') return true;
279
+ const result = parsePermissionResponse(permResp);
280
+ if (result.queryFailed) {
281
+ // 查询本身失败:说一句,然后**闭嘴**。既不打印权限引导(问题不在用户的设置里),
282
+ // 也不阻断(真正的动作走的是另一条通道,它自己会如实报错)。
283
+ process.stderr.write(
284
+ '[computer-use] 权限自检未能取得结果(守护进程没有返回可识别的权限响应)。'
285
+ + '这是自检本身的问题,不代表权限缺失;实际操作若受阻会单独报错。\n',
286
+ );
287
+ return true;
288
+ }
289
+ if (result.hasMissingPermissions) {
290
+ showPermissionGuidance(result);
291
+ return false;
292
+ }
293
+ return true;
294
+ }
@@ -0,0 +1,96 @@
1
+ /**
2
+ * ============================================================
3
+ * axSearch.ts —— 无障碍树里的查找原语(纯函数)
4
+ * ------------------------------------------------------------
5
+ * 三个消费方共用这一份:
6
+ * · `manualSchema.ts::evaluatePrecondition` 的 element_exists / 文本谓词
7
+ * · `waitFor.ts` 的 wait_for_element / wait_for_text
8
+ * · `computeruse.ts` 的 click-by-text(`textTarget` → elementId)
9
+ *
10
+ * 分出来的理由不是「代码复用」,是**判据必须一致**:说明书里写
11
+ * `precondition: element_exists AXButton:发送`,模型接着 `wait_for_element`
12
+ * 等同一个控件,然后 `textTarget:"发送"` 去点它 —— 这三步要是各用一套匹配
13
+ * 规则,就会出现「前提说成立、等待等不到」或者「等到了、点的是另一个」。
14
+ *
15
+ * ★ 匹配一律**大小写不敏感的子串**,而不是相等。AX 的 name 常带修饰
16
+ * (「发送 (⌘↩)」「Send Message」),要求相等等于要求调用方精确复述系统文案。
17
+ * role 例外:它是枚举(AXButton/AXTextField…),用相等。
18
+ * ============================================================
19
+ */
20
+ /** 大小写不敏感的子串包含。空 needle 视为不匹配(避免「搜空串命中一切」)。 */
21
+ export function containsFold(haystack, needle) {
22
+ if (!needle)
23
+ return false;
24
+ return (haystack ?? '').toLowerCase().includes(needle.toLowerCase());
25
+ }
26
+ /** 去所有空白(空格/全角空格/制表符/换行)后再做大小写不敏感包含匹配。
27
+ * 用于中文场景:AX name 常带空格(如「发 送」「微信(3)」),模型输入可能不带空格。 */
28
+ export function containsFoldLoose(haystack, needle) {
29
+ if (!needle)
30
+ return false;
31
+ const strip = (s) => s.replace(/[\s\u3000\u00a0\u200b]/g, '').toLowerCase();
32
+ return strip(haystack ?? '').includes(strip(needle));
33
+ }
34
+ /** 深度优先展平。顺序稳定 —— 多个候选时「第一个」必须可复现。 */
35
+ export function flattenAx(node) {
36
+ if (!node || typeof node !== 'object')
37
+ return [];
38
+ return [node, ...(node.children ?? []).flatMap(flattenAx)];
39
+ }
40
+ /** role 相等(大小写不敏感)。缺 role 的节点永不匹配。 */
41
+ export function matchesRole(node, role) {
42
+ if (!role)
43
+ return false;
44
+ return (node.role ?? '').toLowerCase() === role.toLowerCase();
45
+ }
46
+ /** 节点的可见文本:name 或 value 任一含给定片段。 */
47
+ export function matchesText(node, text) {
48
+ return containsFold(node.name, text) || containsFold(node.value, text);
49
+ }
50
+ /** 宽松文本匹配:先按普通 containsFold,再试去空白的 loose 匹配(中文场景友好)。 */
51
+ export function matchesTextLoose(node, text) {
52
+ if (matchesText(node, text))
53
+ return true;
54
+ return containsFoldLoose(node.name, text) || containsFoldLoose(node.value, text);
55
+ }
56
+ /**
57
+ * 按 role(+ 可选名字片段)找控件。
58
+ *
59
+ * `spec` 用说明书里 `element_exists` 的同一语法:`AXButton` 或 `AXButton:发送`。
60
+ * 共用语法是有意的 —— 模型在注入的摘要里见到的就是这个形状。
61
+ */
62
+ export function findByElementSpec(nodes, spec) {
63
+ const [rawRole, ...rest] = spec.split(':');
64
+ const role = (rawRole ?? '').trim();
65
+ const namePart = rest.join(':').trim();
66
+ return nodes.filter((node) => matchesRole(node, role) && (!namePart || containsFold(node.name, namePart)));
67
+ }
68
+ /** 按 role + 可选名字片段找控件(结构化入参版本)。 */
69
+ export function findByRole(nodes, role, nameFragment) {
70
+ return nodes.filter((node) => matchesRole(node, role) && (!nameFragment || containsFold(node.name, nameFragment)));
71
+ }
72
+ /**
73
+ * 按文字找**可点**的控件。
74
+ *
75
+ * 只返回带 `elementId` 且有 `bounds` 的节点:click-by-text 最终要走 elementId
76
+ * 定位,一个说得出名字却给不出位置的节点点不了,把它算进候选只会让「多个匹配」
77
+ * 的拒绝变得莫名其妙。
78
+ *
79
+ * 匹配策略:先精确包含匹配,命中为 0 时再试去空白的宽松匹配(中文场景下 AX name
80
+ * 常夹杂空格/全角空格,模型输入不会带这些)。
81
+ */
82
+ export function findClickableByText(nodes, text) {
83
+ const eligible = nodes.filter((node) => Boolean(node.elementId) && Boolean(node.bounds));
84
+ const exact = eligible.filter((node) => matchesText(node, text));
85
+ if (exact.length > 0)
86
+ return exact;
87
+ return eligible.filter((node) => matchesTextLoose(node, text));
88
+ }
89
+ /** 人话描述一个候选,用于「多个匹配」时把选择权交回给模型。 */
90
+ export function describeNode(node) {
91
+ const name = node.name ? `「${node.name}」` : '(无名字)';
92
+ const where = node.bounds
93
+ ? `位于 (${Math.round(node.bounds.x)},${Math.round(node.bounds.y)})`
94
+ : '无位置';
95
+ return `${node.role ?? '未知角色'} ${name} ${where}${node.elementId ? ` · ${node.elementId}` : ''}`;
96
+ }
@@ -0,0 +1,120 @@
1
+ /**
2
+ * ============================================================
3
+ * axSearch.ts —— 无障碍树里的查找原语(纯函数)
4
+ * ------------------------------------------------------------
5
+ * 三个消费方共用这一份:
6
+ * · `manualSchema.ts::evaluatePrecondition` 的 element_exists / 文本谓词
7
+ * · `waitFor.ts` 的 wait_for_element / wait_for_text
8
+ * · `computeruse.ts` 的 click-by-text(`textTarget` → elementId)
9
+ *
10
+ * 分出来的理由不是「代码复用」,是**判据必须一致**:说明书里写
11
+ * `precondition: element_exists AXButton:发送`,模型接着 `wait_for_element`
12
+ * 等同一个控件,然后 `textTarget:"发送"` 去点它 —— 这三步要是各用一套匹配
13
+ * 规则,就会出现「前提说成立、等待等不到」或者「等到了、点的是另一个」。
14
+ *
15
+ * ★ 匹配一律**大小写不敏感的子串**,而不是相等。AX 的 name 常带修饰
16
+ * (「发送 (⌘↩)」「Send Message」),要求相等等于要求调用方精确复述系统文案。
17
+ * role 例外:它是枚举(AXButton/AXTextField…),用相等。
18
+ * ============================================================
19
+ */
20
+
21
+ /** 查找只关心这几件事,不绑具体协议类型(便于合成测试)。 */
22
+ export interface AxSearchNode {
23
+ elementId?: string;
24
+ role?: string;
25
+ name?: string;
26
+ value?: string;
27
+ subrole?: string;
28
+ focused?: boolean;
29
+ enabled?: boolean;
30
+ actions?: string[];
31
+ bounds?: { x: number; y: number; width: number; height: number };
32
+ children?: AxSearchNode[];
33
+ }
34
+
35
+ /** 大小写不敏感的子串包含。空 needle 视为不匹配(避免「搜空串命中一切」)。 */
36
+ export function containsFold(haystack: string | undefined, needle: string): boolean {
37
+ if (!needle) return false;
38
+ return (haystack ?? '').toLowerCase().includes(needle.toLowerCase());
39
+ }
40
+
41
+ /** 去所有空白(空格/全角空格/制表符/换行)后再做大小写不敏感包含匹配。
42
+ * 用于中文场景:AX name 常带空格(如「发 送」「微信(3)」),模型输入可能不带空格。 */
43
+ export function containsFoldLoose(haystack: string | undefined, needle: string): boolean {
44
+ if (!needle) return false;
45
+ const strip = (s: string) => s.replace(/[\s\u3000\u00a0\u200b]/g, '').toLowerCase();
46
+ return strip(haystack ?? '').includes(strip(needle));
47
+ }
48
+
49
+ /** 深度优先展平。顺序稳定 —— 多个候选时「第一个」必须可复现。 */
50
+ export function flattenAx(node: AxSearchNode | undefined | null): AxSearchNode[] {
51
+ if (!node || typeof node !== 'object') return [];
52
+ return [node, ...(node.children ?? []).flatMap(flattenAx)];
53
+ }
54
+
55
+ /** role 相等(大小写不敏感)。缺 role 的节点永不匹配。 */
56
+ export function matchesRole(node: AxSearchNode, role: string): boolean {
57
+ if (!role) return false;
58
+ return (node.role ?? '').toLowerCase() === role.toLowerCase();
59
+ }
60
+
61
+ /** 节点的可见文本:name 或 value 任一含给定片段。 */
62
+ export function matchesText(node: AxSearchNode, text: string): boolean {
63
+ return containsFold(node.name, text) || containsFold(node.value, text);
64
+ }
65
+
66
+ /** 宽松文本匹配:先按普通 containsFold,再试去空白的 loose 匹配(中文场景友好)。 */
67
+ export function matchesTextLoose(node: AxSearchNode, text: string): boolean {
68
+ if (matchesText(node, text)) return true;
69
+ return containsFoldLoose(node.name, text) || containsFoldLoose(node.value, text);
70
+ }
71
+
72
+ /**
73
+ * 按 role(+ 可选名字片段)找控件。
74
+ *
75
+ * `spec` 用说明书里 `element_exists` 的同一语法:`AXButton` 或 `AXButton:发送`。
76
+ * 共用语法是有意的 —— 模型在注入的摘要里见到的就是这个形状。
77
+ */
78
+ export function findByElementSpec(nodes: AxSearchNode[], spec: string): AxSearchNode[] {
79
+ const [rawRole, ...rest] = spec.split(':');
80
+ const role = (rawRole ?? '').trim();
81
+ const namePart = rest.join(':').trim();
82
+ return nodes.filter((node) =>
83
+ matchesRole(node, role) && (!namePart || containsFold(node.name, namePart)));
84
+ }
85
+
86
+ /** 按 role + 可选名字片段找控件(结构化入参版本)。 */
87
+ export function findByRole(
88
+ nodes: AxSearchNode[],
89
+ role: string,
90
+ nameFragment?: string,
91
+ ): AxSearchNode[] {
92
+ return nodes.filter((node) =>
93
+ matchesRole(node, role) && (!nameFragment || containsFold(node.name, nameFragment)));
94
+ }
95
+
96
+ /**
97
+ * 按文字找**可点**的控件。
98
+ *
99
+ * 只返回带 `elementId` 且有 `bounds` 的节点:click-by-text 最终要走 elementId
100
+ * 定位,一个说得出名字却给不出位置的节点点不了,把它算进候选只会让「多个匹配」
101
+ * 的拒绝变得莫名其妙。
102
+ *
103
+ * 匹配策略:先精确包含匹配,命中为 0 时再试去空白的宽松匹配(中文场景下 AX name
104
+ * 常夹杂空格/全角空格,模型输入不会带这些)。
105
+ */
106
+ export function findClickableByText(nodes: AxSearchNode[], text: string): AxSearchNode[] {
107
+ const eligible = nodes.filter((node) => Boolean(node.elementId) && Boolean(node.bounds));
108
+ const exact = eligible.filter((node) => matchesText(node, text));
109
+ if (exact.length > 0) return exact;
110
+ return eligible.filter((node) => matchesTextLoose(node, text));
111
+ }
112
+
113
+ /** 人话描述一个候选,用于「多个匹配」时把选择权交回给模型。 */
114
+ export function describeNode(node: AxSearchNode): string {
115
+ const name = node.name ? `「${node.name}」` : '(无名字)';
116
+ const where = node.bounds
117
+ ? `位于 (${Math.round(node.bounds.x)},${Math.round(node.bounds.y)})`
118
+ : '无位置';
119
+ return `${node.role ?? '未知角色'} ${name} ${where}${node.elementId ? ` · ${node.elementId}` : ''}`;
120
+ }