cli-jaw 2.1.1 → 2.1.3

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 (477) hide show
  1. package/README.ja.md +8 -6
  2. package/README.ko.md +8 -6
  3. package/README.md +18 -11
  4. package/README.zh-CN.md +8 -6
  5. package/dist/bin/cli-jaw.js +19 -3
  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-search.js +71 -0
  10. package/dist/bin/commands/chat-search.js.map +1 -0
  11. package/dist/bin/commands/chat.js +98 -58
  12. package/dist/bin/commands/chat.js.map +1 -1
  13. package/dist/bin/commands/dispatch.js +130 -5
  14. package/dist/bin/commands/dispatch.js.map +1 -1
  15. package/dist/bin/commands/goal.js +66 -9
  16. package/dist/bin/commands/goal.js.map +1 -1
  17. package/dist/bin/commands/history.js +61 -0
  18. package/dist/bin/commands/history.js.map +1 -0
  19. package/dist/bin/commands/lock.js +104 -0
  20. package/dist/bin/commands/lock.js.map +1 -0
  21. package/dist/bin/commands/memory.js +23 -2
  22. package/dist/bin/commands/memory.js.map +1 -1
  23. package/dist/bin/commands/orchestrate.js.map +1 -1
  24. package/dist/bin/commands/project.js +4 -1
  25. package/dist/bin/commands/project.js.map +1 -1
  26. package/dist/bin/commands/tui/fullscreen-mode.js +237 -0
  27. package/dist/bin/commands/tui/fullscreen-mode.js.map +1 -0
  28. package/dist/bin/commands/tui/input-handler.js +139 -52
  29. package/dist/bin/commands/tui/input-handler.js.map +1 -1
  30. package/dist/bin/commands/tui/overlays.js +177 -70
  31. package/dist/bin/commands/tui/overlays.js.map +1 -1
  32. package/dist/bin/commands/tui/renderer.js +70 -20
  33. package/dist/bin/commands/tui/renderer.js.map +1 -1
  34. package/dist/bin/commands/tui/simple-mode.js +1 -2
  35. package/dist/bin/commands/tui/simple-mode.js.map +1 -1
  36. package/dist/bin/commands/tui/tui-io.js +8 -0
  37. package/dist/bin/commands/tui/tui-io.js.map +1 -0
  38. package/dist/bin/commands/tui/types.js +9 -0
  39. package/dist/bin/commands/tui/types.js.map +1 -1
  40. package/dist/bin/commands/tui/ws-handler.js +115 -23
  41. package/dist/bin/commands/tui/ws-handler.js.map +1 -1
  42. package/dist/bin/commands/worker.js +159 -0
  43. package/dist/bin/commands/worker.js.map +1 -0
  44. package/dist/bin/postinstall.js +0 -76
  45. package/dist/bin/postinstall.js.map +1 -1
  46. package/dist/lib/mcp/format-converters.js +21 -2
  47. package/dist/lib/mcp/format-converters.js.map +1 -1
  48. package/dist/lib/mcp/mcp-registry.js +75 -0
  49. package/dist/lib/mcp/mcp-registry.js.map +1 -0
  50. package/dist/lib/stt.js +1 -1
  51. package/dist/lib/stt.js.map +1 -1
  52. package/dist/lib/upload.js +7 -0
  53. package/dist/lib/upload.js.map +1 -1
  54. package/dist/scripts/fresh-install-smoke.js +1 -1
  55. package/dist/scripts/fresh-install-smoke.js.map +1 -1
  56. package/dist/server.js +151 -22
  57. package/dist/server.js.map +1 -1
  58. package/dist/src/agent/agy-runtime.js +1 -0
  59. package/dist/src/agent/agy-runtime.js.map +1 -1
  60. package/dist/src/agent/agy-transcript-watcher.js +78 -0
  61. package/dist/src/agent/agy-transcript-watcher.js.map +1 -0
  62. package/dist/src/agent/agy-transcript.js +158 -0
  63. package/dist/src/agent/agy-transcript.js.map +1 -0
  64. package/dist/src/agent/args.js +51 -5
  65. package/dist/src/agent/args.js.map +1 -1
  66. package/dist/src/agent/claude-e-runtime.js +1 -1
  67. package/dist/src/agent/claude-e-runtime.js.map +1 -1
  68. package/dist/src/agent/codex-app-client.js +2 -2
  69. package/dist/src/agent/codex-app-client.js.map +1 -1
  70. package/dist/src/agent/cursor-runtime.js +1 -0
  71. package/dist/src/agent/cursor-runtime.js.map +1 -1
  72. package/dist/src/agent/error-classifier.js +6 -1
  73. package/dist/src/agent/error-classifier.js.map +1 -1
  74. package/dist/src/agent/events/claude.js +1 -0
  75. package/dist/src/agent/events/claude.js.map +1 -1
  76. package/dist/src/agent/events/codex.js +0 -44
  77. package/dist/src/agent/events/codex.js.map +1 -1
  78. package/dist/src/agent/events/helpers.js +52 -5
  79. package/dist/src/agent/events/helpers.js.map +1 -1
  80. package/dist/src/agent/events/opencode.js +6 -2
  81. package/dist/src/agent/events/opencode.js.map +1 -1
  82. package/dist/src/agent/events/summary.js +3 -2
  83. package/dist/src/agent/events/summary.js.map +1 -1
  84. package/dist/src/agent/events/tool-labels.js +8 -5
  85. package/dist/src/agent/events/tool-labels.js.map +1 -1
  86. package/dist/src/agent/kiro-auth.js +213 -0
  87. package/dist/src/agent/kiro-auth.js.map +1 -0
  88. package/dist/src/agent/kiro-models.js +79 -0
  89. package/dist/src/agent/kiro-models.js.map +1 -0
  90. package/dist/src/agent/kiro-runtime.js +314 -0
  91. package/dist/src/agent/kiro-runtime.js.map +1 -0
  92. package/dist/src/agent/lifecycle-handler.js +208 -23
  93. package/dist/src/agent/lifecycle-handler.js.map +1 -1
  94. package/dist/src/agent/memory-flush-controller.js +3 -4
  95. package/dist/src/agent/memory-flush-controller.js.map +1 -1
  96. package/dist/src/agent/resume-classifier.js +18 -1
  97. package/dist/src/agent/resume-classifier.js.map +1 -1
  98. package/dist/src/agent/session-persistence.js +2 -2
  99. package/dist/src/agent/session-persistence.js.map +1 -1
  100. package/dist/src/agent/smoke-detector.js +3 -0
  101. package/dist/src/agent/smoke-detector.js.map +1 -1
  102. package/dist/src/agent/spawn/queue.js +11 -5
  103. package/dist/src/agent/spawn/queue.js.map +1 -1
  104. package/dist/src/agent/spawn/resume.js +6 -1
  105. package/dist/src/agent/spawn/resume.js.map +1 -1
  106. package/dist/src/agent/spawn-env.js +1 -1
  107. package/dist/src/agent/spawn-env.js.map +1 -1
  108. package/dist/src/agent/spawn.js +231 -43
  109. package/dist/src/agent/spawn.js.map +1 -1
  110. package/dist/src/agent/watchdog.js +1 -1
  111. package/dist/src/agent/watchdog.js.map +1 -1
  112. package/dist/src/browser/actions.js +0 -8
  113. package/dist/src/browser/actions.js.map +1 -1
  114. package/dist/src/browser/adaptive-fetch/browser-escalation.js +5 -29
  115. package/dist/src/browser/adaptive-fetch/browser-escalation.js.map +1 -1
  116. package/dist/src/browser/adaptive-fetch/browser-runtime.js +5 -14
  117. package/dist/src/browser/adaptive-fetch/browser-runtime.js.map +1 -1
  118. package/dist/src/browser/adaptive-fetch/browser-session.js +14 -28
  119. package/dist/src/browser/adaptive-fetch/browser-session.js.map +1 -1
  120. package/dist/src/browser/adaptive-fetch/challenge-detector.js +4 -26
  121. package/dist/src/browser/adaptive-fetch/challenge-detector.js.map +1 -1
  122. package/dist/src/browser/adaptive-fetch/content-scorer.js +5 -29
  123. package/dist/src/browser/adaptive-fetch/content-scorer.js.map +1 -1
  124. package/dist/src/browser/adaptive-fetch/endpoint-resolvers.js +0 -64
  125. package/dist/src/browser/adaptive-fetch/endpoint-resolvers.js.map +1 -1
  126. package/dist/src/browser/adaptive-fetch/fetcher.js +4 -19
  127. package/dist/src/browser/adaptive-fetch/fetcher.js.map +1 -1
  128. package/dist/src/browser/adaptive-fetch/human-loop.js +0 -26
  129. package/dist/src/browser/adaptive-fetch/human-loop.js.map +1 -1
  130. package/dist/src/browser/adaptive-fetch/index.js +74 -145
  131. package/dist/src/browser/adaptive-fetch/index.js.map +1 -1
  132. package/dist/src/browser/adaptive-fetch/metadata.js +1 -41
  133. package/dist/src/browser/adaptive-fetch/metadata.js.map +1 -1
  134. package/dist/src/browser/adaptive-fetch/output.js +1 -18
  135. package/dist/src/browser/adaptive-fetch/output.js.map +1 -1
  136. package/dist/src/browser/adaptive-fetch/reader-adapters.js +43 -75
  137. package/dist/src/browser/adaptive-fetch/reader-adapters.js.map +1 -1
  138. package/dist/src/browser/adaptive-fetch/safety.js +5 -48
  139. package/dist/src/browser/adaptive-fetch/safety.js.map +1 -1
  140. package/dist/src/browser/adaptive-fetch/third-party-readers.js +0 -11
  141. package/dist/src/browser/adaptive-fetch/third-party-readers.js.map +1 -1
  142. package/dist/src/browser/adaptive-fetch/trace.js +3 -18
  143. package/dist/src/browser/adaptive-fetch/trace.js.map +1 -1
  144. package/dist/src/browser/adaptive-fetch/transforms.js +0 -23
  145. package/dist/src/browser/adaptive-fetch/transforms.js.map +1 -1
  146. package/dist/src/browser/adaptive-fetch/types.js +3 -0
  147. package/dist/src/browser/adaptive-fetch/types.js.map +1 -0
  148. package/dist/src/browser/adaptive-fetch/validators.js +0 -17
  149. package/dist/src/browser/adaptive-fetch/validators.js.map +1 -1
  150. package/dist/src/browser/adaptive-fetch/waf-profiles.js +0 -10
  151. package/dist/src/browser/adaptive-fetch/waf-profiles.js.map +1 -1
  152. package/dist/src/browser/connection.js +1 -1
  153. package/dist/src/browser/connection.js.map +1 -1
  154. package/dist/src/browser/web-ai/chatgpt-response.js +0 -1
  155. package/dist/src/browser/web-ai/chatgpt-response.js.map +1 -1
  156. package/dist/src/browser/web-ai/chatgpt.js +0 -33
  157. package/dist/src/browser/web-ai/chatgpt.js.map +1 -1
  158. package/dist/src/browser/web-ai/diagnostics.js +0 -16
  159. package/dist/src/browser/web-ai/diagnostics.js.map +1 -1
  160. package/dist/src/browser/web-ai/doctor.js.map +1 -1
  161. package/dist/src/browser/web-ai/errors.js +1 -1
  162. package/dist/src/browser/web-ai/errors.js.map +1 -1
  163. package/dist/src/browser/web-ai/grok-live.js +2 -0
  164. package/dist/src/browser/web-ai/grok-live.js.map +1 -1
  165. package/dist/src/cli/claude-models.js +2 -2
  166. package/dist/src/cli/claude-models.js.map +1 -1
  167. package/dist/src/cli/command-context.js.map +1 -1
  168. package/dist/src/cli/commands.js +16 -4
  169. package/dist/src/cli/commands.js.map +1 -1
  170. package/dist/src/cli/compact.js +2 -1
  171. package/dist/src/cli/compact.js.map +1 -1
  172. package/dist/src/cli/handlers/session-handlers.js +34 -0
  173. package/dist/src/cli/handlers/session-handlers.js.map +1 -0
  174. package/dist/src/cli/handlers-project.js.map +1 -1
  175. package/dist/src/cli/handlers-runtime.js +2 -0
  176. package/dist/src/cli/handlers-runtime.js.map +1 -1
  177. package/dist/src/cli/handlers-workflows.js +85 -17
  178. package/dist/src/cli/handlers-workflows.js.map +1 -1
  179. package/dist/src/cli/handlers.js +84 -43
  180. package/dist/src/cli/handlers.js.map +1 -1
  181. package/dist/src/cli/readiness.js +17 -1
  182. package/dist/src/cli/readiness.js.map +1 -1
  183. package/dist/src/cli/registry-live.js +17 -0
  184. package/dist/src/cli/registry-live.js.map +1 -0
  185. package/dist/src/cli/registry.js +51 -10
  186. package/dist/src/cli/registry.js.map +1 -1
  187. package/dist/src/cli/tui/composer.js +135 -5
  188. package/dist/src/cli/tui/composer.js.map +1 -1
  189. package/dist/src/cli/tui/diffview.js +41 -0
  190. package/dist/src/cli/tui/diffview.js.map +1 -0
  191. package/dist/src/cli/tui/editor.js +45 -0
  192. package/dist/src/cli/tui/editor.js.map +1 -0
  193. package/dist/src/cli/tui/file-mention.js +78 -0
  194. package/dist/src/cli/tui/file-mention.js.map +1 -0
  195. package/dist/src/cli/tui/highlight.js +82 -0
  196. package/dist/src/cli/tui/highlight.js.map +1 -0
  197. package/dist/src/cli/tui/keymap.js +21 -0
  198. package/dist/src/cli/tui/keymap.js.map +1 -1
  199. package/dist/src/cli/tui/markdown.js +124 -0
  200. package/dist/src/cli/tui/markdown.js.map +1 -0
  201. package/dist/src/cli/tui/mode.js +26 -0
  202. package/dist/src/cli/tui/mode.js.map +1 -0
  203. package/dist/src/cli/tui/overlay.js +121 -98
  204. package/dist/src/cli/tui/overlay.js.map +1 -1
  205. package/dist/src/cli/tui/render/frame.js +72 -0
  206. package/dist/src/cli/tui/render/frame.js.map +1 -0
  207. package/dist/src/cli/tui/render/layout.js +22 -0
  208. package/dist/src/cli/tui/render/layout.js.map +1 -0
  209. package/dist/src/cli/tui/render/mouse.js +25 -0
  210. package/dist/src/cli/tui/render/mouse.js.map +1 -0
  211. package/dist/src/cli/tui/render/scheduler.js +37 -0
  212. package/dist/src/cli/tui/render/scheduler.js.map +1 -0
  213. package/dist/src/cli/tui/render/viewport.js +82 -0
  214. package/dist/src/cli/tui/render/viewport.js.map +1 -0
  215. package/dist/src/cli/tui/renderers.js +37 -0
  216. package/dist/src/cli/tui/renderers.js.map +1 -1
  217. package/dist/src/cli/tui/stream.js +48 -0
  218. package/dist/src/cli/tui/stream.js.map +1 -0
  219. package/dist/src/cli/tui/text-buffer.js +143 -0
  220. package/dist/src/cli/tui/text-buffer.js.map +1 -0
  221. package/dist/src/cli/tui/theme.js +128 -0
  222. package/dist/src/cli/tui/theme.js.map +1 -0
  223. package/dist/src/cli/tui/transcript.js +4 -0
  224. package/dist/src/cli/tui/transcript.js.map +1 -1
  225. package/dist/src/command-contract/help-renderer.js +1 -1
  226. package/dist/src/command-contract/help-renderer.js.map +1 -1
  227. package/dist/src/core/chat-sessions.js +63 -0
  228. package/dist/src/core/chat-sessions.js.map +1 -0
  229. package/dist/src/core/cli-detection.js +14 -0
  230. package/dist/src/core/cli-detection.js.map +1 -1
  231. package/dist/src/core/compact.js +43 -11
  232. package/dist/src/core/compact.js.map +1 -1
  233. package/dist/src/core/config.js +14 -1
  234. package/dist/src/core/config.js.map +1 -1
  235. package/dist/src/core/db.js +52 -12
  236. package/dist/src/core/db.js.map +1 -1
  237. package/dist/src/core/employees.js +2 -2
  238. package/dist/src/core/employees.js.map +1 -1
  239. package/dist/src/core/main-session.js +3 -2
  240. package/dist/src/core/main-session.js.map +1 -1
  241. package/dist/src/discord/bot.js.map +1 -1
  242. package/dist/src/discord/discord-file.js +1 -1
  243. package/dist/src/discord/discord-file.js.map +1 -1
  244. package/dist/src/discord/send-only-client.js +1 -3
  245. package/dist/src/discord/send-only-client.js.map +1 -1
  246. package/dist/src/goal/heartbeat.js +113 -7
  247. package/dist/src/goal/heartbeat.js.map +1 -1
  248. package/dist/src/goal/store.js +44 -5
  249. package/dist/src/goal/store.js.map +1 -1
  250. package/dist/src/ide/diff.js +37 -0
  251. package/dist/src/ide/diff.js.map +1 -1
  252. package/dist/src/manager/launchd-service.js +1 -1
  253. package/dist/src/manager/launchd-service.js.map +1 -1
  254. package/dist/src/manager/lifecycle-helpers.js +14 -0
  255. package/dist/src/manager/lifecycle-helpers.js.map +1 -1
  256. package/dist/src/manager/lifecycle-store.js.map +1 -1
  257. package/dist/src/manager/lifecycle.js +94 -5
  258. package/dist/src/manager/lifecycle.js.map +1 -1
  259. package/dist/src/manager/notes/routes.js +0 -31
  260. package/dist/src/manager/notes/routes.js.map +1 -1
  261. package/dist/src/manager/notes/ws.js.map +1 -1
  262. package/dist/src/manager/preview-link-policy.js +11 -4
  263. package/dist/src/manager/preview-link-policy.js.map +1 -1
  264. package/dist/src/manager/registry.js.map +1 -1
  265. package/dist/src/manager/routes/dashboard-memory.js.map +1 -1
  266. package/dist/src/manager/scan.js +36 -1
  267. package/dist/src/manager/scan.js.map +1 -1
  268. package/dist/src/manager/server.js +42 -7
  269. package/dist/src/manager/server.js.map +1 -1
  270. package/dist/src/manager/shutdown.js +8 -3
  271. package/dist/src/manager/shutdown.js.map +1 -1
  272. package/dist/src/manager/systemd-service.js +1 -1
  273. package/dist/src/manager/systemd-service.js.map +1 -1
  274. package/dist/src/memory/indexing.js +49 -1
  275. package/dist/src/memory/indexing.js.map +1 -1
  276. package/dist/src/memory/keyword-expand.js +0 -187
  277. package/dist/src/memory/keyword-expand.js.map +1 -1
  278. package/dist/src/memory/runtime.js +3 -2
  279. package/dist/src/memory/runtime.js.map +1 -1
  280. package/dist/src/memory/shared.js.map +1 -1
  281. package/dist/src/messaging/send.js +66 -7
  282. package/dist/src/messaging/send.js.map +1 -1
  283. package/dist/src/orchestrator/collect.js +3 -2
  284. package/dist/src/orchestrator/collect.js.map +1 -1
  285. package/dist/src/orchestrator/distribute.js +9 -3
  286. package/dist/src/orchestrator/distribute.js.map +1 -1
  287. package/dist/src/orchestrator/friction.js +59 -0
  288. package/dist/src/orchestrator/friction.js.map +1 -0
  289. package/dist/src/orchestrator/gateway.js +4 -4
  290. package/dist/src/orchestrator/gateway.js.map +1 -1
  291. package/dist/src/orchestrator/pipeline.js +89 -45
  292. package/dist/src/orchestrator/pipeline.js.map +1 -1
  293. package/dist/src/orchestrator/sanitize.js +69 -0
  294. package/dist/src/orchestrator/sanitize.js.map +1 -0
  295. package/dist/src/orchestrator/seed.js +50 -0
  296. package/dist/src/orchestrator/seed.js.map +1 -0
  297. package/dist/src/orchestrator/state-machine.js +215 -76
  298. package/dist/src/orchestrator/state-machine.js.map +1 -1
  299. package/dist/src/orchestrator/worker-monitor.js +1 -1
  300. package/dist/src/orchestrator/worker-monitor.js.map +1 -1
  301. package/dist/src/orchestrator/worker-progress.js +29 -0
  302. package/dist/src/orchestrator/worker-progress.js.map +1 -0
  303. package/dist/src/orchestrator/worker-registry.js +63 -2
  304. package/dist/src/orchestrator/worker-registry.js.map +1 -1
  305. package/dist/src/prompt/builder.js +190 -115
  306. package/dist/src/prompt/builder.js.map +1 -1
  307. package/dist/src/prompt/templates/a1-system.md +124 -61
  308. package/dist/src/prompt/templates/control-system.md +2 -2
  309. package/dist/src/prompt/templates/employee.md +41 -56
  310. package/dist/src/prompt/templates/orchestration.md +23 -8
  311. package/dist/src/prompt/templates/skills.md +6 -0
  312. package/dist/src/routes/browser.js +3 -3
  313. package/dist/src/routes/browser.js.map +1 -1
  314. package/dist/src/routes/employees.js +4 -4
  315. package/dist/src/routes/employees.js.map +1 -1
  316. package/dist/src/routes/goal.js +48 -4
  317. package/dist/src/routes/goal.js.map +1 -1
  318. package/dist/src/routes/heartbeat.js +1 -1
  319. package/dist/src/routes/heartbeat.js.map +1 -1
  320. package/dist/src/routes/i18n.js +1 -1
  321. package/dist/src/routes/i18n.js.map +1 -1
  322. package/dist/src/routes/jaw-memory.js +1 -1
  323. package/dist/src/routes/jaw-memory.js.map +1 -1
  324. package/dist/src/routes/memory.js.map +1 -1
  325. package/dist/src/routes/messaging.js +8 -3
  326. package/dist/src/routes/messaging.js.map +1 -1
  327. package/dist/src/routes/orchestrate.js +267 -117
  328. package/dist/src/routes/orchestrate.js.map +1 -1
  329. package/dist/src/routes/quota-agy-reverse.js +6 -5
  330. package/dist/src/routes/quota-agy-reverse.js.map +1 -1
  331. package/dist/src/routes/quota-kiro-reverse.js +187 -0
  332. package/dist/src/routes/quota-kiro-reverse.js.map +1 -0
  333. package/dist/src/routes/quota.js +68 -6
  334. package/dist/src/routes/quota.js.map +1 -1
  335. package/dist/src/routes/settings.js +37 -8
  336. package/dist/src/routes/settings.js.map +1 -1
  337. package/dist/src/routes/skills.js.map +1 -1
  338. package/dist/src/security/path-guards.js +0 -3
  339. package/dist/src/security/path-guards.js.map +1 -1
  340. package/dist/src/security/security-audit-log.js.map +1 -1
  341. package/dist/src/shared/shell-command-display.js +51 -0
  342. package/dist/src/shared/shell-command-display.js.map +1 -0
  343. package/dist/src/telegram/bot.js.map +1 -1
  344. package/dist/src/trace/store.js +32 -0
  345. package/dist/src/trace/store.js.map +1 -1
  346. package/dist/src/types/cli-engine.js +1 -0
  347. package/dist/src/types/cli-engine.js.map +1 -1
  348. package/dist/src/workflows/employee-boundary.js +7 -7
  349. package/dist/src/workflows/employee-boundary.js.map +1 -1
  350. package/dist/src/workflows/handoff.js +16 -16
  351. package/dist/src/workflows/handoff.js.map +1 -1
  352. package/dist/src/workflows/scope-sandbox.js +58 -0
  353. package/dist/src/workflows/scope-sandbox.js.map +1 -0
  354. package/package.json +1 -1
  355. package/public/assets/providers/kiro-color.svg +15 -0
  356. package/public/assets/providers/kiro.svg +14 -0
  357. package/public/css/chat.css +27 -0
  358. package/public/css/modals.css +79 -0
  359. package/public/css/orc-state.css +10 -6
  360. package/public/css/sidebar.css +85 -0
  361. package/public/css/variables.css +6 -2
  362. package/public/dist/assets/{Agent-CIUGaUVn.js → Agent-DBKNQ6tp.js} +1 -1
  363. package/public/dist/assets/{DocPanel-C1pGgE-S.js → DocPanel-BU16GUlB.js} +1 -1
  364. package/public/dist/assets/DocPanel-gU-WkgyA.css +1 -0
  365. package/public/dist/assets/Employees-F0ssNuO-.js +1 -0
  366. package/public/dist/assets/{FolderPanel-DSkanaGN.js → FolderPanel-DT0fU8f2.js} +1 -1
  367. package/public/dist/assets/Heartbeat-fsuLzY9c.js +1 -0
  368. package/public/dist/assets/Mcp-_Yq4N3Sk.js +4 -0
  369. package/public/dist/assets/{Memory-BgN8djV4.js → Memory-CRR8kotI.js} +1 -1
  370. package/public/dist/assets/{ModelProvider-DHQ1Zvw0.js → ModelProvider-DQgISbKw.js} +1 -1
  371. package/public/dist/assets/agent-meta-C4mauPL5.js +1 -0
  372. package/public/dist/assets/app-0OQhPpTG.css +1 -0
  373. package/public/dist/assets/app-CSqIyg9A.js +55 -0
  374. package/public/dist/assets/constants-BHMkzpN_.js +1 -0
  375. package/public/dist/assets/{employees-DiNLzEXS.js → employees-CZdWHH-r.js} +7 -7
  376. package/public/dist/assets/idb-cache-0LNMskFB.js +1 -0
  377. package/public/dist/assets/idb-cache-5H89a4l8.js +1 -0
  378. package/public/dist/assets/manager-CGTQ5EIm.js +12 -0
  379. package/public/dist/assets/manager-UBunDqMH.css +1 -0
  380. package/public/dist/assets/{memory-B_nn0A4v.js → memory-B3QSmj_e.js} +9 -9
  381. package/public/dist/assets/memory-DOBqiuPc.js +1 -0
  382. package/public/dist/assets/{provider-icons-XEfJPGTe.js → provider-icons-Crv6yvlG.js} +35 -6
  383. package/public/dist/assets/render-J11oxfnl.js +28 -0
  384. package/public/dist/assets/settings-BV_2Bh0_.js +1 -0
  385. package/public/dist/assets/settings-m_cim0ov.js +151 -0
  386. package/public/dist/assets/sidebar-ZBXdBgF7.js +49 -0
  387. package/public/dist/assets/{skills-COa4iSwL.js → skills-CjaBmIPV.js} +6 -6
  388. package/public/dist/assets/skills-Xm3fl1zr.js +1 -0
  389. package/public/dist/assets/{slash-commands-C_ePvrPi.js → slash-commands-71jc07Wf.js} +1 -1
  390. package/public/dist/assets/slash-commands-BO6ssnAz.js +1 -0
  391. package/public/dist/assets/{trace-drawer-CY4z_Ie8.js → trace-drawer-Czvf2P2o.js} +1 -1
  392. package/public/dist/assets/ui-CverZJnd.js +1 -0
  393. package/public/dist/assets/ui-qKxy-4p9.js +142 -0
  394. package/public/dist/index.html +113 -86
  395. package/public/dist/manager/index.html +2 -2
  396. package/public/index.html +111 -84
  397. package/public/js/constants.ts +34 -11
  398. package/public/js/features/chat-messages.ts +13 -2
  399. package/public/js/features/chat-search.ts +5 -1
  400. package/public/js/features/chat.ts +86 -44
  401. package/public/js/features/employees.ts +7 -2
  402. package/public/js/features/idb-cache.ts +4 -0
  403. package/public/js/features/media-lightbox.ts +40 -0
  404. package/public/js/features/message-history.ts +55 -7
  405. package/public/js/features/pending-queue.ts +28 -4
  406. package/public/js/features/process-block.ts +32 -17
  407. package/public/js/features/process-log-adapter.ts +11 -2
  408. package/public/js/features/settings-cli-status-render.ts +161 -0
  409. package/public/js/features/settings-cli-status.ts +136 -187
  410. package/public/js/features/settings-core.ts +5 -1
  411. package/public/js/features/settings-mcp.ts +513 -7
  412. package/public/js/features/settings-types.ts +1 -0
  413. package/public/js/features/settings.ts +1 -1
  414. package/public/js/features/tool-ui.ts +18 -4
  415. package/public/js/features/transport-status-row.ts +3 -0
  416. package/public/js/features/ui-status.ts +5 -1
  417. package/public/js/main.ts +5 -0
  418. package/public/js/preview-parent-origin.ts +14 -0
  419. package/public/js/provider-icons.ts +6 -1
  420. package/public/js/render/file-links.ts +10 -2
  421. package/public/js/render/markdown.ts +16 -0
  422. package/public/js/ui.ts +8 -1
  423. package/public/js/virtual-scroll.ts +19 -0
  424. package/public/js/ws.ts +151 -15
  425. package/public/locales/en.json +9 -2
  426. package/public/locales/ja.json +9 -2
  427. package/public/locales/ko.json +9 -2
  428. package/public/locales/zh.json +9 -2
  429. package/public/manager/src/App.tsx +13 -70
  430. package/public/manager/src/InstancePreview.tsx +56 -11
  431. package/public/manager/src/SidebarRailRouter.tsx +32 -4
  432. package/public/manager/src/components/InstanceRow.tsx +0 -1
  433. package/public/manager/src/components/WorkbenchHeader.tsx +17 -7
  434. package/public/manager/src/doc-panel/DocPanel.tsx +14 -1
  435. package/public/manager/src/doc-panel/doc-panel.css +16 -0
  436. package/public/manager/src/folder-panel/FolderPanel.tsx +13 -2
  437. package/public/manager/src/hooks/useElectronDroppedPaths.ts +89 -0
  438. package/public/manager/src/hooks/useInstanceMessageEvents.ts +4 -15
  439. package/public/manager/src/manager-components.css +35 -1
  440. package/public/manager/src/manager-polish.css +11 -1
  441. package/public/manager/src/manager-shortcut-runner.ts +107 -0
  442. package/public/manager/src/manager-shortcuts.ts +15 -0
  443. package/public/manager/src/panels/desktop-bridge.ts +13 -0
  444. package/public/manager/src/settings/SettingsSidebar.tsx +1 -1
  445. package/public/manager/src/settings/components/sidebar-filter.ts +2 -0
  446. package/public/manager/src/settings/pages/Mcp.tsx +311 -43
  447. package/public/manager/src/settings/pages/components/McpServerCard.tsx +89 -55
  448. package/public/manager/src/settings/pages/components/agent/agent-meta.ts +32 -9
  449. package/public/manager/src/settings/pages/components/employees-helpers.ts +1 -0
  450. package/public/manager/src/settings/pages/components/heartbeat-helpers.ts +1 -0
  451. package/public/manager/src/settings/pages/mcp-helpers.ts +54 -12
  452. package/public/manager/src/settings/types.ts +1 -0
  453. package/public/manager/src/types.ts +2 -1
  454. package/scripts/fresh-install-smoke.ts +1 -1
  455. package/scripts/smoke/agy-transcript-tail-smoke.mjs +89 -0
  456. package/public/dist/assets/DocPanel-CL1scIfq.css +0 -1
  457. package/public/dist/assets/Employees-BL9MAzzx.js +0 -1
  458. package/public/dist/assets/Heartbeat-D64JCg4t.js +0 -1
  459. package/public/dist/assets/Mcp-wYwJA_61.js +0 -3
  460. package/public/dist/assets/agent-meta-BhEbjy4P.js +0 -1
  461. package/public/dist/assets/app-2Rz848bQ.js +0 -48
  462. package/public/dist/assets/app-BW-Xz2p6.css +0 -1
  463. package/public/dist/assets/constants-ahKI_aEG.js +0 -1
  464. package/public/dist/assets/idb-cache-BnZfG5FD.js +0 -1
  465. package/public/dist/assets/idb-cache-CZ3JdK8r.js +0 -1
  466. package/public/dist/assets/manager-CfyZloIP.js +0 -12
  467. package/public/dist/assets/manager-DyrwJLZr.css +0 -1
  468. package/public/dist/assets/memory-CCjNFWmO.js +0 -1
  469. package/public/dist/assets/render-CgDEBoCX.js +0 -28
  470. package/public/dist/assets/settings-CY_6tGuS.js +0 -1
  471. package/public/dist/assets/settings-DWW4GzNc.js +0 -66
  472. package/public/dist/assets/sidebar-DQKE5IA1.js +0 -23
  473. package/public/dist/assets/skills-DYTlqoke.js +0 -1
  474. package/public/dist/assets/slash-commands-D7CU5oso.js +0 -1
  475. package/public/dist/assets/ui-Car1OUvV.js +0 -1
  476. package/public/dist/assets/ui-DK_9ndj0.js +0 -140
  477. /package/public/dist/assets/{locale-DT1WRaeJ.js → locale-BHMJIzyw.js} +0 -0
