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
@@ -9,6 +9,7 @@ import antigravitySvg from '../assets/providers/antigravity-color.svg?raw';
9
9
  import grokSvg from '../assets/providers/grok-color.svg?raw';
10
10
  import copilotSvg from '../assets/providers/copilot-color.svg?raw';
11
11
  import cursorSvg from '../assets/providers/cursor-color.svg?raw';
12
+ import kiroSvg from '../assets/providers/kiro-color.svg?raw';
12
13
 
13
14
  // Mono variants for dark/light mode flexibility
14
15
  import claudeMonoSvg from '../assets/providers/claude.svg?raw';
@@ -17,13 +18,14 @@ import antigravityMonoSvg from '../assets/providers/antigravity.svg?raw';
17
18
  import grokMonoSvg from '../assets/providers/grok.svg?raw';
18
19
  import copilotMonoSvg from '../assets/providers/copilot.svg?raw';
19
20
  import cursorMonoSvg from '../assets/providers/cursor.svg?raw';
21
+ import kiroMonoSvg from '../assets/providers/kiro.svg?raw';
20
22
 
21
23
  // Service icons (Discord, Telegram)
22
24
  import discordSvg from '../assets/providers/discord.svg?raw';
23
25
  import telegramSvg from '../assets/providers/telegram.svg?raw';
24
26
  import opencodeSvg from '../assets/providers/opencode.svg?raw';
25
27
 
26
- export type ProviderSlug = 'ai-e' | 'claude' | 'openai' | 'gemini' | 'antigravity' | 'grok' | 'copilot' | 'cursor' | 'codex' | 'codex-app' | 'opencode' | 'discord' | 'telegram';
28
+ export type ProviderSlug = 'ai-e' | 'claude' | 'openai' | 'gemini' | 'antigravity' | 'grok' | 'copilot' | 'cursor' | 'kiro-code' | 'codex' | 'codex-app' | 'opencode' | 'discord' | 'telegram';
27
29
 
28
30
  interface ProviderIcon {
29
31
  color: string;
@@ -42,6 +44,7 @@ const PROVIDER_ICONS: Record<ProviderSlug, ProviderIcon> = {
42
44
  grok: { color: grokSvg, mono: grokMonoSvg, label: 'Grok' },
43
45
  copilot: { color: copilotSvg, mono: copilotMonoSvg, label: 'Copilot' },
44
46
  cursor: { color: cursorSvg, mono: cursorMonoSvg, label: 'Cursor' },
47
+ 'kiro-code': { color: kiroSvg, mono: kiroMonoSvg, label: 'Kiro' },
45
48
  codex: { color: openaiSvg, mono: openaiSvg, label: 'Codex' },
46
49
  'codex-app': { color: openaiColorSvg, mono: openaiSvg, label: 'Codex App' },
47
50
  opencode: { color: opencodeSvg, mono: opencodeSvg, label: 'OpenCode' },
@@ -57,6 +60,7 @@ const PROVIDER_LABEL_ALIASES: Record<string, string> = {
57
60
  'claude-i': 'Claude E',
58
61
  'agy': 'Antigravity',
59
62
  cursor: 'Cursor',
63
+ 'kiro-code': 'Kiro',
60
64
  };
61
65
 
62
66
  function resolveProviderSlug(slug: string): ProviderSlug | null {
@@ -68,6 +72,7 @@ function resolveProviderSlug(slug: string): ProviderSlug | null {
68
72
  if (normalized === 'grok' || normalized.startsWith('grok')) return 'grok';
69
73
  if (normalized.startsWith('copilot') || normalized === 'githubcopilot') return 'copilot';
70
74
  if (normalized === 'cursor' || normalized.startsWith('cursor')) return 'cursor';
75
+ if (normalized === 'kirocode' || normalized === 'kiro') return 'kiro-code';
71
76
  if (normalized === 'codexapp' || normalized === 'codexappserver') return 'codex-app';
72
77
  if (normalized === 'codex') return 'codex';
73
78
  if (normalized === 'opencode') return 'opencode';
@@ -1,6 +1,6 @@
1
1
  // ── File path linkification and click-to-open delegation ──
2
2
  import { apiJson } from '../api.js';
3
- import { postPreviewOpenNotes, previewParentOrigin } from '../preview-parent-origin.js';
3
+ import { postPreviewOpenNotes, postPreviewOpenDoc, previewParentOrigin } from '../preview-parent-origin.js';
4
4
  import { normalizeNotesVaultPath } from './notes-vault-path.js';
5
5
 
6
6
  const FILE_PATH_RE_G = /(?:~\/[^\s)`\]"'<>]+|\/(?:Users|home|tmp|var|opt|private)\/[^\s)`\]"'<>]+)/g;
@@ -88,7 +88,10 @@ function appendFileLink(
88
88
  if (vaultRel) span.setAttribute('data-vault-rel', vaultRel);
89
89
  span.setAttribute('role', 'button');
90
90
  span.setAttribute('tabindex', '0');
91
- span.textContent = clean;
91
+ const basename = clean.split('/').pop() || clean;
92
+ const hasExt = /\.\w{1,10}$/.test(basename);
93
+ span.textContent = hasExt ? basename : clean;
94
+ if (hasExt) span.title = clean;
92
95
  frag.appendChild(span);
93
96
  }
94
97
 
@@ -203,6 +206,11 @@ async function handleFilePathClick(path: string, link: HTMLElement): Promise<voi
203
206
  setTimeout(() => link.classList.remove('opened'), 1500);
204
207
  return;
205
208
  }
209
+ if (/\.(md|mdx)$/i.test(path) && previewParentOrigin() && postPreviewOpenDoc(path)) {
210
+ link.classList.add('opened');
211
+ setTimeout(() => link.classList.remove('opened'), 1500);
212
+ return;
213
+ }
206
214
  openLocalPath(path, link);
207
215
  }
208
216
 
package/public/js/ui.ts CHANGED
@@ -307,9 +307,11 @@ export function finalizeAgent(text: string, toolLog?: ToolLogEntry[]): void {
307
307
  }
308
308
  state.currentAgentDiv.removeAttribute(ACTIVE_RUN_HYDRATED_ATTR);
309
309
  const content = (state.currentAgentDiv as HTMLElement)?.querySelector('.msg-content');
310
- // Live stream is preview-only; agent_done text stays authoritative.
310
+ // Live stream is preview-only; agent_done text stays authoritative unless stream is longer.
311
311
  const streamedText = currentStream ? finalizeStream(currentStream, true) : '';
312
- const finalText = text || streamedText;
312
+ const finalText = text && streamedText && streamedText.length > text.length
313
+ ? streamedText
314
+ : (text || streamedText);
313
315
  currentStream = null;
314
316
  if (content) content.innerHTML = renderMarkdown(finalText);
315
317
  if (hasTools && state.currentAgentDiv && !hadProcessBlock && !hasAgentToolBlock(state.currentAgentDiv)) {
@@ -359,6 +361,7 @@ export function finalizeAgent(text: string, toolLog?: ToolLogEntry[]): void {
359
361
  tool_log: durableToolLogJson,
360
362
  }, vs.count));
361
363
  releaseProcessBlockDetails(div);
364
+ vs.scrollToBottom();
362
365
  } else {
363
366
  vs.appendLiveItem(div);
364
367
  }
