minimal-agent 0.13.0 → 0.14.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 (470) hide show
  1. package/README.md +6 -5
  2. package/package.json +60 -4
  3. package/plugins/computer_use/.claude-plugin/plugin.json +1 -1
  4. package/plugins/cron-runner/src/commands.js +4 -4
  5. package/plugins/cron-runner/src/commands.ts +4 -4
  6. package/plugins/workflow-runner/.claude-plugin/plugin.json +2 -2
  7. package/plugins/workflow-runner/commands/workflow.md +57 -90
  8. package/plugins/workflow-runner/commands/workflows.md +4 -4
  9. package/plugins/workflow-runner/plugin.js +24 -13
  10. package/plugins/workflow-runner/plugin.ts +28 -13
  11. package/plugins/workflow-runner/src/discovery.js +160 -0
  12. package/plugins/workflow-runner/src/discovery.ts +194 -0
  13. package/plugins/workflow-runner/src/goalAnchor.js +53 -0
  14. package/plugins/workflow-runner/src/goalAnchor.ts +59 -0
  15. package/plugins/workflow-runner/src/index.js +197 -206
  16. package/plugins/workflow-runner/src/index.ts +248 -249
  17. package/plugins/workflow-runner/src/inputCoercion.js +40 -0
  18. package/plugins/workflow-runner/src/inputCoercion.ts +43 -0
  19. package/plugins/workflow-runner/src/journal.js +224 -0
  20. package/plugins/workflow-runner/src/journal.ts +274 -0
  21. package/plugins/workflow-runner/src/jsonSchema.js +132 -0
  22. package/plugins/workflow-runner/src/jsonSchema.ts +162 -0
  23. package/plugins/workflow-runner/src/moduleResolution.js +64 -0
  24. package/plugins/workflow-runner/src/moduleResolution.ts +71 -0
  25. package/plugins/workflow-runner/src/resourceInputs.js +220 -0
  26. package/plugins/workflow-runner/src/resourceInputs.ts +300 -0
  27. package/plugins/workflow-runner/src/runner.js +400 -489
  28. package/plugins/workflow-runner/src/runner.ts +488 -560
  29. package/plugins/workflow-runner/src/runtime/config.js +46 -0
  30. package/plugins/workflow-runner/src/runtime/config.ts +69 -0
  31. package/plugins/workflow-runner/src/runtime/context.js +1304 -0
  32. package/plugins/workflow-runner/src/runtime/context.ts +1786 -0
  33. package/plugins/workflow-runner/src/runtime/exec.js +34 -0
  34. package/plugins/workflow-runner/src/runtime/exec.ts +53 -0
  35. package/plugins/workflow-runner/src/runtime/flow.js +8 -0
  36. package/plugins/workflow-runner/src/runtime/flow.ts +12 -0
  37. package/plugins/workflow-runner/src/runtime/fs.js +27 -0
  38. package/plugins/workflow-runner/src/runtime/fs.ts +41 -0
  39. package/plugins/workflow-runner/src/runtime/model.js +6 -0
  40. package/plugins/workflow-runner/src/runtime/model.ts +8 -0
  41. package/plugins/workflow-runner/src/runtime/output.js +7 -0
  42. package/plugins/workflow-runner/src/runtime/output.ts +21 -0
  43. package/plugins/workflow-runner/src/runtime/scheduler.js +141 -0
  44. package/plugins/workflow-runner/src/runtime/scheduler.ts +166 -0
  45. package/plugins/workflow-runner/src/runtime/state.js +16 -0
  46. package/plugins/workflow-runner/src/runtime/state.ts +19 -0
  47. package/plugins/workflow-runner/src/runtime/tools.js +3 -0
  48. package/plugins/workflow-runner/src/runtime/tools.ts +6 -0
  49. package/plugins/workflow-runner/src/sandbox.js +141 -0
  50. package/plugins/workflow-runner/src/sandbox.ts +182 -0
  51. package/plugins/workflow-runner/src/scriptGuard.d.mts +38 -0
  52. package/plugins/workflow-runner/src/scriptGuard.mjs +449 -0
  53. package/plugins/workflow-runner/src/taskIdentity.js +151 -307
  54. package/plugins/workflow-runner/src/taskIdentity.ts +207 -355
  55. package/plugins/workflow-runner/src/toolRuntime.js +29 -8
  56. package/plugins/workflow-runner/src/toolRuntime.ts +36 -11
  57. package/plugins/workflow-runner/src/types.js +7 -211
  58. package/plugins/workflow-runner/src/types.ts +154 -623
  59. package/plugins/workflow-runner/src/util.js +47 -0
  60. package/plugins/workflow-runner/src/util.ts +51 -0
  61. package/plugins/workflow-runner/src/workflowContext.js +20 -0
  62. package/plugins/workflow-runner/src/workflowContext.ts +58 -0
  63. package/plugins/workflow-runner/src/workflowDependencies.js +36 -0
  64. package/plugins/workflow-runner/src/workflowDependencies.ts +59 -0
  65. package/plugins/workflow-runner/src/workflowFingerprint.js +118 -0
  66. package/plugins/workflow-runner/src/workflowFingerprint.ts +122 -0
  67. package/plugins/workflow-runner/src/workflowState.js +474 -802
  68. package/plugins/workflow-runner/src/workflowState.ts +575 -970
  69. package/plugins/workflow-runner/test/api.test.ts +223 -0
  70. package/plugins/workflow-runner/test/apiCapabilities.test.ts +614 -0
  71. package/plugins/workflow-runner/test/apiConcurrencyGate.test.ts +104 -0
  72. package/plugins/workflow-runner/test/apiEcho.test.ts +210 -0
  73. package/plugins/workflow-runner/test/apiReadText.test.ts +178 -0
  74. package/plugins/workflow-runner/test/apiResourceLedger.test.ts +184 -0
  75. package/plugins/workflow-runner/test/childWorkflow.test.ts +304 -0
  76. package/plugins/workflow-runner/test/discovery.test.ts +234 -0
  77. package/plugins/workflow-runner/test/goalAnchor.test.ts +106 -0
  78. package/plugins/workflow-runner/test/goalController.test.ts +317 -0
  79. package/plugins/workflow-runner/test/journalLanes.test.ts +198 -0
  80. package/plugins/workflow-runner/test/listResources.test.ts +106 -0
  81. package/plugins/workflow-runner/test/resourceInputs.test.ts +294 -0
  82. package/plugins/workflow-runner/test/sandbox.test.ts +126 -0
  83. package/plugins/workflow-runner/test/scheduler.test.ts +70 -0
  84. package/plugins/workflow-runner/test/scriptGuard.test.ts +276 -0
  85. package/plugins/workflow-runner/test/skillDocSync.test.ts +78 -0
  86. package/plugins/workflow-runner/test/taskIdentity.test.ts +288 -179
  87. package/plugins/workflow-runner/test/workflowFingerprint.test.ts +106 -0
  88. package/plugins/workflow-runner/test/workflowState.test.ts +429 -0
  89. package/skills/pptx/examples/assets/cover-bg.svg +23 -0
  90. package/skills/pptx/examples/assets/icon-spark.svg +5 -0
  91. package/skills/ui-design/SKILL.md +5 -2
  92. package/skills/ui-design/references/layout-composition.md +1 -1
  93. package/skills/workflow-creator/SKILL.md +344 -0
  94. package/skills/workflow-creator/assets/template/workflow.mjs +48 -0
  95. package/skills/workflow-creator/references/api.md +216 -0
  96. package/skills/workflow-creator/references/migration.md +103 -0
  97. package/skills/workflow-creator/references/patterns.md +779 -0
  98. package/skills/workflow-creator/scripts/list-resources.mjs +205 -0
  99. package/skills/workflow-creator/scripts/scaffold.mjs +148 -0
  100. package/skills/workflow-creator/scripts/validate.mjs +275 -0
  101. package/skills/workflow-creator/scripts/workflow-creator.test.mjs +82 -0
  102. package/src/advisor/advisorCoordinator.js +503 -0
  103. package/src/advisor/advisorCoordinator.ts +657 -0
  104. package/src/cli/configMenu.tsx +0 -1
  105. package/src/cli/print.js +27 -6
  106. package/src/cli/print.ts +48 -4
  107. package/src/cli/streamJson.js +5 -6
  108. package/src/cli/streamJson.ts +8 -4
  109. package/src/cli/wizards/advisorWizard.js +4 -2
  110. package/src/cli/wizards/advisorWizard.tsx +8 -2
  111. package/src/cli/wizards/contextAdvisorWizard.js +5 -4
  112. package/src/cli/wizards/contextAdvisorWizard.tsx +7 -6
  113. package/src/collaboration/taskFlow.js +115 -0
  114. package/src/collaboration/taskFlow.ts +169 -0
  115. package/src/config/configDefaults.js +41 -1
  116. package/src/config/configDefaults.ts +43 -1
  117. package/src/config/configDiagnostics.ts +2 -2
  118. package/src/config/configFile.js +40 -9
  119. package/src/config/configFile.ts +60 -11
  120. package/src/config/configService.js +419 -74
  121. package/src/config/configService.ts +703 -145
  122. package/src/config/numericLimits.js +22 -0
  123. package/src/config/numericLimits.ts +24 -0
  124. package/src/config.js +1 -0
  125. package/src/config.ts +3 -2
  126. package/src/context/budgetPlan.js +1 -1
  127. package/src/context/budgetPlan.ts +1 -1
  128. package/src/context/compact.js +7 -2
  129. package/src/context/compact.ts +9 -2
  130. package/src/context/microCompactLite.js +212 -13
  131. package/src/context/microCompactLite.ts +261 -12
  132. package/src/context/sessionRegistry.js +8 -1
  133. package/src/context/sessionRegistry.ts +18 -5
  134. package/src/context/toolResultArchive.js +72 -0
  135. package/src/context/toolResultArchive.ts +95 -0
  136. package/src/goal/errors.js +8 -0
  137. package/src/goal/errors.ts +18 -0
  138. package/src/goal/goalRuntime.js +344 -0
  139. package/src/goal/goalRuntime.ts +466 -0
  140. package/src/goal/goalStore.js +200 -0
  141. package/src/goal/goalStore.ts +219 -0
  142. package/src/goal/index.js +4 -0
  143. package/src/goal/index.ts +4 -0
  144. package/src/goal/statusMapping.js +71 -0
  145. package/src/goal/statusMapping.ts +95 -0
  146. package/src/goal/types.js +7 -0
  147. package/src/goal/types.ts +179 -0
  148. package/src/goal/workflowController.js +306 -0
  149. package/src/goal/workflowController.ts +360 -0
  150. package/src/harness/evidenceLedger.js +2 -0
  151. package/src/harness/evidenceLedger.ts +1 -0
  152. package/src/harness/stallGuard.js +9 -3
  153. package/src/harness/stallGuard.ts +7 -3
  154. package/src/images/imageResolver.js +161 -0
  155. package/src/images/imageResolver.ts +189 -0
  156. package/src/infra/verification.js +34 -5
  157. package/src/infra/verification.ts +39 -4
  158. package/src/llm/client.js +79 -21
  159. package/src/llm/client.ts +182 -35
  160. package/src/llm/gatewayClient.js +201 -0
  161. package/src/llm/gatewayClient.ts +299 -0
  162. package/src/llm/messageProvenance.js +46 -0
  163. package/src/llm/messageProvenance.ts +58 -0
  164. package/src/llm/modelProvider.js +1 -0
  165. package/src/llm/modelProvider.ts +22 -0
  166. package/src/llm/providers/anthropicFormat.js +108 -1
  167. package/src/llm/providers/anthropicFormat.ts +115 -4
  168. package/src/llm/providers/openaiFormat.js +9 -0
  169. package/src/llm/providers/openaiFormat.ts +12 -3
  170. package/src/loop.js +319 -54
  171. package/src/loop.ts +373 -57
  172. package/src/main.js +4 -1
  173. package/src/main.tsx +4 -1
  174. package/src/managedExecution/index.js +2 -0
  175. package/src/managedExecution/index.ts +2 -0
  176. package/src/managedExecution/registry.js +15 -0
  177. package/src/managedExecution/registry.ts +20 -0
  178. package/src/managedExecution/types.js +1 -0
  179. package/src/managedExecution/types.ts +86 -0
  180. package/src/modelRef.js +9 -0
  181. package/src/modelRef.ts +31 -0
  182. package/src/multimodal.js +14 -28
  183. package/src/multimodal.ts +17 -33
  184. package/src/net/lanDiscovery.js +65 -0
  185. package/src/net/lanDiscovery.ts +82 -0
  186. package/src/plugin-sdk.js +28 -3
  187. package/src/plugin-sdk.ts +39 -6
  188. package/src/plugins/pluginApi.ts +16 -1
  189. package/src/plugins/pluginLoader.js +4 -0
  190. package/src/plugins/pluginLoader.ts +6 -0
  191. package/src/plugins/pluginRunner.js +139 -7
  192. package/src/plugins/pluginRunner.ts +173 -9
  193. package/src/plugins/slashFallback.js +113 -0
  194. package/src/plugins/slashFallback.ts +137 -0
  195. package/src/prompts/policyRegistry.js +12 -32
  196. package/src/prompts/policyRegistry.ts +15 -32
  197. package/src/prompts/promptAssembly.js +103 -12
  198. package/src/prompts/promptAssembly.ts +114 -12
  199. package/src/prompts/skillList.js +21 -3
  200. package/src/prompts/skillList.ts +27 -2
  201. package/src/prompts/stableSystemPrompt.js +18 -0
  202. package/src/prompts/stableSystemPrompt.ts +33 -0
  203. package/src/runtime/agentRuntimeContext.js +8 -2
  204. package/src/runtime/agentRuntimeContext.ts +17 -4
  205. package/src/session/runAgentTurn.js +78 -12
  206. package/src/session/runAgentTurn.ts +105 -23
  207. package/src/session/runTurn.js +10 -9
  208. package/src/session/runTurn.ts +17 -8
  209. package/src/session/sessionState.ts +2 -0
  210. package/src/team/auth.js +186 -0
  211. package/src/team/auth.ts +298 -0
  212. package/src/team/cli.js +105 -0
  213. package/src/team/cli.ts +122 -0
  214. package/src/team/onlineToolContract.js +64 -0
  215. package/src/team/onlineToolContract.ts +109 -0
  216. package/src/team/toolPolicy.js +36 -0
  217. package/src/team/toolPolicy.ts +75 -0
  218. package/src/tools/advisor/advisor.js +90 -46
  219. package/src/tools/advisor/advisor.ts +100 -47
  220. package/src/tools/advisor/advisorDecision.js +71 -0
  221. package/src/tools/advisor/advisorDecision.ts +85 -0
  222. package/src/tools/agent/agent.js +18 -5
  223. package/src/tools/agent/agent.ts +21 -7
  224. package/src/tools/agent/agentControl.js +246 -0
  225. package/src/tools/agent/agentControl.ts +284 -0
  226. package/src/tools/agent/agentTaskService.js +40 -1
  227. package/src/tools/agent/agentTaskService.ts +44 -1
  228. package/src/tools/agent/agentTypes.js +14 -2
  229. package/src/tools/agent/agentTypes.ts +15 -2
  230. package/src/tools/applypatch/applyPatch.js +362 -0
  231. package/src/tools/applypatch/applyPatch.ts +428 -0
  232. package/src/tools/bash/bash.js +22 -15
  233. package/src/tools/bash/bash.ts +23 -17
  234. package/src/tools/capabilities.js +10 -5
  235. package/src/tools/capabilities.ts +10 -5
  236. package/src/tools/computeruse/computerIntent.js +32 -0
  237. package/src/tools/computeruse/computerIntent.ts +46 -0
  238. package/src/tools/computeruse/telemetryLog.js +12 -0
  239. package/src/tools/computeruse/telemetryLog.ts +16 -0
  240. package/src/tools/computeruse/vision/telemetry.js +1 -0
  241. package/src/tools/computeruse/vision/telemetry.ts +1 -0
  242. package/src/tools/effectiveToolSet.js +4 -0
  243. package/src/tools/effectiveToolSet.ts +4 -0
  244. package/src/tools/index.js +21 -2
  245. package/src/tools/index.ts +33 -2
  246. package/src/tools/presentresult/presentresult.js +6 -15
  247. package/src/tools/presentresult/presentresult.ts +6 -15
  248. package/src/tools/read/read.js +62 -9
  249. package/src/tools/read/read.ts +63 -9
  250. package/src/tools/shared/fileUtils.js +1 -2
  251. package/src/tools/shared/fileUtils.ts +1 -2
  252. package/src/tools/shared/toolOutputStore.js +23 -1
  253. package/src/tools/shared/toolOutputStore.ts +22 -1
  254. package/src/tools/skill/skill.js +9 -3
  255. package/src/tools/skill/skill.ts +8 -4
  256. package/src/tools/toolPromptGuides.js +117 -0
  257. package/src/tools/toolPromptGuides.ts +137 -0
  258. package/src/tools/webbrowser/agentBrowserPath.js +19 -9
  259. package/src/tools/webbrowser/agentBrowserPath.ts +70 -28
  260. package/src/tools/webbrowser/browser.js +27 -11
  261. package/src/tools/webbrowser/browser.ts +68 -24
  262. package/src/tools/webbrowser/browserAutomation.js +329 -0
  263. package/src/tools/webbrowser/browserAutomation.ts +467 -0
  264. package/src/tools/webbrowser/browserAxState.js +97 -0
  265. package/src/tools/webbrowser/browserAxState.ts +142 -0
  266. package/src/tools/webbrowser/browserBatch.js +1578 -0
  267. package/src/tools/webbrowser/browserBatch.ts +2382 -0
  268. package/src/tools/webbrowser/browserCdp.js +208 -0
  269. package/src/tools/webbrowser/browserCdp.ts +255 -0
  270. package/src/tools/webbrowser/browserConditions.js +24 -0
  271. package/src/tools/webbrowser/browserConditions.ts +45 -0
  272. package/src/tools/webbrowser/browserContent.js +281 -0
  273. package/src/tools/webbrowser/browserContent.ts +438 -0
  274. package/src/tools/webbrowser/browserControl.js +131 -34
  275. package/src/tools/webbrowser/browserControl.ts +210 -56
  276. package/src/tools/webbrowser/browserDaemon.js +22 -14
  277. package/src/tools/webbrowser/browserDaemon.ts +54 -21
  278. package/src/tools/webbrowser/browserFrames.js +47 -0
  279. package/src/tools/webbrowser/browserFrames.ts +54 -0
  280. package/src/tools/webbrowser/browserInteractionResolver.js +17 -0
  281. package/src/tools/webbrowser/browserInteractionResolver.ts +40 -0
  282. package/src/tools/webbrowser/browserLocator.js +140 -0
  283. package/src/tools/webbrowser/browserLocator.ts +194 -0
  284. package/src/tools/webbrowser/browserOutcome.js +10 -17
  285. package/src/tools/webbrowser/browserOutcome.ts +48 -31
  286. package/src/tools/webbrowser/browserRecovery.js +58 -0
  287. package/src/tools/webbrowser/browserRecovery.ts +83 -0
  288. package/src/tools/webbrowser/browserRunRegistry.js +35 -3
  289. package/src/tools/webbrowser/browserRunRegistry.ts +91 -15
  290. package/src/tools/webbrowser/browserService.js +28 -2
  291. package/src/tools/webbrowser/browserService.ts +49 -9
  292. package/src/tools/webbrowser/browserStream.js +132 -33
  293. package/src/tools/webbrowser/browserStream.ts +224 -50
  294. package/src/tools/webbrowser/browserTabs.js +48 -15
  295. package/src/tools/webbrowser/browserTabs.ts +178 -96
  296. package/src/tools/webbrowser/webbrowser.js +679 -144
  297. package/src/tools/webbrowser/webbrowser.ts +975 -236
  298. package/src/tools/webfetch/preapproved.js +0 -2
  299. package/src/tools/webfetch/preapproved.ts +0 -2
  300. package/src/tools/websearch/websearch.js +129 -8
  301. package/src/tools/websearch/websearch.ts +138 -6
  302. package/src/types.ts +440 -38
  303. package/src/ui/App.js +377 -58
  304. package/src/ui/App.tsx +576 -111
  305. package/src/ui/LiveArea.js +14 -8
  306. package/src/ui/LiveArea.tsx +14 -10
  307. package/src/ui/MessageList.js +63 -20
  308. package/src/ui/MessageList.tsx +101 -16
  309. package/src/ui/ModelPicker.js +7 -4
  310. package/src/ui/ModelPicker.tsx +55 -8
  311. package/src/ui/hooks/useChat.js +152 -163
  312. package/src/ui/hooks/useChat.ts +396 -334
  313. package/src/ui/loginCommand.js +56 -0
  314. package/src/ui/loginCommand.ts +63 -0
  315. package/src/ui/toolProgress.js +41 -0
  316. package/src/ui/toolProgress.ts +44 -0
  317. package/src/web/browserBridge.js +20 -2
  318. package/src/web/browserBridge.ts +20 -2
  319. package/src/web/protocol.ts +1897 -194
  320. package/workflows/adaptive-research/workflow.mjs +86 -0
  321. package/workflows/e2e-capabilities/workflow.mjs +102 -0
  322. package/workflows/e2e-llm/workflow.mjs +52 -0
  323. package/workflows/e2e-smoke/workflow.mjs +59 -0
  324. package/workflows/e2e-vision-schema/README.md +48 -0
  325. package/workflows/e2e-vision-schema/workflow.mjs +149 -0
  326. package/workflows/e2e-write-greet/workflow.mjs +37 -0
  327. package/workflows/file-census/README.md +14 -0
  328. package/workflows/file-census/scripts/.gitkeep +2 -0
  329. package/workflows/file-census/workflow.mjs +110 -0
  330. package/workflows/goal/README.md +166 -0
  331. package/workflows/goal/prompts/audit.md +57 -0
  332. package/workflows/goal/prompts/contract.md +56 -0
  333. package/workflows/goal/prompts/iterate.md +37 -0
  334. package/workflows/goal/workflow.mjs +501 -0
  335. package/workflows/illustrate/README.md +90 -0
  336. package/workflows/illustrate/assets/engines.json +20 -0
  337. package/workflows/illustrate/assets/extract-baidu.js +21 -0
  338. package/workflows/illustrate/assets/extract-bing.js +33 -0
  339. package/workflows/illustrate/assets/extract-google.js +31 -0
  340. package/workflows/illustrate/workflow.mjs +301 -0
  341. package/workflows/plan/workflow.mjs +389 -0
  342. package/workflows/question-crops/README.md +35 -0
  343. package/workflows/question-crops/prompts/inventory.md +23 -0
  344. package/workflows/question-crops/scripts/image-ops.mjs +305 -0
  345. package/workflows/question-crops/scripts/image-ops.test.mjs +95 -0
  346. package/workflows/question-crops/workflow.mjs +172 -0
  347. package/workflows/ralph-loop/workflow.mjs +162 -0
  348. package/workflows/research/README.md +74 -0
  349. package/workflows/research/prompts/s0-goal.md +43 -0
  350. package/workflows/research/prompts/s1-early-exit.md +22 -0
  351. package/workflows/research/prompts/s1-map.md +58 -0
  352. package/workflows/research/prompts/s2-options.md +53 -0
  353. package/workflows/research/prompts/s3-deep-dive.md +56 -0
  354. package/workflows/research/prompts/s4-verify.md +74 -0
  355. package/workflows/research/prompts/s5-synthesis.md +81 -0
  356. package/workflows/research/prompts/s5b-fill-gaps.md +32 -0
  357. package/workflows/research/prompts/s6-package.md +32 -0
  358. package/workflows/research/scripts/build-report.mjs +98 -0
  359. package/workflows/research/workflow.mjs +288 -0
  360. package/workflows/wechat-reading-shots/prompts/collect-params.md +16 -0
  361. package/workflows/wechat-reading-shots/prompts/evaluate.md +20 -0
  362. package/workflows/wechat-reading-shots/prompts/open-book.md +28 -0
  363. package/workflows/wechat-reading-shots/prompts/read-page.md +13 -0
  364. package/workflows/wechat-reading-shots/prompts/turn-batch.md +24 -0
  365. package/workflows/wechat-reading-shots/test/control-flow.test.ts +329 -0
  366. package/workflows/wechat-reading-shots/workflow.mjs +266 -0
  367. package/workflows/wrong-question-docx/README.md +55 -0
  368. package/workflows/wrong-question-docx/prompts/figure-qa.md +8 -0
  369. package/workflows/wrong-question-docx/prompts/transcribe.md +25 -0
  370. package/workflows/wrong-question-docx/scripts/workbook.mjs +857 -0
  371. package/workflows/wrong-question-docx/test/control-flow.test.ts +165 -0
  372. package/workflows/wrong-question-docx/test/workbook.test.mjs +303 -0
  373. package/workflows/wrong-question-docx/workflow.mjs +485 -0
  374. package/plugins/workflow-runner/src/agentCommon.js +0 -354
  375. package/plugins/workflow-runner/src/agentCommon.ts +0 -435
  376. package/plugins/workflow-runner/src/controlFlow/branch.js +0 -40
  377. package/plugins/workflow-runner/src/controlFlow/branch.ts +0 -46
  378. package/plugins/workflow-runner/src/controlFlow/loop.js +0 -211
  379. package/plugins/workflow-runner/src/controlFlow/loop.ts +0 -248
  380. package/plugins/workflow-runner/src/controlFlow/pause.js +0 -129
  381. package/plugins/workflow-runner/src/controlFlow/pause.ts +0 -141
  382. package/plugins/workflow-runner/src/controlFlow/signal.js +0 -21
  383. package/plugins/workflow-runner/src/controlFlow/signal.ts +0 -29
  384. package/plugins/workflow-runner/src/controlFlow/types.js +0 -18
  385. package/plugins/workflow-runner/src/controlFlow/types.ts +0 -63
  386. package/plugins/workflow-runner/src/dslManifest.js +0 -72
  387. package/plugins/workflow-runner/src/dslManifest.ts +0 -127
  388. package/plugins/workflow-runner/src/expressions.js +0 -639
  389. package/plugins/workflow-runner/src/expressions.ts +0 -640
  390. package/plugins/workflow-runner/src/loader.js +0 -573
  391. package/plugins/workflow-runner/src/loader.ts +0 -721
  392. package/plugins/workflow-runner/src/multimodal.js +0 -38
  393. package/plugins/workflow-runner/src/multimodal.ts +0 -64
  394. package/plugins/workflow-runner/src/recovery.js +0 -126
  395. package/plugins/workflow-runner/src/recovery.ts +0 -156
  396. package/plugins/workflow-runner/src/stepExecutors/agent.js +0 -173
  397. package/plugins/workflow-runner/src/stepExecutors/agent.ts +0 -234
  398. package/plugins/workflow-runner/src/stepExecutors/assert.js +0 -42
  399. package/plugins/workflow-runner/src/stepExecutors/assert.ts +0 -52
  400. package/plugins/workflow-runner/src/stepExecutors/echo.js +0 -31
  401. package/plugins/workflow-runner/src/stepExecutors/echo.ts +0 -38
  402. package/plugins/workflow-runner/src/stepExecutors/llm.js +0 -99
  403. package/plugins/workflow-runner/src/stepExecutors/llm.ts +0 -133
  404. package/plugins/workflow-runner/src/stepExecutors/set.js +0 -49
  405. package/plugins/workflow-runner/src/stepExecutors/set.ts +0 -56
  406. package/plugins/workflow-runner/src/stepExecutors/skill.js +0 -111
  407. package/plugins/workflow-runner/src/stepExecutors/skill.ts +0 -140
  408. package/plugins/workflow-runner/src/stepExecutors/tool.js +0 -227
  409. package/plugins/workflow-runner/src/stepExecutors/tool.ts +0 -274
  410. package/plugins/workflow-runner/src/stepExecutors/verify.js +0 -61
  411. package/plugins/workflow-runner/src/stepExecutors/verify.ts +0 -72
  412. package/plugins/workflow-runner/src/stepPipeline.js +0 -277
  413. package/plugins/workflow-runner/src/stepPipeline.ts +0 -366
  414. package/plugins/workflow-runner/test/agent.test.ts +0 -587
  415. package/plugins/workflow-runner/test/agentLlmError.test.ts +0 -373
  416. package/plugins/workflow-runner/test/bashBlacklist.sweep.test.ts +0 -65
  417. package/plugins/workflow-runner/test/captureMisbind.test.ts +0 -99
  418. package/plugins/workflow-runner/test/cli.e2e.test.ts +0 -167
  419. package/plugins/workflow-runner/test/context-files.test.ts +0 -320
  420. package/plugins/workflow-runner/test/e2e.test.ts +0 -370
  421. package/plugins/workflow-runner/test/e2eNewLayout.test.ts +0 -314
  422. package/plugins/workflow-runner/test/engineRobustness.test.ts +0 -234
  423. package/plugins/workflow-runner/test/expressions.test.ts +0 -439
  424. package/plugins/workflow-runner/test/foundation.test.ts +0 -126
  425. package/plugins/workflow-runner/test/graceful.test.ts +0 -139
  426. package/plugins/workflow-runner/test/greedyInputs.load.test.ts +0 -47
  427. package/plugins/workflow-runner/test/hostCapability.test.ts +0 -108
  428. package/plugins/workflow-runner/test/illustrate.load.test.ts +0 -183
  429. package/plugins/workflow-runner/test/jsonPayload.test.ts +0 -83
  430. package/plugins/workflow-runner/test/loader.test.ts +0 -617
  431. package/plugins/workflow-runner/test/maxTurnsRetryDelay.test.ts +0 -33
  432. package/plugins/workflow-runner/test/multimodal.test.ts +0 -342
  433. package/plugins/workflow-runner/test/output-schema.test.ts +0 -213
  434. package/plugins/workflow-runner/test/parseWorkflowArgs.test.ts +0 -106
  435. package/plugins/workflow-runner/test/pluginRunner.isolation.test.ts +0 -269
  436. package/plugins/workflow-runner/test/ppt.load.test.ts +0 -1220
  437. package/plugins/workflow-runner/test/ralphLoop.e2e.test.ts +0 -221
  438. package/plugins/workflow-runner/test/recovery.test.ts +0 -265
  439. package/plugins/workflow-runner/test/research.load.test.ts +0 -328
  440. package/plugins/workflow-runner/test/runner.test.ts +0 -911
  441. package/plugins/workflow-runner/test/runnerPreflight.test.ts +0 -436
  442. package/plugins/workflow-runner/test/skillTurnDone.test.ts +0 -71
  443. package/plugins/workflow-runner/test/stateLifecycle.test.ts +0 -198
  444. package/plugins/workflow-runner/test/stepPipeline.test.ts +0 -114
  445. package/plugins/workflow-runner/test/taskArbitration.test.ts +0 -354
  446. package/plugins/workflow-runner/test/taskLifecycle.test.ts +0 -324
  447. package/plugins/workflow-runner/test/toolArtifactOverwrite.test.ts +0 -221
  448. package/plugins/workflow-runner/test/toolCapabilityBoundary.test.ts +0 -29
  449. package/plugins/workflow-runner/test/toolRuntimeIntegration.test.ts +0 -168
  450. package/plugins/workflow-runner/test/webppt.load.test.ts +0 -250
  451. package/plugins/workflow-runner/test/word.load.test.ts +0 -208
  452. package/plugins/workflow-runner/test/workflows.smoke.test.ts +0 -76
  453. package/plugins/workflow-runner/test/yamlGuardConditions.test.ts +0 -207
  454. package/src/advisorState.js +0 -22
  455. package/src/cli/configWizard.js +0 -293
  456. package/src/tools/toolProgressBridge.js +0 -48
  457. package/workflows/adaptive-research.yaml +0 -50
  458. package/workflows/book-review-short.yaml +0 -125
  459. package/workflows/e2e-write-greet.yaml +0 -31
  460. package/workflows/illustrate.yaml +0 -227
  461. package/workflows/plan.yaml +0 -470
  462. package/workflows/ppt.yaml +0 -1670
  463. package/workflows/ralph-loop.yaml +0 -201
  464. package/workflows/research.yaml +0 -873
  465. package/workflows/schema.json +0 -176
  466. package/workflows/webppt.yaml +0 -496
  467. package/workflows/wechat-reading-shots.yaml +0 -315
  468. package/workflows/word.yaml +0 -720
  469. package/workflows/youtube-shorts.yaml +0 -202
  470. /package/workflows/{research.md → research/DESIGN.md} +0 -0