@@ -26,21 +26,22 @@ const FALLBACK_CLI_REGISTRY: CliRegistry = {
26
26
  'ai-e': {
27
27
  label: 'AI-E',
28
28
  defaultProvider: 'claude',
29
- providers: ['claude', 'codex', 'gemini', 'grok', 'copilot'],
29
+ providers: ['claude', 'codex', 'gemini', 'grok', 'copilot', 'kiro'],
30
30
  efforts: ['low', 'medium', 'high', 'xhigh', 'max'],
31
31
  models: [
32
32
  'opus', 'sonnet', 'haiku',
33
- 'gpt-5.4', 'gpt-5.4-mini',
33
+ 'gpt-5.5', 'gpt-5.4', 'gpt-5.4-mini',
34
34
  'gemini-3-flash-preview',
35
- 'grok-build',
35
+ 'grok-build', 'grok-composer-2.5-fast',
36
36
  'gpt-5-mini',
37
37
  ],
38
38
  modelsByProvider: {
39
- claude: ['opus', 'sonnet', 'haiku'],
40
- codex: ['gpt-5.4', 'gpt-5.4-mini'],
39
+ claude: ['claude-opus-4-8', 'opus', 'sonnet', 'haiku'],
40
+ codex: ['gpt-5.5', 'gpt-5.4', 'gpt-5.4-mini'],
41
41
  gemini: ['gemini-3-flash-preview'],
42
- grok: ['grok-build'],
42
+ grok: ['grok-build', 'grok-composer-2.5-fast'],
43
43
  copilot: ['gpt-5-mini'],
44
+ kiro: ['auto', 'claude-sonnet-4.6', 'deepseek-3.2', 'minimax-m2.5', 'glm-5', 'qwen3-coder-next'],
44
45
  },
45
46
  effortsByProvider: {
46
47
  claude: ['low', 'medium', 'high', 'xhigh', 'max'],
@@ -48,6 +49,7 @@ const FALLBACK_CLI_REGISTRY: CliRegistry = {
48
49
  gemini: [],
49
50
  grok: [],
50
51
  copilot: ['low', 'medium', 'high'],
52
+ kiro: [],
51
53
  },
52
54
  },
53
55
  claude: {
@@ -55,8 +57,8 @@ const FALLBACK_CLI_REGISTRY: CliRegistry = {
55
57
  efforts: ['low', 'medium', 'high', 'xhigh', 'max'],
56
58
  // Mirrors getDefaultClaudeChoices() in src/cli/claude-models.ts —
57
59
  // aliases first, then verified pinned full IDs (hyphen form). The
58
- // [1m] suffix activates Claude Code's 1M-context window (Opus 4.7,
59
- // Opus 4.6, Sonnet 4.6 only).
60
+ // [1m] suffix activates Claude Code's 1M-context window (Opus 4.8,
61
+ // Opus 4.7, Opus 4.6, Sonnet 4.6).
60
62
  models: [
61
63
  'opus',
62
64
  'sonnet',
@@ -113,6 +115,27 @@ const FALLBACK_CLI_REGISTRY: CliRegistry = {
113
115
  'grok-4.3', 'grok-build-0.1', 'gpt-5-mini', 'kimi-k2.5',
114
116
  ],
115
117
  },
118
+ 'kiro-code': {
119
+ label: 'Kiro',
120
+ efforts: [],
121
+ effortNote: 'Kiro CLI has no separate effort flag',
122
+ models: [
123
+ 'auto',
124
+ 'claude-opus-4.8',
125
+ 'claude-opus-4.7',
126
+ 'claude-opus-4.6',
127
+ 'claude-sonnet-4.6',
128
+ 'claude-opus-4.5',
129
+ 'claude-sonnet-4.5',
130
+ 'claude-sonnet-4',
131
+ 'claude-haiku-4.5',
132
+ 'deepseek-3.2',
133
+ 'minimax-m2.5',
134
+ 'minimax-m2.1',
135
+ 'glm-5',
136
+ 'qwen3-coder-next',
137
+ ],
138
+ },
116
139
  gemini: {
117
140
  label: 'Gemini',
118
141
  efforts: [],
@@ -121,8 +144,8 @@ const FALLBACK_CLI_REGISTRY: CliRegistry = {
121
144
  grok: {
122
145
  label: 'Grok',
123
146
  efforts: [],
124
- effortNote: 'unsupported by grok-build; do not pass --effort',
125
- models: ['grok-build'],
147
+ effortNote: 'unsupported by grok-build/composer; do not pass --effort',
148
+ models: ['grok-build', 'grok-composer-2.5-fast'],
126
149
  },
127
150
  opencode: {
128
151
  label: 'OpenCode',
@@ -237,7 +260,7 @@ export function getCliMeta(cli: string): CliEntry | null {
237
260
  return CLI_REGISTRY[cli] || null;
238
261
  }
239
262
 
240
- export const PRIMARY_CLIS: readonly string[] = ['claude', 'claude-e', 'agy', 'codex', 'cursor', 'gemini'];
263
+ export const PRIMARY_CLIS: readonly string[] = ['claude', 'claude-e', 'agy', 'codex', 'cursor', 'kiro-code', 'gemini'];
241
264
 
242
265
  export interface RolePreset {
243
266
  value: string;
@@ -8,6 +8,7 @@ import { getAppName } from './appname.js';
8
8
  import { getAgentAvatarMarkup, getUserAvatarMarkup } from './avatar.js';
9
9
  import { t } from './i18n.js';
10
10
  import { renderMessageActionsHtml } from './message-actions.js';
11
+ import { API_BASE } from '../api.js';
11
12
  import { normalizeAgentToolBlocks } from './process-block-dom.js';
12
13
  import { scrollToBottom } from './chat-scroll.js';
13
14
 
@@ -67,13 +68,23 @@ export function formatUserPrompt(text: string): string {
67
68
  const userMsg = userMsgMatch ? ' ' + userMsgMatch[1].trim() : '';
68
69
  return `📎 [${count} files]${userMsg}`;
69
70
  }
70
- const fileMatch = text.match(/^\[(?:사용자가 파일을 보냈습니다|User sent a file): ([^\]]+)\]/);
71
+ const fileMatch = text.match(/^\[(?:사용자가 파일을 보냈습니다|사용자가 이미지를 보냈습니다|사용자가 동영상을 보냈습니다|User sent a file|User sent an image|User sent a video): ([^\]]+)\]/);
71
72
  if (fileMatch) {
72
- const fileName = fileMatch[1].split('/').pop() || fileMatch[1];
73
+ const fullPath = fileMatch[1];
74
+ const fileName = fullPath.split('/').pop() || fullPath;
73
75
  const voiceMatch = text.match(/🎤\s*(.{0,80})/);
74
76
  const voicePart = voiceMatch ? `${t('chat.voice.label')} ` : '';
75
77
  const userMsgMatch = text.match(/(?:사용자 메시지|User message): (.+)$/s);
76
78
  const userMsg = userMsgMatch ? ' ' + userMsgMatch[1].trim() : '';
79
+ // Inline media rendering
80
+ const ext = (fileName.split('.').pop() || '').toLowerCase();
81
+ const mediaUrl = `${API_BASE}/media/${encodeURIComponent(fileName)}`;
82
+ if (['png', 'jpg', 'jpeg', 'gif', 'webp', 'svg'].includes(ext)) {
83
+ return `${voicePart}<img src="${mediaUrl}" alt="${fileName}" class="chat-inline-img" loading="lazy" />${userMsg ? `<br>${userMsg}` : ''}`;
84
+ }
85
+ if (['mp4', 'webm', 'mov', 'ogg'].includes(ext)) {
86
+ return `${voicePart}<video src="${mediaUrl}" controls class="chat-inline-video" preload="metadata"></video>${userMsg ? `<br>${userMsg}` : ''}`;
87
+ }
77
88
  return `${voicePart}📎 [${fileName}]${userMsg}`;
78
89
  }
79
90
  return text;
@@ -1,6 +1,7 @@
1
1
  import { api } from '../api.js';
2
2
  import { getVirtualScroll } from '../virtual-scroll.js';
3
3
  import { escapeHtml } from '../render.js';
4
+ import { bootMessageQuery } from './message-history.js';
4
5
 
5
6
  const IS_IFRAME = window.parent !== window;
6
7
 
@@ -94,7 +95,10 @@ export function closeChatSearch(): void {
94
95
 
95
96
  function buildMessageIndexMap(): void {
96
97
  messageIdToVsIndex = new Map();
97
- api<{ id: number }[]>('/api/messages').then(msgs => {
98
+ // Must mirror the rendered boot window so id→virtual-scroll index stays
99
+ // aligned with what loadMessages() actually rendered (embedded: recent-N;
100
+ // standalone: full history).
101
+ api<{ id: number }[]>(`/api/messages${bootMessageQuery()}`).then(msgs => {
98
102
  if (!msgs) return;
99
103
  messageIdToVsIndex = new Map();
100
104
  msgs.forEach((m, i) => messageIdToVsIndex!.set(m.id, i));
@@ -49,6 +49,16 @@ function getCommandTimeoutMs(text: string): number {
49
49
  return /^\/compact(?:\s|$)/i.test(String(text || '').trim()) ? 5 * 60 * 1000 : 10_000;
50
50
  }
51
51
 
52
+ function buildAttachmentPrompt(paths: string[], text = ''): string {
53
+ const prompt = paths.map(p => t('chat.file.sent', { path: p })).join('\n');
54
+ return text ? `${prompt}${t('chat.file.sentWithMsg', { text })}` : prompt;
55
+ }
56
+
57
+ function buildSlashCommandAttachmentText(text: string, paths: string[]): string {
58
+ const fileContext = paths.map(p => t('chat.file.sent', { path: p })).join('\n');
59
+ return fileContext ? `${text}\n\n${fileContext}` : text;
60
+ }
61
+
52
62
  function sendPreviewMessageViaParent(prompt: string): Promise<MessagePostResult | null> {
53
63
  const targetOrigin = previewParentOrigin();
54
64
  if (!targetOrigin) return Promise.resolve(null);
@@ -102,6 +112,63 @@ async function postChatMessage(prompt: string): Promise<MessagePostResult> {
102
112
  }
103
113
  }
104
114
 
115
+ async function postSlashCommand(text: string): Promise<{ ok: boolean; status: number; result: CommandResult }> {
116
+ let signal: AbortSignal; let timer: ReturnType<typeof setTimeout> | undefined;
117
+ const timeoutMs = getCommandTimeoutMs(text);
118
+ if (typeof AbortSignal?.timeout === 'function') {
119
+ signal = AbortSignal.timeout(timeoutMs);
120
+ } else {
121
+ const ac = new AbortController();
122
+ signal = ac.signal;
123
+ timer = setTimeout(() => ac.abort(), timeoutMs);
124
+ }
125
+ const locale = getPreferredLocale();
126
+ const token = await getAuthToken();
127
+ const res = await fetch(`${API_BASE}/api/command`, {
128
+ method: 'POST',
129
+ headers: {
130
+ 'Content-Type': 'application/json',
131
+ 'Accept-Language': locale,
132
+ ...(token ? { 'Authorization': `Bearer ${token}` } : {}),
133
+ },
134
+ body: JSON.stringify({ text, locale }),
135
+ signal,
136
+ });
137
+ if (timer) clearTimeout(timer);
138
+ const result: CommandResult = await res.json().catch(() => ({}));
139
+ return { ok: res.ok, status: res.status, result };
140
+ }
141
+
142
+ async function handleSlashCommandResponse(
143
+ originalText: string,
144
+ response: { ok: boolean; status: number; result: CommandResult },
145
+ fallbackToMessage?: () => Promise<void>,
146
+ ): Promise<void> {
147
+ const result = response.result;
148
+ // not_command → fall through to normal chat
149
+ if (result?.code === 'not_command') {
150
+ if (fallbackToMessage) {
151
+ await fallbackToMessage();
152
+ return;
153
+ }
154
+ addMessage('user', originalText);
155
+ upsertMessage({ role: 'user', content: originalText, timestamp: Date.now() });
156
+ await apiJson('/api/message', 'POST', { prompt: originalText });
157
+ return;
158
+ }
159
+ if (!response.ok && !result?.text) throw new Error(`HTTP ${response.status}`);
160
+ if (result?.code === 'clear_screen') {
161
+ cancelPostRender();
162
+ getVirtualScroll().clear();
163
+ const chatEl = document.getElementById('chatMessages');
164
+ if (chatEl) chatEl.innerHTML = '';
165
+ }
166
+ if (result?.text || result?.recovery) addSystemMsg(renderCommandRecovery(result), '', result.type);
167
+ if (result?.steerPrompt) {
168
+ await apiJson('/api/message', 'POST', { prompt: result.steerPrompt });
169
+ }
170
+ }
171
+
105
172
 
106
173
  function renderCommandRecovery(result: CommandResult): string {
107
174
  const recovery = result.recovery;
@@ -194,53 +261,14 @@ export async function sendMessage(source: SendSource = 'enter'): Promise<void> {
194
261
  const afterSlash = text.slice(1).trim();
195
262
  const firstToken = afterSlash.split(/\s+/)[0] || '';
196
263
  const isFilePath = firstToken.includes('/') || firstToken.includes('\\');
264
+ const isSlashCommand = text.startsWith('/') && !isFilePath;
197
265
 
198
- if (text.startsWith('/') && !state.attachedFiles.length && !isFilePath) {
266
+ if (isSlashCommand && !state.attachedFiles.length) {
199
267
  input.value = '';
200
268
  resetInputHeight();
201
269
  slashCmd.close();
202
270
  try {
203
- let signal: AbortSignal; let timer: ReturnType<typeof setTimeout> | undefined;
204
- const timeoutMs = getCommandTimeoutMs(text);
205
- if (typeof AbortSignal?.timeout === 'function') {
206
- signal = AbortSignal.timeout(timeoutMs);
207
- } else {
208
- const ac = new AbortController();
209
- signal = ac.signal;
210
- timer = setTimeout(() => ac.abort(), timeoutMs);
211
- }
212
- const locale = getPreferredLocale();
213
- const token = await getAuthToken();
214
- const res = await fetch(`${API_BASE}/api/command`, {
215
- method: 'POST',
216
- headers: {
217
- 'Content-Type': 'application/json',
218
- 'Accept-Language': locale,
219
- ...(token ? { 'Authorization': `Bearer ${token}` } : {}),
220
- },
221
- body: JSON.stringify({ text, locale }),
222
- signal,
223
- });
224
- if (timer) clearTimeout(timer);
225
- const result: CommandResult = await res.json().catch(() => ({}));
226
- // not_command → fall through to normal chat
227
- if (result?.code === 'not_command') {
228
- addMessage('user', text);
229
- upsertMessage({ role: 'user', content: text, timestamp: Date.now() });
230
- await apiJson('/api/message', 'POST', { prompt: text });
231
- return;
232
- }
233
- if (!res.ok && !result?.text) throw new Error(`HTTP ${res.status}`);
234
- if (result?.code === 'clear_screen') {
235
- cancelPostRender();
236
- getVirtualScroll().clear();
237
- const chatEl = document.getElementById('chatMessages');
238
- if (chatEl) chatEl.innerHTML = '';
239
- }
240
- if (result?.text || result?.recovery) addSystemMsg(renderCommandRecovery(result), '', result.type);
241
- if (result?.steerPrompt) {
242
- await apiJson('/api/message', 'POST', { prompt: result.steerPrompt });
243
- }
271
+ await handleSlashCommandResponse(text, await postSlashCommand(text));
244
272
  } catch (err) {
245
273
  addSystemMsg(t('chat.cmd.fail', { msg: (err as Error).message }), '', 'error');
246
274
  } finally {
@@ -259,9 +287,23 @@ export async function sendMessage(source: SendSource = 'enter'): Promise<void> {
259
287
  try {
260
288
  // Upload all files in parallel
261
289
  const paths = await Promise.all(state.attachedFiles.map((f: File) => uploadFile(f)));
262
- let prompt = paths.map(p => t('chat.file.sent', { path: p })).join('\n');
263
- if (text) prompt += t('chat.file.sentWithMsg', { text });
290
+ const prompt = buildAttachmentPrompt(paths, text);
264
291
  clearAttachedFiles();
292
+ if (isSlashCommand) {
293
+ slashCmd.close();
294
+ try {
295
+ const commandText = buildSlashCommandAttachmentText(text, paths);
296
+ const commandResponse = await postSlashCommand(commandText);
297
+ await handleSlashCommandResponse(commandText, commandResponse, async () => {
298
+ await apiJson('/api/message', 'POST', { prompt });
299
+ });
300
+ } catch (err) {
301
+ addSystemMsg(t('chat.cmd.fail', { msg: (err as Error).message }), '', 'error');
302
+ } finally {
303
+ syncOrchestrateSnapshot('command').catch(() => {});
304
+ }
305
+ return;
306
+ }
265
307
  await apiJson('/api/message', 'POST', { prompt });
266
308
  } catch (err) {
267
309
  addSystemMsg(t('chat.file.uploadFail', { msg: (err as Error).message }));
@@ -53,8 +53,13 @@ function normalizeEmployeeModel(_cli: string, model?: string): string {
53
53
  }
54
54
 
55
55
  function getDefaultEmployeeModel(cli: string, models: string[]): string {
56
- if (cli !== 'claude') return 'default';
57
- if (models.includes('sonnet')) return 'sonnet';
56
+ if (cli === 'claude' || cli === 'claude-e') {
57
+ if (models.includes('claude-opus-4-8')) return 'claude-opus-4-8';
58
+ if (models.includes('opus')) return 'opus';
59
+ }
60
+ if (cli === 'codex' || cli === 'codex-app') {
61
+ if (models.includes('gpt-5.5')) return 'gpt-5.5';
62
+ }
58
63
  return models[0] || 'default';
59
64
  }
60
65
 
@@ -14,6 +14,10 @@ export function setMessageScope(scope: string): void {
14
14
  localStorage.setItem(SCOPE_KEY, currentScope);
15
15
  }
16
16
 
17
+ export function getMessageScope(): string {
18
+ return currentScope;
19
+ }
20
+
17
21
  export interface CachedMessage {
18
22
  id?: number;
19
23
  role: string;
@@ -0,0 +1,40 @@
1
+ // ── Media Lightbox — click inline image → modal popup, dblclick/button → open in browser ──
2
+
3
+ export function initMediaLightbox(): void {
4
+ const overlay = document.createElement('div');
5
+ overlay.id = 'mediaLightbox';
6
+ overlay.className = 'media-lightbox hidden';
7
+ overlay.innerHTML = `<div class="media-lightbox-backdrop"></div>
8
+ <div class="media-lightbox-content">
9
+ <img class="media-lightbox-img" alt="" />
10
+ <div class="media-lightbox-controls">
11
+ <button class="media-lightbox-open" aria-label="Open in browser">↗ Open</button>
12
+ <button class="media-lightbox-close" aria-label="Close">✕</button>
13
+ </div></div>`;
14
+ document.body.appendChild(overlay);
15
+
16
+ let currentSrc = '';
17
+
18
+ const close = () => overlay.classList.add('hidden');
19
+ const openInBrowser = () => { if (currentSrc) window.open(currentSrc, '_blank'); };
20
+
21
+ overlay.querySelector('.media-lightbox-backdrop')!.addEventListener('click', close);
22
+ overlay.querySelector('.media-lightbox-close')!.addEventListener('click', close);
23
+ overlay.querySelector('.media-lightbox-open')!.addEventListener('click', openInBrowser);
24
+ overlay.querySelector('.media-lightbox-img')!.addEventListener('dblclick', openInBrowser);
25
+
26
+ // Escape key closes
27
+ document.addEventListener('keydown', (e) => {
28
+ if (e.key === 'Escape' && !overlay.classList.contains('hidden')) close();
29
+ });
30
+
31
+ // Delegate click on all inline images (chat + file preview)
32
+ document.addEventListener('click', (e) => {
33
+ const target = e.target as HTMLElement;
34
+ if (target.classList.contains('chat-inline-img') || (target.closest('.file-preview-list') && target.tagName === 'IMG')) {
35
+ currentSrc = (target as HTMLImageElement).src;
36
+ (overlay.querySelector('.media-lightbox-img') as HTMLImageElement).src = currentSrc;
37
+ overlay.classList.remove('hidden');
38
+ }
39
+ });
40
+ }
@@ -6,7 +6,7 @@ import { bootstrapVirtualHistory, type VirtualHistoryBootstrapDeps } from '../vi
6
6
  import { activateWidgets } from '../diagram/iframe-renderer.js';
7
7
  import { ICONS } from '../icons.js';
8
8
  import { t } from './i18n.js';
9
- import { cacheMessages, getScopedMessages, setMessageScope } from './idb-cache.js';
9
+ import { cacheMessages, getMessageScope, getScopedMessages, setMessageScope } from './idb-cache.js';
10
10
  import { addMessage, addSystemMsg, showEmptyState } from './chat-messages.js';
11
11
  import { buildLazyVirtualMessageItem } from './message-item-html.js';
12
12
  import { addStep, buildProcessBlockHtml, collapseBlock, createProcessBlock } from './process-block.js';
@@ -19,6 +19,47 @@ export function buildVirtualHistoryItems(msgs: MessageItem[]): VirtualItem[] {
19
19
  return msgs.map((m, index) => buildLazyVirtualMessageItem(normalizeMessageToolLog(m), index));
20
20
  }
21
21
 
22
+ // Only the embedded dashboard preview frame remounts on every instance switch,
23
+ // so it fetches a bounded recent-N window to keep the per-remount payload small
24
+ // (the full all-time history was ~tens of MB). The standalone chat tab loads
25
+ // once and never remounts, so it keeps the full scrollable history — bounding it
26
+ // would silently drop access to older messages (no load-older mechanism exists).
27
+ export const BOOT_MESSAGE_LIMIT = 300;
28
+
29
+ export function bootMessageQuery(): string {
30
+ let embedded = true;
31
+ try { embedded = window.parent !== window; } catch { embedded = true; }
32
+ return embedded ? `?limit=${BOOT_MESSAGE_LIMIT}` : '';
33
+ }
34
+
35
+ function normalizeMessageScopePart(value: string | null | undefined): string {
36
+ return String(value || '').trim() || 'unknown';
37
+ }
38
+
39
+ export function buildMessageLocationKey(input: { origin?: string; pathname?: string | null }): string {
40
+ const origin = normalizeMessageScopePart(input.origin);
41
+ const pathname = normalizeMessageScopePart(input.pathname || '/');
42
+ return `${origin}${pathname.startsWith('/') ? pathname : `/${pathname}`}`;
43
+ }
44
+
45
+ export function buildMessageScopeIdentity(input: { locationKey?: string; workingDir?: string | null }): string {
46
+ return `${normalizeMessageScopePart(input.locationKey)}::${normalizeMessageScopePart(input.workingDir)}`;
47
+ }
48
+
49
+ function readCurrentMessageLocationKey(): string {
50
+ if (typeof window === 'undefined') return buildMessageLocationKey({});
51
+ return buildMessageLocationKey({
52
+ origin: window.location.origin,
53
+ pathname: window.location.pathname,
54
+ });
55
+ }
56
+
57
+ function readWorkingDirFromScope(scope: string): string | null {
58
+ if (!scope || scope === 'default') return null;
59
+ const markerIndex = scope.indexOf('::');
60
+ return markerIndex >= 0 ? scope.slice(markerIndex + 2) : scope;
61
+ }
62
+
22
63
  export function registerVirtualScrollCallbacks(vs: ReturnType<typeof getVirtualScroll>): void {
23
64
  vs.onLazyRender = (targets: HTMLElement[]) => {
24
65
  for (const el of targets) {
@@ -89,25 +130,32 @@ function hydrateSmallHistory(messages: MessageItem[]): void {
89
130
  export async function loadMessages(): Promise<void> {
90
131
  const vs = getVirtualScroll();
91
132
  const chatEl = document.getElementById('chatMessages');
133
+ const previousScope = getMessageScope();
134
+ const locationKey = readCurrentMessageLocationKey();
135
+ let workingDir = readWorkingDirFromScope(previousScope);
92
136
  try {
93
137
  const settings = await api<{ workingDir?: string }>('/api/settings');
94
- if (settings?.workingDir) setMessageScope(settings.workingDir);
138
+ if (settings?.workingDir) workingDir = settings.workingDir;
95
139
  } catch { /* localStorage fallback already initialized currentScope */ }
96
- const msgs = await api<MessageItem[]>('/api/messages');
140
+ const nextScope = buildMessageScopeIdentity({ locationKey, workingDir });
141
+ setMessageScope(nextScope);
142
+ const scopeChanged = nextScope !== previousScope;
143
+ const msgs = await api<MessageItem[]>(`/api/messages${bootMessageQuery()}`);
97
144
  if (msgs !== null) {
98
145
  const safeMsgs = msgs.map(normalizeMessageToolLog);
99
146
  const hadRenderedHistory = Boolean(chatEl?.querySelector('.msg')) || vs.active;
100
- const savedIndex = vs.active ? vs.firstVisibleIndex() : null;
147
+ const shouldForceBottom = scopeChanged || !hadRenderedHistory;
148
+ const savedIndex = !shouldForceBottom && vs.active ? vs.firstVisibleIndex() : null;
101
149
  vs.clear();
102
150
  if (chatEl) chatEl.innerHTML = '';
103
151
  if (safeMsgs.length >= VS_THRESHOLD) {
104
152
  bootstrapVirtualHistory(buildVirtualHistoryItems(safeMsgs), makeBootstrapDeps(vs, {
105
- forceInitialBottom: !hadRenderedHistory,
106
- restoreIndex: hadRenderedHistory ? savedIndex : null,
153
+ forceInitialBottom: shouldForceBottom,
154
+ restoreIndex: shouldForceBottom ? null : savedIndex,
107
155
  }));
108
156
  } else {
109
157
  hydrateSmallHistory(safeMsgs);
110
- if (!hadRenderedHistory) settleChatBottomAfterInitialLoad();
158
+ if (shouldForceBottom) settleChatBottomAfterInitialLoad();
111
159
  }
112
160
  cacheMessages(safeMsgs.map(m => ({
113
161
  role: m.role, content: m.content, cli: m.cli ?? null, tool_log: m.tool_log ?? null, timestamp: Date.now(),
@@ -11,6 +11,8 @@ import { ICONS } from '../icons.js';
11
11
  import { apiJson } from '../api.js';
12
12
  import { t } from './i18n.js';
13
13
  import { setStatus } from './ui-status.js';
14
+ import { syncOrchestrateSnapshot } from '../ws.js';
15
+ import { copyText } from './copy-text.js';
14
16
 
15
17
  export interface PendingItem {
16
18
  id: string;
@@ -56,11 +58,13 @@ function renderRow(item: PendingItem): string {
56
58
  const preview = (item.prompt || '').replace(/\s+/g, ' ').trim();
57
59
  const truncated = preview.length > 140 ? preview.slice(0, 140) + '…' : preview;
58
60
  const source = item.source ? `<span class="pending-row-source">${escapeHtml(item.source)}</span>` : '';
61
+ const copyLabel = escapeHtml(t('queue.copy'));
59
62
  const steerLabel = escapeHtml(t('queue.steer'));
60
63
  const deleteLabel = escapeHtml(t('queue.delete'));
61
64
  return `<div class="pending-row" data-pending-id="${escapeHtml(item.id)}" title="${escapeHtml(preview)}">
62
65
  <span class="pending-row-text">${escapeHtml(truncated)}</span>
63
66
  ${source}
67
+ <button class="pending-row-btn pending-row-copy" data-pending-action="copy" title="${copyLabel}" aria-label="${copyLabel}"><span class="pending-btn-content">${ICONS.copy}</span></button>
64
68
  <button class="pending-row-btn pending-row-steer" data-pending-action="steer" data-i18n-title="queue.steer" title="${steerLabel}" aria-label="${steerLabel}"><span class="pending-arm-fill" aria-hidden="true"></span><span class="pending-btn-content"><span class="pending-steer-arrow" aria-hidden="true">↳</span><span class="pending-steer-label">${steerLabel}</span></span></button>
65
69
  <button class="pending-row-btn pending-row-delete" data-pending-action="delete" data-i18n-title="queue.delete" title="${deleteLabel}" aria-label="${deleteLabel}"><span class="pending-arm-fill" aria-hidden="true"></span><span class="pending-btn-content">${ICONS.trash}</span></button>
66
70
  </div>`;
@@ -144,8 +148,13 @@ async function fire(id: string, action: Action): Promise<void> {
144
148
  if (action === 'steer') setStatus('running');
145
149
  const result = await apiJson<{ pending: number }>(path, method, {});
146
150
  if (result == null) {
147
- unpaintArmed(id, action);
148
- if (action === 'steer') setStatus('idle');
151
+ // Item may have been processed by processQueue while arm was pending.
152
+ // Remove from UI regardless — snapshot sync will reconcile.
153
+ lastItems = lastItems.filter(it => it.id !== id);
154
+ renderPendingQueue(lastItems);
155
+ if (action === 'steer') {
156
+ syncOrchestrateSnapshot('steer-fire-miss').catch(() => {});
157
+ }
149
158
  return;
150
159
  }
151
160
  lastItems = lastItems.filter(it => it.id !== id);
@@ -163,13 +172,28 @@ function handleClick(id: string, action: Action): void {
163
172
  export function initPendingQueue(): void {
164
173
  const host = document.getElementById('pendingQueue');
165
174
  if (!host) return;
166
- host.addEventListener('click', (e) => {
175
+ host.addEventListener('click', async (e) => {
167
176
  const btn = (e.target as HTMLElement)?.closest('[data-pending-action]') as HTMLElement | null;
168
177
  if (!btn) return;
169
178
  const row = btn.closest('.pending-row') as HTMLElement | null;
170
179
  const id = row?.dataset['pendingId'];
171
180
  if (!id) return;
172
- const action: Action = btn.dataset['pendingAction'] === 'steer' ? 'steer' : 'delete';
181
+ const actionStr = btn.dataset['pendingAction'];
182
+ if (actionStr === 'copy') {
183
+ const item = lastItems.find(it => it.id === id);
184
+ if (item?.prompt) {
185
+ const result = await copyText(item.prompt);
186
+ if (result.ok) {
187
+ const content = btn.querySelector('.pending-btn-content');
188
+ if (content) {
189
+ content.innerHTML = ICONS.checkSimple;
190
+ setTimeout(() => { content.innerHTML = ICONS.copy; }, 600);
191
+ }
192
+ }
193
+ }
194
+ return;
195
+ }
196
+ const action: Action = actionStr === 'steer' ? 'steer' : 'delete';
173
197
  handleClick(id, action);
174
198
  });
175
199
  }
@@ -1,5 +1,9 @@
1
1
  import { escapeHtml } from '../render.js';
2
2
  import { ICONS } from '../icons.js';
3
+ import {
4
+ displayShellCommand,
5
+ displayShellCommandDetail,
6
+ } from '../../../src/shared/shell-command-display.js';
3
7
 
4
8
  declare global {
5
9
  interface Window {
@@ -107,36 +111,47 @@ export function getStoredProcessStepDetail(stepId: string): string {
107
111
  return processDetailStore.get(stepId)?.detail || '';
108
112
  }
109
113
 
114
+ function normalizeProcessStepForDisplay(step: ProcessStep): ProcessStep {
115
+ if (step.type !== 'tool') return step;
116
+ return {
117
+ ...step,
118
+ label: displayShellCommand(step.label || ''),
119
+ detail: displayShellCommandDetail(step.detail || ''),
120
+ detailPreview: step.detailPreview ? displayShellCommandDetail(step.detailPreview) : step.detailPreview,
121
+ };
122
+ }
123
+
110
124
  export function compactProcessStepForStorage(step: ProcessStep): ProcessStep {
111
- const storedDetail = getStoredProcessStepDetail(step.id);
112
- const fullDetail = storedDetail || step.detail || '';
125
+ const displayStep = normalizeProcessStepForDisplay(step);
126
+ const storedDetail = displayShellCommandDetail(getStoredProcessStepDetail(displayStep.id));
127
+ const fullDetail = storedDetail || displayStep.detail || '';
113
128
  const retained = retainedDetail(fullDetail);
114
- const preview = step.detailPreview || previewText(fullDetail, PROCESS_DETAIL_PREVIEW_CHARS);
129
+ const preview = displayStep.detailPreview || previewText(fullDetail, PROCESS_DETAIL_PREVIEW_CHARS);
115
130
  if (fullDetail) {
116
- processDetailStore.set(step.id, {
131
+ processDetailStore.set(displayStep.id, {
117
132
  detail: retained.detail,
118
133
  originalLength: fullDetail.length,
119
134
  truncated: retained.truncated,
120
135
  });
121
136
  }
122
- processStepMetaStore.set(step.id, {
123
- id: step.id,
124
- type: step.type,
125
- icon: step.icon,
126
- rawIcon: step.rawIcon,
127
- label: step.label,
128
- isEmployee: step.isEmployee,
129
- stepRef: step.stepRef,
130
- traceRunId: step.traceRunId, traceSeq: step.traceSeq, detailAvailable: step.detailAvailable,
131
- detailBytes: step.detailBytes, rawRetentionStatus: step.rawRetentionStatus,
132
- status: step.status,
133
- startTime: step.startTime,
137
+ processStepMetaStore.set(displayStep.id, {
138
+ id: displayStep.id,
139
+ type: displayStep.type,
140
+ icon: displayStep.icon,
141
+ rawIcon: displayStep.rawIcon,
142
+ label: displayStep.label,
143
+ isEmployee: displayStep.isEmployee,
144
+ stepRef: displayStep.stepRef,
145
+ traceRunId: displayStep.traceRunId, traceSeq: displayStep.traceSeq, detailAvailable: displayStep.detailAvailable,
146
+ detailBytes: displayStep.detailBytes, rawRetentionStatus: displayStep.rawRetentionStatus,
147
+ status: displayStep.status,
148
+ startTime: displayStep.startTime,
134
149
  preview,
135
150
  detailLength: fullDetail.length,
136
151
  detailTruncated: retained.truncated,
137
152
  });
138
153
  return {
139
- ...step,
154
+ ...displayStep,
140
155
  detail: preview,
141
156
  detailPreview: preview,
142
157
  detailLength: fullDetail.length,