cli-jaw 2.1.1 → 2.1.2

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 (355) hide show
  1. package/README.ja.md +8 -6
  2. package/README.ko.md +8 -6
  3. package/README.md +12 -6
  4. package/README.zh-CN.md +8 -6
  5. package/dist/bin/cli-jaw.js +5 -1
  6. package/dist/bin/cli-jaw.js.map +1 -1
  7. package/dist/bin/commands/browser.js +1 -1
  8. package/dist/bin/commands/browser.js.map +1 -1
  9. package/dist/bin/commands/chat.js +98 -58
  10. package/dist/bin/commands/chat.js.map +1 -1
  11. package/dist/bin/commands/dispatch.js +130 -5
  12. package/dist/bin/commands/dispatch.js.map +1 -1
  13. package/dist/bin/commands/goal.js +18 -6
  14. package/dist/bin/commands/goal.js.map +1 -1
  15. package/dist/bin/commands/orchestrate.js.map +1 -1
  16. package/dist/bin/commands/tui/fullscreen-mode.js +237 -0
  17. package/dist/bin/commands/tui/fullscreen-mode.js.map +1 -0
  18. package/dist/bin/commands/tui/input-handler.js +139 -52
  19. package/dist/bin/commands/tui/input-handler.js.map +1 -1
  20. package/dist/bin/commands/tui/overlays.js +177 -70
  21. package/dist/bin/commands/tui/overlays.js.map +1 -1
  22. package/dist/bin/commands/tui/renderer.js +70 -20
  23. package/dist/bin/commands/tui/renderer.js.map +1 -1
  24. package/dist/bin/commands/tui/simple-mode.js +1 -1
  25. package/dist/bin/commands/tui/simple-mode.js.map +1 -1
  26. package/dist/bin/commands/tui/tui-io.js +8 -0
  27. package/dist/bin/commands/tui/tui-io.js.map +1 -0
  28. package/dist/bin/commands/tui/types.js +9 -0
  29. package/dist/bin/commands/tui/types.js.map +1 -1
  30. package/dist/bin/commands/tui/ws-handler.js +115 -23
  31. package/dist/bin/commands/tui/ws-handler.js.map +1 -1
  32. package/dist/bin/commands/worker.js +159 -0
  33. package/dist/bin/commands/worker.js.map +1 -0
  34. package/dist/bin/postinstall.js +0 -76
  35. package/dist/bin/postinstall.js.map +1 -1
  36. package/dist/lib/mcp/format-converters.js +21 -2
  37. package/dist/lib/mcp/format-converters.js.map +1 -1
  38. package/dist/lib/mcp/mcp-registry.js +75 -0
  39. package/dist/lib/mcp/mcp-registry.js.map +1 -0
  40. package/dist/lib/stt.js +1 -1
  41. package/dist/lib/stt.js.map +1 -1
  42. package/dist/scripts/fresh-install-smoke.js +1 -1
  43. package/dist/scripts/fresh-install-smoke.js.map +1 -1
  44. package/dist/server.js +27 -6
  45. package/dist/server.js.map +1 -1
  46. package/dist/src/agent/args.js +33 -1
  47. package/dist/src/agent/args.js.map +1 -1
  48. package/dist/src/agent/claude-e-runtime.js +1 -1
  49. package/dist/src/agent/claude-e-runtime.js.map +1 -1
  50. package/dist/src/agent/codex-app-client.js +1 -1
  51. package/dist/src/agent/error-classifier.js +6 -1
  52. package/dist/src/agent/error-classifier.js.map +1 -1
  53. package/dist/src/agent/events/claude.js +1 -0
  54. package/dist/src/agent/events/claude.js.map +1 -1
  55. package/dist/src/agent/events/codex.js +0 -44
  56. package/dist/src/agent/events/codex.js.map +1 -1
  57. package/dist/src/agent/events/helpers.js +52 -5
  58. package/dist/src/agent/events/helpers.js.map +1 -1
  59. package/dist/src/agent/events/opencode.js +6 -2
  60. package/dist/src/agent/events/opencode.js.map +1 -1
  61. package/dist/src/agent/events/summary.js +3 -2
  62. package/dist/src/agent/events/summary.js.map +1 -1
  63. package/dist/src/agent/events/tool-labels.js +8 -5
  64. package/dist/src/agent/events/tool-labels.js.map +1 -1
  65. package/dist/src/agent/kiro-auth.js +213 -0
  66. package/dist/src/agent/kiro-auth.js.map +1 -0
  67. package/dist/src/agent/kiro-models.js +79 -0
  68. package/dist/src/agent/kiro-models.js.map +1 -0
  69. package/dist/src/agent/kiro-runtime.js +306 -0
  70. package/dist/src/agent/kiro-runtime.js.map +1 -0
  71. package/dist/src/agent/lifecycle-handler.js +190 -12
  72. package/dist/src/agent/lifecycle-handler.js.map +1 -1
  73. package/dist/src/agent/memory-flush-controller.js +1 -3
  74. package/dist/src/agent/memory-flush-controller.js.map +1 -1
  75. package/dist/src/agent/resume-classifier.js +18 -1
  76. package/dist/src/agent/resume-classifier.js.map +1 -1
  77. package/dist/src/agent/session-persistence.js +1 -1
  78. package/dist/src/agent/session-persistence.js.map +1 -1
  79. package/dist/src/agent/smoke-detector.js +3 -0
  80. package/dist/src/agent/smoke-detector.js.map +1 -1
  81. package/dist/src/agent/spawn/queue.js +10 -4
  82. package/dist/src/agent/spawn/queue.js.map +1 -1
  83. package/dist/src/agent/spawn/resume.js +6 -1
  84. package/dist/src/agent/spawn/resume.js.map +1 -1
  85. package/dist/src/agent/spawn-env.js +1 -1
  86. package/dist/src/agent/spawn-env.js.map +1 -1
  87. package/dist/src/agent/spawn.js +188 -28
  88. package/dist/src/agent/spawn.js.map +1 -1
  89. package/dist/src/browser/web-ai/grok-live.js +2 -0
  90. package/dist/src/browser/web-ai/grok-live.js.map +1 -1
  91. package/dist/src/cli/claude-models.js +2 -2
  92. package/dist/src/cli/claude-models.js.map +1 -1
  93. package/dist/src/cli/commands.js +3 -2
  94. package/dist/src/cli/commands.js.map +1 -1
  95. package/dist/src/cli/handlers-runtime.js +2 -0
  96. package/dist/src/cli/handlers-runtime.js.map +1 -1
  97. package/dist/src/cli/handlers-workflows.js +9 -4
  98. package/dist/src/cli/handlers-workflows.js.map +1 -1
  99. package/dist/src/cli/handlers.js +47 -7
  100. package/dist/src/cli/handlers.js.map +1 -1
  101. package/dist/src/cli/readiness.js +17 -1
  102. package/dist/src/cli/readiness.js.map +1 -1
  103. package/dist/src/cli/registry-live.js +17 -0
  104. package/dist/src/cli/registry-live.js.map +1 -0
  105. package/dist/src/cli/registry.js +44 -3
  106. package/dist/src/cli/registry.js.map +1 -1
  107. package/dist/src/cli/tui/composer.js +135 -5
  108. package/dist/src/cli/tui/composer.js.map +1 -1
  109. package/dist/src/cli/tui/diffview.js +41 -0
  110. package/dist/src/cli/tui/diffview.js.map +1 -0
  111. package/dist/src/cli/tui/editor.js +45 -0
  112. package/dist/src/cli/tui/editor.js.map +1 -0
  113. package/dist/src/cli/tui/file-mention.js +78 -0
  114. package/dist/src/cli/tui/file-mention.js.map +1 -0
  115. package/dist/src/cli/tui/highlight.js +82 -0
  116. package/dist/src/cli/tui/highlight.js.map +1 -0
  117. package/dist/src/cli/tui/keymap.js +21 -0
  118. package/dist/src/cli/tui/keymap.js.map +1 -1
  119. package/dist/src/cli/tui/markdown.js +124 -0
  120. package/dist/src/cli/tui/markdown.js.map +1 -0
  121. package/dist/src/cli/tui/mode.js +26 -0
  122. package/dist/src/cli/tui/mode.js.map +1 -0
  123. package/dist/src/cli/tui/overlay.js +121 -98
  124. package/dist/src/cli/tui/overlay.js.map +1 -1
  125. package/dist/src/cli/tui/render/frame.js +72 -0
  126. package/dist/src/cli/tui/render/frame.js.map +1 -0
  127. package/dist/src/cli/tui/render/layout.js +22 -0
  128. package/dist/src/cli/tui/render/layout.js.map +1 -0
  129. package/dist/src/cli/tui/render/mouse.js +25 -0
  130. package/dist/src/cli/tui/render/mouse.js.map +1 -0
  131. package/dist/src/cli/tui/render/scheduler.js +37 -0
  132. package/dist/src/cli/tui/render/scheduler.js.map +1 -0
  133. package/dist/src/cli/tui/render/viewport.js +82 -0
  134. package/dist/src/cli/tui/render/viewport.js.map +1 -0
  135. package/dist/src/cli/tui/renderers.js +37 -0
  136. package/dist/src/cli/tui/renderers.js.map +1 -1
  137. package/dist/src/cli/tui/stream.js +48 -0
  138. package/dist/src/cli/tui/stream.js.map +1 -0
  139. package/dist/src/cli/tui/text-buffer.js +143 -0
  140. package/dist/src/cli/tui/text-buffer.js.map +1 -0
  141. package/dist/src/cli/tui/theme.js +128 -0
  142. package/dist/src/cli/tui/theme.js.map +1 -0
  143. package/dist/src/cli/tui/transcript.js +4 -0
  144. package/dist/src/cli/tui/transcript.js.map +1 -1
  145. package/dist/src/command-contract/help-renderer.js +1 -1
  146. package/dist/src/command-contract/help-renderer.js.map +1 -1
  147. package/dist/src/core/cli-detection.js +14 -0
  148. package/dist/src/core/cli-detection.js.map +1 -1
  149. package/dist/src/core/config.js +5 -0
  150. package/dist/src/core/config.js.map +1 -1
  151. package/dist/src/core/db.js +7 -0
  152. package/dist/src/core/db.js.map +1 -1
  153. package/dist/src/core/employees.js +2 -2
  154. package/dist/src/core/employees.js.map +1 -1
  155. package/dist/src/discord/bot.js.map +1 -1
  156. package/dist/src/discord/discord-file.js +1 -1
  157. package/dist/src/discord/discord-file.js.map +1 -1
  158. package/dist/src/discord/send-only-client.js +1 -3
  159. package/dist/src/discord/send-only-client.js.map +1 -1
  160. package/dist/src/goal/heartbeat.js +30 -7
  161. package/dist/src/goal/heartbeat.js.map +1 -1
  162. package/dist/src/goal/store.js +6 -2
  163. package/dist/src/goal/store.js.map +1 -1
  164. package/dist/src/ide/diff.js +37 -0
  165. package/dist/src/ide/diff.js.map +1 -1
  166. package/dist/src/manager/launchd-service.js +1 -1
  167. package/dist/src/manager/launchd-service.js.map +1 -1
  168. package/dist/src/manager/lifecycle-helpers.js +14 -0
  169. package/dist/src/manager/lifecycle-helpers.js.map +1 -1
  170. package/dist/src/manager/lifecycle.js +49 -4
  171. package/dist/src/manager/lifecycle.js.map +1 -1
  172. package/dist/src/manager/notes/routes.js +0 -31
  173. package/dist/src/manager/notes/routes.js.map +1 -1
  174. package/dist/src/manager/notes/ws.js.map +1 -1
  175. package/dist/src/manager/registry.js.map +1 -1
  176. package/dist/src/manager/routes/dashboard-memory.js.map +1 -1
  177. package/dist/src/manager/scan.js +36 -1
  178. package/dist/src/manager/scan.js.map +1 -1
  179. package/dist/src/manager/server.js +21 -2
  180. package/dist/src/manager/server.js.map +1 -1
  181. package/dist/src/manager/systemd-service.js +1 -1
  182. package/dist/src/manager/systemd-service.js.map +1 -1
  183. package/dist/src/memory/keyword-expand.js +0 -187
  184. package/dist/src/memory/keyword-expand.js.map +1 -1
  185. package/dist/src/memory/runtime.js +2 -2
  186. package/dist/src/memory/runtime.js.map +1 -1
  187. package/dist/src/memory/shared.js.map +1 -1
  188. package/dist/src/orchestrator/collect.js +3 -2
  189. package/dist/src/orchestrator/collect.js.map +1 -1
  190. package/dist/src/orchestrator/distribute.js +7 -1
  191. package/dist/src/orchestrator/distribute.js.map +1 -1
  192. package/dist/src/orchestrator/friction.js +59 -0
  193. package/dist/src/orchestrator/friction.js.map +1 -0
  194. package/dist/src/orchestrator/pipeline.js +88 -45
  195. package/dist/src/orchestrator/pipeline.js.map +1 -1
  196. package/dist/src/orchestrator/sanitize.js +19 -0
  197. package/dist/src/orchestrator/sanitize.js.map +1 -0
  198. package/dist/src/orchestrator/seed.js +50 -0
  199. package/dist/src/orchestrator/seed.js.map +1 -0
  200. package/dist/src/orchestrator/state-machine.js +206 -74
  201. package/dist/src/orchestrator/state-machine.js.map +1 -1
  202. package/dist/src/orchestrator/worker-monitor.js +1 -1
  203. package/dist/src/orchestrator/worker-monitor.js.map +1 -1
  204. package/dist/src/orchestrator/worker-progress.js +29 -0
  205. package/dist/src/orchestrator/worker-progress.js.map +1 -0
  206. package/dist/src/orchestrator/worker-registry.js +63 -2
  207. package/dist/src/orchestrator/worker-registry.js.map +1 -1
  208. package/dist/src/prompt/builder.js +19 -29
  209. package/dist/src/prompt/builder.js.map +1 -1
  210. package/dist/src/prompt/templates/a1-system.md +40 -5
  211. package/dist/src/prompt/templates/control-system.md +2 -2
  212. package/dist/src/prompt/templates/employee.md +4 -1
  213. package/dist/src/prompt/templates/orchestration.md +23 -8
  214. package/dist/src/routes/employees.js +4 -4
  215. package/dist/src/routes/employees.js.map +1 -1
  216. package/dist/src/routes/goal.js +11 -3
  217. package/dist/src/routes/goal.js.map +1 -1
  218. package/dist/src/routes/heartbeat.js +1 -1
  219. package/dist/src/routes/heartbeat.js.map +1 -1
  220. package/dist/src/routes/i18n.js +1 -1
  221. package/dist/src/routes/i18n.js.map +1 -1
  222. package/dist/src/routes/jaw-memory.js +1 -1
  223. package/dist/src/routes/jaw-memory.js.map +1 -1
  224. package/dist/src/routes/memory.js.map +1 -1
  225. package/dist/src/routes/messaging.js.map +1 -1
  226. package/dist/src/routes/orchestrate.js +265 -116
  227. package/dist/src/routes/orchestrate.js.map +1 -1
  228. package/dist/src/routes/quota-agy-reverse.js +0 -5
  229. package/dist/src/routes/quota-agy-reverse.js.map +1 -1
  230. package/dist/src/routes/quota-kiro-reverse.js +187 -0
  231. package/dist/src/routes/quota-kiro-reverse.js.map +1 -0
  232. package/dist/src/routes/settings.js +31 -2
  233. package/dist/src/routes/settings.js.map +1 -1
  234. package/dist/src/routes/skills.js.map +1 -1
  235. package/dist/src/security/security-audit-log.js.map +1 -1
  236. package/dist/src/shared/shell-command-display.js +51 -0
  237. package/dist/src/shared/shell-command-display.js.map +1 -0
  238. package/dist/src/telegram/bot.js.map +1 -1
  239. package/dist/src/trace/store.js +32 -0
  240. package/dist/src/trace/store.js.map +1 -1
  241. package/dist/src/types/cli-engine.js +1 -0
  242. package/dist/src/types/cli-engine.js.map +1 -1
  243. package/dist/src/workflows/employee-boundary.js +7 -7
  244. package/dist/src/workflows/employee-boundary.js.map +1 -1
  245. package/dist/src/workflows/handoff.js +16 -16
  246. package/dist/src/workflows/handoff.js.map +1 -1
  247. package/dist/src/workflows/scope-sandbox.js +46 -0
  248. package/dist/src/workflows/scope-sandbox.js.map +1 -0
  249. package/package.json +1 -1
  250. package/public/assets/providers/kiro-color.svg +15 -0
  251. package/public/assets/providers/kiro.svg +14 -0
  252. package/public/css/modals.css +79 -0
  253. package/public/css/sidebar.css +85 -0
  254. package/public/css/variables.css +2 -2
  255. package/public/dist/assets/{Agent-CIUGaUVn.js → Agent-DkH7eoHd.js} +1 -1
  256. package/public/dist/assets/{DocPanel-C1pGgE-S.js → DocPanel-BU16GUlB.js} +1 -1
  257. package/public/dist/assets/DocPanel-gU-WkgyA.css +1 -0
  258. package/public/dist/assets/Employees-F0ssNuO-.js +1 -0
  259. package/public/dist/assets/Heartbeat-C3JS6gkF.js +1 -0
  260. package/public/dist/assets/Mcp-_Yq4N3Sk.js +4 -0
  261. package/public/dist/assets/{Memory-BgN8djV4.js → Memory-C-EQubN2.js} +1 -1
  262. package/public/dist/assets/{ModelProvider-DHQ1Zvw0.js → ModelProvider-BD2KrypI.js} +1 -1
  263. package/public/dist/assets/agent-meta-B1098B_a.js +1 -0
  264. package/public/dist/assets/app-ByHYOMZE.js +48 -0
  265. package/public/dist/assets/app-CYdhP6Vh.css +1 -0
  266. package/public/dist/assets/constants-s2UJodER.js +1 -0
  267. package/public/dist/assets/{employees-DiNLzEXS.js → employees-_A-p_bZg.js} +7 -7
  268. package/public/dist/assets/idb-cache-0LNMskFB.js +1 -0
  269. package/public/dist/assets/idb-cache-5H89a4l8.js +1 -0
  270. package/public/dist/assets/{manager-DyrwJLZr.css → manager-B2qEQRxN.css} +1 -1
  271. package/public/dist/assets/manager-CR9BA-wO.js +12 -0
  272. package/public/dist/assets/memory-D1RKYvyu.js +1 -0
  273. package/public/dist/assets/{memory-B_nn0A4v.js → memory-D9AUn8fG.js} +9 -9
  274. package/public/dist/assets/{provider-icons-XEfJPGTe.js → provider-icons-CVVK5xUP.js} +35 -6
  275. package/public/dist/assets/{render-CgDEBoCX.js → render-DFBujF8n.js} +4 -4
  276. package/public/dist/assets/settings-B4ZkeaU-.js +1 -0
  277. package/public/dist/assets/settings-D9jTceN0.js +151 -0
  278. package/public/dist/assets/sidebar-DPPRNiTc.js +48 -0
  279. package/public/dist/assets/skills-8nHJkv-r.js +1 -0
  280. package/public/dist/assets/{skills-COa4iSwL.js → skills-BDVLIrVT.js} +6 -6
  281. package/public/dist/assets/{slash-commands-C_ePvrPi.js → slash-commands-C5da3q1p.js} +1 -1
  282. package/public/dist/assets/slash-commands-RJWO8wJZ.js +1 -0
  283. package/public/dist/assets/{trace-drawer-CY4z_Ie8.js → trace-drawer-5kqBzFMk.js} +1 -1
  284. package/public/dist/assets/ui-Crnp79bG.js +142 -0
  285. package/public/dist/assets/ui-HtSKByR3.js +1 -0
  286. package/public/dist/index.html +113 -86
  287. package/public/dist/manager/index.html +2 -2
  288. package/public/index.html +111 -84
  289. package/public/js/constants.ts +30 -7
  290. package/public/js/features/chat-search.ts +5 -1
  291. package/public/js/features/employees.ts +7 -2
  292. package/public/js/features/idb-cache.ts +4 -0
  293. package/public/js/features/message-history.ts +55 -7
  294. package/public/js/features/pending-queue.ts +8 -2
  295. package/public/js/features/process-block.ts +32 -17
  296. package/public/js/features/process-log-adapter.ts +11 -2
  297. package/public/js/features/settings-cli-status-render.ts +163 -0
  298. package/public/js/features/settings-cli-status.ts +130 -185
  299. package/public/js/features/settings-core.ts +5 -1
  300. package/public/js/features/settings-mcp.ts +513 -7
  301. package/public/js/features/settings.ts +1 -1
  302. package/public/js/features/tool-ui.ts +18 -4
  303. package/public/js/features/transport-status-row.ts +3 -0
  304. package/public/js/main.ts +3 -0
  305. package/public/js/preview-parent-origin.ts +14 -0
  306. package/public/js/provider-icons.ts +6 -1
  307. package/public/js/render/file-links.ts +10 -2
  308. package/public/js/ui.ts +5 -2
  309. package/public/js/virtual-scroll.ts +19 -0
  310. package/public/js/ws.ts +133 -8
  311. package/public/locales/en.json +8 -2
  312. package/public/locales/ja.json +8 -2
  313. package/public/locales/ko.json +8 -2
  314. package/public/locales/zh.json +8 -2
  315. package/public/manager/src/App.tsx +13 -70
  316. package/public/manager/src/InstancePreview.tsx +36 -11
  317. package/public/manager/src/SidebarRailRouter.tsx +1 -1
  318. package/public/manager/src/doc-panel/DocPanel.tsx +14 -1
  319. package/public/manager/src/doc-panel/doc-panel.css +16 -0
  320. package/public/manager/src/hooks/useInstanceMessageEvents.ts +4 -15
  321. package/public/manager/src/manager-components.css +1 -1
  322. package/public/manager/src/manager-polish.css +1 -1
  323. package/public/manager/src/manager-shortcut-runner.ts +107 -0
  324. package/public/manager/src/manager-shortcuts.ts +15 -0
  325. package/public/manager/src/panels/desktop-bridge.ts +2 -0
  326. package/public/manager/src/settings/SettingsSidebar.tsx +1 -1
  327. package/public/manager/src/settings/components/sidebar-filter.ts +2 -0
  328. package/public/manager/src/settings/pages/Mcp.tsx +311 -43
  329. package/public/manager/src/settings/pages/components/McpServerCard.tsx +89 -55
  330. package/public/manager/src/settings/pages/components/agent/agent-meta.ts +29 -6
  331. package/public/manager/src/settings/pages/components/employees-helpers.ts +1 -0
  332. package/public/manager/src/settings/pages/components/heartbeat-helpers.ts +1 -0
  333. package/public/manager/src/settings/pages/mcp-helpers.ts +54 -12
  334. package/public/manager/src/settings/types.ts +1 -0
  335. package/public/manager/src/types.ts +2 -1
  336. package/scripts/fresh-install-smoke.ts +1 -1
  337. package/public/dist/assets/DocPanel-CL1scIfq.css +0 -1
  338. package/public/dist/assets/Employees-BL9MAzzx.js +0 -1
  339. package/public/dist/assets/Heartbeat-D64JCg4t.js +0 -1
  340. package/public/dist/assets/Mcp-wYwJA_61.js +0 -3
  341. package/public/dist/assets/agent-meta-BhEbjy4P.js +0 -1
  342. package/public/dist/assets/app-2Rz848bQ.js +0 -48
  343. package/public/dist/assets/app-BW-Xz2p6.css +0 -1
  344. package/public/dist/assets/constants-ahKI_aEG.js +0 -1
  345. package/public/dist/assets/idb-cache-BnZfG5FD.js +0 -1
  346. package/public/dist/assets/idb-cache-CZ3JdK8r.js +0 -1
  347. package/public/dist/assets/manager-CfyZloIP.js +0 -12
  348. package/public/dist/assets/memory-CCjNFWmO.js +0 -1
  349. package/public/dist/assets/settings-CY_6tGuS.js +0 -1
  350. package/public/dist/assets/settings-DWW4GzNc.js +0 -66
  351. package/public/dist/assets/sidebar-DQKE5IA1.js +0 -23
  352. package/public/dist/assets/skills-DYTlqoke.js +0 -1
  353. package/public/dist/assets/slash-commands-D7CU5oso.js +0 -1
  354. package/public/dist/assets/ui-Car1OUvV.js +0 -1
  355. package/public/dist/assets/ui-DK_9ndj0.js +0 -140