@@ -421,6 +421,25 @@ export class VirtualScroll {
421
421
  });
422
422
  containerObserver.observe(this.container);
423
423
  cleanupFns.push(() => containerObserver.disconnect());
424
+
425
+ // ── Content-growth bottom lock ──
426
+ // innerEl height tracks the virtualizer total size (set in render).
427
+ // Lazy markdown / mermaid / images grow it *after* the time-boxed
428
+ // initial settle finishes, drifting the bottom anchor upward with
429
+ // nothing left to re-bottom. Re-bottom when total content height
430
+ // grows — but only while bottom-follow intent still holds, so it
431
+ // releases the moment the user scrolls up (260508 rule preserved).
432
+ let prevTotal = this.virtualizer?.getTotalSize() ?? 0;
433
+ const contentObserver = new ResizeObserver(() => {
434
+ const total = this.virtualizer?.getTotalSize() ?? 0;
435
+ if (total <= prevTotal) { prevTotal = total; return; }
436
+ prevTotal = total;
437
+ if (this.shouldFollowAfterRestore()) {
438
+ this.reconcileBottomAfterLayout('manual', true);
439
+ }
440
+ });
441
+ contentObserver.observe(this.innerEl);
442
+ cleanupFns.push(() => contentObserver.disconnect());
424
443
  }
425
444
 
426
445
  // ── Browser restore reconciliation ──