@@ -0,0 +1,298 @@
1
+ /** Minimal, opt-in team credential store. Standalone startup never imports or
2
+ * reads it; only explicit team commands / online-model resolution do. */
3
+ import { chmod, mkdir, readFile, rename, writeFile } from 'node:fs/promises';
4
+ import { dirname, join } from 'node:path';
5
+ import { getConfigFilePath } from '../config/configFile.js';
6
+ import type { OnlineModelAvailability } from './onlineToolContract.js';
7
+
8
+ const TEAM_REQUEST_TIMEOUT_MS = Math.max(
9
+ 3_000,
10
+ Math.min(
11
+ 60_000,
12
+ Number(process.env.MINIMAL_AGENT_TEAM_REQUEST_TIMEOUT_MS ?? 15_000),
13
+ ),
14
+ );
15
+
16
+ export interface TeamCredentials {
17
+ serverUrl: string;
18
+ deviceToken: string;
19
+ deviceLabel?: string;
20
+ updatedAt: number;
21
+ }
22
+
23
+ export interface OnlineModelCatalogItem {
24
+ id: string;
25
+ displayName: string;
26
+ model: string;
27
+ apiFormat: 'openai' | 'anthropic';
28
+ contextWindow: number;
29
+ maxTokens: number;
30
+ supportsVision: boolean;
31
+ capabilities?: { vision: boolean; tools: boolean; structuredOutput: boolean };
32
+ isDefault: boolean;
33
+ maxToolCategories: string[];
34
+ defaultToolCategories: string[];
35
+ availability?: OnlineModelAvailability;
36
+ }
37
+
38
+ export interface TeamAccountSubscription {
39
+ status: string;
40
+ planName: string;
41
+ billingInterval: string;
42
+ requestLimit: number;
43
+ inputTokenLimit: number;
44
+ outputTokenLimit: number;
45
+ requestCount: number;
46
+ inputTokens: number;
47
+ outputTokens: number;
48
+ }
49
+
50
+ function authPath(): string {
51
+ return join(dirname(getConfigFilePath()), 'team-auth.json');
52
+ }
53
+
54
+ export function normalizeTeamServerUrl(value: string): string {
55
+ const url = new URL(value.trim());
56
+ if (url.protocol !== 'https:' && url.protocol !== 'http:')
57
+ throw new Error('团队服务器必须使用 http(s) 地址');
58
+ const hostname = url.hostname.toLowerCase().replace(/^\[|\]$/g, '');
59
+ const isLocalDevelopmentHost =
60
+ hostname === 'localhost' || hostname === '127.0.0.1' || hostname === '::1';
61
+ if (
62
+ url.protocol === 'http:' &&
63
+ !isLocalDevelopmentHost &&
64
+ process.env.KAKADEAI_ALLOW_HTTP_TEAM_SERVER !== '1'
65
+ ) {
66
+ throw new Error(
67
+ '团队服务器必须使用 HTTPS(开发环境可使用本机地址或显式允许 HTTP)',
68
+ );
69
+ }
70
+ url.search = '';
71
+ url.hash = '';
72
+ return url.toString().replace(/\/$/, '');
73
+ }
74
+
75
+ export async function loadTeamCredentials(
76
+ expectedServerUrl?: string,
77
+ ): Promise<TeamCredentials | null> {
78
+ const rawServerUrl = process.env.KAKADEAI_SOCIAL_SERVER_URL;
79
+ // The Desktop shell deliberately injects an empty value in standalone mode.
80
+ // An empty environment value is an explicit opt-out and must not fall back
81
+ // to a stale team-auth.json left by an earlier team-mode run.
82
+ if (rawServerUrl !== undefined && !rawServerUrl.trim()) return null;
83
+ const serverUrl = rawServerUrl?.trim() ?? expectedServerUrl?.trim();
84
+ if (
85
+ rawServerUrl?.trim() &&
86
+ expectedServerUrl?.trim() &&
87
+ normalizeTeamServerUrl(rawServerUrl) !==
88
+ normalizeTeamServerUrl(expectedServerUrl)
89
+ )
90
+ return null;
91
+ const deviceToken = process.env.KAKADEAI_TEAM_DEVICE_TOKEN?.trim();
92
+ if (serverUrl && deviceToken) {
93
+ return {
94
+ serverUrl: normalizeTeamServerUrl(serverUrl),
95
+ deviceToken,
96
+ ...(process.env.KAKADEAI_TEAM_DEVICE_LABEL
97
+ ? { deviceLabel: process.env.KAKADEAI_TEAM_DEVICE_LABEL }
98
+ : {}),
99
+ updatedAt: Date.now(),
100
+ };
101
+ }
102
+ try {
103
+ const raw = JSON.parse(
104
+ await readFile(authPath(), 'utf8'),
105
+ ) as Partial<TeamCredentials>;
106
+ if (!raw.serverUrl || !raw.deviceToken) return null;
107
+ const storedServerUrl = normalizeTeamServerUrl(raw.serverUrl);
108
+ if (serverUrl && storedServerUrl !== normalizeTeamServerUrl(serverUrl))
109
+ return null;
110
+ return {
111
+ serverUrl: storedServerUrl,
112
+ deviceToken: raw.deviceToken,
113
+ ...(raw.deviceLabel ? { deviceLabel: raw.deviceLabel } : {}),
114
+ updatedAt: Number(raw.updatedAt) || 0,
115
+ };
116
+ } catch {
117
+ return null;
118
+ }
119
+ }
120
+
121
+ export async function saveTeamCredentials(
122
+ value: TeamCredentials,
123
+ ): Promise<void> {
124
+ const path = authPath();
125
+ await mkdir(dirname(path), { recursive: true });
126
+ const temporary = `${path}.${process.pid}.tmp`;
127
+ await writeFile(
128
+ temporary,
129
+ `${JSON.stringify({ ...value, serverUrl: normalizeTeamServerUrl(value.serverUrl) }, null, 2)}\n`,
130
+ { mode: 0o600 },
131
+ );
132
+ await chmod(temporary, 0o600).catch(() => {});
133
+ await rename(temporary, path);
134
+ await chmod(path, 0o600).catch(() => {});
135
+ }
136
+
137
+ export async function clearTeamCredentials(): Promise<void> {
138
+ const path = authPath();
139
+ await writeFile(path, '{}\n', { mode: 0o600 }).catch(() => {});
140
+ }
141
+
142
+ /**
143
+ * Revoke exactly the credentials supplied by the caller, then clear the local
144
+ * copy. A null value is deliberately local-only: silently discovering an old
145
+ * team-auth.json here could make standalone logout contact a historical
146
+ * server. Callers that want remote revocation must first load credentials
147
+ * against the currently configured server.
148
+ */
149
+ export async function revokeTeamCredentials(
150
+ credentials: TeamCredentials | null,
151
+ ): Promise<void> {
152
+ if (credentials?.serverUrl && credentials.deviceToken) {
153
+ await fetch(`${credentials.serverUrl}/api/auth/device/logout`, {
154
+ method: 'POST',
155
+ headers: { authorization: `Bearer ${credentials.deviceToken}` },
156
+ }).catch(() => {});
157
+ }
158
+ await clearTeamCredentials();
159
+ }
160
+
161
+ export async function fetchOnlineModels(
162
+ credentials: TeamCredentials,
163
+ ): Promise<OnlineModelCatalogItem[]> {
164
+ const response = await fetch(`${credentials.serverUrl}/api/models`, {
165
+ headers: { authorization: `Bearer ${credentials.deviceToken}` },
166
+ signal: AbortSignal.timeout(TEAM_REQUEST_TIMEOUT_MS),
167
+ });
168
+ const body = (await response.json().catch(() => ({}))) as {
169
+ models?: OnlineModelCatalogItem[];
170
+ error?: string;
171
+ code?: string;
172
+ };
173
+ if (!response.ok) {
174
+ const code =
175
+ body.code ??
176
+ (response.status === 401
177
+ ? 'DEVICE_REVOKED'
178
+ : response.status === 403
179
+ ? 'MODEL_UNAVAILABLE'
180
+ : `HTTP_${response.status}`);
181
+ throw new Error(
182
+ `[${code}] ${body.error ?? `读取在线模型失败(${response.status})`}`,
183
+ );
184
+ }
185
+ return (body.models ?? []).filter((model) => typeof model.id === 'string');
186
+ }
187
+
188
+ export async function fetchTeamSubscription(
189
+ credentials: TeamCredentials,
190
+ ): Promise<TeamAccountSubscription | null> {
191
+ const response = await fetch(
192
+ `${credentials.serverUrl}/api/account/subscription`,
193
+ {
194
+ headers: { authorization: `Bearer ${credentials.deviceToken}` },
195
+ signal: AbortSignal.timeout(TEAM_REQUEST_TIMEOUT_MS),
196
+ },
197
+ );
198
+ const body = (await response.json().catch(() => ({}))) as {
199
+ subscription?: TeamAccountSubscription | null;
200
+ error?: string;
201
+ };
202
+ if (!response.ok)
203
+ throw new Error(body.error ?? `读取订阅失败(${response.status})`);
204
+ return body.subscription ?? null;
205
+ }
206
+
207
+ export async function fetchTeamUsage(
208
+ credentials: TeamCredentials,
209
+ ): Promise<unknown[]> {
210
+ const response = await fetch(`${credentials.serverUrl}/api/account/usage`, {
211
+ headers: { authorization: `Bearer ${credentials.deviceToken}` },
212
+ signal: AbortSignal.timeout(TEAM_REQUEST_TIMEOUT_MS),
213
+ });
214
+ const body = (await response.json().catch(() => ({}))) as {
215
+ usage?: unknown[];
216
+ error?: string;
217
+ };
218
+ if (!response.ok)
219
+ throw new Error(body.error ?? `读取用量失败(${response.status})`);
220
+ return body.usage ?? [];
221
+ }
222
+
223
+ export async function resolveOnlineModel(
224
+ modelId: string,
225
+ expectedServerUrl?: string,
226
+ ): Promise<{
227
+ credentials: TeamCredentials;
228
+ model: OnlineModelCatalogItem;
229
+ } | null> {
230
+ const credentials = await loadTeamCredentials(expectedServerUrl);
231
+ if (!credentials) return null;
232
+ const models = await fetchOnlineModels(credentials);
233
+ const model = models.find((item) => item.id === modelId);
234
+ return model ? { credentials, model } : null;
235
+ }
236
+
237
+ export async function beginTeamLogin(
238
+ serverUrl: string,
239
+ deviceLabel = 'minimal-agent',
240
+ ): Promise<{ authorizeUrl: string; complete: () => Promise<TeamCredentials> }> {
241
+ const normalized = normalizeTeamServerUrl(serverUrl);
242
+ const start = await fetch(`${normalized}/api/auth/device/start`, {
243
+ method: 'POST',
244
+ headers: { 'content-type': 'application/json' },
245
+ body: JSON.stringify({ clientLabel: deviceLabel }),
246
+ signal: AbortSignal.timeout(TEAM_REQUEST_TIMEOUT_MS),
247
+ });
248
+ const authorization = (await start.json().catch(() => ({}))) as {
249
+ requestId?: string;
250
+ deviceCode?: string;
251
+ authorizeUrl?: string;
252
+ error?: string;
253
+ };
254
+ if (
255
+ !start.ok ||
256
+ !authorization.requestId ||
257
+ !authorization.deviceCode ||
258
+ !authorization.authorizeUrl
259
+ )
260
+ throw new Error(authorization.error ?? '无法发起团队登录');
261
+ return {
262
+ authorizeUrl: authorization.authorizeUrl,
263
+ complete: async () => {
264
+ const deadline = Date.now() + 10 * 60_000;
265
+ while (Date.now() < deadline) {
266
+ const poll = await fetch(
267
+ `${normalized}/api/auth/device/poll?requestId=${encodeURIComponent(authorization.requestId!)}`,
268
+ {
269
+ headers: {
270
+ 'x-kakadeai-device-code': authorization.deviceCode!,
271
+ },
272
+ signal: AbortSignal.timeout(TEAM_REQUEST_TIMEOUT_MS),
273
+ },
274
+ );
275
+ const result = (await poll.json().catch(() => ({}))) as {
276
+ state?: string;
277
+ deviceToken?: string;
278
+ error?: string;
279
+ };
280
+ if (result.state === 'approved' && result.deviceToken) {
281
+ const credentials: TeamCredentials = {
282
+ serverUrl: normalized,
283
+ deviceToken: result.deviceToken,
284
+ deviceLabel,
285
+ updatedAt: Date.now(),
286
+ };
287
+ await saveTeamCredentials(credentials);
288
+ return credentials;
289
+ }
290
+ if (result.state === 'expired')
291
+ throw new Error('浏览器授权已过期,请重新登录');
292
+ if (!poll.ok && result.error) throw new Error(result.error);
293
+ await new Promise((resolve) => setTimeout(resolve, 1500));
294
+ }
295
+ throw new Error('等待浏览器授权超时');
296
+ },
297
+ };
298
+ }
@@ -0,0 +1,105 @@
1
+ import { configService } from '../config/configService.js';
2
+ import { beginTeamLogin, clearTeamCredentials, fetchOnlineModels, fetchTeamSubscription, fetchTeamUsage, loadTeamCredentials, revokeTeamCredentials, } from './auth.js';
3
+ async function openBrowser(url) {
4
+ const command = process.platform === 'darwin'
5
+ ? ['open', url]
6
+ : process.platform === 'win32'
7
+ ? ['cmd', '/c', 'start', '', url]
8
+ : ['xdg-open', url];
9
+ try {
10
+ Bun.spawn({ cmd: command, stdout: 'ignore', stderr: 'ignore' });
11
+ }
12
+ catch {
13
+ /* URL is printed as a reliable fallback */
14
+ }
15
+ }
16
+ async function configuredCredentials() {
17
+ const configured = await configService.resolveTeamServerUrl();
18
+ return configured.value ? loadTeamCredentials(configured.value) : null;
19
+ }
20
+ /** Returns true when argv was a team command and has been fully handled. */
21
+ export async function runTeamCommand(args) {
22
+ const topLevel = args[0] === 'login' || args[0] === 'logout' || args[0] === 'status';
23
+ if (args[0] !== 'team' && !topLevel)
24
+ return false;
25
+ const action = topLevel ? args[0] : (args[1] ?? 'status');
26
+ if (action === 'status') {
27
+ const credentials = await configuredCredentials();
28
+ if (!credentials)
29
+ console.log('团队在线模型:未登录(单机模式不受影响)');
30
+ else {
31
+ try {
32
+ const models = await fetchOnlineModels(credentials);
33
+ console.log(`团队服务器:${credentials.serverUrl}\n设备授权:有效\n可用在线模型:${models.length}`);
34
+ }
35
+ catch (error) {
36
+ console.log(`团队服务器:${credentials.serverUrl}\n设备授权:不可用(${error instanceof Error ? error.message : String(error)})`);
37
+ }
38
+ }
39
+ return true;
40
+ }
41
+ if (action === 'logout') {
42
+ // Resolve against the currently configured server first. If standalone
43
+ // mode has no server configured, a stale team-auth.json must only be
44
+ // cleared locally and must never trigger a request to an old server.
45
+ const configured = await configService.resolveTeamServerUrl();
46
+ if (configured.value) {
47
+ const credentials = await loadTeamCredentials(configured.value);
48
+ if (credentials)
49
+ await revokeTeamCredentials(credentials);
50
+ else
51
+ await clearTeamCredentials();
52
+ }
53
+ else {
54
+ // No configured server is the standalone boundary. Do not let
55
+ // revokeTeamCredentials() discover and contact a stale auth file.
56
+ await clearTeamCredentials();
57
+ }
58
+ console.log('已清除本机团队设备授权;本地模型配置和 Session 未受影响。');
59
+ return true;
60
+ }
61
+ if (action === 'models') {
62
+ const credentials = await configuredCredentials();
63
+ if (!credentials) {
64
+ console.log('未登录团队服务器;当前仅使用本机模型。');
65
+ return true;
66
+ }
67
+ const models = await fetchOnlineModels(credentials);
68
+ for (const model of models)
69
+ console.log(`${model.displayName} · ${model.model}${model.isDefault ? ' · 默认' : ''}${model.availability?.reason ? ` · ${model.availability.reason}` : ''}`);
70
+ return true;
71
+ }
72
+ if (action === 'usage') {
73
+ const credentials = await configuredCredentials();
74
+ if (!credentials) {
75
+ console.log('未登录团队服务器。');
76
+ return true;
77
+ }
78
+ const subscription = await fetchTeamSubscription(credentials);
79
+ console.log(subscription
80
+ ? `订阅:${subscription.planName} · ${subscription.status}\n请求:${subscription.requestCount}/${subscription.requestLimit}\n输入 Token:${subscription.inputTokens}/${subscription.inputTokenLimit}\n输出 Token:${subscription.outputTokens}/${subscription.outputTokenLimit}`
81
+ : '当前没有有效订阅');
82
+ const usage = await fetchTeamUsage(credentials);
83
+ console.log(`模型用量记录:${usage.length} 条`);
84
+ return true;
85
+ }
86
+ if (action === 'login') {
87
+ const explicit = topLevel ? undefined : args[2];
88
+ const resolved = explicit
89
+ ? undefined
90
+ : await configService.resolveTeamServerUrl();
91
+ const serverUrl = explicit ?? resolved?.value;
92
+ if (!serverUrl)
93
+ throw new Error('KakadeAI 登录服务暂时不可用,请稍后重试');
94
+ if (!explicit)
95
+ console.log(`使用 KakadeAI 服务(${resolved.source === 'env' ? '环境变量覆盖' : resolved.source === 'config' ? '本机配置' : '内置默认'})`);
96
+ const login = await beginTeamLogin(serverUrl, 'minimal-agent CLI');
97
+ console.log(`请在浏览器完成登录并允许此设备:\n${login.authorizeUrl}`);
98
+ await openBrowser(login.authorizeUrl);
99
+ const credentials = await login.complete();
100
+ const models = await fetchOnlineModels(credentials);
101
+ console.log(`团队登录完成,可用在线模型:${models.length}`);
102
+ return true;
103
+ }
104
+ throw new Error('用法:minimal-agent login|logout|status 或 minimal-agent team [login|logout|status|models|usage]');
105
+ }
@@ -0,0 +1,122 @@
1
+ import { configService } from '../config/configService.js';
2
+ import {
3
+ beginTeamLogin,
4
+ clearTeamCredentials,
5
+ fetchOnlineModels,
6
+ fetchTeamSubscription,
7
+ fetchTeamUsage,
8
+ loadTeamCredentials,
9
+ revokeTeamCredentials,
10
+ } from './auth.js';
11
+
12
+ async function openBrowser(url: string): Promise<void> {
13
+ const command =
14
+ process.platform === 'darwin'
15
+ ? ['open', url]
16
+ : process.platform === 'win32'
17
+ ? ['cmd', '/c', 'start', '', url]
18
+ : ['xdg-open', url];
19
+ try {
20
+ Bun.spawn({ cmd: command, stdout: 'ignore', stderr: 'ignore' });
21
+ } catch {
22
+ /* URL is printed as a reliable fallback */
23
+ }
24
+ }
25
+
26
+ async function configuredCredentials() {
27
+ const configured = await configService.resolveTeamServerUrl();
28
+ return configured.value ? loadTeamCredentials(configured.value) : null;
29
+ }
30
+
31
+ /** Returns true when argv was a team command and has been fully handled. */
32
+ export async function runTeamCommand(args: string[]): Promise<boolean> {
33
+ const topLevel =
34
+ args[0] === 'login' || args[0] === 'logout' || args[0] === 'status';
35
+ if (args[0] !== 'team' && !topLevel) return false;
36
+ const action = topLevel ? args[0] : (args[1] ?? 'status');
37
+ if (action === 'status') {
38
+ const credentials = await configuredCredentials();
39
+ if (!credentials) console.log('团队在线模型:未登录(单机模式不受影响)');
40
+ else {
41
+ try {
42
+ const models = await fetchOnlineModels(credentials);
43
+ console.log(
44
+ `团队服务器:${credentials.serverUrl}\n设备授权:有效\n可用在线模型:${models.length}`,
45
+ );
46
+ } catch (error) {
47
+ console.log(
48
+ `团队服务器:${credentials.serverUrl}\n设备授权:不可用(${error instanceof Error ? error.message : String(error)})`,
49
+ );
50
+ }
51
+ }
52
+ return true;
53
+ }
54
+ if (action === 'logout') {
55
+ // Resolve against the currently configured server first. If standalone
56
+ // mode has no server configured, a stale team-auth.json must only be
57
+ // cleared locally and must never trigger a request to an old server.
58
+ const configured = await configService.resolveTeamServerUrl();
59
+ if (configured.value) {
60
+ const credentials = await loadTeamCredentials(configured.value);
61
+ if (credentials) await revokeTeamCredentials(credentials);
62
+ else await clearTeamCredentials();
63
+ } else {
64
+ // No configured server is the standalone boundary. Do not let
65
+ // revokeTeamCredentials() discover and contact a stale auth file.
66
+ await clearTeamCredentials();
67
+ }
68
+ console.log('已清除本机团队设备授权;本地模型配置和 Session 未受影响。');
69
+ return true;
70
+ }
71
+ if (action === 'models') {
72
+ const credentials = await configuredCredentials();
73
+ if (!credentials) {
74
+ console.log('未登录团队服务器;当前仅使用本机模型。');
75
+ return true;
76
+ }
77
+ const models = await fetchOnlineModels(credentials);
78
+ for (const model of models)
79
+ console.log(
80
+ `${model.displayName} · ${model.model}${model.isDefault ? ' · 默认' : ''}${model.availability?.reason ? ` · ${model.availability.reason}` : ''}`,
81
+ );
82
+ return true;
83
+ }
84
+ if (action === 'usage') {
85
+ const credentials = await configuredCredentials();
86
+ if (!credentials) {
87
+ console.log('未登录团队服务器。');
88
+ return true;
89
+ }
90
+ const subscription = await fetchTeamSubscription(credentials);
91
+ console.log(
92
+ subscription
93
+ ? `订阅:${subscription.planName} · ${subscription.status}\n请求:${subscription.requestCount}/${subscription.requestLimit}\n输入 Token:${subscription.inputTokens}/${subscription.inputTokenLimit}\n输出 Token:${subscription.outputTokens}/${subscription.outputTokenLimit}`
94
+ : '当前没有有效订阅',
95
+ );
96
+ const usage = await fetchTeamUsage(credentials);
97
+ console.log(`模型用量记录:${usage.length} 条`);
98
+ return true;
99
+ }
100
+ if (action === 'login') {
101
+ const explicit = topLevel ? undefined : args[2];
102
+ const resolved = explicit
103
+ ? undefined
104
+ : await configService.resolveTeamServerUrl();
105
+ const serverUrl = explicit ?? resolved?.value;
106
+ if (!serverUrl) throw new Error('KakadeAI 登录服务暂时不可用,请稍后重试');
107
+ if (!explicit)
108
+ console.log(
109
+ `使用 KakadeAI 服务(${resolved!.source === 'env' ? '环境变量覆盖' : resolved!.source === 'config' ? '本机配置' : '内置默认'})`,
110
+ );
111
+ const login = await beginTeamLogin(serverUrl, 'minimal-agent CLI');
112
+ console.log(`请在浏览器完成登录并允许此设备:\n${login.authorizeUrl}`);
113
+ await openBrowser(login.authorizeUrl);
114
+ const credentials = await login.complete();
115
+ const models = await fetchOnlineModels(credentials);
116
+ console.log(`团队登录完成,可用在线模型:${models.length}`);
117
+ return true;
118
+ }
119
+ throw new Error(
120
+ '用法:minimal-agent login|logout|status 或 minimal-agent team [login|logout|status|models|usage]',
121
+ );
122
+ }
@@ -0,0 +1,64 @@
1
+ export const ONLINE_TOOL_CATEGORIES = [
2
+ 'workspace',
3
+ 'web',
4
+ 'computer',
5
+ 'subagents',
6
+ 'integrations',
7
+ ];
8
+ export const ONLINE_TOOL_CATEGORY_BY_NAME = {
9
+ Read: 'workspace',
10
+ Edit: 'workspace',
11
+ MultiEdit: 'workspace',
12
+ Write: 'workspace',
13
+ NotebookEdit: 'workspace',
14
+ Glob: 'workspace',
15
+ Grep: 'workspace',
16
+ LSP: 'workspace',
17
+ Bash: 'workspace',
18
+ PowerShell: 'workspace',
19
+ ApplyPatch: 'workspace',
20
+ Trash: 'workspace',
21
+ EnterWorktree: 'workspace',
22
+ ExitWorktree: 'workspace',
23
+ TerminalCapture: 'workspace',
24
+ TaskCreate: 'workspace',
25
+ TaskGet: 'workspace',
26
+ TaskUpdate: 'workspace',
27
+ TaskList: 'workspace',
28
+ TaskOutput: 'workspace',
29
+ TaskStop: 'workspace',
30
+ PresentResult: 'workspace',
31
+ Snip: 'workspace',
32
+ RecallMemory: 'workspace',
33
+ RememberMemory: 'workspace',
34
+ UpdateMemory: 'workspace',
35
+ ListMemories: 'workspace',
36
+ ForgetMemory: 'workspace',
37
+ SetPersona: 'workspace',
38
+ ClearPersona: 'workspace',
39
+ ConfirmMemory: 'workspace',
40
+ ReviewMemories: 'workspace',
41
+ SearchConversations: 'workspace',
42
+ AskUserQuestion: 'workspace',
43
+ Skill: 'workspace',
44
+ WebSearch: 'web',
45
+ WebFetch: 'web',
46
+ WebBrowser: 'web',
47
+ BrowserBatch: 'web',
48
+ BrowserCDP: 'web',
49
+ Download: 'web',
50
+ ComputerUse: 'computer',
51
+ Agent: 'subagents',
52
+ AgentMessage: 'subagents',
53
+ AgentList: 'subagents',
54
+ AgentWait: 'subagents',
55
+ AgentInterrupt: 'subagents',
56
+ AgentFollowup: 'subagents',
57
+ Advisor: 'subagents',
58
+ AdvisorDecision: 'subagents',
59
+ GenerateImage: 'integrations',
60
+ GenerateSpeech: 'integrations',
61
+ };
62
+ export function onlineToolCategory(name) {
63
+ return ONLINE_TOOL_CATEGORY_BY_NAME[name];
64
+ }
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Versioned-by-package contract for tools that may be described to the
3
+ * remote inference gateway. The server imports this allow-list as well as
4
+ * the local Agent, so a newly registered local/plugin tool fails closed until
5
+ * it is deliberately added here.
6
+ */
7
+ export type OnlineToolCategory =
8
+ | 'workspace'
9
+ | 'web'
10
+ | 'computer'
11
+ | 'subagents'
12
+ | 'integrations';
13
+
14
+ /**
15
+ * Shared availability vocabulary for the server catalog and local clients.
16
+ * `offline` and `disabled` are retained as client-side fallback states; the
17
+ * server uses the more specific states when it can determine the cause.
18
+ */
19
+ export type OnlineModelAvailabilityState =
20
+ | 'available'
21
+ | 'quota_exhausted'
22
+ | 'concurrency_exceeded'
23
+ | 'not_authorized'
24
+ | 'model_disabled'
25
+ | 'server_offline'
26
+ | 'device_expired'
27
+ | 'offline'
28
+ | 'disabled';
29
+
30
+ export interface OnlineModelAvailability {
31
+ state: OnlineModelAvailabilityState;
32
+ reason?: string;
33
+ remainingRequests?: number;
34
+ remainingInputTokens?: number;
35
+ remainingOutputTokens?: number;
36
+ activeRequests?: number;
37
+ maxConcurrent?: number;
38
+ }
39
+
40
+ export const ONLINE_TOOL_CATEGORIES = [
41
+ 'workspace',
42
+ 'web',
43
+ 'computer',
44
+ 'subagents',
45
+ 'integrations',
46
+ ] as const satisfies readonly OnlineToolCategory[];
47
+
48
+ export const ONLINE_TOOL_CATEGORY_BY_NAME = {
49
+ Read: 'workspace',
50
+ Edit: 'workspace',
51
+ MultiEdit: 'workspace',
52
+ Write: 'workspace',
53
+ NotebookEdit: 'workspace',
54
+ Glob: 'workspace',
55
+ Grep: 'workspace',
56
+ LSP: 'workspace',
57
+ Bash: 'workspace',
58
+ PowerShell: 'workspace',
59
+ ApplyPatch: 'workspace',
60
+ Trash: 'workspace',
61
+ EnterWorktree: 'workspace',
62
+ ExitWorktree: 'workspace',
63
+ TerminalCapture: 'workspace',
64
+ TaskCreate: 'workspace',
65
+ TaskGet: 'workspace',
66
+ TaskUpdate: 'workspace',
67
+ TaskList: 'workspace',
68
+ TaskOutput: 'workspace',
69
+ TaskStop: 'workspace',
70
+ PresentResult: 'workspace',
71
+ Snip: 'workspace',
72
+ RecallMemory: 'workspace',
73
+ RememberMemory: 'workspace',
74
+ UpdateMemory: 'workspace',
75
+ ListMemories: 'workspace',
76
+ ForgetMemory: 'workspace',
77
+ SetPersona: 'workspace',
78
+ ClearPersona: 'workspace',
79
+ ConfirmMemory: 'workspace',
80
+ ReviewMemories: 'workspace',
81
+ SearchConversations: 'workspace',
82
+ AskUserQuestion: 'workspace',
83
+ Skill: 'workspace',
84
+ WebSearch: 'web',
85
+ WebFetch: 'web',
86
+ WebBrowser: 'web',
87
+ BrowserBatch: 'web',
88
+ BrowserCDP: 'web',
89
+ Download: 'web',
90
+ ComputerUse: 'computer',
91
+ Agent: 'subagents',
92
+ AgentMessage: 'subagents',
93
+ AgentList: 'subagents',
94
+ AgentWait: 'subagents',
95
+ AgentInterrupt: 'subagents',
96
+ AgentFollowup: 'subagents',
97
+ Advisor: 'subagents',
98
+ AdvisorDecision: 'subagents',
99
+ GenerateImage: 'integrations',
100
+ GenerateSpeech: 'integrations',
101
+ } as const satisfies Readonly<Record<string, OnlineToolCategory>>;
102
+
103
+ export function onlineToolCategory(
104
+ name: string,
105
+ ): OnlineToolCategory | undefined {
106
+ return ONLINE_TOOL_CATEGORY_BY_NAME[
107
+ name as keyof typeof ONLINE_TOOL_CATEGORY_BY_NAME
108
+ ];
109
+ }