@@ -6,63 +6,31 @@ import { state } from '../state.js';
6
6
  import { ICONS } from '../icons.js';
7
7
  import { providerIcon, providerLabel } from '../provider-icons.js';
8
8
  import type { QuotaEntry } from './settings-types.js';
9
+ import {
10
+ buildAccountParts,
11
+ normalizeQuotaWindowLabel,
12
+ QUOTA_CUSTOM_MSG,
13
+ QUOTA_HIDDEN_CLIS,
14
+ QUOTA_SETUP_HINTS,
15
+ renderQuotaSetupBox,
16
+ renderSetupHelpMark,
17
+ } from './settings-cli-status-render.js';
18
+
19
+ export { normalizeQuotaWindowLabel } from './settings-cli-status-render.js';
9
20
 
10
21
  const CLI_STATUS_INTERVAL_VALUES = new Set([0, 600, 1800]);
11
22
  const DEFAULT_CLI_STATUS_INTERVAL_SEC = 0;
12
23
  /** Defer heavy /api/quota so chat/history APIs win on initial page load. */
13
24
  const QUOTA_LOAD_DEFER_MS = 2000;
25
+ const CLI_STATUS_REFRESH_DONE_CLEAR_MS = 4000;
14
26
 
15
- const QUOTA_HIDDEN_CLIS = new Set(['ai-e', 'codex-app']);
16
- const QUOTA_CUSTOM_MSG: Record<string, string> = {
17
- claude: 'Currently subscribed, by June with credit',
18
- };
19
-
20
- type QuotaSetupHint = {
21
- title: string;
22
- commands: string[];
23
- note?: string;
24
- };
25
-
26
- /** Actionable setup when plan quota is not wired yet (quotaCapable=false). */
27
- const QUOTA_SETUP_HINTS: Record<string, QuotaSetupHint> = {
28
- cursor: {
29
- title: 'Enable quota bars (dashboard session)',
30
- commands: [
31
- 'cursor-agent login',
32
- 'export CURSOR_SESSION_TOKEN="<WorkosCursorSessionToken from cursor.com DevTools>"',
33
- 'echo "$CURSOR_SESSION_TOKEN" > ~/.cli-jaw/quota/cursor-session-token && chmod 600 ~/.cli-jaw/quota/cursor-session-token',
34
- ],
35
- },
36
- agy: {
37
- title: 'Enable Gem / Cla quota bars',
38
- commands: [
39
- 'npx antigravity-usage login',
40
- 'npx antigravity-usage --json',
41
- ],
42
- },
43
- grok: {
44
- title: 'Grok Build auth (plan quota not in grok CLI)',
45
- commands: [
46
- 'grok login --oauth',
47
- 'grok models # verify auth',
48
- ],
49
- note: 'Subscription remaining quota: xAI console only. No official grok quota subcommand.',
50
- },
51
- opencode: {
52
- title: 'OpenCode auth + optional plan quota plugin',
53
- commands: [
54
- 'opencode auth login',
55
- 'opencode plugin add @slkiser/opencode-quota',
56
- 'npx @slkiser/opencode-quota show',
57
- ],
58
- note: 'Built-in opencode stats shows session tokens/cost, not subscription limits. opencode-go/* models use the same CLI.',
59
- },
60
- };
27
+ type CliStatusRefreshFeedback = 'idle' | 'refreshing' | 'success' | 'error';
61
28
 
