cli-jaw 2.1.0 → 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 (356) 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/orc-state.css +21 -2
  254. package/public/css/sidebar.css +85 -0
  255. package/public/css/variables.css +2 -2
  256. package/public/dist/assets/{Agent-CIUGaUVn.js → Agent-DkH7eoHd.js} +1 -1
  257. package/public/dist/assets/{DocPanel-C1pGgE-S.js → DocPanel-BU16GUlB.js} +1 -1
  258. package/public/dist/assets/DocPanel-gU-WkgyA.css +1 -0
  259. package/public/dist/assets/Employees-F0ssNuO-.js +1 -0
  260. package/public/dist/assets/Heartbeat-C3JS6gkF.js +1 -0
  261. package/public/dist/assets/Mcp-_Yq4N3Sk.js +4 -0
  262. package/public/dist/assets/{Memory-BgN8djV4.js → Memory-C-EQubN2.js} +1 -1
  263. package/public/dist/assets/{ModelProvider-DHQ1Zvw0.js → ModelProvider-BD2KrypI.js} +1 -1
  264. package/public/dist/assets/agent-meta-B1098B_a.js +1 -0
  265. package/public/dist/assets/app-ByHYOMZE.js +48 -0
  266. package/public/dist/assets/app-CYdhP6Vh.css +1 -0
  267. package/public/dist/assets/constants-s2UJodER.js +1 -0
  268. package/public/dist/assets/{employees-DZSPGlaH.js → employees-_A-p_bZg.js} +7 -7
  269. package/public/dist/assets/idb-cache-0LNMskFB.js +1 -0
  270. package/public/dist/assets/idb-cache-5H89a4l8.js +1 -0
  271. package/public/dist/assets/{manager-DyrwJLZr.css → manager-B2qEQRxN.css} +1 -1
  272. package/public/dist/assets/manager-CR9BA-wO.js +12 -0
  273. package/public/dist/assets/memory-D1RKYvyu.js +1 -0
  274. package/public/dist/assets/{memory-B4RpXXJ7.js → memory-D9AUn8fG.js} +9 -9
  275. package/public/dist/assets/{provider-icons-XEfJPGTe.js → provider-icons-CVVK5xUP.js} +35 -6
  276. package/public/dist/assets/{render-DnylWKO1.js → render-DFBujF8n.js} +4 -4
  277. package/public/dist/assets/settings-B4ZkeaU-.js +1 -0
  278. package/public/dist/assets/settings-D9jTceN0.js +151 -0
  279. package/public/dist/assets/sidebar-DPPRNiTc.js +48 -0
  280. package/public/dist/assets/skills-8nHJkv-r.js +1 -0
  281. package/public/dist/assets/{skills-CW7NEhew.js → skills-BDVLIrVT.js} +6 -6
  282. package/public/dist/assets/{slash-commands-CAydTUgf.js → slash-commands-C5da3q1p.js} +1 -1
  283. package/public/dist/assets/slash-commands-RJWO8wJZ.js +1 -0
  284. package/public/dist/assets/{trace-drawer-G-KP3IbQ.js → trace-drawer-5kqBzFMk.js} +1 -1
  285. package/public/dist/assets/ui-Crnp79bG.js +142 -0
  286. package/public/dist/assets/ui-HtSKByR3.js +1 -0
  287. package/public/dist/index.html +113 -86
  288. package/public/dist/manager/index.html +2 -2
  289. package/public/index.html +111 -84
  290. package/public/js/constants.ts +30 -7
  291. package/public/js/features/chat-search.ts +5 -1
  292. package/public/js/features/employees.ts +7 -2
  293. package/public/js/features/idb-cache.ts +4 -0
  294. package/public/js/features/message-history.ts +55 -7
  295. package/public/js/features/pending-queue.ts +8 -2
  296. package/public/js/features/process-block.ts +32 -17
  297. package/public/js/features/process-log-adapter.ts +11 -2
  298. package/public/js/features/settings-cli-status-render.ts +163 -0
  299. package/public/js/features/settings-cli-status.ts +130 -185
  300. package/public/js/features/settings-core.ts +5 -1
  301. package/public/js/features/settings-mcp.ts +513 -7
  302. package/public/js/features/settings.ts +1 -1
  303. package/public/js/features/tool-ui.ts +18 -4
  304. package/public/js/features/transport-status-row.ts +3 -0
  305. package/public/js/main.ts +3 -0
  306. package/public/js/preview-parent-origin.ts +14 -0
  307. package/public/js/provider-icons.ts +6 -1
  308. package/public/js/render/file-links.ts +10 -2
  309. package/public/js/ui.ts +5 -2
  310. package/public/js/virtual-scroll.ts +19 -0
  311. package/public/js/ws.ts +163 -10
  312. package/public/locales/en.json +8 -2
  313. package/public/locales/ja.json +8 -2
  314. package/public/locales/ko.json +8 -2
  315. package/public/locales/zh.json +8 -2
  316. package/public/manager/src/App.tsx +13 -70
  317. package/public/manager/src/InstancePreview.tsx +36 -11
  318. package/public/manager/src/SidebarRailRouter.tsx +1 -1
  319. package/public/manager/src/doc-panel/DocPanel.tsx +14 -1
  320. package/public/manager/src/doc-panel/doc-panel.css +16 -0
  321. package/public/manager/src/hooks/useInstanceMessageEvents.ts +4 -15
  322. package/public/manager/src/manager-components.css +1 -1
  323. package/public/manager/src/manager-polish.css +1 -1
  324. package/public/manager/src/manager-shortcut-runner.ts +107 -0
  325. package/public/manager/src/manager-shortcuts.ts +15 -0
  326. package/public/manager/src/panels/desktop-bridge.ts +2 -0
  327. package/public/manager/src/settings/SettingsSidebar.tsx +1 -1
  328. package/public/manager/src/settings/components/sidebar-filter.ts +2 -0
  329. package/public/manager/src/settings/pages/Mcp.tsx +311 -43
  330. package/public/manager/src/settings/pages/components/McpServerCard.tsx +89 -55
  331. package/public/manager/src/settings/pages/components/agent/agent-meta.ts +29 -6
  332. package/public/manager/src/settings/pages/components/employees-helpers.ts +1 -0
  333. package/public/manager/src/settings/pages/components/heartbeat-helpers.ts +1 -0
  334. package/public/manager/src/settings/pages/mcp-helpers.ts +54 -12
  335. package/public/manager/src/settings/types.ts +1 -0
  336. package/public/manager/src/types.ts +2 -1
  337. package/scripts/fresh-install-smoke.ts +1 -1
  338. package/public/dist/assets/DocPanel-CL1scIfq.css +0 -1
  339. package/public/dist/assets/Employees-BL9MAzzx.js +0 -1
  340. package/public/dist/assets/Heartbeat-D64JCg4t.js +0 -1
  341. package/public/dist/assets/Mcp-wYwJA_61.js +0 -3
  342. package/public/dist/assets/agent-meta-BhEbjy4P.js +0 -1
  343. package/public/dist/assets/app-DLDdZ41k.js +0 -48
  344. package/public/dist/assets/app-RpnKs-sT.css +0 -1
  345. package/public/dist/assets/constants-ahKI_aEG.js +0 -1
  346. package/public/dist/assets/idb-cache-BnZfG5FD.js +0 -1
  347. package/public/dist/assets/idb-cache-CZ3JdK8r.js +0 -1
  348. package/public/dist/assets/manager-CfyZloIP.js +0 -12
  349. package/public/dist/assets/memory-C9EVOb_D.js +0 -1
  350. package/public/dist/assets/settings-DIG_i79X.js +0 -1
  351. package/public/dist/assets/settings-VCXKhhhz.js +0 -66
  352. package/public/dist/assets/sidebar-Bi_ktFVw.js +0 -18
  353. package/public/dist/assets/skills-RjRqvykb.js +0 -1
  354. package/public/dist/assets/slash-commands-DdXu96Zd.js +0 -1
  355. package/public/dist/assets/ui-CIQjTLzc.js +0 -1
  356. package/public/dist/assets/ui-CkHB9Jmo.js +0 -140