package/public/js/ws.ts CHANGED
@@ -51,6 +51,7 @@ interface WsMessage {
51
51
  phase?: string;
52
52
  phaseLabel?: string;
53
53
  pending?: number;
54
+ queued?: Array<{ id: string; prompt: string; source?: string; ts?: number }>;
54
55
  path?: string;
55
56
  round?: number;
56
57
  agentPhases?: { agent?: string; name?: string }[];
@@ -87,6 +88,16 @@ interface WsMessage {
87
88
  deferredPending?: number;
88
89
  taskAnchor?: string | null;
89
90
  resolvedSelection?: ResolvedSelectionState | null;
91
+ buildBudget?: {
92
+ maxWorkerDispatches: number;
93
+ maxSelfHealRetries: number;
94
+ maxVerificationRounds: number;
95
+ spent: {
96
+ workerDispatches: number;
97
+ selfHealRetries: number;
98
+ verificationRounds: number;
99
+ };
100
+ } | null;
90
101
  interview?: { known: string[]; unknown: string[]; round: number } | null;
91
102
  delaySeconds?: number;
92
103
  attempts?: number;
@@ -124,7 +135,9 @@ async function refreshRuntimeSnapshot(options: { hydrateRun?: boolean } = {}): P
124
135
  if (options.hydrateRun) hydrateActiveRun(snap.activeRun);
125
136
  hydrateGoalState();
126
137
  setStatus(snap.runtime.busy ? 'running' : 'idle');
127
- if (snap.runtime.busy && snap.activeRun?.cli === 'agy') showLiveToolActivity(`${providerLabel(snap.activeRun.cli)} working...`);
138
+ if (snap.runtime.busy && (snap.activeRun?.cli === 'agy' || snap.activeRun?.cli === 'kiro-code')) {
139
+ showLiveToolActivity(`${providerLabel(snap.activeRun.cli)} working...`);
140
+ }
128
141
  import('./features/employees.js').then(m => {
129
142
  if (typeof m.renderEmployees === 'function') m.renderEmployees();
130
143
  });
@@ -268,7 +281,70 @@ function setInterviewCollapsed(collapsed: boolean): void {
268
281
  if (toggle) toggle.setAttribute('aria-expanded', String(!collapsed));
269
282
  }
270
283
 
271
- function renderInterviewPanel(interview: { known: string[]; unknown: string[]; round: number } | null): void {
284
+ interface InterviewEvidenceView {
285
+ fact: string;
286
+ source?: string;
287
+ confidence?: number;
288
+ turnNumber?: number;
289
+ dimension?: string;
290
+ }
291
+
292
+ interface DimensionAssessmentView {
293
+ goal: string;
294
+ constraint: string;
295
+ success: string;
296
+ ontology: string;
297
+ }
298
+
299
+ function renderDimensionBars(assessment: DimensionAssessmentView): string {
300
+ const levelToScore = (l: string) => {
301
+ switch (l) {
302
+ case 'max': return 1.0;
303
+ case 'xhigh': return 0.8;
304
+ case 'high': return 0.6;
305
+ case 'medium': return 0.4;
306
+ default: return 0.2;
307
+ }
308
+ };
309
+ const levelColor = (l: string) => {
310
+ switch (l) {
311
+ case 'max': return '#2196f3';
312
+ case 'xhigh': return '#4caf50';
313
+ case 'high': return '#8bc34a';
314
+ case 'medium': return '#ff9800';
315
+ default: return '#f44336';
316
+ }
317
+ };
318
+ const scores = [levelToScore(assessment.goal), levelToScore(assessment.constraint), levelToScore(assessment.success), levelToScore(assessment.ontology)];
319
+ const overall = 1 - (scores.reduce((a, b) => a + b, 0) / scores.length);
320
+ const allMax = Object.values(assessment).every(v => v === 'max');
321
+ const overallLabel = allMax ? '🟢 Ready' : overall <= 0.2 ? '🟢 Ready' : overall <= 0.4 ? '🟡 Almost' : '🔴 Needs work';
322
+
323
+ const bar = (dim: string, level: string) => {
324
+ const score = levelToScore(level);
325
+ const pct = score * 100;
326
+ const color = levelColor(level);
327
+ return `<div style="display:flex;align-items:center;gap:6px;font-size:12px">
328
+ <span style="width:70px;color:var(--text-secondary)">${dim}</span>
329
+ <div style="flex:1;height:5px;background:var(--bg-tertiary);border-radius:3px">
330
+ <div style="width:${pct}%;height:100%;background:${color};border-radius:3px;transition:width .3s"></div>
331
+ </div>
332
+ <span style="width:60px;text-align:right;font-weight:600;font-size:11px">${score.toFixed(1)} ${level.toUpperCase()}</span>
333
+ </div>`;
334
+ };
335
+ return `<div style="display:flex;flex-direction:column;gap:3px;margin:6px 0">
336
+ <div style="display:flex;justify-content:space-between;font-size:11px;margin-bottom:2px">
337
+ <span style="color:var(--text-secondary)">Ambiguity: ${overall.toFixed(2)}</span>
338
+ <span>${overallLabel}</span>
339
+ </div>
340
+ ${bar('Goal', assessment.goal)}
341
+ ${bar('Constraint', assessment.constraint)}
342
+ ${bar('Success', assessment.success)}
343
+ ${bar('Ontology', assessment.ontology)}
344
+ </div>`;
345
+ }
346
+
347
+ function renderInterviewPanel(interview: { known: (string | InterviewEvidenceView)[]; unknown: string[]; round: number; assessment?: DimensionAssessmentView } | null): void {
272
348
  const panel = document.getElementById('interviewPanel');
273
349
  if (!panel) return;
274
350
  if (!interview || (!interview.known.length && !interview.unknown.length)) {
@@ -277,14 +353,33 @@ function renderInterviewPanel(interview: { known: string[]; unknown: string[]; r
277
353
  }
278
354
  panel.hidden = false;
279
355
  panel.classList.toggle('collapsed', interviewCollapsed);
280
- const knownHtml = interview.known.map(k => `<li class="iv-known">${escapeHtml(k)}</li>`).join('');
281
- const unknownHtml = interview.unknown.map(u => `<li class="iv-unknown">${escapeHtml(u)}</li>`).join('');
356
+
357
+ const sourceIcon = (src?: string) => {
358
+ switch (src) {
359
+ case 'user_statement': return '🟢';
360
+ case 'repo_fact': return '🔵';
361
+ case 'inference': return '🟡';
362
+ case 'assumption': return '🟠';
363
+ case 'default': return '⚪';
364
+ default: return '·';
365
+ }
366
+ };
367
+
368
+ const knownHtml = interview.known.map(k => {
369
+ if (typeof k === 'string') return `<li class="iv-known">· ${escapeHtml(k)}</li>`;
370
+ const ev = k as InterviewEvidenceView;
371
+ const icon = sourceIcon(ev.source);
372
+ const dim = ev.dimension ? ` <span class="iv-dim">[${ev.dimension}]</span>` : '';
373
+ return `<li class="iv-known">${icon} ${escapeHtml(ev.fact)}${dim}</li>`;
374
+ }).join('');
375
+ const unknownHtml = interview.unknown.map(u => `<li class="iv-unknown">❓ ${escapeHtml(typeof u === 'string' ? u : JSON.stringify(u))}</li>`).join('');
282
376
  panel.innerHTML = `
283
377
  <button type="button" class="iv-toggle" aria-expanded="${!interviewCollapsed}" aria-controls="interviewBody" title="인터뷰 트래커 접기/펼치기">
284
378
  <span class="iv-chevron" aria-hidden="true">▸</span>
285
- <span class="iv-summary">Interview · <span class="iv-known-count">Known ${interview.known.length}</span> · <span class="iv-unknown-count">Unknown ${interview.unknown.length}</span> · Round ${interview.round}</span>
379
+ <span class="iv-summary">Interview · <span class="iv-known-count">Known ${interview.known.length}</span> · <span class="iv-unknown-count">Unknown ${interview.unknown.length}</span>${interview.known.filter(k => typeof k === 'object' && k && 'source' in k && (k as InterviewEvidenceView).source === 'assumption').length > 0 ? ` · <span class="iv-assumption-count">⚠️ ${interview.known.filter(k => typeof k === 'object' && k && 'source' in k && (k as InterviewEvidenceView).source === 'assumption').length} assumptions</span>` : ''} · Round ${interview.round}</span>
286
380
  </button>
287
381
  <div class="iv-body" id="interviewBody">
382
+ ${interview.assessment ? renderDimensionBars(interview.assessment) : ''}
288
383
  <div class="iv-section"><strong>Known (${interview.known.length})</strong><ul>${knownHtml}</ul></div>
289
384
  <div class="iv-section"><strong>Unknown (${interview.unknown.length})</strong><ul>${unknownHtml}</ul></div>
290
385
  </div>
@@ -299,6 +394,28 @@ function renderInterviewPanel(interview: { known: string[]; unknown: string[]; r
299
394
  }
300
395
  }
301
396
 
397
+ function renderBudgetPanel(budget: { maxWorkerDispatches: number; maxSelfHealRetries: number; maxVerificationRounds: number; spent: { workerDispatches: number; selfHealRetries: number; verificationRounds: number } } | null, orcState: string): void {
398
+ const panel = document.getElementById('budgetPanel');
399
+ if (!panel) return;
400
+ if (!budget || orcState !== 'B') { panel.hidden = true; return; }
401
+ panel.hidden = false;
402
+ const bar = (label: string, spent: number, max: number) => {
403
+ const pct = max > 0 ? Math.min((spent / max) * 100, 100) : 0;
404
+ const color = pct >= 100 ? '#f44336' : pct >= 66 ? '#ff9800' : '#4caf50';
405
+ return `<div style="display:flex;align-items:center;gap:6px;font-size:12px">
406
+ <span style="width:70px;color:var(--text-secondary)">${label}</span>
407
+ <div style="flex:1;height:5px;background:var(--bg-tertiary);border-radius:3px">
408
+ <div style="width:${pct}%;height:100%;background:${color};border-radius:3px"></div>
409
+ </div>
410
+ <span style="width:30px;text-align:right;font-size:11px">${spent}/${max}</span>
411
+ </div>`;
412
+ };
413
+ panel.innerHTML = `<div style="font-size:11px;font-weight:600;margin-bottom:4px;color:var(--text-secondary)">Build Budget</div>
414
+ ${bar('Workers', budget.spent.workerDispatches, budget.maxWorkerDispatches)}
415
+ ${bar('Self-heal', budget.spent.selfHealRetries, budget.maxSelfHealRetries)}
416
+ ${bar('Verify', budget.spent.verificationRounds, budget.maxVerificationRounds)}`;
417
+ }
418
+
302
419
  async function hydrateGoalState(): Promise<void> {
303
420
  try {
304
421
  const res = await fetch(`${API_BASE}/api/goal`);
@@ -465,10 +582,14 @@ export function connect(): void {
465
582
  if (msg.type === 'agent_status') {
466
583
  if (msg.running !== undefined) {
467
584
  setStatus(msg.running ? 'running' : 'idle');
468
- if (msg.running && msg.cli === 'agy') showLiveToolActivity(`${providerLabel(msg.cli)} working...`);
585
+ if (msg.running && (msg.cli === 'agy' || msg.cli === 'kiro-code')) {
586
+ showLiveToolActivity(`${providerLabel(msg.cli)} working...`);
587
+ }
469
588
  } else {
470
589
  setStatus(msg.status || 'idle');
471
- if (msg.status === 'running' && msg.cli === 'agy') showLiveToolActivity(`${providerLabel(msg.cli)} working...`);
590
+ if (msg.status === 'running' && (msg.cli === 'agy' || msg.cli === 'kiro-code')) {
591
+ showLiveToolActivity(`${providerLabel(msg.cli)} working...`);
592
+ }
472
593
  }
473
594
  // Track per-agent phase for badge rendering
474
595
  if (msg.agentId && msg.phase) {
@@ -477,6 +598,9 @@ export function connect(): void {
477
598
  }
478
599
  } else if (msg.type === 'queue_update') {
479
600
  updateQueueBadge(msg.pending || 0);
601
+ if (Array.isArray(msg.queued)) {
602
+ renderPendingQueue(msg.queued);
603
+ }
480
604
  syncOrchestrateSnapshot('queue_update').catch(() => { /* snapshot not critical — UI recovers on next event */ });
481
605
  } else if (msg.type === 'worklog_created') {
482
606
  addSystemMsg(`${ICONS.clipboard} Worklog: ${escapeHtml(msg.path || '')}`);
@@ -513,7 +637,7 @@ export function connect(): void {
513
637
  status: (msg.status as 'running' | 'done' | 'error') || 'running',
514
638
  startTime: Date.now(),
515
639
  });
516
- } else if (msg.type === 'agent_output') {
640
+ } else if (msg.type === 'agent_output' || msg.type === 'agent_chunk') {
517
641
  appendAgentText(msg.text || '');
518
642
  } else if (msg.type === 'agent_retry') {
519
643
  const retryDelay = Number(msg.delay ?? 0);
@@ -578,6 +702,7 @@ export function connect(): void {
578
702
  resolvedSelection: msg.resolvedSelection || null,
579
703
  interview: msg.interview || null,
580
704
  });
705
+ renderBudgetPanel(msg.buildBudget || null, typeof msg.state === 'string' ? msg.state : 'IDLE');
581
706
  } else if (msg.type === 'memory_status') {
582
707
  import('./features/memory.js').then(m => m.refreshMemorySidebar());
583
708
  } else if (msg.type === 'steer_started') {
@@ -1,8 +1,10 @@
1
1
  {
2
2
  "cmd.help.desc": "Command list",
3
3
  "cmd.status.desc": "Current status",
4
- "cmd.clear.desc": "Clear screen (non-destructive)",
5
- "cmd.reset.desc": "Full reset (MCP/Skills/Employees/Session)",
4
+ "cmd.clear.desc": "Clear conversation / all: reset skills+employees+MCP",
5
+ "cmd.purge.desc": "Purge conversation and memory",
6
+ "cmd.purge.tg_desc": "Purge chat+memory",
7
+ "cmd.reset.desc": "Bootstrap reset (conversation/memory/skills/employees/MCP)",
6
8
  "cmd.model.desc": "View/change model",
7
9
  "cmd.cli.desc": "View/change active CLI",
8
10
  "cmd.fallback.desc": "Set fallback CLI order",
@@ -89,9 +91,13 @@
89
91
  "cmd.reset.confirm": "Full reset: MCP, skills, employees, and session will be reset to defaults.\nType /reset confirm to proceed.",
90
92
  "cmd.reset.unavailable": "Reset is not supported in this environment.",
91
93
  "cmd.reset.done": "Reset complete: {items}",
94
+ "cmd.reset.bootstrapDone": "🔄 Bootstrap reset complete: {items}",
95
+ "cmd.reset.memory": "Memory",
92
96
  "cmd.reset.skills": "Skills",
93
97
  "cmd.reset.employees": "Employees",
94
98
  "cmd.reset.sessions": "Session",
99
+ "cmd.purge.done": "✅ Conversation + memory purged",
100
+ "cmd.clearAll.done": "✅ {items} reset complete",
95
101
  "cmd.mcp.syncDone": "MCP sync complete ({count} targets)",
96
102
  "cmd.mcp.installDone": "MCP install complete ({count} servers)",
97
103
  "cmd.memory.empty": "No memory files.",
@@ -1,8 +1,10 @@
1
1
  {
2
2
  "cmd.help.desc": "コマンド一覧",
3
3
  "cmd.status.desc": "現在の状態",
4
- "cmd.clear.desc": "画面をクリア(データは保持)",
5
- "cmd.reset.desc": "完全リセット(MCP/スキル/従業員/セッション)",
4
+ "cmd.clear.desc": "会話削除 / all: スキル+従業員+MCPリセット",
5
+ "cmd.purge.desc": "会話+メモリ削除",
6
+ "cmd.purge.tg_desc": "会話+メモリ削除",
7
+ "cmd.reset.desc": "ブートストラップ初期化(会話/メモリ/スキル/従業員/MCP)",
6
8
  "cmd.model.desc": "モデルの確認/変更",
7
9
  "cmd.cli.desc": "アクティブ CLI の確認/変更",
8
10
  "cmd.fallback.desc": "Fallback CLI の順序を設定",
@@ -89,9 +91,13 @@
89
91
  "cmd.reset.confirm": "完全リセット: MCP、スキル、従業員、セッションをデフォルトに戻します。\n続行するには /reset confirm と入力してください。",
90
92
  "cmd.reset.unavailable": "この環境ではリセットはサポートされていません。",
91
93
  "cmd.reset.done": "リセット完了: {items}",
94
+ "cmd.reset.bootstrapDone": "🔄 ブートストラップ初期化完了: {items}",
95
+ "cmd.reset.memory": "メモリ",
92
96
  "cmd.reset.skills": "スキル",
93
97
  "cmd.reset.employees": "従業員",
94
98
  "cmd.reset.sessions": "セッション",
99
+ "cmd.purge.done": "✅ 会話 + メモリ削除完了",
100
+ "cmd.clearAll.done": "✅ {items} リセット完了",
95
101
  "cmd.mcp.syncDone": "MCP 同期が完了しました({count} 件)",
96
102
  "cmd.mcp.installDone": "MCP インストールが完了しました({count} サーバー)",
97
103
  "cmd.memory.empty": "メモリファイルはありません。",
@@ -1,8 +1,10 @@
1
1
  {
2
2
  "cmd.help.desc": "커맨드 목록",
3
3
  "cmd.status.desc": "현재 상태",
4
- "cmd.clear.desc": "화면 정리 (비파괴)",
5
- "cmd.reset.desc": "전체 초기화 (MCP/스킬/직원/세션)",
4
+ "cmd.clear.desc": "대화 삭제 / all: 스킬+직원+MCP 리셋",
5
+ "cmd.purge.desc": "대화 + 메모리 삭제",
6
+ "cmd.purge.tg_desc": "대화+메모리 삭제",
7
+ "cmd.reset.desc": "부트스트랩 초기화 (대화/메모리/스킬/직원/MCP)",
6
8
  "cmd.model.desc": "모델 확인/변경",
7
9
  "cmd.cli.desc": "활성 CLI 확인/변경",
8
10
  "cmd.fallback.desc": "폴백 CLI 순서 설정",
@@ -89,9 +91,13 @@
89
91
  "cmd.reset.confirm": "전체 초기화: MCP, 스킬, 직원, 세션을 기본값으로 재설정합니다.\n실행하려면 /reset confirm 을 입력하세요.",
90
92
  "cmd.reset.unavailable": "이 환경에서는 초기화가 지원되지 않습니다.",
91
93
  "cmd.reset.done": "초기화 완료: {items}",
94
+ "cmd.reset.bootstrapDone": "🔄 부트스트랩 초기화 완료: {items}",
95
+ "cmd.reset.memory": "메모리",
92
96
  "cmd.reset.skills": "스킬",
93
97
  "cmd.reset.employees": "직원",
94
98
  "cmd.reset.sessions": "세션",
99
+ "cmd.purge.done": "✅ 대화 + 메모리 삭제 완료",
100
+ "cmd.clearAll.done": "✅ {items} 리셋 완료",
95
101
  "cmd.mcp.syncDone": "MCP sync 완료 ({count} target)",
96
102
  "cmd.mcp.installDone": "MCP install 완료 ({count} server)",
97
103
  "cmd.memory.empty": "memory 파일이 없습니다.",
@@ -1,8 +1,10 @@
1
1
  {
2
2
  "cmd.help.desc": "命令列表",
3
3
  "cmd.status.desc": "当前状态",
4
- "cmd.clear.desc": "清屏(不删除数据)",
5
- "cmd.reset.desc": "完全重置(MCP/技能/员工/会话)",
4
+ "cmd.clear.desc": "删除对话 / all: 重置技能+员工+MCP",
5
+ "cmd.purge.desc": "删除对话和记忆",
6
+ "cmd.purge.tg_desc": "删除对话+记忆",
7
+ "cmd.reset.desc": "引导重置(对话/记忆/技能/员工/MCP)",
6
8
  "cmd.model.desc": "查看/切换模型",
7
9
  "cmd.cli.desc": "查看/切换当前 CLI",
8
10
  "cmd.fallback.desc": "设置 CLI fallback 顺序",
@@ -89,9 +91,13 @@
89
91
  "cmd.reset.confirm": "完全重置:MCP、技能、员工和会话都会恢复默认值。\n输入 /reset confirm 继续。",
90
92
  "cmd.reset.unavailable": "当前环境不支持重置。",
91
93
  "cmd.reset.done": "重置完成:{items}",
94
+ "cmd.reset.bootstrapDone": "🔄 引导重置完成:{items}",
95
+ "cmd.reset.memory": "记忆",
92
96
  "cmd.reset.skills": "技能",
93
97
  "cmd.reset.employees": "员工",
94
98
  "cmd.reset.sessions": "会话",
99
+ "cmd.purge.done": "✅ 对话 + 记忆已清除",
100
+ "cmd.clearAll.done": "✅ {items} 重置完成",
95
101
  "cmd.mcp.syncDone": "MCP 同步完成({count} 个目标)",
96
102
  "cmd.mcp.installDone": "MCP 安装完成({count} 个服务器)",
97
103
  "cmd.memory.empty": "没有记忆文件。",
@@ -36,7 +36,7 @@ import { useJawCeoDashboardBridge } from './jaw-ceo/useJawCeoDashboardBridge';
36
36
  import { actionForShortcutEvent, isManagerShortcutEditableTarget } from './manager-shortcuts';
37
37
  import { reconcileActiveProfileFilter } from './profile-filter';
38
38
  import type { DashboardDetailTab, DashboardInstance, DashboardInstanceStatus, DashboardLifecycleAction, DashboardNotesAuthoringMode, DashboardNotesGraphSettings, DashboardNotesViewMode, DashboardProfile, DashboardScanResult, DashboardShortcutAction, DashboardSidebarMode } from './types';
39
- import { panelShortcutBus } from './panels/panel-shortcut-bus';
39
+ import { runManagerShortcut as runManagerShortcutAction } from './manager-shortcut-runner';
40
40
  import { getDesktop } from './panels/desktop-bridge';
41
41
  import type { PanelLayoutState } from './panels/PanelLayoutProvider';
42
42
  import { panelLayoutInitialStateFromUi, panelLayoutUiFromState } from './panels/panel-layout-registry-state';
@@ -355,75 +355,18 @@ export function App() {
355
355
  }
356
356
 
357
357
  function runManagerShortcut(action: DashboardShortcutAction): void {
358
- if (panelShortcutBus.dispatch(action)) return;
359
- if (action === 'focusInstances') {
360
- handleSidebarModeChange('instances');
361
- view.setDrawerOpen(false);
362
- return;
363
- }
364
- if (action === 'focusActiveSession') {
365
- const target = selectedInstance?.ok
366
- ? selectedInstance
367
- : filtered.find(instance => instance.ok) || null;
368
- if (target) handlePreview(target);
369
- else handleSidebarModeChange('instances');
370
- return;
371
- }
372
- if (action === 'focusNotes') {
373
- handleSidebarModeChange('notes');
374
- view.setDrawerOpen(false);
375
- return;
376
- }
377
- if (action === 'previousInstance') {
378
- selectRelativeInstance(-1);
379
- return;
380
- }
381
- if (action === 'nextInstance') {
382
- selectRelativeInstance(1);
383
- return;
384
- }
385
- if (action === 'closeFocusedTab') {
386
- const active = document.activeElement;
387
- if (active?.closest('.browser-webview-stack, .browser-tab-strip')) {
388
- document.dispatchEvent(new CustomEvent('jaw:shortcut-action', { detail: 'closeBrowserTab' }));
389
- } else if (active?.closest('.terminal-panel, .xterm')) {
390
- document.dispatchEvent(new CustomEvent('jaw:shortcut-action', { detail: 'closeTerminalTab' }));
391
- } else if (active?.closest('.bottom-panel')) {
392
- panelShortcutBus.dispatch('closeActiveBottomTab');
393
- } else if (active?.closest('.right-panel')) {
394
- panelShortcutBus.dispatch('toggleRightPanel');
395
- }
396
- return;
397
- }
398
- if (action === 'switchTab1') { handleTabChange('overview'); return; }
399
- if (action === 'switchTab2') { handleTabChange('preview'); return; }
400
- if (action === 'switchTab3') { handleTabChange('logs'); return; }
401
- if (action === 'switchTab4') { handleTabChange('settings'); return; }
402
- if (action === 'previousTab' || action === 'nextTab') {
403
- const tabs: DashboardDetailTab[] = ['overview', 'preview', 'logs', 'settings'];
404
- const idx = tabs.indexOf(view.activeDetailTab);
405
- const dir = action === 'nextTab' ? 1 : -1;
406
- handleTabChange(tabs[(idx + dir + tabs.length) % tabs.length]);
407
- return;
408
- }
409
- if (action === 'browserReload' || action === 'browserHardReload' || action === 'browserFocusUrl' || action === 'browserBack' || action === 'browserForward') {
410
- const el = document.activeElement;
411
- if (el?.closest('.browser-webview-stack, .browser-tab-strip, .browser-panel')) {
412
- document.dispatchEvent(new CustomEvent('jaw:shortcut-action', { detail: action }));
413
- }
414
- return;
415
- }
416
- if (action === 'terminalClear' || action === 'terminalNewTab') {
417
- const el = document.activeElement;
418
- if (el?.closest('.terminal-panel, .xterm')) {
419
- document.dispatchEvent(new CustomEvent('jaw:shortcut-action', { detail: action }));
420
- }
421
- return;
422
- }
423
- if (action === 'toggleLeftSidebar') {
424
- handleSidebarToggle();
425
- return;
426
- }
358
+ runManagerShortcutAction(action, {
359
+ selectedInstance,
360
+ filtered,
361
+ activeDetailTab: view.activeDetailTab,
362
+ setDrawerOpen: view.setDrawerOpen,
363
+ handleSidebarModeChange,
364
+ handlePreview,
365
+ selectRelativeInstance,
366
+ handleTabChange,
367
+ setPreviewRefreshKey,
368
+ handleSidebarToggle,
369
+ });
427
370
  }
428
371
  useEffect(() => {
429
372
  if (!view.dashboardShortcutsEnabled) return undefined;
@@ -12,6 +12,7 @@ type InstancePreviewProps = {
12
12
  refreshKey: number;
13
13
  theme: PreviewTheme;
14
14
  onOpenNotesFromPreview?: (path: string) => void;
15
+ onOpenDocFromPreview?: (absolutePath: string) => void;
15
16
  };
16
17
 
17
18
  type PreviewOpenNotesMessage = {
@@ -114,6 +115,21 @@ function postPreviewSttToggle(frame: HTMLIFrameElement | null, src: string): voi
114
115
  }
115
116
  }
116
117
 
118
+ function postPreviewVisible(frame: HTMLIFrameElement | null, src: string): void {
119
+ const targetWindow = frame?.contentWindow;
120
+ if (!targetWindow) return;
121
+ const targetOrigin = previewTargetOrigin(src, frame);
122
+ if (!targetOrigin || targetOrigin === 'null') return;
123
+ try {
124
+ targetWindow.postMessage(
125
+ { type: 'jaw-preview-visibility', visible: true },
126
+ targetOrigin,
127
+ );
128
+ } catch (error) {
129
+ console.warn('[manager-preview] visibility sync skipped', error);
130
+ }
131
+ }
132
+
117
133
  function isEditableShortcutTarget(target: EventTarget | null): boolean {
118
134
  if (!(target instanceof HTMLElement)) return false;
119
135
  if (target.isContentEditable) return true;
@@ -198,11 +214,22 @@ export function InstancePreview(props: InstancePreviewProps) {
198
214
  props.onOpenNotesFromPreview?.(path);
199
215
  }
200
216
  window.addEventListener('message', onPreviewOpenNotes);
217
+ function onPreviewOpenDoc(event: MessageEvent): void {
218
+ if (event.source !== iframeRef.current?.contentWindow) return;
219
+ if (!state.src || !previewFrameOriginMatches(event.origin, state.src, iframeRef.current)) return;
220
+ const data = event.data as { type?: unknown; path?: unknown } | null;
221
+ if (!data || data.type !== 'jaw-preview-open-doc') return;
222
+ const path = typeof data.path === 'string' ? data.path.trim() : '';
223
+ if (!path) return;
224
+ props.onOpenDocFromPreview?.(path);
225
+ }
226
+ window.addEventListener('message', onPreviewOpenDoc);
201
227
  return () => {
202
228
  window.removeEventListener('message', onPreviewSend);
203
229
  window.removeEventListener('message', onPreviewOpenNotes);
230
+ window.removeEventListener('message', onPreviewOpenDoc);
204
231
  };
205
- }, [props.enabled, props.instance, props.onOpenNotesFromPreview, state.canPreview, state.src]);
232
+ }, [props.enabled, props.instance, props.onOpenNotesFromPreview, props.onOpenDocFromPreview, state.canPreview, state.src]);
206
233
 
207
234
  useEffect(() => {
208
235
  if (!props.active || !props.enabled || !state.canPreview || !state.src) return undefined;
@@ -221,16 +248,8 @@ export function InstancePreview(props: InstancePreviewProps) {
221
248
  useEffect(() => {
222
249
  const wasActive = prevActiveRef.current;
223
250
  prevActiveRef.current = props.active;
224
- if (!wasActive && props.active && iframeRef.current?.contentWindow && state.src) {
225
- const origin = previewTargetOrigin(state.src, iframeRef.current);
226
- if (origin && origin !== 'null') {
227
- try {
228
- iframeRef.current.contentWindow.postMessage(
229
- { type: 'jaw-preview-visibility', visible: true },
230
- origin,
231
- );
232
- } catch { /* cross-origin guard */ }
233
- }
251
+ if (!wasActive && props.active && state.src) {
252
+ postPreviewVisible(iframeRef.current, state.src);
234
253
  }
235
254
  }, [props.active, state.src]);
236
255
 
@@ -250,6 +269,12 @@ export function InstancePreview(props: InstancePreviewProps) {
250
269
  onLoad={() => {
251
270
  loadedSrcRef.current = state.src;
252
271
  syncTheme();
272
+ // Every (re)mount is a fresh document. The active-tab
273
+ // effect only pings on a !wasActive→active transition, so
274
+ // an instance switch (port/key changes, active stays true)
275
+ // remounts without re-settling. Ping here so the embedded
276
+ // chat runs its jaw-preview-visibility re-settle path.
277
+ if (state.src) postPreviewVisible(iframeRef.current, state.src);
253
278
  }}
254
279
  />
255
280
  )}