62
29
  let cliStatusTimer: number | null = null;
63
30
  let cliStatusPreviewHooksRegistered = false;
64
31
  let cliStatusLoadSeq = 0;
65
32
  let cliStatusLoadInFlight: Promise<void> | null = null;
33
+ let cliStatusRefreshFeedbackTimer: number | null = null;
66
34
 
67
35
  const CLI_STATUS_COLLAPSED_KEY = 'cliStatusCollapsed';
68
36
 
@@ -84,6 +52,47 @@ function saveCliStatusCollapsed(collapsed: boolean): void {
84
52
  catch { /* ignore */ }
85
53
  }
86
54
 
55
+ function formatCliStatusRefreshTime(date: Date): string {
56
+ return `${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}:${String(date.getSeconds()).padStart(2, '0')}`;
57
+ }
58
+
59
+ function clearCliStatusRefreshFeedbackTimer(): void {
60
+ if (cliStatusRefreshFeedbackTimer == null) return;
61
+ window.clearTimeout(cliStatusRefreshFeedbackTimer);
62
+ cliStatusRefreshFeedbackTimer = null;
63
+ }
64
+
65
+ function setCliStatusRefreshFeedback(kind: CliStatusRefreshFeedback, message = ''): void {
66
+ clearCliStatusRefreshFeedbackTimer();
67
+
68
+ const button = document.getElementById('cliStatusRefreshBtn') as HTMLButtonElement | null;
69
+ const status = document.getElementById('cliStatusRefreshState');
70
+ const label = button?.querySelector<HTMLElement>('.cli-refresh-label');
71
+
72
+ if (button) {
73
+ button.classList.remove('is-refreshing', 'is-success', 'is-error');
74
+ button.disabled = kind === 'refreshing';
75
+ if (kind === 'idle') button.removeAttribute('aria-busy');
76
+ else button.setAttribute('aria-busy', kind === 'refreshing' ? 'true' : 'false');
77
+ if (kind === 'refreshing') button.classList.add('is-refreshing');
78
+ if (kind === 'success') button.classList.add('is-success');
79
+ if (kind === 'error') button.classList.add('is-error');
80
+ }
81
+
82
+ if (label) label.textContent = kind === 'refreshing' ? 'Refreshing...' : 'Refresh';
83
+ if (status) {
84
+ status.textContent = message;
85
+ status.dataset['state'] = kind;
86
+ }
87
+ }
88
+
89
+ function finishCliStatusRefreshFeedback(kind: Exclude<CliStatusRefreshFeedback, 'idle' | 'refreshing'>, message: string): void {
90
+ setCliStatusRefreshFeedback(kind, message);
91
+ cliStatusRefreshFeedbackTimer = window.setTimeout(() => {
92
+ setCliStatusRefreshFeedback('idle');
93
+ }, CLI_STATUS_REFRESH_DONE_CLEAR_MS);
94
+ }
95
+
87
96
  let cliStatusExpanded = !readCliStatusCollapsed();
