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
package/src/ui/App.js CHANGED
@@ -7,36 +7,39 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
7
7
  * 不直接处理键盘输入,那是 InputBox 的事。
8
8
  * ============================================================
9
9
  */
10
- import React, { useDeferredValue } from 'react';
11
10
  import { Box, Text } from 'ink';
11
+ import React, { useDeferredValue } from 'react';
12
12
  import { getWorkingDir } from '../bootstrap/workingDir.js';
13
+ import { createCliComputerRun, readRecentComputerUseAudit, } from '../cli/computerUse.js';
13
14
  import { ConfigMenu } from '../cli/configMenu.js';
14
15
  import { configService } from '../config/configService.js';
15
16
  import { listArchives, restoreArchive } from '../context/archive.js';
16
17
  import { saveContext } from '../context/persistContext.js';
17
18
  import { sessionFileFor } from '../context/sessionPath.js';
18
- import { workspaceIndexService } from '../context/workspaceIndex.js';
19
- import { memoryService } from '../memory/memoryService.js';
20
19
  import { createSession, listSessionSummaries, updateSessionMetadata, } from '../context/sessionRegistry.js';
20
+ import { workspaceIndexService, } from '../context/workspaceIndex.js';
21
+ import { memoryService } from '../memory/memoryService.js';
22
+ import { legacyModelId, modelRefFromLegacy } from '../modelRef.js';
21
23
  import { activatePlugins } from '../plugins/pluginLifecycle.js';
22
24
  import { runAgentTurn } from '../session/runAgentTurn.js';
23
- import { writeClipboardText } from '../utils/clipboardImage.js';
24
- import { createCliComputerRun, readRecentComputerUseAudit, } from '../cli/computerUse.js';
25
+ import { beginTeamLogin, clearTeamCredentials, fetchOnlineModels, fetchTeamSubscription, fetchTeamUsage, loadTeamCredentials, revokeTeamCredentials, } from '../team/auth.js';
25
26
  import { computerUseService } from '../tools/computeruse/computerUseService.js';
26
- import { advisorHelpText, parseAdvisorCommand } from './advisorCommand.js';
27
+ import { writeClipboardText } from '../utils/clipboardImage.js';
27
28
  import { AskQuestion } from './AskQuestion.js';
28
29
  import { InputBox } from './InputBox.js';
29
30
  import { LiveArea } from './LiveArea.js';
30
- import { QueuedMessagesBanner } from './QueuedMessagesBanner.js';
31
31
  import { MessageList } from './MessageList.js';
32
32
  import { ModelPicker } from './ModelPicker.js';
33
+ import { QueuedMessagesBanner } from './QueuedMessagesBanner.js';
33
34
  import { SessionPicker } from './SessionPicker.js';
34
- import { WorkspacePicker } from './WorkspacePicker.js';
35
35
  import { StatusLine } from './StatusLine.js';
36
- import { theme } from './theme.js';
36
+ import { WorkspacePicker } from './WorkspacePicker.js';
37
+ import { advisorHelpText, parseAdvisorCommand } from './advisorCommand.js';
37
38
  import { parseComputerCommand } from './computerCommand.js';
38
39
  import { useChat } from './hooks/useChat.js';
39
40
  import { useTerminalSize } from './hooks/useTerminalSize.js';
41
+ import { isLogoutCommand, loginHelpText, parseLoginCommand, } from './loginCommand.js';
42
+ import { theme } from './theme.js';
40
43
  /**
41
44
  * ANSI escape: 清屏 + 光标归位。
42
45
  *
@@ -56,6 +59,38 @@ function formatProviderName(apiFormat) {
56
59
  return 'OpenAI兼容';
57
60
  return apiFormat;
58
61
  }
62
+ function toPickerModel(model) {
63
+ return {
64
+ id: legacyModelId({
65
+ source: 'gateway',
66
+ serverId: 'gateway',
67
+ modelId: model.id,
68
+ }),
69
+ apiFormat: model.apiFormat,
70
+ displayName: model.displayName,
71
+ model: model.model,
72
+ contextWindow: model.contextWindow,
73
+ maxTokens: model.maxTokens,
74
+ supportsVision: model.supportsVision,
75
+ enabled: true,
76
+ source: 'gateway',
77
+ isDefault: model.isDefault,
78
+ availability: model.availability,
79
+ };
80
+ }
81
+ async function openTeamBrowser(url) {
82
+ const command = process.platform === 'darwin'
83
+ ? ['open', url]
84
+ : process.platform === 'win32'
85
+ ? ['cmd', '/c', 'start', '', url]
86
+ : ['xdg-open', url];
87
+ try {
88
+ Bun.spawn({ cmd: command, stdout: 'ignore', stderr: 'ignore' });
89
+ }
90
+ catch {
91
+ /* TUI prints the URL below */
92
+ }
93
+ }
59
94
  export function App({ provider, initialHistory }) {
60
95
  // v2 multi-session:持久化路径完全由 useChat 内部管控(按 activeSessionId 选文件)。
61
96
  // App 不再传 onPersist —— 之前 App 端调 saveContext(messages) 会污染 default session。
@@ -74,13 +109,15 @@ export function App({ provider, initialHistory }) {
74
109
  provider,
75
110
  signal: controller.signal,
76
111
  runAgentTurn,
77
- }).then((fn) => {
112
+ })
113
+ .then((fn) => {
78
114
  if (controller.signal.aborted) {
79
115
  fn();
80
116
  return;
81
117
  }
82
118
  cleanup = fn;
83
- }).catch((err) => {
119
+ })
120
+ .catch((err) => {
84
121
  console.warn(`[minimal-agent] plugin activation failed: ${err instanceof Error ? err.message : String(err)}`);
85
122
  });