@@ -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
  )}
@@ -243,7 +243,7 @@ export function SidebarRailRouter(props: Props) {
243
243
  <div className="workspace-surface-layer">
244
244
  <WorkspaceSurface active={props.sidebarMode === 'instances'}>
245
245
  <Workbench mode={props.activeDetailTab} onModeChange={props.onDetailTabChange} header={props.workbenchHeader} modeActions={props.jawCeoWorkbenchButton} overview={props.detailContent('overview')} preview={(
246
- <InstancePreview instance={props.selectedInstance} data={props.data} enabled={props.previewEnabled} active={props.sidebarMode === 'instances' && props.activeDetailTab === 'preview'} refreshKey={props.previewRefreshKey} theme={props.previewTheme} {...(props.onOpenNotesFromPreview ? { onOpenNotesFromPreview: props.onOpenNotesFromPreview } : {})} />
246
+ <InstancePreview instance={props.selectedInstance} data={props.data} enabled={props.previewEnabled} active={props.sidebarMode === 'instances' && props.activeDetailTab === 'preview'} refreshKey={props.previewRefreshKey} theme={props.previewTheme} {...(props.onOpenNotesFromPreview ? { onOpenNotesFromPreview: props.onOpenNotesFromPreview } : {})} onOpenDocFromPreview={handleRightPreviewFile} />
247
247
  )} logs={props.detailContent('logs')} settings={props.detailContent('settings')} />
248
248
  </WorkspaceSurface>
249
249
  <WorkspaceSurface active={props.sidebarMode === 'notes'}>
@@ -103,7 +103,20 @@ export function DocPanel(props: { filePath?: string | undefined }) {
103
103
  return (
104
104
  <div className="doc-panel">
105
105
  <div className="doc-toolbar">
106
- <span className="doc-file-name">{props.filePath.split('/').pop()}</span>
106
+ <span className="doc-file-name" title={props.filePath}>{props.filePath.split('/').pop()}</span>
107
+ <button
108
+ type="button"
109
+ className="doc-copy-path"
110
+ title="Copy full path"
111
+ onClick={() => {
112
+ void navigator.clipboard.writeText(props.filePath!).then(() => {
113
+ const btn = document.querySelector('.doc-copy-path');
114
+ if (btn) { btn.textContent = 'Copied'; setTimeout(() => { btn.textContent = 'Path'; }, 1200); }
115
+ });
116
+ }}
117
+ >
118
+ Path
119
+ </button>
107
120
  </div>
108
121
  <div className="doc-content">
109
122
  <DocContent filePath={props.filePath} content={content} />
@@ -30,6 +30,22 @@
30
30
  overflow: hidden;
31
31
  text-overflow: ellipsis;
32
32
  white-space: nowrap;
33
+ flex: 1;
34
+ }
35
+ .doc-copy-path {
36
+ font-size: 10px;
37
+ padding: 1px 6px;
38
+ border: 1px solid var(--border-subtle);
39
+ border-radius: 3px;
40
+ background: transparent;
41
+ color: var(--text-dim);
42
+ cursor: pointer;
43
+ flex-shrink: 0;
44
+ margin-left: 6px;
45
+ }
46
+ .doc-copy-path:hover {
47
+ background: var(--border-subtle);
48
+ color: var(--text-base);
33
49
  }
34
50
  .doc-content {
35
51
  flex: 1;
@@ -57,20 +57,9 @@ function titleSupportFromEnvelope(data: MessageEnvelope['data']): DashboardActiv
57
57
  return 'activity' in data || 'latestAssistant' in data ? 'ready' : 'legacy';
58
58
  }
59
59
 
60
- const BUSY_STALE_MS = 2 * 60 * 60_000;
61
-
62
- function parseUtcTimestamp(raw: string): number {
63
- const iso = raw.includes('T') ? raw : raw.replace(' ', 'T');
64
- return Date.parse(iso.endsWith('Z') ? iso : iso + 'Z');
65
- }
66
-
67
- function isActivityBusy(data: MessageEnvelope['data']): boolean {
68
- if (!data || !('activity' in data)) return false;
69
- const activity = data.activity;
70
- if (!activity || activity.role !== 'user') return false;
71
- const updatedAt = parseUtcTimestamp(activity.updatedAt);
72
- if (Number.isNaN(updatedAt)) return false;
73
- return Date.now() - updatedAt < BUSY_STALE_MS;
60
+ function isProcessBusy(data: MessageEnvelope['data']): boolean {
61
+ if (!data || typeof data !== 'object') return false;
62
+ return 'processBusy' in data && data.processBusy === true;
74
63
  }
75
64
 
76
65
  async function fetchLatestAssistantMessage(port: number): Promise<{
@@ -86,7 +75,7 @@ async function fetchLatestAssistantMessage(port: number): Promise<{
86
75
  latest: notifiableAssistantFromEnvelope(body.data),
87
76
  title: activityTitleFromEnvelope(body.data),
88
77
  support: titleSupportFromEnvelope(body.data),
89
- busy: isActivityBusy(body.data),
78
+ busy: isProcessBusy(body.data),
90
79
  };
91
80
  }
92
81
 
@@ -87,7 +87,7 @@ h2 { font-size: 13px; }
87
87
  .command-actions { justify-self: end; }
88
88
  .is-electron-titlebar {
89
89
  -webkit-app-region: drag;
90
- padding-left: 80px;
90
+ padding-left: 96px;
91
91
  }
92
92
  .is-electron-titlebar button,
93
93
  .is-electron-titlebar input,
@@ -55,7 +55,7 @@
55
55
  padding: 6px 10px;
56
56
  }
57
57
  .command-bar.is-electron-titlebar {
58
- padding-left: 80px;
58
+ padding-left: 96px;
59
59
  }
60
60
 
61
61
  .command-primary {
@@ -0,0 +1,107 @@
1
+ import type { DashboardDetailTab, DashboardInstance, DashboardShortcutAction, DashboardSidebarMode } from './types';
2
+ import { panelShortcutBus } from './panels/panel-shortcut-bus';
3
+ import { getDesktop } from './panels/desktop-bridge';
4
+
5
+ /**
6
+ * Dependencies the manager keyboard-shortcut runner needs from <App>.
7
+ * Extracted from App.tsx to keep the component under the dashboard line budget;
8
+ * behaviour is identical — App passes current render values on every call.
9
+ */
10
+ export interface ManagerShortcutRunnerDeps {
11
+ selectedInstance: DashboardInstance | null;
12
+ filtered: DashboardInstance[];
13
+ activeDetailTab: DashboardDetailTab;
14
+ setDrawerOpen: (open: boolean) => void;
15
+ handleSidebarModeChange: (mode: DashboardSidebarMode) => void;
16
+ handlePreview: (instance: DashboardInstance) => void;
17
+ selectRelativeInstance: (direction: 1 | -1) => void;
18
+ handleTabChange: (tab: DashboardDetailTab) => void;
19
+ setPreviewRefreshKey: (updater: (key: number) => number) => void;
20
+ handleSidebarToggle: () => void;
21
+ }
22
+
23
+ export function runManagerShortcut(action: DashboardShortcutAction, deps: ManagerShortcutRunnerDeps): void {
24
+ if (panelShortcutBus.dispatch(action)) return;
25
+ if (action === 'focusInstances') {
26
+ deps.handleSidebarModeChange('instances');
27
+ deps.setDrawerOpen(false);
28
+ return;
29
+ }
30
+ if (action === 'focusActiveSession') {
31
+ const target = deps.selectedInstance?.ok
32
+ ? deps.selectedInstance
33
+ : deps.filtered.find(instance => instance.ok) || null;
34
+ if (target) deps.handlePreview(target);
35
+ else deps.handleSidebarModeChange('instances');
36
+ return;
37
+ }
38
+ if (action === 'focusNotes') {
39
+ deps.handleSidebarModeChange('notes');
40
+ deps.setDrawerOpen(false);
41
+ return;
42
+ }
43
+ if (action === 'previousInstance') {
44
+ deps.selectRelativeInstance(-1);
45
+ return;
46
+ }
47
+ if (action === 'nextInstance') {
48
+ deps.selectRelativeInstance(1);
49
+ return;
50
+ }
51
+ if (action === 'closeFocusedTab') {
52
+ const active = document.activeElement;
53
+ if (active?.closest('.browser-webview-stack, .browser-tab-strip')) {
54
+ document.dispatchEvent(new CustomEvent('jaw:shortcut-action', { detail: 'closeBrowserTab' }));
55
+ } else if (active?.closest('.terminal-panel, .xterm')) {
56
+ document.dispatchEvent(new CustomEvent('jaw:shortcut-action', { detail: 'closeTerminalTab' }));
57
+ } else if (active?.closest('.bottom-panel')) {
58
+ panelShortcutBus.dispatch('closeActiveBottomTab');
59
+ } else if (active?.closest('.right-panel')) {
60
+ panelShortcutBus.dispatch('toggleRightPanel');
61
+ }
62
+ return;
63
+ }
64
+ if (action === 'switchTab1') { deps.handleTabChange('overview'); return; }
65
+ if (action === 'switchTab2') { deps.handleTabChange('preview'); return; }
66
+ if (action === 'switchTab3') { deps.handleTabChange('logs'); return; }
67
+ if (action === 'switchTab4') { deps.handleTabChange('settings'); return; }
68
+ if (action === 'previousTab' || action === 'nextTab') {
69
+ const tabs: DashboardDetailTab[] = ['overview', 'preview', 'logs', 'settings'];
70
+ const idx = tabs.indexOf(deps.activeDetailTab);
71
+ const dir = action === 'nextTab' ? 1 : -1;
72
+ deps.handleTabChange(tabs[(idx + dir + tabs.length) % tabs.length]);
73
+ return;
74
+ }
75
+ if (action === 'browserReload' || action === 'browserHardReload' || action === 'browserFocusUrl' || action === 'browserBack' || action === 'browserForward') {
76
+ const el = document.activeElement;
77
+ if (el?.closest('.browser-webview-stack, .browser-tab-strip, .browser-panel')) {
78
+ document.dispatchEvent(new CustomEvent('jaw:shortcut-action', { detail: action }));
79
+ return;
80
+ }
81
+ // Focus is NOT in the browser panel → reload acts on the preview or app.
82
+ // Preview focus refreshes the preview for both soft and hard (the iframe
83
+ // has no separate hard-reload concept).
84
+ if (action === 'browserReload' || action === 'browserHardReload') {
85
+ if (el?.closest('.preview-panel')) {
86
+ deps.setPreviewRefreshKey(key => key + 1);
87
+ } else if (action === 'browserReload') {
88
+ getDesktop()?.reloadWindow?.();
89
+ } else {
90
+ getDesktop()?.hardReloadWindow?.();
91
+ }
92
+ }
93
+ // browserFocusUrl / Back / Forward are browser-only → no-op outside the panel.
94
+ return;
95
+ }
96
+ if (action === 'terminalClear' || action === 'terminalNewTab') {
97
+ const el = document.activeElement;
98
+ if (el?.closest('.terminal-panel, .xterm')) {
99
+ document.dispatchEvent(new CustomEvent('jaw:shortcut-action', { detail: action }));
100
+ }
101
+ return;
102
+ }
103
+ if (action === 'toggleLeftSidebar') {
104
+ deps.handleSidebarToggle();
105
+ return;
106
+ }
107
+ }
@@ -134,12 +134,27 @@ export function shortcutMatches(event: KeyboardEvent, raw: string): boolean {
134
134
  && resolveEventKey(event) === parsed.key;
135
135
  }
136
136
 
137
+ /**
138
+ * Actions whose keyboard shortcut is owned by the Electron application menu
139
+ * accelerator (single source of truth), so the renderer keydown matcher must
140
+ * NOT also match them — otherwise ⌘R fires twice (menu + keydown). The actions
141
+ * stay in MANAGER_SHORTCUT_ACTIONS so the menu can still dispatch them by name;
142
+ * only the renderer-side keyboard binding is suppressed. This also makes a
143
+ * persisted user keymap carrying Meta+R harmless, and preserves the browser's
144
+ * native ⌘R in a pure web build (no menu, no match → no preventDefault).
145
+ */
146
+ export const RENDERER_DISABLED_SHORTCUT_ACTIONS = new Set<DashboardShortcutAction>([
147
+ 'browserReload',
148
+ 'browserHardReload',
149
+ ]);
150
+
137
151
  export function actionForShortcutEvent(
138
152
  event: KeyboardEvent,
139
153
  keymap: unknown,
140
154
  ): DashboardShortcutAction | null {
141
155
  const shortcuts = normalizeManagerShortcutKeymap(keymap);
142
156
  for (const action of MANAGER_SHORTCUT_ACTIONS) {
157
+ if (RENDERER_DISABLED_SHORTCUT_ACTIONS.has(action)) continue;
143
158
  if (shortcutMatches(event, shortcuts[action])) return action;
144
159
  if (MANAGER_SHORTCUT_ALIASES[action]?.some(shortcut => shortcutMatches(event, shortcut))) return action;
145
160
  }
@@ -91,6 +91,8 @@ export type CliJawDesktopApi = {
91
91
  permissions?: PermissionDiagnosticsBridgeApi | undefined;
92
92
  shortcuts?: ShortcutBridgeApi | undefined;
93
93
  browser?: BrowserBridgeApi | undefined;
94
+ reloadWindow?: (() => void) | undefined;
95
+ hardReloadWindow?: (() => void) | undefined;
94
96
  };
95
97
 
96
98
  export function getDesktop(): CliJawDesktopApi | null {
@@ -21,9 +21,9 @@ const CATEGORIES: SidebarEntry[] = [
21
21
  { id: 'channels-discord', label: 'Channels — Discord', group: 'channels' },
22
22
  { id: 'heartbeat', label: 'Heartbeat & schedules', group: 'automation' },
23
23
  { id: 'memory', label: 'Memory', group: 'automation' },
24
+ { id: 'mcp', label: 'MCP servers', group: 'mcp' },
24
25
  { id: 'speech', label: 'Speech & keys', group: 'integrations' },
25
26
  { id: 'prompts', label: 'Prompts', group: 'integrations' },
26
- { id: 'mcp', label: 'MCP servers', group: 'integrations' },
27
27
  { id: 'browser', label: 'Browser / CDP', group: 'integrations' },
28
28
  { id: 'network', label: 'Network', group: 'network-security' },
29
29
  { id: 'permissions', label: 'Permissions', group: 'network-security' },
@@ -14,6 +14,7 @@ export type SidebarEntry = {
14
14
  export const SIDEBAR_GROUP_ORDER: ReadonlyArray<SettingsCategoryGroup> = [
15
15
  'runtime',
16
16
  'identity',
17
+ 'mcp',
17
18
  'channels',
18
19
  'automation',
19
20
  'integrations',
@@ -24,6 +25,7 @@ export const SIDEBAR_GROUP_ORDER: ReadonlyArray<SettingsCategoryGroup> = [
24
25
  export const SIDEBAR_GROUP_LABELS: Record<SettingsCategoryGroup, string> = {
25
26
  runtime: 'Runtime',
26
27
  identity: 'Identity',
28
+ mcp: 'MCP',
27
29
  channels: 'Channels',
28
30
  automation: 'Automation',
29
31
  integrations: 'Integrations',