88
97
 
89
98
  export function isCliStatusExpanded(): boolean {
@@ -172,118 +181,6 @@ export function setCliStatusInterval(value: string): void {
172
181
  scheduleCliStatusRefresh();
173
182
  }
174
183
 
175
- export function normalizeQuotaWindowLabel(cliName: string, label: string): string {
176
- if (cliName === 'gemini') {
177
- if (label === 'Pro' || label === 'P') return 'P';
178
- if (label === 'Flash' || label === 'F') return 'F';
179
- return label;
180
- }
181
-
182
- if (cliName === 'copilot') {
183
- if (label === 'Premium' || label === 'Prem') return '30d';
184
- if (label.includes('plus monthly subscriber quota')) return '30d';
185
- }
186
-
187
- return label
188
- .replace('-hour', 'h')
189
- .replace('-day', 'd')
190
- .replace(' Sonnet', '')
191
- .replace(' Opus', '');
192
- }
193
-
194
- function describeStatusOnlyQuota(cliName: string, q: QuotaEntry): string {
195
- if (q.delegatedProvider) return `Delegates quota/status to ${q.delegatedProvider}`;
196
- const match = q.quotaSource?.match(/^not-exposed-by-(.*?)-cli$/);
197
- if (match) return `Quota not exposed by ${match[1].toUpperCase()} CLI`;
198
- if (q.quotaSource) return q.quotaSource;
199
- return cliName === 'opencode' ? 'Auth/status only' : 'Usage data not exposed by this CLI';
200
- }
201
-
202
- function normalizeAccountToken(value: string): string {
203
- return value.toLowerCase().replace(/^cursor\s+/i, '').trim();
204
- }
205
-
206
- const ACCOUNT_LABEL_SKIP = new Set([
207
- 'auth/status only',
208
- 'google cloud code',
209
- 'runtime-checked',
210
- ]);
211
-
212
- const PROVIDER_ACCOUNT_TYPES = new Set([
213
- 'cursor',
214
- 'antigravity.google',
215
- 'antigravity',
216
- 'max',
217
- 'copilot',
218
- 'gemini',
219
- ]);
220
-
221
- function buildAccountParts(_cliName: string, q: QuotaEntry): string[] {
222
- const account = q.account;
223
- if (!account) return [];
224
-
225
- const parts: string[] = [];
226
- if (account.email) parts.push(account.email);
227
-
228
- const seen = new Set(parts.map(normalizeAccountToken));
229
- for (const value of [account.plan, account.tier]) {
230
- if (!value) continue;
231
- const norm = normalizeAccountToken(value);
232
- if (!norm || ACCOUNT_LABEL_SKIP.has(norm)) continue;
233
- if (PROVIDER_ACCOUNT_TYPES.has(norm)) continue;
234
- if (seen.has(norm)) continue;
235
- seen.add(norm);
236
- parts.push(value);
237
- break;
238
- }
239
-
240
- return parts;
241
- }
242
-
243
- function renderSetupHelpMark(cliName: string, q: QuotaEntry, extraTooltip: string[] = []): string {
244
- const hint = QUOTA_SETUP_HINTS[cliName];
245
- const tooltipParts = [
246
- ...extraTooltip,
247
- ...(hint ? hint.commands : []),
248
- ...(hint?.note ? [hint.note] : []),
249
- ].filter(Boolean);
250
- if (!tooltipParts.length) return '';
251
- return `<span style="cursor:help;opacity:0.55;margin-left:4px;font-weight:400" title="${escapeHtml(tooltipParts.join('\n'))}">?</span>`;
252
- }
253
-
254
- function renderQuotaSetupBox(cliName: string, q: QuotaEntry): string {
255
- const hint = QUOTA_SETUP_HINTS[cliName];
256
- const usage = q.sessionUsage;
257
- const extraTooltip: string[] = [];
258
- if (usage?.primaryModelId) extraTooltip.push(`Model: ${usage.primaryModelId}`);
259
- if (usage?.contextTokensUsed && usage?.contextWindowTokens) {
260
- extraTooltip.push(`Session context: ${Math.round(usage.contextTokensUsed).toLocaleString()} / ${Math.round(usage.contextWindowTokens).toLocaleString()} tokens`);
261
- } else if (usage?.turnCount) {
262
- extraTooltip.push(`Session turns: ${Math.round(usage.turnCount).toLocaleString()}`);
263
- }
264
- const helpMark = renderSetupHelpMark(cliName, q, extraTooltip);
265
-
266
- if (hint) {
267
- const commandLines = hint.commands.map(cmd => `
268
- <div style="margin-top:3px"><code style="font-size:10px;background:var(--border);padding:1px 4px;border-radius:2px;word-break:break-all">${escapeHtml(cmd)}</code></div>
269
- `).join('');
270
- return `
271
- <div style="font-size:10px;color:var(--text-dim);margin:4px 0 0 16px;padding:5px 7px;background:var(--surface);border:1px solid var(--border);border-radius:5px">
272
- <div style="color:var(--text);font-weight:600">${escapeHtml(hint.title)}${helpMark}</div>
273
- ${commandLines}
274
- ${hint.note ? `<div style="margin-top:4px;opacity:0.75">${escapeHtml(hint.note)}</div>` : ''}
275
- </div>
276
- `;
277
- }
278
-
279
- return `
280
- <div style="font-size:10px;color:var(--text-dim);margin:4px 0 0 16px;padding:5px 7px;background:var(--surface);border:1px solid var(--border);border-radius:5px">
281
- <div style="color:var(--text);font-weight:600">${escapeHtml(q.displayTier || providerLabel(cliName))}${helpMark}</div>
282
- <div style="margin-top:2px">${escapeHtml(describeStatusOnlyQuota(cliName, q))}</div>
283
- </div>
284
- `;
285
- }
286
-
287
184
  function scheduleEmbeddedQuotaRetry(
288
185
  seq: number,
289
186
  cliStatus: Record<string, { available: boolean }>,
@@ -305,9 +202,9 @@ async function fetchAndRenderQuota(
305
202
  seq: number,
306
203
  cliStatus: Record<string, { available: boolean }>,
307
204
  cachedQuota: Record<string, QuotaEntry> | null | undefined,
308
- ): Promise<void> {
205
+ ): Promise<boolean> {
309
206
  const quota = await api<Record<string, QuotaEntry>>('/api/quota');
310
- if (seq !== cliStatusLoadSeq) return;
207
+ if (seq !== cliStatusLoadSeq) return false;
311
208
 
312
209
  const resolvedQuota = quota ?? cachedQuota ?? null;
313
210
  state.cliStatusCache = { cliStatus, quota: resolvedQuota } as Record<string, unknown>;
@@ -315,6 +212,7 @@ async function fetchAndRenderQuota(
315
212
  renderCliStatus({ cliStatus, quota: resolvedQuota });
316
213
 
317
214
  if (!quota) scheduleEmbeddedQuotaRetry(seq, cliStatus, cachedQuota);
215
+ return Boolean(quota);
318
216
  }
319
217
 
320
218
  function scheduleQuotaFetch(
@@ -322,17 +220,15 @@ function scheduleQuotaFetch(
322
220
  seq: number,
323
221
  cliStatus: Record<string, { available: boolean }>,
324
222
  cachedQuota: Record<string, QuotaEntry> | null | undefined,
325
- ): void {
326
- const run = () => { void fetchAndRenderQuota(seq, cliStatus, cachedQuota); };
327
- if (force) {
328
- void fetchAndRenderQuota(seq, cliStatus, cachedQuota);
329
- return;
330
- }
223
+ ): Promise<boolean> | void {
224
+ const run = () => { void fetchAndRenderQuota(seq, cliStatus, cachedQuota).catch(() => {}); };
225
+ if (force) return fetchAndRenderQuota(seq, cliStatus, cachedQuota);
331
226
  window.setTimeout(run, QUOTA_LOAD_DEFER_MS);
332
227
  }
333
228
 
334
229
  export async function loadCliStatus(force = false): Promise<void> {
335
230
  if (!cliStatusExpanded) return;
231
+ if (force) setCliStatusRefreshFeedback('refreshing', 'Refreshing quota...');
336
232
 
337
233
  if (cliStatusLoadInFlight) {
338
234
  if (force) await cliStatusLoadInFlight.catch(() => {});
@@ -341,29 +237,39 @@ export async function loadCliStatus(force = false): Promise<void> {
341
237
 
342
238
  cliStatusLoadInFlight = (async () => {
343
239
  const seq = ++cliStatusLoadSeq;
344
- const interval = readCliStatusInterval();
345
- if (!force && state.cliStatusCache && interval > 0 && (Date.now() - state.cliStatusTs) < interval * 1000) {
346
- renderCliStatus({
347
- cliStatus: (state.cliStatusCache as Record<string, unknown>)?.['cliStatus'] as Record<string, { available: boolean }> | null,
348
- quota: (state.cliStatusCache as Record<string, unknown>)?.['quota'] as Record<string, QuotaEntry> | null,
349
- });
350
- return;
351
- }
352
-
353
240
  const el = document.getElementById('cliStatusList');
354
- const cachedQuota = (state.cliStatusCache as Record<string, unknown> | null)?.['quota'] as Record<string, QuotaEntry> | null | undefined;
355
- if (el && !cachedQuota) el.innerHTML = '<div style="color:var(--text-dim);font-size:11px">Loading...</div>';
241
+ try {
242
+ const interval = readCliStatusInterval();
243
+ if (!force && state.cliStatusCache && interval > 0 && (Date.now() - state.cliStatusTs) < interval * 1000) {
244
+ renderCliStatus({
245
+ cliStatus: (state.cliStatusCache as Record<string, unknown>)?.['cliStatus'] as Record<string, { available: boolean }> | null,
246
+ quota: (state.cliStatusCache as Record<string, unknown>)?.['quota'] as Record<string, QuotaEntry> | null,
247
+ });
248
+ return;
249
+ }
356
250
 
357
- const cliStatus = await api<Record<string, { available: boolean }>>('/api/cli-status');
358
- if (seq !== cliStatusLoadSeq) return;
359
- if (!cliStatus || typeof cliStatus !== 'object') {
360
- if (el) el.innerHTML = '<div style="color:var(--text-dim);font-size:11px">Failed to load CLI status</div>';
361
- return;
362
- }
251
+ const cachedQuota = (state.cliStatusCache as Record<string, unknown> | null)?.['quota'] as Record<string, QuotaEntry> | null | undefined;
252
+ if (el && !cachedQuota) el.innerHTML = '<div style="color:var(--text-dim);font-size:11px">Loading...</div>';
253
+
254
+ const cliStatus = await api<Record<string, { available: boolean }>>('/api/cli-status');
255
+ if (seq !== cliStatusLoadSeq) return;
256
+ if (!cliStatus || typeof cliStatus !== 'object') {
257
+ if (el) el.innerHTML = '<div style="color:var(--text-dim);font-size:11px">Failed to load CLI status</div>';
258
+ if (force) finishCliStatusRefreshFeedback('error', 'Refresh failed');
259
+ return;
260
+ }
363
261
 
364
- renderCliStatus({ cliStatus, quota: cachedQuota ?? null });
262
+ renderCliStatus({ cliStatus, quota: cachedQuota ?? null });
365
263
 
366
- scheduleQuotaFetch(force, seq, cliStatus, cachedQuota);
264
+ const quotaUpdated = await scheduleQuotaFetch(force, seq, cliStatus, cachedQuota);
265
+ if (force && seq === cliStatusLoadSeq) {
266
+ const verb = quotaUpdated ? 'Updated' : 'Checked';
267
+ finishCliStatusRefreshFeedback('success', `${verb} ${formatCliStatusRefreshTime(new Date())}`);
268
+ }
269
+ } catch {
270
+ if (el) el.innerHTML = '<div style="color:var(--text-dim);font-size:11px">Failed to load CLI status</div>';
271
+ if (force) finishCliStatusRefreshFeedback('error', 'Refresh failed');
272
+ }
367
273
  })().finally(() => {
368
274
  cliStatusLoadInFlight = null;
369
275
  });
@@ -383,6 +289,7 @@ function renderCliStatus(data: { cliStatus: Record<string, { available: boolean
383
289
  codex: { install: 'npm i -g @openai/codex', auth: 'codex login' },
384
290
  'codex-app': { install: 'npm i -g @openai/codex', auth: 'codex login' },
385
291
  cursor: { install: 'curl https://cursor.com/install -fsS | bash', auth: 'cursor-agent login, CURSOR_API_KEY, or CURSOR_SESSION_TOKEN for quota' },
292
+ 'kiro-code': { install: 'Install Kiro CLI from https://kiro.dev/docs/cli', auth: 'kiro-cli login' },
386
293
  gemini: { install: 'npm i -g @google/gemini-cli', auth: `gemini (${t('cli.gemini.auth')})` },
387
294
  grok: { install: 'curl -fsSL https://x.ai/cli/install.sh | bash', auth: 'grok login --oauth' },
388
295
  opencode: { install: 'npm i -g opencode-ai', auth: 'opencode auth' },
@@ -530,4 +437,42 @@ function renderCliStatus(data: { cliStatus: Record<string, { available: boolean
530
437
  setTimeout(() => { btn.innerHTML = ICONS.key; btn.disabled = false; }, 2000);
531
438
  });
532
439
  }
440
+
441
+ // Bind CLI setup help ? buttons (rendered as data-cli-help)
442
+ if (el) {
443
+ el.querySelectorAll<HTMLButtonElement>('[data-cli-help]').forEach(btn => {
444
+ btn.addEventListener('click', (e) => {
445
+ e.stopPropagation();
446
+ const text = btn.getAttribute('data-cli-help') || '';
447
+ showCliHelpPopup(text);
448
+ });
449
+ });
450
+ }
451
+ }
452
+
453
+ function showCliHelpPopup(text: string): void {
454
+ const existing = document.getElementById('cliHelpOverlay');
455
+ if (existing) existing.remove();
456
+
457
+ const overlay = document.createElement('div');
458
+ overlay.id = 'cliHelpOverlay';
459
+ overlay.className = 'mcp-help-overlay';
460
+ overlay.addEventListener('click', (e) => { if (e.target === overlay) overlay.remove(); });
461
+
462
+ const inner = document.createElement('div');
463
+ inner.className = 'mcp-help-inner';
464
+ const lines = text.split('\n').filter(Boolean);
465
+ inner.innerHTML = `
466
+ <h4>CLI Setup</h4>
467
+ ${lines.map(l => `<p><code>${l.replace(/&/g, '&amp;').replace(/</g, '&lt;')}</code></p>`).join('')}
468
+ <div style="text-align:right;margin-top:12px">
469
+ <button type="button" class="btn-save" id="cliHelpClose">OK</button>
470
+ </div>
471
+ `;
472
+ overlay.append(inner);
473
+ document.body.append(overlay);
474
+ inner.querySelector('#cliHelpClose')?.addEventListener('click', () => overlay.remove());
475
+ document.addEventListener('keydown', function esc(e) {
476
+ if (e.key === 'Escape') { overlay.remove(); document.removeEventListener('keydown', esc, true); }
477
+ }, true);
533
478
  }
@@ -11,6 +11,7 @@ import { loadDiscordSettings } from './settings-discord.js';
11
11
  import { loadActiveChannel, loadFallbackOrder } from './settings-channel.js';
12
12
  import { loadMcpServers } from './settings-mcp.js';
13
13
  import { providerIcon, providerLabel } from '../provider-icons.js';
14
+ import { postPreviewInvalidate } from '../preview-parent-origin.js';
14
15
 
15
16
  let activeSettingsSave: Promise<void> | null = null;
16
17
 
@@ -336,6 +337,7 @@ export async function updateSettings(): Promise<void> {
336
337
  selCli.dataset['prev'] = confirmedCli;
337
338
  }
338
339
  setHeaderCli(confirmedCli);
340
+ postPreviewInvalidate(['instances'], 'active-cli-changed');
339
341
  })());
340
342
  }
341
343
 
@@ -518,7 +520,9 @@ export async function saveActiveCliSettings(): Promise<void> {
518
520
  if (effortEl && !effortEl.disabled) overrides[cli].effort = effortEl.value || '';
519
521
  const patch: Record<string, unknown> = { activeOverrides: overrides };
520
522
  if (cli === 'ai-e') patch['perCli'] = { 'ai-e': { provider: getSelectedAiEProvider() } };
521
- await apiJson('/api/settings', 'PUT', patch);
523
+ if (await apiJson('/api/settings', 'PUT', patch)) {
524
+ postPreviewInvalidate(['instances'], 'active-cli-changed');
525
+ }
522
526
  }
523
527
 
524
528
  // ── Flush Agent Sidebar ──