86
123
  return () => {
@@ -160,13 +197,47 @@ export function App({ provider, initialHistory }) {
160
197
  return;
161
198
  const snap = await configService.getSnapshot();
162
199
  const model = snap.config?.models.find((m) => m.id === modelId);
200
+ const selectedRef = modelRefFromLegacy(modelId);
201
+ const isGateway = selectedRef.source === 'gateway';
202
+ if (isGateway) {
203
+ const provider = await configService.providerForRef(selectedRef);
204
+ if (provider) {
205
+ const gatewayProvider = provider.source === 'gateway' ? provider : null;
206
+ if (!gatewayProvider)
207
+ return;
208
+ await updateSessionMetadata(getWorkingDir(), chat.activeSessionId, {
209
+ modelId: null,
210
+ preferredModel: {
211
+ source: 'gateway',
212
+ serverId: gatewayProvider.gatewayUrl,
213
+ modelId: selectedRef.modelId,
214
+ },
215
+ effectiveModel: {
216
+ source: 'gateway',
217
+ serverId: gatewayProvider.gatewayUrl,
218
+ modelId: selectedRef.modelId,
219
+ },
220
+ restoreWhenAvailable: true,
221
+ });
222
+ chat.setProvider(provider);
223
+ forceRerender((v) => v + 1);
224
+ chat.ephemeralLine(`[/model] 当前 Session 已切换为在线模型 ${provider.name},下一轮对话生效。`);
225
+ }
226
+ return;
227
+ }
163
228
  if (!model) {
164
229
  chat.ephemeralLine(`[/model] 未找到模型 "${modelId}"`);
165
230
  return;
166
231
  }
167
232
  const newProvider = await configService.providerForModel(modelId);
168
233
  if (newProvider) {
169
- await updateSessionMetadata(getWorkingDir(), chat.activeSessionId, { modelId });
234
+ await updateSessionMetadata(getWorkingDir(), chat.activeSessionId, {
235
+ modelId: null,
236
+ preferredModel: { source: 'local', modelId },
237
+ effectiveModel: { source: 'local', modelId },
238
+ fallbackReason: undefined,
239
+ restoreWhenAvailable: false,
240
+ });
170
241
  chat.setProvider(newProvider);
171
242
  forceRerender((v) => v + 1);
172
243
  chat.ephemeralLine(`[/model] 当前 Session 已切换为 ${model.displayName || model.model}(${formatProviderName(model.apiFormat)}),下一轮对话生效。`);
@@ -174,22 +245,100 @@ export function App({ provider, initialHistory }) {
174
245
  }, [chat.activeSessionId, chat.setProvider, chat.ephemeralLine]);
175
246
  React.useEffect(() => {
176
247
  let cancelled = false;
177
- void listSessionSummaries(getWorkingDir()).then(async (sessions) => {
178
- const modelId = sessions.find((session) => session.id === chat.activeSessionId)?.modelId;
179
- const provider = await configService.providerForModel(modelId ?? null)
180
- ?? await configService.providerForModel(null);
181
- if (!cancelled && provider)
248
+ void listSessionSummaries(getWorkingDir())
249
+ .then(async (sessions) => {
250
+ const currentSession = sessions.find((session) => session.id === chat.activeSessionId);
251
+ const preferredModel = currentSession?.preferredModel ??
252
+ (currentSession?.modelId
253
+ ? modelRefFromLegacy(currentSession.modelId)
254
+ : null);
255
+ let provider = null;
256
+ let fallbackReason = null;
257
+ if (preferredModel) {
258
+ const resolved = await configService.resolveModelRef(preferredModel);
259
+ provider = resolved.provider;
260
+ fallbackReason = resolved.fallbackReason;
261
+ if (!provider && preferredModel.source === 'gateway')
262
+ provider = await configService.providerForModel(null);
263
+ }
264
+ else {
265
+ provider = await configService.onlineDefaultProvider();
266
+ if (!provider)
267
+ provider = await configService.providerForModel(null);
268
+ }
269
+ if (cancelled)
270
+ return;
271
+ if (provider) {
272
+ const localModelId = currentSession?.preferredModel?.source === 'local'
273
+ ? currentSession.preferredModel.modelId
274
+ : currentSession?.modelId &&
275
+ !currentSession.modelId.startsWith('online:')
276
+ ? currentSession.modelId
277
+ : ((await configService.getSnapshot()).config?.baseModelId ??
278
+ provider.model);
279
+ const effectiveModel = provider.source === 'gateway'
280
+ ? {
281
+ source: 'gateway',
282
+ serverId: provider.gatewayUrl ?? 'gateway',
283
+ modelId: provider.remoteModelId ?? provider.model,
284
+ }
285
+ : { source: 'local', modelId: localModelId };
286
+ const isGatewayPreference = preferredModel?.source === 'gateway';
287
+ const shouldPersist = (provider.source === 'gateway' && !preferredModel) ||
288
+ (isGatewayPreference &&
289
+ (currentSession?.effectiveModel?.source !==
290
+ effectiveModel.source ||
291
+ currentSession?.effectiveModel?.modelId !==
292
+ effectiveModel.modelId ||
293
+ currentSession.fallbackReason !== fallbackReason));
182
294
  chat.setProvider(provider);
183
- }).catch(() => { });
184
- return () => { cancelled = true; };
185
- }, [chat.activeSessionId, chat.setProvider]);
295
+ if (shouldPersist ||
296
+ (isGatewayPreference && provider.source === 'local')) {
297
+ await updateSessionMetadata(getWorkingDir(), chat.activeSessionId, {
298
+ ...(provider.source === 'gateway' && !preferredModel
299
+ ? { preferredModel: effectiveModel }
300
+ : {}),
301
+ effectiveModel,
302
+ fallbackReason: provider.source === 'local' ? fallbackReason : null,
303
+ restoreWhenAvailable: isGatewayPreference || provider.source === 'gateway',
304
+ }).catch(() => { });
305
+ if (isGatewayPreference && provider.source === 'local')
306
+ chat.ephemeralLine(`[/model] 在线模型暂不可用,已回退本地模型(${fallbackReason ?? 'offline'});服务恢复后将自动恢复。`);
307
+ else if (isGatewayPreference &&
308
+ provider.source === 'gateway' &&
309
+ currentSession?.fallbackReason)
310
+ chat.ephemeralLine(`[/model] 在线模型已恢复,当前 Session 已恢复在线模型 ${provider.name}。`);
311
+ }
312
+ }
313
+ else if (preferredModel?.source === 'gateway') {
314
+ chat.ephemeralLine('[/model] 在线模型不可用,且未配置本地模型;请连接团队服务器或配置本地模型。');
315
+ }
316
+ })
317
+ .catch(() => { });
318
+ return () => {
319
+ cancelled = true;
320
+ };
321
+ }, [chat.activeSessionId, chat.setProvider, chat.ephemeralLine]);
186
322
  const handleAdvisorModelSelect = React.useCallback(async (modelId) => {
187
323
  setAdvisorModelPicker(null);
188
324
  if (modelId === null) {
189
- await configService.savePatch({ advisor: { modelId: null, enabled: false } });
325
+ await configService.savePatch({
326
+ advisor: { modelId: null, enabled: false },
327
+ });
190
328
  chat.ephemeralLine('[/advisor] 已关闭顾问模型。');
191
329
  return;
192
330
  }
331
+ const selectedRef = modelRefFromLegacy(modelId);
332
+ if (selectedRef.source === 'gateway') {
333
+ const provider = await configService.providerForRef(selectedRef);
334
+ if (!provider) {
335
+ chat.ephemeralLine('[/advisor] 在线模型不可用、未授权或设备凭据已过期。');
336
+ return;
337
+ }
338
+ await configService.savePatch({ advisor: { modelId, enabled: true } });
339
+ chat.ephemeralLine(`[/advisor] 已设置顾问模型为 ${provider.name}(在线)。`);
340
+ return;
341
+ }
193
342
  const snap = await configService.getSnapshot();
194
343
  const model = snap.config?.models.find((m) => m.id === modelId);
195
344
  if (!model) {
@@ -220,15 +369,23 @@ export function App({ provider, initialHistory }) {
220
369
  */
221
370
  const handleSubmit = React.useCallback(async (text) => {
222
371
  const trimmed = text.trim();
223
- const isBareSessionCmd = trimmed === '/session' || trimmed === '/sessions' || trimmed === '/resume';
372
+ const isBareSessionCmd = trimmed === '/session' ||
373
+ trimmed === '/sessions' ||
374
+ trimmed === '/resume';
224
375
  const sessionArgMatch = /^\/(?:session|resume)\s+(.+)$/.exec(trimmed);
225
376
  if (trimmed === '/workspaces') {
226
377
  await openWorkspacePicker();
227
378
  return;
228
379
  }
229
380
  if (trimmed === '/copy') {
230
- const latest = [...historyRef.current].reverse().find((message) => message.role === 'assistant' && typeof message.content === 'string' && message.content.length > 0);
231
- if (!latest || latest.role !== 'assistant' || typeof latest.content !== 'string') {
381
+ const latest = [...historyRef.current]
382
+ .reverse()
383
+ .find((message) => message.role === 'assistant' &&
384
+ typeof message.content === 'string' &&
385
+ message.content.length > 0);
386
+ if (!latest ||
387
+ latest.role !== 'assistant' ||
388
+ typeof latest.content !== 'string') {
232
389
  chat.ephemeralLine('[/copy] 当前会话还没有可复制的 AI 最终回复。');
233
390
  return;
234
391
  }
@@ -247,7 +404,7 @@ export function App({ provider, initialHistory }) {
247
404
  if (sub === 'help') {
248
405
  const helperAvailable = computerUseService.available();
249
406
  let helperBackend = '未知';
250
- let modeLabel = chat.computerUseMode;
407
+ const modeLabel = chat.computerUseMode;
251
408
  try {
252
409
  const workspace = await workspaceIndexService
253
410
  .findByPath(getWorkingDir())
@@ -260,7 +417,9 @@ export function App({ provider, initialHistory }) {
260
417
  allowedFileRoots: [getWorkingDir()],
261
418
  supervised: true,
262
419
  });
263
- const resp = await computerUseService.request(context, { action: 'status' });
420
+ const resp = await computerUseService.request(context, {
421
+ action: 'status',
422
+ });
264
423
  if (resp.ok && resp.state?.backend) {
265
424
  helperBackend = resp.state.backend;
266
425
  }
@@ -358,7 +517,7 @@ export function App({ provider, initialHistory }) {
358
517
  const apps = response.state?.windows
359
518
  .map((window) => window.appId)
360
519
  .filter((id, index, all) => all.indexOf(id) === index);
361
- chat.ephemeralLine(`[/computer] 可见应用:${apps?.length ? apps.join('、') : response.content ?? '当前没有可见应用'}`);
520
+ chat.ephemeralLine(`[/computer] 可见应用:${apps?.length ? apps.join('、') : (response.content ?? '当前没有可见应用')}`);
362
521
  return;
363
522
  }
364
523
  if (sub === 'permissions') {
@@ -366,11 +525,7 @@ export function App({ provider, initialHistory }) {
366
525
  return;
367
526
  }
368
527
  // status
369
- chat.ephemeralLine(`[/computer] 状态:\n` +
370
- ` 模式:${chat.computerUseMode}\n` +
371
- ` Helper:${computerUseService.available() ? '✅ 可用' : '❌ 不可用'}\n` +
372
- ` Backend:${response.state?.backend ?? '未知'}\n` +
373
- ` 提示:输入 /computer help 查看所有可用命令`);
528
+ chat.ephemeralLine(`[/computer] 状态:\n 模式:${chat.computerUseMode}\n Helper:${computerUseService.available() ? '✅ 可用' : '❌ 不可用'}\n Backend:${response.state?.backend ?? '未知'}\n 提示:输入 /computer help 查看所有可用命令`);
374
529
  return;
375
530
  }
376
531
  if (computerCommand.matched) {
@@ -378,18 +533,24 @@ export function App({ provider, initialHistory }) {
378
533
  return;
379
534
  }
380
535
  if (trimmed === '/memories') {
381
- const workspace = await workspaceIndexService.findByPath(getWorkingDir()).catch(() => null);
536
+ const workspace = await workspaceIndexService
537
+ .findByPath(getWorkingDir())
538
+ .catch(() => null);
382
539
  const records = await memoryService.recall('', workspace?.id, 100);
383
540
  if (!records.length) {
384
541
  chat.ephemeralLine('[/memories] 当前没有本机长期记忆。');
385
542
  return;
386
543
  }
387
- chat.ephemeralLine(`[/memories] 本机长期记忆:\n${records.map((record) => ` ${record.id} · ${record.scope === 'personal' ? '个人' : '工作区'} · ${record.subject}: ${record.statement}`).join('\n')}\n使用 /forget-memory <id> 删除一条记忆。`);
544
+ chat.ephemeralLine(`[/memories] 本机长期记忆:\n${records
545
+ .map((record) => ` ${record.id} · ${record.scope === 'personal' ? '个人' : '工作区'} · ${record.subject}: ${record.statement}`)
546
+ .join('\n')}\n使用 /forget-memory <id> 删除一条记忆。`);
388
547
  return;
389
548
  }
390
549
  if (trimmed.startsWith('/forget-memory ')) {
391
550
  const id = trimmed.slice('/forget-memory '.length).trim();
392
- const workspace = await workspaceIndexService.findByPath(getWorkingDir()).catch(() => null);
551
+ const workspace = await workspaceIndexService
552
+ .findByPath(getWorkingDir())
553
+ .catch(() => null);
393
554
  const records = await memoryService.recall('', workspace?.id, 100);
394
555
  const record = records.find((item) => item.id === id);
395
556
  if (!record) {
@@ -428,7 +589,9 @@ export function App({ provider, initialHistory }) {
428
589
  .slice(0, 30)
429
590
  .map((e) => ` ${e.id} · ${e.msgCount} msgs · ${e.firstUserPreview || '(empty)'}`)
430
591
  .join('\n');
431
- const tail = entries.length > 30 ? `\n ...(共 ${entries.length} 条,仅显示前 30)` : '';
592
+ const tail = entries.length > 30
593
+ ? `\n ...(共 ${entries.length} 条,仅显示前 30)`
594
+ : '';
432
595
  chat.ephemeralLine(`[/list-archive] 归档列表(最新优先):\n${lines}${tail}`);
433
596
  return;
434
597
  }
@@ -466,33 +629,171 @@ export function App({ provider, initialHistory }) {
466
629
  chat.ephemeralLine(`[tool result · #${hit.tool_call_id.slice(-8)} · 完整 ${hit.content.split('\n').length} 行]\n${hit.content}`);
467
630
  return;
468
631
  }
469
- // /plan <目标> —— 便捷别名,等价 /workflow plan(跑 plan 工作流:
470
- // 调研 → AskUserQuestion 选择 → 产出 ./PLAN.md)。改写后透传给 pluginRunner。
471
- // 目标里的引号剥掉,避免破坏 workflow 参数 tokenizer("..." 整体当一个位置参数)。
472
- if (text.startsWith('/plan ') || text.trim() === '/plan') {
473
- const goal = text.slice('/plan'.length).trim().replace(/"/g, '');
474
- if (goal.length === 0) {
475
- chat.ephemeralLine('[/plan] 用法:/plan <目标>(= /workflow plan:调研→提问选择→产出 ./PLAN.md)');
632
+ // ⚠️ 这里曾有一个 `/plan` 的硬编码特例(改写成 `/workflow plan`)。
633
+ // 已删 —— `src/plugins/slashFallback.ts` 把它通用化了:`/xxx` 没命中插件
634
+ // 命令时会按「工具 → skill → 工作流目录」继续找,所以 `/plan`、`/research`、
635
+ // `/pptx` 全都自动可用,加一条工作流不用再回来改 TUI。
636
+ // /model —— 列出已配置的基座模型并切换选择器;/model <id> 直接切换
637
+ // /login /logout —— 团队在线模型登录;不登录不影响本机模型(原 /team,改名理由见 loginCommand.ts)。
638
+ if (isLogoutCommand(trimmed)) {
639
+ // A standalone session can retain an old auth file from a previous
640
+ // team run. Only revoke over the network when the credential matches
641
+ // the currently configured server; otherwise just clear it locally.
642
+ const configuredServer = await configService.resolveTeamServerUrl();
643
+ if (configuredServer.value) {
644
+ const credentials = await loadTeamCredentials(configuredServer.value);
645
+ if (credentials)
646
+ await revokeTeamCredentials(credentials);
647
+ else
648
+ await clearTeamCredentials();
649
+ }
650
+ else {
651
+ // No configured server is the standalone boundary. Do not let
652
+ // revokeTeamCredentials() discover and contact a stale auth file.
653
+ await clearTeamCredentials();
654
+ }
655
+ chat.ephemeralLine('[/logout] 已登出并撤销本机设备授权;本地模型配置和 Session 未受影响。');
656
+ return;
657
+ }
658
+ // 发起一次登录尝试。普通用户只使用发行版/配置中的服务端地址。
659
+ const attemptTeamLogin = async (server, sourceNote) => {
660
+ if (sourceNote)
661
+ chat.ephemeralLine(`[/login] ${sourceNote}`);
662
+ try {
663
+ const resolved = server
664
+ ? { value: server, source: 'explicit' }
665
+ : await configService.resolveTeamServerUrl();
666
+ if (!resolved.value)
667
+ throw new Error('KakadeAI 登录服务暂时不可用,请稍后重试');
668
+ const login = await beginTeamLogin(resolved.value, 'minimal-agent TUI');
669
+ chat.ephemeralLine(`[/login] 已打开浏览器授权:${login.authorizeUrl}`);
670
+ await openTeamBrowser(login.authorizeUrl);
671
+ await login.complete();
672
+ chat.ephemeralLine('[/login] 登录完成;使用 /login models 查看在线模型。');
673
+ }
674
+ catch (error) {
675
+ chat.ephemeralLine(`[/login] ${error instanceof Error ? error.message : String(error)}`);
676
+ }
677
+ };
678
+ const loginCommand = parseLoginCommand(trimmed);
679
+ if (loginCommand.matched) {
680
+ if (loginCommand.command === 'help') {
681
+ chat.ephemeralLine(loginHelpText());
682
+ return;
683
+ }
684
+ if (loginCommand.command === 'login') {
685
+ await attemptTeamLogin(loginCommand.server);
686
+ return;
687
+ }
688
+ const configuredServer = await configService.resolveTeamServerUrl();
689
+ const credentials = configuredServer.value
690
+ ? await loadTeamCredentials(configuredServer.value)
691
+ : null;
692
+ if (loginCommand.command === 'models') {
693
+ if (!credentials) {
694
+ chat.ephemeralLine('[/login models] 未登录;当前仅使用本机模型。输入 /login 登录。');
695
+ return;
696
+ }
697
+ try {
698
+ const models = await fetchOnlineModels(credentials);
699
+ chat.ephemeralLine(models.length
700
+ ? models
701
+ .map((model) => `${model.displayName} · ${model.model}${model.isDefault ? ' · 默认' : ''}${model.availability?.reason ? ` · ${model.availability.reason}` : ''}`)
702
+ .join('\n')
703
+ : '没有可用在线模型。');
704
+ }
705
+ catch (error) {
706
+ chat.ephemeralLine(`[/login models] ${error instanceof Error ? error.message : String(error)}`);
707
+ }
708
+ return;
709
+ }
710
+ if (loginCommand.command === 'usage') {
711
+ if (!credentials) {
712
+ chat.ephemeralLine('[/login usage] 未登录。');
713
+ return;
714
+ }
715
+ try {
716
+ const subscription = await fetchTeamSubscription(credentials);
717
+ const usage = await fetchTeamUsage(credentials);
718
+ chat.ephemeralLine(subscription
719
+ ? `[/login usage] ${subscription.planName} · ${subscription.status}\n请求 ${subscription.requestCount}/${subscription.requestLimit} · 输入 ${subscription.inputTokens}/${subscription.inputTokenLimit} · 输出 ${subscription.outputTokens}/${subscription.outputTokenLimit}\n模型记录 ${usage.length} 条`
720
+ : '[/login usage] 当前没有有效订阅。');
721
+ }
722
+ catch (error) {
723
+ chat.ephemeralLine(`[/login usage] ${error instanceof Error ? error.message : String(error)}`);
724
+ }
725
+ return;
726
+ }
727
+ if (loginCommand.command === 'status') {
728
+ if (!credentials) {
729
+ chat.ephemeralLine('[/login status] 未登录;当前仅使用本机模型。输入 /login 登录。');
730
+ }
731
+ else {
732
+ try {
733
+ const online = await fetchOnlineModels(credentials);
734
+ chat.ephemeralLine(`[/login status] 已连接 ${credentials.serverUrl};可用在线模型 ${online.length} 个。/logout 登出。`);
735
+ }
736
+ catch (error) {
737
+ chat.ephemeralLine(`[/login status] 设备凭据存在,但在线服务不可用:${error instanceof Error ? error.message : String(error)};当前使用本机模型。`);
738
+ }
739
+ }
740
+ return;
741
+ }
742
+ if (loginCommand.command === 'tools') {
743
+ const current = (await listSessionSummaries(getWorkingDir())).find((session) => session.id === chat.activeSessionId);
744
+ const value = loginCommand.value;
745
+ if (!value || value === 'list') {
746
+ chat.ephemeralLine(`[/login tools] 当前 Session 类别:${current?.onlineToolCategories?.join(', ') || '未设置(使用服务器模型预设)'}\n可选:workspace web computer subagents integrations\n设置:/login tools workspace,web`);
747
+ }
748
+ else {
749
+ const categories = [
750
+ ...new Set(value.split(/[ ,]+/).filter(Boolean)),
751
+ ];
752
+ const allowed = new Set([
753
+ 'workspace',
754
+ 'web',
755
+ 'computer',
756
+ 'subagents',
757
+ 'integrations',
758
+ ]);
759
+ if (categories.some((category) => !allowed.has(category))) {
760
+ chat.ephemeralLine('[/login tools] 类别无效,可用:workspace web computer subagents integrations');
761
+ return;
762
+ }
763
+ await updateSessionMetadata(getWorkingDir(), chat.activeSessionId, {
764
+ onlineToolCategories: categories,
765
+ });
766
+ chat.ephemeralLine(`[/login tools] 已设置当前 Session 工具类别:${categories.join(', ') || '无'}`);
767
+ }
476
768
  return;
477
769
  }
478
- void chat.submit(`/workflow plan "${goal}"`);
479
- return;
480
770
  }
481
- // /model —— 列出已配置的基座模型并切换选择器;/model <id> 直接切换
482
771
  const modelArgMatch = /^\/model(?:\s+(.+))?$/.exec(trimmed);
483
772
  if (modelArgMatch) {
484
773
  const arg = modelArgMatch[1]?.trim();
485
774
  const models = await configService.models();
486
775
  const enabledModels = models.filter((m) => m.enabled && m.apiKey);
487
- if (enabledModels.length === 0) {
776
+ const configuredServer = await configService.resolveTeamServerUrl();
777
+ const credentials = configuredServer.value
778
+ ? await loadTeamCredentials(configuredServer.value)
779
+ : null;
780
+ const online = credentials
781
+ ? await fetchOnlineModels(credentials).catch((error) => {
782
+ chat.ephemeralLine(`[/model] 在线模型暂时不可用:${error instanceof Error ? error.message : String(error)};仍可选择本机模型。`);
783
+ return [];
784
+ })
785
+ : [];
786
+ const onlinePickerModels = online.map(toPickerModel);
787
+ const pickerModels = [...enabledModels, ...onlinePickerModels];
788
+ if (pickerModels.length === 0) {
488
789
  chat.ephemeralLine('[/model] 尚未配置任何模型,请先通过 Desktop 设置或 /config 添加模型。');
489
790
  return;
490
791
  }
491
792
  if (arg) {
492
793
  // 直接切换到指定模型(支持精确匹配 id 或模糊匹配 displayName/model)
493
- const target = enabledModels.find((m) => m.id === arg || m.model === arg || m.displayName === arg);
794
+ const target = pickerModels.find((m) => m.id === arg || m.model === arg || m.displayName === arg);
494
795
  if (!target) {
495
- chat.ephemeralLine(`[/model] 未找到模型 "${arg}",可用模型:\n${enabledModels.map((m) => ` ${m.id} · ${m.displayName || m.model}`).join('\n')}`);
796
+ chat.ephemeralLine(`[/model] 未找到模型 "${arg}",可用模型:\n${pickerModels.map((m) => ` ${m.id} · ${m.displayName || m.model}`).join('\n')}`);
496
797
  return;
497
798
  }
498
799
  await handleBaseModelSelect(target.id);
@@ -501,7 +802,11 @@ export function App({ provider, initialHistory }) {
501
802
  // 无参数:打开交互选择器
502
803
  const currentSession = (await listSessionSummaries(getWorkingDir())).find((session) => session.id === chat.activeSessionId);
503
804
  const snap = await configService.getSnapshot();
504
- setBaseModelPicker({ models: enabledModels, currentId: currentSession?.modelId ?? snap.config?.baseModelId ?? null });
805
+ const currentRef = currentSession?.preferredModel;
806
+ const currentId = currentRef
807
+ ? legacyModelId(currentRef)
808
+ : (currentSession?.modelId ?? snap.config?.baseModelId ?? null);
809
+ setBaseModelPicker({ models: pickerModels, currentId });
505
810
  return;
506
811
  }
507
812
  // /advisor [help|status|on|off|ask|select] —— 与 Desktop 共用统一配置。
@@ -546,24 +851,40 @@ export function App({ provider, initialHistory }) {
546
851
  if (sub === 'select') {
547
852
  const models = await configService.models();
548
853
  const enabledModels = models.filter((m) => m.enabled && m.apiKey);
549
- if (enabledModels.length === 0) {
854
+ const configuredServer = await configService.resolveTeamServerUrl();
855
+ const credentials = configuredServer.value
856
+ ? await loadTeamCredentials(configuredServer.value)
857
+ : null;
858
+ const online = credentials
859
+ ? await fetchOnlineModels(credentials).catch((error) => {
860
+ chat.ephemeralLine(`[/advisor] 在线顾问模型暂时不可用:${error instanceof Error ? error.message : String(error)};仍可选择本机顾问模型。`);
861
+ return [];
862
+ })
863
+ : [];
864
+ const pickerModels = [...enabledModels, ...online.map(toPickerModel)];
865
+ if (pickerModels.length === 0) {
550
866
  chat.ephemeralLine('[/advisor] 尚未配置任何模型,请先添加模型。');
551
867
  return;
552
868
  }
553
869
  if (note) {
554
870
  // /advisor select <id> 直接指定模型
555
- const target = enabledModels.find((m) => m.id === note || m.model === note || m.displayName === note);
871
+ const target = pickerModels.find((m) => m.id === note || m.model === note || m.displayName === note);
556
872
  if (!target) {
557
- chat.ephemeralLine(`[/advisor] 未找到模型 "${note}",可用模型:\n${enabledModels.map((m) => ` ${m.id} · ${m.displayName || m.model}`).join('\n')}`);
873
+ chat.ephemeralLine(`[/advisor] 未找到模型 "${note}",可用模型:\n${pickerModels.map((m) => ` ${m.id} · ${m.displayName || m.model}`).join('\n')}`);
558
874
  return;
559
875
  }
560
- await configService.savePatch({ advisor: { modelId: target.id, enabled: true } });
876
+ await configService.savePatch({
877
+ advisor: { modelId: target.id, enabled: true },
878
+ });
561
879
  chat.ephemeralLine(`[/advisor] 已设置顾问模型为 ${target.displayName || target.model}(${formatProviderName(target.apiFormat)})。`);
562
880
  }
563
881
  else {
564
882
  // 无参数:打开交互选择器(含"关闭"选项)
565
883
  const snap = await configService.getSnapshot();
566
- setAdvisorModelPicker({ models: enabledModels, currentId: snap.config?.advisor?.modelId ?? null });
884
+ setAdvisorModelPicker({
885
+ models: pickerModels,
886
+ currentId: snap.config?.advisor?.modelId ?? null,
887
+ });
567
888
  }
568
889
  return;
569
890
  }
@@ -603,7 +924,6 @@ export function App({ provider, initialHistory }) {
603
924
  chat.activeSessionId,
604
925
  chat.submit,
605
926
  chat.runManualAdvisor,
606
- chat.setProvider,
607
927
  chat.computerUseMode,
608
928
  chat.setComputerUseMode,
609
929
  chat.stopComputerUse,
@@ -613,7 +933,6 @@ export function App({ provider, initialHistory }) {
613
933
  handleSessionCreate,
614
934
  openWorkspacePicker,
615
935
  handleBaseModelSelect,
616
- handleAdvisorModelSelect,
617
936
  ]);
618
937
  // banner 改作为 Static items[0] 走 MessageList。原因:Ink 5 的 Static 约定
619
938
  // 它必须是兄弟节点中第一个,否则 above-sibling 会跟 Static commit 一起被重打
@@ -621,7 +940,7 @@ export function App({ provider, initialHistory }) {
621
940
  // 使用 getCurrentProvider() 获取最新 provider(/model 切换后实时显示)
622
941
  const currentProvider = chat.getCurrentProvider();
623
942
  const bannerText = `minimal-agent · ${currentProvider.name}/${currentProvider.model} · /model 切模型 · /computer 控制桌面 · /copy 复制回复 · /paste-image 添加图片 · /new 清空 · /compact 压缩 · Ctrl+C 中断`;
624
- return (_jsxs(Box, { flexDirection: "column", children: [_jsx(MessageList, { history: deferredHistory, compactGeneration: chat.compactGeneration, bannerText: bannerText, terminalRows: terminalRows }), _jsxs(Box, { flexDirection: "column", width: Math.max(1, terminalCols - 1), children: [_jsx(LiveArea, { progressStage: chat.progressStage, reasoningPreview: chat.reasoningPreview, streamingText: chat.streamingText, runningTools: chat.runningTools, pluginProgress: chat.pluginProgress, transientError: chat.transientError, terminalCols: terminalCols, terminalRows: terminalRows }), _jsx(QueuedMessagesBanner, { items: chat.queuedItems }), chat.pendingComputerIntervention && (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: theme.warning, paddingX: 1, marginBottom: 1, children: [_jsxs(Text, { color: theme.warning, children: ["\u9700\u8981\u4EBA\u5DE5\u64CD\u4F5C\uFF1A", chat.pendingComputerIntervention.sanitizedSummary] }), _jsx(Text, { dimColor: true, children: "\u8BF7\u76F4\u63A5\u5728\u76EE\u6807\u5E94\u7528\u4E2D\u5904\u7406\uFF1B\u654F\u611F\u5185\u5BB9\u4E0D\u4F1A\u8FDB\u5165\u7EC8\u7AEF\u6216\u6A21\u578B\u3002\u5B8C\u6210\u540E\u8F93\u5165 /computer resume\uFF0C\u53D6\u6D88\u8F93\u5165 /computer cancel\u3002" })] })), chat.error && (_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { color: theme.error, children: ["\u26A0 ", chat.error] }) })), chat.interrupted && (_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { color: theme.warning, children: "\u26A1 \u64CD\u4F5C\u88AB\u7528\u6237\u4E2D\u65AD\uFF0C\u7B49\u5F85\u65B0\u7684\u4EFB\u52A1\u8F93\u5165..." }), _jsx(Text, { dimColor: true, children: " \u8C03\u6574\u4E0A\u4E00\u6B21\u8BA1\u5212\uFF1A\u76F4\u63A5\u8BF4\u8C03\u6574\u5185\u5BB9 / \u91CD\u65B0\u8DD1 /plan \u76EE\u6807 / \u65B0\u4EFB\u52A1\u76F4\u63A5\u8BF4" })] })), configMenuOpen ? (_jsx(ConfigMenu, { mode: "reconfigure", onDone: () => setConfigMenuOpen(false) })) : baseModelPicker ? (_jsx(ModelPicker, { models: baseModelPicker.models, currentModelId: baseModelPicker.currentId, title: "\u9009\u62E9\u57FA\u5EA7\u6A21\u578B", onSelect: handleBaseModelSelect, onCancel: () => setBaseModelPicker(null) })) : advisorModelPicker ? (_jsx(ModelPicker, { models: advisorModelPicker.models, currentModelId: advisorModelPicker.currentId, title: "\u9009\u62E9\u987E\u95EE\u6A21\u578B", nullOptionLabel: "\u25CB \u4E0D\u4F7F\u7528\u987E\u95EE\u6A21\u578B", onSelect: handleAdvisorModelSelect, onCancel: () => setAdvisorModelPicker(null) })) : workspacePicker ? (_jsx(WorkspacePicker, { workspaces: workspacePicker, currentPath: getWorkingDir(), currentSessionId: chat.activeSessionId, onSelect: handleWorkspaceSelect, onCancel: () => setWorkspacePicker(null) })) : sessionPicker ? (_jsx(SessionPicker, { sessions: sessionPicker, activeSessionId: chat.activeSessionId, onSelect: handleSessionSelect, onCreate: handleSessionCreate, onCancel: () => setSessionPicker(null) })) : chat.pendingAsk ? (_jsx(AskQuestion, { questions: chat.pendingAsk, source: chat.pendingAskSource, queuedCount: chat.pendingAskQueueCount, onAnswer: chat.answerAsk, onCancel: chat.cancelAsk })) : (
943
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(MessageList, { history: deferredHistory, compactGeneration: chat.compactGeneration, bannerText: bannerText, terminalRows: terminalRows }), _jsxs(Box, { flexDirection: "column", width: Math.max(1, terminalCols - 1), children: [_jsx(LiveArea, { progressStage: chat.progressStage, reasoningPreview: chat.reasoningPreview, streamingText: chat.streamingText, runningTools: chat.runningTools, pluginProgress: chat.pluginProgress, transientError: chat.transientError, terminalCols: terminalCols, terminalRows: terminalRows }), _jsx(QueuedMessagesBanner, { items: chat.queuedItems }), chat.pendingComputerIntervention && (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: theme.warning, paddingX: 1, marginBottom: 1, children: [_jsxs(Text, { color: theme.warning, children: ["\u9700\u8981\u4EBA\u5DE5\u64CD\u4F5C\uFF1A", chat.pendingComputerIntervention.sanitizedSummary] }), _jsx(Text, { dimColor: true, children: "\u8BF7\u76F4\u63A5\u5728\u76EE\u6807\u5E94\u7528\u4E2D\u5904\u7406\uFF1B\u654F\u611F\u5185\u5BB9\u4E0D\u4F1A\u8FDB\u5165\u7EC8\u7AEF\u6216\u6A21\u578B\u3002\u5B8C\u6210\u540E\u8F93\u5165 /computer resume\uFF0C\u53D6\u6D88\u8F93\u5165 /computer cancel\u3002" })] })), chat.error && (_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { color: theme.error, children: ["\u26A0 ", chat.error] }) })), chat.interrupted && (_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { color: theme.warning, children: "\u26A1 \u64CD\u4F5C\u88AB\u7528\u6237\u4E2D\u65AD\uFF0C\u7B49\u5F85\u65B0\u7684\u4EFB\u52A1\u8F93\u5165..." }), _jsxs(Text, { dimColor: true, children: [' ', "\u8C03\u6574\u4E0A\u4E00\u6B21\u8BA1\u5212\uFF1A\u76F4\u63A5\u8BF4\u8C03\u6574\u5185\u5BB9 / \u91CD\u65B0\u8DD1 /plan \u76EE\u6807 / \u65B0\u4EFB\u52A1\u76F4\u63A5\u8BF4"] })] })), configMenuOpen ? (_jsx(ConfigMenu, { mode: "reconfigure", onDone: () => setConfigMenuOpen(false) })) : baseModelPicker ? (_jsx(ModelPicker, { models: baseModelPicker.models, currentModelId: baseModelPicker.currentId, title: "\u9009\u62E9\u57FA\u5EA7\u6A21\u578B", onSelect: handleBaseModelSelect, onCancel: () => setBaseModelPicker(null) })) : advisorModelPicker ? (_jsx(ModelPicker, { models: advisorModelPicker.models, currentModelId: advisorModelPicker.currentId, title: "\u9009\u62E9\u987E\u95EE\u6A21\u578B", nullOptionLabel: "\u25CB \u4E0D\u4F7F\u7528\u987E\u95EE\u6A21\u578B", onSelect: handleAdvisorModelSelect, onCancel: () => setAdvisorModelPicker(null) })) : workspacePicker ? (_jsx(WorkspacePicker, { workspaces: workspacePicker, currentPath: getWorkingDir(), currentSessionId: chat.activeSessionId, onSelect: handleWorkspaceSelect, onCancel: () => setWorkspacePicker(null) })) : sessionPicker ? (_jsx(SessionPicker, { sessions: sessionPicker, activeSessionId: chat.activeSessionId, onSelect: handleSessionSelect, onCreate: handleSessionCreate, onCancel: () => setSessionPicker(null) })) : chat.pendingAsk ? (_jsx(AskQuestion, { questions: chat.pendingAsk, source: chat.pendingAskSource, queuedCount: chat.pendingAskQueueCount, onAnswer: chat.answerAsk, onCancel: chat.cancelAsk })) : (
625
944
  /* handleSubmit 包装做 slash 命令拦截,非命令透传 chat.submit */
626
945
  _jsx(InputBox, { onSubmit: handleSubmit, disabled: chat.isLoading && !chat.pendingComputerIntervention, onAbort: chat.abort, onClear: handleClear, onCompact: chat.compactNow, onWorkspaces: openWorkspacePicker })), _jsx(StatusLine, { provider: currentProvider, history: chat.history, pluginProgress: chat.pluginProgress, contextUsage: chat.contextUsage })] })] }));
627
946
  }