cli-jaw 2.0.1 → 2.0.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 (607) hide show
  1. package/README.ko.md +3 -2
  2. package/README.md +41 -12
  3. package/dist/bin/_http-client.js +34 -0
  4. package/dist/bin/_http-client.js.map +1 -0
  5. package/dist/bin/cli-jaw.js +10 -5
  6. package/dist/bin/cli-jaw.js.map +1 -1
  7. package/dist/bin/commands/browser-web-ai.js +155 -38
  8. package/dist/bin/commands/browser-web-ai.js.map +1 -1
  9. package/dist/bin/commands/browser.js +265 -37
  10. package/dist/bin/commands/browser.js.map +1 -1
  11. package/dist/bin/commands/chat.js +18 -14
  12. package/dist/bin/commands/chat.js.map +1 -1
  13. package/dist/bin/commands/clone.js +3 -2
  14. package/dist/bin/commands/clone.js.map +1 -1
  15. package/dist/bin/commands/dashboard.js +22 -18
  16. package/dist/bin/commands/dashboard.js.map +1 -1
  17. package/dist/bin/commands/dispatch.js +9 -11
  18. package/dist/bin/commands/dispatch.js.map +1 -1
  19. package/dist/bin/commands/doctor.js +26 -14
  20. package/dist/bin/commands/doctor.js.map +1 -1
  21. package/dist/bin/commands/employee.js +12 -7
  22. package/dist/bin/commands/employee.js.map +1 -1
  23. package/dist/bin/commands/init.js +9 -9
  24. package/dist/bin/commands/init.js.map +1 -1
  25. package/dist/bin/commands/launchd.js +17 -7
  26. package/dist/bin/commands/launchd.js.map +1 -1
  27. package/dist/bin/commands/mcp.js +7 -4
  28. package/dist/bin/commands/mcp.js.map +1 -1
  29. package/dist/bin/commands/memory.js +7 -5
  30. package/dist/bin/commands/memory.js.map +1 -1
  31. package/dist/bin/commands/orchestrate.js +6 -3
  32. package/dist/bin/commands/orchestrate.js.map +1 -1
  33. package/dist/bin/commands/reset.js +4 -3
  34. package/dist/bin/commands/reset.js.map +1 -1
  35. package/dist/bin/commands/serve.js +3 -2
  36. package/dist/bin/commands/serve.js.map +1 -1
  37. package/dist/bin/commands/service.js +2 -2
  38. package/dist/bin/commands/service.js.map +1 -1
  39. package/dist/bin/commands/status.js +10 -9
  40. package/dist/bin/commands/status.js.map +1 -1
  41. package/dist/bin/commands/tui/api.js +26 -18
  42. package/dist/bin/commands/tui/api.js.map +1 -1
  43. package/dist/bin/commands/tui/overlays.js +3 -1
  44. package/dist/bin/commands/tui/overlays.js.map +1 -1
  45. package/dist/bin/commands/tui/simple-mode.js +1 -1
  46. package/dist/bin/commands/tui/simple-mode.js.map +1 -1
  47. package/dist/bin/commands/tui/types.js.map +1 -1
  48. package/dist/bin/postinstall.js +153 -65
  49. package/dist/bin/postinstall.js.map +1 -1
  50. package/dist/bin/star-prompt.js +4 -3
  51. package/dist/bin/star-prompt.js.map +1 -1
  52. package/dist/lib/mcp/format-converters.js +15 -10
  53. package/dist/lib/mcp/format-converters.js.map +1 -1
  54. package/dist/lib/mcp/mcp-install.js +2 -2
  55. package/dist/lib/mcp/mcp-install.js.map +1 -1
  56. package/dist/lib/mcp/skills-distribution.js +2 -2
  57. package/dist/lib/mcp/skills-distribution.js.map +1 -1
  58. package/dist/lib/mcp/skills-reset.js +5 -4
  59. package/dist/lib/mcp/skills-reset.js.map +1 -1
  60. package/dist/lib/mcp/skills-symlinks.js +9 -9
  61. package/dist/lib/mcp/skills-symlinks.js.map +1 -1
  62. package/dist/lib/mcp/skills-utils.js +5 -4
  63. package/dist/lib/mcp/skills-utils.js.map +1 -1
  64. package/dist/lib/mcp/unified-config.js +3 -2
  65. package/dist/lib/mcp/unified-config.js.map +1 -1
  66. package/dist/lib/mime-detect.js +65 -0
  67. package/dist/lib/mime-detect.js.map +1 -0
  68. package/dist/lib/quota-copilot.js +12 -10
  69. package/dist/lib/quota-copilot.js.map +1 -1
  70. package/dist/lib/stt.js +3 -3
  71. package/dist/lib/stt.js.map +1 -1
  72. package/dist/lib/upload.js +14 -5
  73. package/dist/lib/upload.js.map +1 -1
  74. package/dist/scripts/i18n-registry.js +4 -4
  75. package/dist/scripts/i18n-registry.js.map +1 -1
  76. package/dist/server.js +61 -57
  77. package/dist/server.js.map +1 -1
  78. package/dist/src/agent/alert-escalation.js +61 -0
  79. package/dist/src/agent/alert-escalation.js.map +1 -0
  80. package/dist/src/agent/args.js +71 -2
  81. package/dist/src/agent/args.js.map +1 -1
  82. package/dist/src/agent/error-classifier.js +9 -4
  83. package/dist/src/agent/error-classifier.js.map +1 -1
  84. package/dist/src/agent/events.js +130 -101
  85. package/dist/src/agent/events.js.map +1 -1
  86. package/dist/src/agent/lifecycle-handler.js +44 -19
  87. package/dist/src/agent/lifecycle-handler.js.map +1 -1
  88. package/dist/src/agent/live-run-state.js +7 -3
  89. package/dist/src/agent/live-run-state.js.map +1 -1
  90. package/dist/src/agent/memory-flush-controller.js +6 -4
  91. package/dist/src/agent/memory-flush-controller.js.map +1 -1
  92. package/dist/src/agent/opencode-diagnostics.js +7 -6
  93. package/dist/src/agent/opencode-diagnostics.js.map +1 -1
  94. package/dist/src/agent/session-persistence.js +1 -1
  95. package/dist/src/agent/session-persistence.js.map +1 -1
  96. package/dist/src/agent/spawn-env.js +33 -16
  97. package/dist/src/agent/spawn-env.js.map +1 -1
  98. package/dist/src/agent/spawn.js +176 -110
  99. package/dist/src/agent/spawn.js.map +1 -1
  100. package/dist/src/agent/watchdog.js +56 -0
  101. package/dist/src/agent/watchdog.js.map +1 -0
  102. package/dist/src/browser/actions.js +179 -70
  103. package/dist/src/browser/actions.js.map +1 -1
  104. package/dist/src/browser/connection.js +296 -19
  105. package/dist/src/browser/connection.js.map +1 -1
  106. package/dist/src/browser/index.js +4 -1
  107. package/dist/src/browser/index.js.map +1 -1
  108. package/dist/src/browser/launch-policy.js +1 -1
  109. package/dist/src/browser/launch-policy.js.map +1 -1
  110. package/dist/src/browser/primitives.js +11 -7
  111. package/dist/src/browser/primitives.js.map +1 -1
  112. package/dist/src/browser/runtime-diagnostics.js +45 -0
  113. package/dist/src/browser/runtime-diagnostics.js.map +1 -0
  114. package/dist/src/browser/runtime-orphans.js +127 -0
  115. package/dist/src/browser/runtime-orphans.js.map +1 -0
  116. package/dist/src/browser/runtime-owner-store.js +51 -0
  117. package/dist/src/browser/runtime-owner-store.js.map +1 -0
  118. package/dist/src/browser/runtime-owner.js +2 -2
  119. package/dist/src/browser/runtime-owner.js.map +1 -1
  120. package/dist/src/browser/tab-lifecycle.js +157 -0
  121. package/dist/src/browser/tab-lifecycle.js.map +1 -0
  122. package/dist/src/browser/vision.js +35 -11
  123. package/dist/src/browser/vision.js.map +1 -1
  124. package/dist/src/browser/web-ai/action-breadth.js +56 -0
  125. package/dist/src/browser/web-ai/action-breadth.js.map +1 -0
  126. package/dist/src/browser/web-ai/action-cache.js +9 -8
  127. package/dist/src/browser/web-ai/action-cache.js.map +1 -1
  128. package/dist/src/browser/web-ai/action-intent.js +64 -0
  129. package/dist/src/browser/web-ai/action-intent.js.map +1 -0
  130. package/dist/src/browser/web-ai/action-memory.js +82 -0
  131. package/dist/src/browser/web-ai/action-memory.js.map +1 -0
  132. package/dist/src/browser/web-ai/action-trace.js +11 -6
  133. package/dist/src/browser/web-ai/action-trace.js.map +1 -1
  134. package/dist/src/browser/web-ai/annotated-screenshot.js +2 -1
  135. package/dist/src/browser/web-ai/annotated-screenshot.js.map +1 -1
  136. package/dist/src/browser/web-ai/answer-artifact.js +97 -0
  137. package/dist/src/browser/web-ai/answer-artifact.js.map +1 -0
  138. package/dist/src/browser/web-ai/ax-snapshot.js +3 -2
  139. package/dist/src/browser/web-ai/ax-snapshot.js.map +1 -1
  140. package/dist/src/browser/web-ai/browser-primitives.js +10 -7
  141. package/dist/src/browser/web-ai/browser-primitives.js.map +1 -1
  142. package/dist/src/browser/web-ai/capability-registry.js +1 -1
  143. package/dist/src/browser/web-ai/capability-registry.js.map +1 -1
  144. package/dist/src/browser/web-ai/chatgpt-composer.js +12 -12
  145. package/dist/src/browser/web-ai/chatgpt-composer.js.map +1 -1
  146. package/dist/src/browser/web-ai/chatgpt-model.js +469 -50
  147. package/dist/src/browser/web-ai/chatgpt-model.js.map +1 -1
  148. package/dist/src/browser/web-ai/chatgpt-response.js +82 -10
  149. package/dist/src/browser/web-ai/chatgpt-response.js.map +1 -1
  150. package/dist/src/browser/web-ai/chatgpt.js +325 -49
  151. package/dist/src/browser/web-ai/chatgpt.js.map +1 -1
  152. package/dist/src/browser/web-ai/churn-log.js +1 -1
  153. package/dist/src/browser/web-ai/churn-log.js.map +1 -1
  154. package/dist/src/browser/web-ai/cli-sessions.js +42 -26
  155. package/dist/src/browser/web-ai/cli-sessions.js.map +1 -1
  156. package/dist/src/browser/web-ai/context-pack/builder.js +1 -1
  157. package/dist/src/browser/web-ai/context-pack/builder.js.map +1 -1
  158. package/dist/src/browser/web-ai/context-pack/file-selector.js +2 -2
  159. package/dist/src/browser/web-ai/context-pack/file-selector.js.map +1 -1
  160. package/dist/src/browser/web-ai/context-pack/report.js +1 -1
  161. package/dist/src/browser/web-ai/context-pack/report.js.map +1 -1
  162. package/dist/src/browser/web-ai/copy-markdown.js +25 -5
  163. package/dist/src/browser/web-ai/copy-markdown.js.map +1 -1
  164. package/dist/src/browser/web-ai/diagnostics.js +17 -14
  165. package/dist/src/browser/web-ai/diagnostics.js.map +1 -1
  166. package/dist/src/browser/web-ai/doctor.js +10 -6
  167. package/dist/src/browser/web-ai/doctor.js.map +1 -1
  168. package/dist/src/browser/web-ai/dom-hash.js.map +1 -1
  169. package/dist/src/browser/web-ai/errors.js +5 -22
  170. package/dist/src/browser/web-ai/errors.js.map +1 -1
  171. package/dist/src/browser/web-ai/gemini-live.js +7 -6
  172. package/dist/src/browser/web-ai/gemini-live.js.map +1 -1
  173. package/dist/src/browser/web-ai/grok-live.js +9 -5
  174. package/dist/src/browser/web-ai/grok-live.js.map +1 -1
  175. package/dist/src/browser/web-ai/index.js +5 -0
  176. package/dist/src/browser/web-ai/index.js.map +1 -1
  177. package/dist/src/browser/web-ai/observation-bundle.js +90 -0
  178. package/dist/src/browser/web-ai/observation-bundle.js.map +1 -0
  179. package/dist/src/browser/web-ai/observe-actions.js +186 -0
  180. package/dist/src/browser/web-ai/observe-actions.js.map +1 -0
  181. package/dist/src/browser/web-ai/observe-targets.js +6 -1
  182. package/dist/src/browser/web-ai/observe-targets.js.map +1 -1
  183. package/dist/src/browser/web-ai/planner-contract.js +18 -0
  184. package/dist/src/browser/web-ai/planner-contract.js.map +1 -0
  185. package/dist/src/browser/web-ai/post-action-assert.js +8 -7
  186. package/dist/src/browser/web-ai/post-action-assert.js.map +1 -1
  187. package/dist/src/browser/web-ai/product-surfaces.js +2 -1
  188. package/dist/src/browser/web-ai/product-surfaces.js.map +1 -1
  189. package/dist/src/browser/web-ai/provider-adapter.js.map +1 -1
  190. package/dist/src/browser/web-ai/question.js +14 -7
  191. package/dist/src/browser/web-ai/question.js.map +1 -1
  192. package/dist/src/browser/web-ai/ref-registry.js.map +1 -1
  193. package/dist/src/browser/web-ai/self-heal.js +20 -14
  194. package/dist/src/browser/web-ai/self-heal.js.map +1 -1
  195. package/dist/src/browser/web-ai/session-store.js +61 -1
  196. package/dist/src/browser/web-ai/session-store.js.map +1 -1
  197. package/dist/src/browser/web-ai/session.js +43 -2
  198. package/dist/src/browser/web-ai/session.js.map +1 -1
  199. package/dist/src/browser/web-ai/source-audit.js +116 -0
  200. package/dist/src/browser/web-ai/source-audit.js.map +1 -0
  201. package/dist/src/browser/web-ai/tab-finalizer.js +18 -0
  202. package/dist/src/browser/web-ai/tab-finalizer.js.map +1 -0
  203. package/dist/src/browser/web-ai/tab-lease-store.js +390 -0
  204. package/dist/src/browser/web-ai/tab-lease-store.js.map +1 -0
  205. package/dist/src/browser/web-ai/tab-pool.js +44 -0
  206. package/dist/src/browser/web-ai/tab-pool.js.map +1 -0
  207. package/dist/src/browser/web-ai/target-resolver.js +31 -0
  208. package/dist/src/browser/web-ai/target-resolver.js.map +1 -0
  209. package/dist/src/browser/web-ai/trace-persistence.js +4 -2
  210. package/dist/src/browser/web-ai/trace-persistence.js.map +1 -1
  211. package/dist/src/browser/web-ai/vendor-editor-contract.js.map +1 -1
  212. package/dist/src/browser/web-ai/watcher.js +8 -7
  213. package/dist/src/browser/web-ai/watcher.js.map +1 -1
  214. package/dist/src/cli/acp-client.js +40 -26
  215. package/dist/src/cli/acp-client.js.map +1 -1
  216. package/dist/src/cli/command-context.js +3 -3
  217. package/dist/src/cli/command-context.js.map +1 -1
  218. package/dist/src/cli/commands.js +25 -16
  219. package/dist/src/cli/commands.js.map +1 -1
  220. package/dist/src/cli/compact.js.map +1 -1
  221. package/dist/src/cli/handlers-completions.js +6 -4
  222. package/dist/src/cli/handlers-completions.js.map +1 -1
  223. package/dist/src/cli/handlers-runtime.js +45 -38
  224. package/dist/src/cli/handlers-runtime.js.map +1 -1
  225. package/dist/src/cli/handlers.js +44 -36
  226. package/dist/src/cli/handlers.js.map +1 -1
  227. package/dist/src/cli/readiness.js +3 -1
  228. package/dist/src/cli/readiness.js.map +1 -1
  229. package/dist/src/cli/registry.js +1 -1
  230. package/dist/src/cli/registry.js.map +1 -1
  231. package/dist/src/cli/tui/overlay.js +4 -1
  232. package/dist/src/cli/tui/overlay.js.map +1 -1
  233. package/dist/src/cli/types.js +4 -0
  234. package/dist/src/cli/types.js.map +1 -0
  235. package/dist/src/command-contract/catalog.js +1 -1
  236. package/dist/src/command-contract/catalog.js.map +1 -1
  237. package/dist/src/command-contract/help-renderer.js +1 -1
  238. package/dist/src/command-contract/help-renderer.js.map +1 -1
  239. package/dist/src/core/browser-open-default.js +13 -0
  240. package/dist/src/core/browser-open-default.js.map +1 -0
  241. package/dist/src/core/browser-open.js +41 -0
  242. package/dist/src/core/browser-open.js.map +1 -0
  243. package/dist/src/core/bus.js +13 -2
  244. package/dist/src/core/bus.js.map +1 -1
  245. package/dist/src/core/compact.js +5 -4
  246. package/dist/src/core/compact.js.map +1 -1
  247. package/dist/src/core/config.js +51 -52
  248. package/dist/src/core/config.js.map +1 -1
  249. package/dist/src/core/db.js +48 -6
  250. package/dist/src/core/db.js.map +1 -1
  251. package/dist/src/core/employees.js +9 -8
  252. package/dist/src/core/employees.js.map +1 -1
  253. package/dist/src/core/instance.js +7 -6
  254. package/dist/src/core/instance.js.map +1 -1
  255. package/dist/src/core/logger.js +1 -1
  256. package/dist/src/core/logger.js.map +1 -1
  257. package/dist/src/core/main-session.js +7 -7
  258. package/dist/src/core/main-session.js.map +1 -1
  259. package/dist/src/core/path-expand.js +10 -0
  260. package/dist/src/core/path-expand.js.map +1 -0
  261. package/dist/src/core/runtime-path.js +1 -1
  262. package/dist/src/core/runtime-path.js.map +1 -1
  263. package/dist/src/core/runtime-settings.js +13 -13
  264. package/dist/src/core/runtime-settings.js.map +1 -1
  265. package/dist/src/core/settings-merge.js +14 -14
  266. package/dist/src/core/settings-merge.js.map +1 -1
  267. package/dist/src/core/strip-undefined.js +13 -0
  268. package/dist/src/core/strip-undefined.js.map +1 -0
  269. package/dist/src/core/tcc.js +1 -1
  270. package/dist/src/core/tcc.js.map +1 -1
  271. package/dist/src/discord/bot.js +19 -18
  272. package/dist/src/discord/bot.js.map +1 -1
  273. package/dist/src/discord/channel-types.js +14 -0
  274. package/dist/src/discord/channel-types.js.map +1 -0
  275. package/dist/src/discord/commands.js +7 -6
  276. package/dist/src/discord/commands.js.map +1 -1
  277. package/dist/src/discord/discord-file.js.map +1 -1
  278. package/dist/src/discord/forwarder.js +3 -3
  279. package/dist/src/discord/forwarder.js.map +1 -1
  280. package/dist/src/http/error-middleware.js +3 -3
  281. package/dist/src/http/error-middleware.js.map +1 -1
  282. package/dist/src/http/response.js +2 -2
  283. package/dist/src/http/response.js.map +1 -1
  284. package/dist/src/ide/diff.js +7 -7
  285. package/dist/src/ide/diff.js.map +1 -1
  286. package/dist/src/manager/board/routes.js +28 -27
  287. package/dist/src/manager/board/routes.js.map +1 -1
  288. package/dist/src/manager/dashboard-home.js +3 -5
  289. package/dist/src/manager/dashboard-home.js.map +1 -1
  290. package/dist/src/manager/dashboard-service.js +2 -2
  291. package/dist/src/manager/dashboard-service.js.map +1 -1
  292. package/dist/src/manager/health-history.js +10 -9
  293. package/dist/src/manager/health-history.js.map +1 -1
  294. package/dist/src/manager/launchd-service.js +2 -2
  295. package/dist/src/manager/launchd-service.js.map +1 -1
  296. package/dist/src/manager/lifecycle-helpers.js +7 -6
  297. package/dist/src/manager/lifecycle-helpers.js.map +1 -1
  298. package/dist/src/manager/lifecycle.js +7 -6
  299. package/dist/src/manager/lifecycle.js.map +1 -1
  300. package/dist/src/manager/logs.js +18 -18
  301. package/dist/src/manager/logs.js.map +1 -1
  302. package/dist/src/manager/metadata.js +10 -2
  303. package/dist/src/manager/metadata.js.map +1 -1
  304. package/dist/src/manager/notes/assets.js +216 -0
  305. package/dist/src/manager/notes/assets.js.map +1 -0
  306. package/dist/src/manager/notes/capabilities.js +56 -0
  307. package/dist/src/manager/notes/capabilities.js.map +1 -0
  308. package/dist/src/manager/notes/constants.js +11 -0
  309. package/dist/src/manager/notes/constants.js.map +1 -0
  310. package/dist/src/manager/notes/frontmatter.js +120 -0
  311. package/dist/src/manager/notes/frontmatter.js.map +1 -0
  312. package/dist/src/manager/notes/link-resolver.js +96 -0
  313. package/dist/src/manager/notes/link-resolver.js.map +1 -0
  314. package/dist/src/manager/notes/path-guards.js +4 -0
  315. package/dist/src/manager/notes/path-guards.js.map +1 -1
  316. package/dist/src/manager/notes/remote-assets.js +128 -0
  317. package/dist/src/manager/notes/remote-assets.js.map +1 -0
  318. package/dist/src/manager/notes/routes.js +63 -13
  319. package/dist/src/manager/notes/routes.js.map +1 -1
  320. package/dist/src/manager/notes/store.js +3 -2
  321. package/dist/src/manager/notes/store.js.map +1 -1
  322. package/dist/src/manager/notes/system-trash.js +3 -3
  323. package/dist/src/manager/notes/system-trash.js.map +1 -1
  324. package/dist/src/manager/notes/vault-index.js +220 -0
  325. package/dist/src/manager/notes/vault-index.js.map +1 -0
  326. package/dist/src/manager/notes/watcher.js +27 -0
  327. package/dist/src/manager/notes/watcher.js.map +1 -0
  328. package/dist/src/manager/notes/wiki-links.js +109 -0
  329. package/dist/src/manager/notes/wiki-links.js.map +1 -0
  330. package/dist/src/manager/process-verify.js +29 -0
  331. package/dist/src/manager/process-verify.js.map +1 -1
  332. package/dist/src/manager/profiles.js +3 -2
  333. package/dist/src/manager/profiles.js.map +1 -1
  334. package/dist/src/manager/registry.js +60 -58
  335. package/dist/src/manager/registry.js.map +1 -1
  336. package/dist/src/manager/routes/electron-metrics.js +22 -22
  337. package/dist/src/manager/routes/electron-metrics.js.map +1 -1
  338. package/dist/src/manager/scan.js +2 -2
  339. package/dist/src/manager/scan.js.map +1 -1
  340. package/dist/src/manager/schedule/routes.js +24 -23
  341. package/dist/src/manager/schedule/routes.js.map +1 -1
  342. package/dist/src/manager/server.js +28 -28
  343. package/dist/src/manager/server.js.map +1 -1
  344. package/dist/src/manager/systemd-service.js +1 -1
  345. package/dist/src/manager/systemd-service.js.map +1 -1
  346. package/dist/src/memory/bootstrap.js +5 -4
  347. package/dist/src/memory/bootstrap.js.map +1 -1
  348. package/dist/src/memory/heartbeat-schedule.js +10 -10
  349. package/dist/src/memory/heartbeat-schedule.js.map +1 -1
  350. package/dist/src/memory/heartbeat.js +23 -22
  351. package/dist/src/memory/heartbeat.js.map +1 -1
  352. package/dist/src/memory/indexing.js.map +1 -1
  353. package/dist/src/memory/keyword-expand.js +1 -1
  354. package/dist/src/memory/keyword-expand.js.map +1 -1
  355. package/dist/src/memory/memory.js +2 -2
  356. package/dist/src/memory/memory.js.map +1 -1
  357. package/dist/src/memory/runtime.js +6 -5
  358. package/dist/src/memory/runtime.js.map +1 -1
  359. package/dist/src/memory/shared.js +2 -1
  360. package/dist/src/memory/shared.js.map +1 -1
  361. package/dist/src/memory/worklog.js +1 -1
  362. package/dist/src/memory/worklog.js.map +1 -1
  363. package/dist/src/messaging/runtime.js +13 -10
  364. package/dist/src/messaging/runtime.js.map +1 -1
  365. package/dist/src/messaging/send.js +16 -15
  366. package/dist/src/messaging/send.js.map +1 -1
  367. package/dist/src/orchestrator/collect.js +6 -6
  368. package/dist/src/orchestrator/collect.js.map +1 -1
  369. package/dist/src/orchestrator/distribute.js +112 -77
  370. package/dist/src/orchestrator/distribute.js.map +1 -1
  371. package/dist/src/orchestrator/gateway.js +6 -5
  372. package/dist/src/orchestrator/gateway.js.map +1 -1
  373. package/dist/src/orchestrator/pipeline.js +42 -42
  374. package/dist/src/orchestrator/pipeline.js.map +1 -1
  375. package/dist/src/orchestrator/state-machine.js +3 -3
  376. package/dist/src/orchestrator/state-machine.js.map +1 -1
  377. package/dist/src/orchestrator/worker-registry.js +4 -3
  378. package/dist/src/orchestrator/worker-registry.js.map +1 -1
  379. package/dist/src/prompt/builder.js +24 -19
  380. package/dist/src/prompt/builder.js.map +1 -1
  381. package/dist/src/prompt/templates/a1-system.md +15 -10
  382. package/dist/src/prompt/templates/control-system.md +9 -7
  383. package/dist/src/prompt/templates/employee.md +5 -4
  384. package/dist/src/prompt/templates/vision-click.md +1 -1
  385. package/dist/src/routes/_http-error.js +15 -0
  386. package/dist/src/routes/_http-error.js.map +1 -0
  387. package/dist/src/routes/avatar.js +6 -5
  388. package/dist/src/routes/avatar.js.map +1 -1
  389. package/dist/src/routes/browser.js +132 -45
  390. package/dist/src/routes/browser.js.map +1 -1
  391. package/dist/src/routes/employees.js +28 -21
  392. package/dist/src/routes/employees.js.map +1 -1
  393. package/dist/src/routes/heartbeat.js +12 -9
  394. package/dist/src/routes/heartbeat.js.map +1 -1
  395. package/dist/src/routes/i18n.js +13 -7
  396. package/dist/src/routes/i18n.js.map +1 -1
  397. package/dist/src/routes/jaw-memory.js +15 -11
  398. package/dist/src/routes/jaw-memory.js.map +1 -1
  399. package/dist/src/routes/memory.js +25 -20
  400. package/dist/src/routes/memory.js.map +1 -1
  401. package/dist/src/routes/messaging.js +50 -29
  402. package/dist/src/routes/messaging.js.map +1 -1
  403. package/dist/src/routes/orchestrate.js +38 -24
  404. package/dist/src/routes/orchestrate.js.map +1 -1
  405. package/dist/src/routes/quota.js +81 -17
  406. package/dist/src/routes/quota.js.map +1 -1
  407. package/dist/src/routes/settings.js +28 -18
  408. package/dist/src/routes/settings.js.map +1 -1
  409. package/dist/src/routes/skills.js +22 -13
  410. package/dist/src/routes/skills.js.map +1 -1
  411. package/dist/src/routes/traces.js +77 -0
  412. package/dist/src/routes/traces.js.map +1 -0
  413. package/dist/src/security/path-guards.js +2 -1
  414. package/dist/src/security/path-guards.js.map +1 -1
  415. package/dist/src/shared/tool-log-sanitize.js +191 -0
  416. package/dist/src/shared/tool-log-sanitize.js.map +1 -0
  417. package/dist/src/telegram/bot.js +65 -55
  418. package/dist/src/telegram/bot.js.map +1 -1
  419. package/dist/src/telegram/forwarder.js +5 -9
  420. package/dist/src/telegram/forwarder.js.map +1 -1
  421. package/dist/src/telegram/telegram-file.js +28 -24
  422. package/dist/src/telegram/telegram-file.js.map +1 -1
  423. package/dist/src/telegram/voice.js +4 -3
  424. package/dist/src/telegram/voice.js.map +1 -1
  425. package/dist/src/trace/redact.js +50 -0
  426. package/dist/src/trace/redact.js.map +1 -0
  427. package/dist/src/trace/store.js +162 -0
  428. package/dist/src/trace/store.js.map +1 -0
  429. package/dist/src/trace/types.js +2 -0
  430. package/dist/src/trace/types.js.map +1 -0
  431. package/dist/src/types/cli-engine.js +34 -0
  432. package/dist/src/types/cli-engine.js.map +1 -0
  433. package/dist/src/types/cli-events.js +31 -0
  434. package/dist/src/types/cli-events.js.map +1 -0
  435. package/package.json +22 -2
  436. package/public/css/tool-ui.css +3 -1
  437. package/public/css/trace-drawer.css +48 -0
  438. package/public/dist/assets/{AdvancedExport-3WAYIabE.js → AdvancedExport-DJZ2VmBR.js} +1 -1
  439. package/public/dist/assets/Agent-CgpLT8IY.js +1 -0
  440. package/public/dist/assets/Browser-CrkiQoB8.js +1 -0
  441. package/public/dist/assets/{ChannelsDiscord-UzFPlWT4.js → ChannelsDiscord-CVUC22D4.js} +1 -1
  442. package/public/dist/assets/{ChannelsTelegram-DNWtPX0w.js → ChannelsTelegram-DEatIQNM.js} +1 -1
  443. package/public/dist/assets/{DashboardMeta-Y_6nVeJO.js → DashboardMeta-BKoxRc7i.js} +1 -1
  444. package/public/dist/assets/{Display-D8vGOl4s.js → Display-DnNGV9Km.js} +1 -1
  445. package/public/dist/assets/{Employees-YR_sIRK4.js → Employees-DZ2iJYKy.js} +1 -1
  446. package/public/dist/assets/{HealthBadge-CPePajyU.js → HealthBadge-Cq2c7G9s.js} +1 -1
  447. package/public/dist/assets/{Heartbeat-DTpAULQR.js → Heartbeat-BML6eTXZ.js} +1 -1
  448. package/public/dist/assets/{Mcp-DM-PgG6z.js → Mcp-BlEviQ3h.js} +1 -1
  449. package/public/dist/assets/{Memory-C_LvJnkn.js → Memory-BRyH80He.js} +1 -1
  450. package/public/dist/assets/MilkdownWysiwygEditor-Cm3uXfWf.js +52 -0
  451. package/public/dist/assets/ModelProvider-DxyR7EL9.js +1 -0
  452. package/public/dist/assets/Network-DDOOESh1.js +1 -0
  453. package/public/dist/assets/{Permissions-B1naJjjw.js → Permissions-Br0eSbKb.js} +1 -1
  454. package/public/dist/assets/{Permissions-BKffrMJD.js → Permissions-QHkzStqQ.js} +1 -1
  455. package/public/dist/assets/{Profile-DIqjSe2C.js → Profile-C79NKumk.js} +1 -1
  456. package/public/dist/assets/{Prompts-BMfbV6Y4.js → Prompts-BmiIDiXW.js} +1 -1
  457. package/public/dist/assets/{SpeechKeys-DjiQTzSL.js → SpeechKeys-B8304XJK.js} +1 -1
  458. package/public/dist/assets/app-Be58Cs3Y.js +32 -0
  459. package/public/dist/assets/{app-BzvwJJiv.css → app-CphocJzo.css} +1 -1
  460. package/public/dist/assets/{dist-DTvxN3ux.js → dist-BD0UXfgF2.js} +1 -1
  461. package/public/dist/assets/{dist-CASeq-Tl.js → dist-BNfXO3Yr.js} +1 -1
  462. package/public/dist/assets/{dist-BMPiaUzF.js → dist-BUnPYbK3.js} +1 -1
  463. package/public/dist/assets/{dist-CT_X3hVT.js → dist-BZosRD2u.js} +1 -1
  464. package/public/dist/assets/{dist-4J6YbNXv.js → dist-Bd9PlnQm.js} +1 -1
  465. package/public/dist/assets/{dist-BcZjyn5g.js → dist-BsT5UdNP.js} +1 -1
  466. package/public/dist/assets/{dist-BfBhOPR-.js → dist-CIuXW-sc.js} +1 -1
  467. package/public/dist/assets/{dist-BMiCig3A2.js → dist-CL4PTYWf.js} +1 -1
  468. package/public/dist/assets/{dist-VyP6-HLb.js → dist-Ch5VAlV9.js} +1 -1
  469. package/public/dist/assets/dist-ClqO40BE.js +1 -0
  470. package/public/dist/assets/{dist-c98Tp7bP.js → dist-Cp42cMcI.js} +1 -1
  471. package/public/dist/assets/{dist-CIlYL1qe.js → dist-CpUK8ypo.js} +1 -1
  472. package/public/dist/assets/dist-CxeLAw2Y.js +1 -0
  473. package/public/dist/assets/dist-D2SH8nxa.js +1 -0
  474. package/public/dist/assets/{dist-84fwQ7bO.js → dist-D6cUXP7K.js} +1 -1
  475. package/public/dist/assets/{dist-BOCcQAyF.js → dist-D7bCuS3f.js} +1 -1
  476. package/public/dist/assets/{dist-DMmpfLVP.js → dist-DFYRUAjN.js} +1 -1
  477. package/public/dist/assets/{dist-DdY6pTJr.js → dist-DZsFVYF4.js} +1 -1
  478. package/public/dist/assets/{dist-B0p3Eyme.js → dist-Db16ogVk.js} +1 -1
  479. package/public/dist/assets/{dist-DlnNtr6L.js → dist-DfodGES_.js} +1 -1
  480. package/public/dist/assets/{dist-DO9so2a2.js → dist-SU-YTAIg.js} +1 -1
  481. package/public/dist/assets/{dist-DUjXiMLP.js → dist-UYn7T-GH.js} +1 -1
  482. package/public/dist/assets/{dist-BW1409rz.js → dist-W51oDoeA.js} +1 -1
  483. package/public/dist/assets/{dist-BimBQZx1.js → dist-eU7TyC86.js} +1 -1
  484. package/public/dist/assets/dist-l9HH00ip.js +1 -0
  485. package/public/dist/assets/{dist-BrOPNxdH.js → dist-urPTQzXL.js} +1 -1
  486. package/public/dist/assets/{dist-AloEV3J52.js → dist-yHP6L0Ty.js} +1 -1
  487. package/public/dist/assets/{employees-Bbabvbyx.js → employees-CxdghzoD.js} +7 -7
  488. package/public/dist/assets/{error-normalize-DdvKGLt_.js → error-normalize-5n-zlEQ3.js} +1 -1
  489. package/public/dist/assets/insert-image-markdown-DIEa-zjk.js +22 -0
  490. package/public/dist/assets/{manager-DyB2ZUr9.css → manager-DEiyrWDP.css} +1 -1
  491. package/public/dist/assets/manager-UEXd1_9T.js +25 -0
  492. package/public/dist/assets/{memory-B_plvcuQ.js → memory-CsMNkYtv.js} +9 -9
  493. package/public/dist/assets/memory-DXad_DPO.js +1 -0
  494. package/public/dist/assets/{page-shell-DML_HneX.js → page-shell-D5tbivHH.js} +1 -1
  495. package/public/dist/assets/{render-DEhbfUAW.js → render-DGQX46ei.js} +2 -2
  496. package/public/dist/assets/{settings-D7F-_kYG.js → settings-BH213Yv3.js} +14 -14
  497. package/public/dist/assets/settings-DXT87G2U.js +1 -0
  498. package/public/dist/assets/settings-client-ajlwI-oK.js +1 -0
  499. package/public/dist/assets/skills-5o_1v0nz.js +1 -0
  500. package/public/dist/assets/{skills-DoGJOc0D.js → skills-CQtCtHPA.js} +6 -6
  501. package/public/dist/assets/slash-commands-D4-hrrmh.js +1 -0
  502. package/public/dist/assets/{slash-commands-khNFPOyF.js → slash-commands-Dzk1xHWS.js} +1 -1
  503. package/public/dist/assets/trace-drawer-SRKcfm2S.js +15 -0
  504. package/public/dist/assets/ui-CdRKN2S6.js +141 -0
  505. package/public/dist/assets/ui-n43jmg_f.js +1 -0
  506. package/public/dist/assets/{ws-B2aJ-nD2.js → ws-CTHQFzM1.js} +8 -8
  507. package/public/dist/index.html +2 -2
  508. package/public/dist/manager/index.html +2 -2
  509. package/public/index.html +1 -0
  510. package/public/js/constants.ts +5 -5
  511. package/public/js/diagram/iframe-renderer.ts +11 -11
  512. package/public/js/features/chat.ts +1 -1
  513. package/public/js/features/memory.ts +10 -10
  514. package/public/js/features/pending-queue.ts +2 -2
  515. package/public/js/features/process-block.ts +257 -29
  516. package/public/js/features/process-step-match.ts +18 -0
  517. package/public/js/features/settings-cli-status.ts +1 -1
  518. package/public/js/features/settings-stt.ts +37 -11
  519. package/public/js/features/settings-templates.ts +2 -2
  520. package/public/js/features/slash-commands.ts +1 -1
  521. package/public/js/features/tool-ui.ts +13 -7
  522. package/public/js/features/trace-drawer.ts +122 -0
  523. package/public/js/icons.ts +1 -1
  524. package/public/js/main.ts +28 -28
  525. package/public/js/provider-icons.ts +1 -1
  526. package/public/js/render.ts +29 -27
  527. package/public/js/sanitizer.ts +4 -0
  528. package/public/js/ui.ts +234 -68
  529. package/public/js/virtual-scroll.ts +19 -33
  530. package/public/js/ws.ts +22 -10
  531. package/public/manager/src/App.tsx +34 -6
  532. package/public/manager/src/api.ts +55 -1
  533. package/public/manager/src/components/ActivityTimeline.tsx +1 -1
  534. package/public/manager/src/components/InstanceDetailPanel.tsx +2 -2
  535. package/public/manager/src/components/InstanceGroups.tsx +5 -5
  536. package/public/manager/src/components/InstanceListContent.tsx +1 -1
  537. package/public/manager/src/dashboard-features.ts +1 -1
  538. package/public/manager/src/manager-notes.css +49 -2
  539. package/public/manager/src/notes/MarkdownEditor.tsx +7 -3
  540. package/public/manager/src/notes/NotesFileTree.tsx +45 -6
  541. package/public/manager/src/notes/NotesSidebar.tsx +24 -55
  542. package/public/manager/src/notes/NotesWorkspace.tsx +50 -3
  543. package/public/manager/src/notes/image-assets/clipboard-images.ts +100 -0
  544. package/public/manager/src/notes/image-assets/insert-image-markdown.ts +85 -0
  545. package/public/manager/src/notes/notes-api.ts +2 -0
  546. package/public/manager/src/notes/notes-types.ts +8 -1
  547. package/public/manager/src/notes/rendering/MarkdownRenderer.tsx +6 -0
  548. package/public/manager/src/notes/rendering/markdown-render-security.ts +19 -1
  549. package/public/manager/src/notes/rich-markdown/paste-policy.ts +6 -2
  550. package/public/manager/src/notes/rich-markdown/rich-markdown-extension.ts +5 -5
  551. package/public/manager/src/notes/rich-markdown/rich-widget.ts +8 -8
  552. package/public/manager/src/notes/useNotesExternalSync.ts +37 -0
  553. package/public/manager/src/notes/useNotesModel.ts +91 -0
  554. package/public/manager/src/notes/wysiwyg/MilkdownWysiwygEditor.tsx +157 -17
  555. package/public/manager/src/notes/wysiwyg/milkdown-block-keymap.ts +14 -2
  556. package/public/manager/src/notes/wysiwyg/milkdown-code-block-view.ts +20 -20
  557. package/public/manager/src/notes/wysiwyg/milkdown-heading-source-view.ts +8 -8
  558. package/public/manager/src/notes/wysiwyg/milkdown-math.ts +25 -25
  559. package/public/manager/src/settings/pages/Browser.tsx +38 -20
  560. package/public/manager/src/settings/pages/ModelProvider.tsx +11 -9
  561. package/public/manager/src/settings/pages/Network.tsx +10 -10
  562. package/public/manager/src/settings/pages/components/HealthBadge.tsx +12 -12
  563. package/public/manager/src/settings/pages/components/agent/runtime-employees-helpers.ts +12 -10
  564. package/public/manager/src/settings/pages/components/employees-helpers.ts +9 -9
  565. package/public/manager/src/settings/pages/components/heartbeat-helpers.ts +13 -13
  566. package/public/manager/src/settings/pages/components/memory-helpers.ts +4 -4
  567. package/public/manager/src/settings/pages/mcp-helpers.ts +7 -7
  568. package/public/manager/src/settings/settings-client.ts +4 -3
  569. package/public/manager/src/sync/IframeBridge.tsx +29 -0
  570. package/public/manager/src/sync/VisibilityBridge.tsx +24 -0
  571. package/public/manager/src/sync/invalidation-bus.ts +30 -0
  572. package/public/manager/src/sync/useInvalidationSubscription.ts +19 -0
  573. package/public/manager/src/types.ts +101 -0
  574. package/scripts/check-strict-baseline.mjs +255 -0
  575. package/scripts/claim-audit.mjs +159 -0
  576. package/scripts/i18n-registry.ts +4 -4
  577. package/scripts/install-officecli.sh +2 -2
  578. package/scripts/install-wsl.sh +2 -1
  579. package/scripts/release-gates.mjs +347 -0
  580. package/scripts/release-preview.sh +3 -0
  581. package/scripts/release.sh +4 -0
  582. package/scripts/smoke/opencode-external-dir-smoke.ts +14 -5
  583. package/public/dist/assets/Agent-BYdzZwD0.js +0 -1
  584. package/public/dist/assets/Browser-CkGeczuN.js +0 -1
  585. package/public/dist/assets/MilkdownWysiwygEditor-B7k9bAey.js +0 -52
  586. package/public/dist/assets/ModelProvider-CX3Qhowu.js +0 -1
  587. package/public/dist/assets/Network-DfPLFAvw.js +0 -1
  588. package/public/dist/assets/app-DLYoRkU9.js +0 -32
  589. package/public/dist/assets/dist-8zNAQAIa.js +0 -1
  590. package/public/dist/assets/dist-BgeY6nvK.js +0 -1
  591. package/public/dist/assets/dist-BzDGGxHQ.js +0 -1
  592. package/public/dist/assets/dist-D3YKbVi-.js +0 -1
  593. package/public/dist/assets/manager-CUSgFbMO.js +0 -25
  594. package/public/dist/assets/markdown-render-security-DJfJPWO-.js +0 -22
  595. package/public/dist/assets/memory-DQ6dU0qs.js +0 -1
  596. package/public/dist/assets/settings-DxLPUbpj.js +0 -1
  597. package/public/dist/assets/settings-client-CGf3uPPf.js +0 -1
  598. package/public/dist/assets/skills-yMfNYJ8m.js +0 -1
  599. package/public/dist/assets/slash-commands-CZcwr1W6.js +0 -1
  600. package/public/dist/assets/ui-04YlOMgn.js +0 -136
  601. package/public/dist/assets/ui-D6hlMjRq.js +0 -1
  602. /package/public/dist/assets/{InlineWarn-CqgWEC41.js → InlineWarn-BooBRm7o.js} +0 -0
  603. /package/public/dist/assets/{agent-meta-puNn13DV.js → agent-meta-DHddpWHQ.js} +0 -0
  604. /package/public/dist/assets/{fields-DH9JS3mb.js → fields-BtncIZYA.js} +0 -0
  605. /package/public/dist/assets/{mermaid-loader-6XC0y10y.js → mermaid-loader-BEFIOoJn.js} +0 -0
  606. /package/public/dist/assets/{path-utils-CtsDDGZg.js → path-utils-BuEEtj9w.js} +0 -0
  607. /package/public/dist/assets/{w3c-keyname-VSld09PZ.js → w3c-keyname-IiiZScED.js} +0 -0
@@ -6,6 +6,7 @@ import { join } from 'path';
6
6
  import { spawn, execFileSync } from 'child_process';
7
7
  import { broadcast } from '../core/bus.js';
8
8
  import { settings, UPLOADS_DIR, detectCli, normalizeModelForCli } from '../core/config.js';
9
+ import { stripUndefined } from '../core/strip-undefined.js';
9
10
  import { clearEmployeeSession, getSession, insertMessage, getRecentMessages, listQueuedMessages, insertQueuedMessage, deleteQueuedMessage, getSessionBucket, } from '../core/db.js';
10
11
  import { getSystemPrompt, regenerateB } from '../prompt/builder.js';
11
12
  import { extractSessionId, extractFromEvent, extractFromAcpUpdate, extractOutputChunk, logEventSummary, flushClaudeBuffers } from './events.js';
@@ -23,7 +24,10 @@ import { resolveOrcScope } from '../orchestrator/scope.js';
23
24
  import { beginLiveRun, appendLiveRunText, clearLiveRun, replaceLiveRunTools, appendLiveRunTool } from './live-run-state.js';
24
25
  import { setSpawnRef as setMemorySpawnRef, } from './memory-flush-controller.js';
25
26
  import { applyCliEnvDefaults, buildSessionResumeKey, ensureOpencodeAlwaysAllowPermissions } from './spawn-env.js';
27
+ import { attachWatchdog } from './watchdog.js';
26
28
  import { buildOpencodeRuntimeSnapshot, buildOpencodeSpawnAudit, pushOpencodeRawEvent, resolveOpencodeBinary, } from './opencode-diagnostics.js';
29
+ import { asCliEventRecord, discriminate, fieldString } from '../types/cli-events.js';
30
+ import { appendTraceEvent, stampTraceTool, startTraceRun } from '../trace/store.js';
27
31
  // ─── State ───────────────────────────────────────────
28
32
  export let activeProcess = null;
29
33
  export const activeProcesses = new Map(); // agentId → child process
@@ -99,7 +103,7 @@ function normalizeQueueItem(row) {
99
103
  if (typeof parsed?.id !== 'string' || typeof parsed?.prompt !== 'string' || typeof parsed?.source !== 'string') {
100
104
  return [];
101
105
  }
102
- return [{
106
+ return [stripUndefined({
103
107
  id: parsed.id,
104
108
  prompt: parsed.prompt,
105
109
  source: parsed.source,
@@ -108,7 +112,7 @@ function normalizeQueueItem(row) {
108
112
  chatId: parsed.chatId,
109
113
  requestId: parsed.requestId,
110
114
  ts: typeof parsed.ts === 'number' ? parsed.ts : Date.now(),
111
- }];
115
+ })];
112
116
  }
113
117
  catch {
114
118
  return [];
@@ -330,7 +334,7 @@ export async function steerAgent(newPrompt, source) {
330
334
  const wasRunning = killActiveAgent('steer');
331
335
  if (wasRunning)
332
336
  await waitForProcessEnd(3000);
333
- insertMessage.run('user', newPrompt, source, '', settings.workingDir || null);
337
+ insertMessage.run('user', newPrompt, source, '', settings["workingDir"] || null);
334
338
  broadcast('new_message', { role: 'user', content: newPrompt, source });
335
339
  const { orchestrate, orchestrateContinue, orchestrateReset, isContinueIntent, isResetIntent } = await import('../orchestrator/pipeline.js');
336
340
  const origin = source || 'web';
@@ -371,7 +375,7 @@ export function removeQueuedMessage(id) {
371
375
  return { removed: removed, pending: messageQueue.length };
372
376
  }
373
377
  export function enqueueMessage(prompt, source, meta) {
374
- const item = {
378
+ const item = stripUndefined({
375
379
  id: crypto.randomUUID(),
376
380
  prompt,
377
381
  source,
@@ -380,7 +384,7 @@ export function enqueueMessage(prompt, source, meta) {
380
384
  chatId: meta?.chatId,
381
385
  requestId: meta?.requestId,
382
386
  ts: Date.now(),
383
- };
387
+ });
384
388
  insertQueuedMessage.run(item.id, JSON.stringify(item));
385
389
  messageQueue.push(item);
386
390
  console.log(`[queue] +1 (${messageQueue.length} pending)`);
@@ -449,7 +453,7 @@ export async function processQueue() {
449
453
  console.log(`[queue] processing 1/${batch.length} message(s) for ${groupKey}, ${messageQueue.length} remaining`);
450
454
  let inserted = false;
451
455
  try {
452
- insertMessage.run('user', combined, source, '', settings.workingDir || null);
456
+ insertMessage.run('user', combined, source, '', settings["workingDir"] || null);
453
457
  deleteQueuedMessage.run(item.id);
454
458
  inserted = true;
455
459
  // Broadcast WITH fromQueue=true so the web client renders the user bubble
@@ -491,20 +495,20 @@ export async function processQueue() {
491
495
  // ─── Helpers ─────────────────────────────────────────
492
496
  function makeCleanEnv(extraEnv = {}) {
493
497
  const env = { ...process.env };
494
- delete env.CLAUDE_CODE_SSE_PORT;
495
- delete env.GEMINI_SYSTEM_MD;
498
+ delete env["CLAUDE_CODE_SSE_PORT"];
499
+ delete env["GEMINI_SYSTEM_MD"];
496
500
  // Phase 8: strip boss-only dispatch token from employee spawns so employees
497
501
  // cannot authenticate against /api/orchestrate/dispatch even via localhost.
498
502
  // Detect employee spawn by the explicit JAW_EMPLOYEE_MODE flag; main spawns
499
503
  // pass an empty extraEnv and keep the token inherited from process.env.
500
- if (extraEnv.JAW_EMPLOYEE_MODE === '1') {
501
- delete env.JAW_BOSS_TOKEN;
504
+ if (extraEnv["JAW_EMPLOYEE_MODE"] === '1') {
505
+ delete env["JAW_BOSS_TOKEN"];
502
506
  }
503
- env.PATH = buildServicePath(env.PATH || '');
507
+ env["PATH"] = buildServicePath(env["PATH"] || '');
504
508
  return {
505
509
  ...env,
506
510
  ...extraEnv,
507
- PATH: buildServicePath(extraEnv.PATH || env.PATH || ''),
511
+ PATH: buildServicePath(extraEnv["PATH"] || env["PATH"] || ''),
508
512
  };
509
513
  }
510
514
  function buildHistoryBlock(currentPrompt, workingDir, maxSessions = 10, maxTotalChars = 8000) {
@@ -517,6 +521,8 @@ function buildHistoryBlock(currentPrompt, workingDir, maxSessions = 10, maxTotal
517
521
  let charCount = 0;
518
522
  for (let i = 0; i < recent.length; i++) {
519
523
  const row = recent[i];
524
+ if (!row)
525
+ continue;
520
526
  const role = String(row.role || '');
521
527
  const content = String(row.content || '').trim();
522
528
  // Exclude the just-inserted current prompt when caller path stores user text
@@ -562,7 +568,7 @@ function withHistoryPrompt(prompt, historyBlock) {
562
568
  import { buildArgs, buildResumeArgs, resolveSessionBucket } from './args.js';
563
569
  export { buildArgs, buildResumeArgs, resolveSessionBucket };
564
570
  // ─── Upload wrapper ──────────────────────────────────
565
- export const saveUpload = (buffer, originalName) => _saveUpload(UPLOADS_DIR, buffer, originalName);
571
+ export const saveUpload = (buffer, originalName, options) => _saveUpload(UPLOADS_DIR, Buffer.isBuffer(buffer) ? buffer : Buffer.from(buffer), originalName, options);
566
572
  export { buildMediaPrompt, buildMediaPromptMany };
567
573
  // ─── Spawn Agent ─────────────────────────────────────
568
574
  import { AcpClient } from '../cli/acp-client.js';
@@ -599,7 +605,7 @@ export function spawnAgent(prompt, opts = {}) {
599
605
  const { forceNew = false, agentId, sysPrompt: customSysPrompt, memorySnapshot } = opts;
600
606
  const origin = opts.origin || 'web';
601
607
  const empSid = opts.employeeSessionId || null;
602
- const mainManaged = !forceNew && !empSid;
608
+ const mainManaged = !forceNew && !empSid && !opts.internal;
603
609
  const gateEligibleMain = mainManaged && !opts.agentId && !opts.internal && !opts._isFallback && !opts._isSmokeContinuation;
604
610
  const isEmployee = !mainManaged;
605
611
  const empTag = isEmployee ? { isEmployee: true } : {};
@@ -638,7 +644,7 @@ export function spawnAgent(prompt, opts = {}) {
638
644
  // Skip for employee spawns — distribute.ts manages AGENTS.md isolation
639
645
  if (!opts.internal && !opts._isFallback && !opts.agentId)
640
646
  regenerateB();
641
- const liveScope = resolveOrcScope({ origin, chatId: opts.chatId, workingDir: settings.workingDir || null });
647
+ const liveScope = resolveOrcScope(stripUndefined({ origin, chatId: opts.chatId, workingDir: settings["workingDir"] || null }));
642
648
  // Employee must not pollute boss's liveRun (see devlog 260423_employee_liverun_contamination)
643
649
  const effectiveLiveScope = mainManaged ? liveScope : null;
644
650
  // INVARIANT: 모든 외부 호출은 gateway.ts isAgentBusy()를 거침.
@@ -650,17 +656,17 @@ export function spawnAgent(prompt, opts = {}) {
650
656
  // Capture Boss main session channel so disconnected worker results can be
651
657
  // replayed to the correct origin/chatId later. Cleared in lifecycle-handler.
652
658
  if (mainManaged) {
653
- setCurrentMainMeta({
659
+ setCurrentMainMeta(stripUndefined({
654
660
  origin,
655
661
  target: opts.target,
656
662
  chatId: opts.chatId,
657
663
  requestId: opts.requestId,
658
664
  scopeId: liveScope,
659
- });
665
+ }));
660
666
  }
661
667
  let resolve;
662
668
  const resultPromise = new Promise(r => { resolve = r; });
663
- const session = getSession();
669
+ const session = getSession() ?? {};
664
670
  const ownerGeneration = getSessionOwnershipGeneration();
665
671
  let cli = resolveMainCli(opts.cli, settings, session);
666
672
  // Phase 52: Bootstrap consumption is moved BELOW the bucket-aware `isResume`
@@ -680,17 +686,20 @@ export function spawnAgent(prompt, opts = {}) {
680
686
  }
681
687
  }
682
688
  }
683
- const permissions = opts.permissions || settings.permissions || session.permissions || 'auto';
689
+ const permissions = opts.permissions || settings["permissions"] || session.permissions || 'auto';
684
690
  if (cli === 'opencode') {
685
691
  ensureOpencodeAlwaysAllowPermissions();
686
692
  }
687
- const cfg = settings.perCli?.[cli] || {};
688
- const ao = settings.activeOverrides?.[cli] || {};
693
+ const cfg = settings["perCli"]?.[cli] || {};
694
+ const ao = settings["activeOverrides"]?.[cli] || {};
689
695
  const model = opts.model || ao.model || cfg.model || 'default';
690
696
  const effort = opts.effort || ao.effort || cfg.effort || '';
697
+ const includeDirectories = Array.isArray(cfg.includeDirectories)
698
+ ? cfg.includeDirectories.filter((dir) => typeof dir === 'string' && dir.trim().length > 0)
699
+ : [];
691
700
  const sysPrompt = customSysPrompt !== undefined
692
701
  ? customSysPrompt
693
- : getSystemPrompt({ currentPrompt: prompt, forDisk: false, memorySnapshot, activeCli: cli });
702
+ : getSystemPrompt(stripUndefined({ currentPrompt: prompt, forDisk: false, memorySnapshot, activeCli: cli }));
694
703
  // Bucket-aware resume: codex-spark is kept in its own session bucket so
695
704
  // cross-model resume (gpt-5.4 ↔ gpt-5.3-codex-spark) doesn't send a
696
705
  // mismatched session_id to the server.
@@ -738,23 +747,26 @@ export function spawnAgent(prompt, opts = {}) {
738
747
  prompt = `${ts}\n${prompt}\n(need history? cli-jaw memory search "<keywords>" in "ENGLISH")`;
739
748
  }
740
749
  const resumeSessionId = empSid || (isResume ? bucketSessionId : null);
741
- const historyBlock = !isResume ? buildHistoryBlock(prompt, settings.workingDir) : '';
750
+ const historyBlock = !isResume && !opts._skipHistory ? buildHistoryBlock(prompt, settings["workingDir"]) : '';
742
751
  const promptForArgs = (cli === 'gemini' || cli === 'opencode')
743
752
  ? withHistoryPrompt(prompt, historyBlock)
744
753
  : prompt;
745
754
  let args;
746
755
  if (isResume) {
747
- console.log(`[jaw:resume] ${cli} session=${resumeSessionId.slice(0, 12)}...`);
748
- args = buildResumeArgs(cli, model, effort, resumeSessionId, prompt, permissions, { fastMode: cfg.fastMode, sysPrompt });
756
+ const sid = resumeSessionId || '';
757
+ console.log(`[jaw:resume] ${cli} session=${sid.slice(0, 12)}...`);
758
+ args = buildResumeArgs(cli, model, effort, sid, prompt, permissions, { fastMode: cfg.fastMode, sysPrompt, includeDirectories });
749
759
  }
750
760
  else {
751
- args = buildArgs(cli, model, effort, promptForArgs, sysPrompt, permissions, { fastMode: cfg.fastMode });
761
+ args = buildArgs(cli, model, effort, promptForArgs, sysPrompt, permissions, { fastMode: cfg.fastMode, includeDirectories });
752
762
  }
753
763
  const agentLabel = agentId || 'main';
764
+ const traceAudience = (opts.internal || isEmployee) ? 'internal' : 'public';
765
+ const parentLiveScopeForChild = !opts.internal && isEmployee ? liveScope : null;
754
766
  // ─── Universal employee isolation ────────────────────
755
767
  // All CLIs auto-read AGENTS.md/CLAUDE.md/GEMINI.md from cwd.
756
768
  // Employees must NOT see the Boss's instruction files.
757
- let spawnCwd = settings.workingDir;
769
+ let spawnCwd = settings["workingDir"];
758
770
  if (opts.agentId && (customSysPrompt || sysPrompt)) {
759
771
  const empPrompt = customSysPrompt || sysPrompt;
760
772
  const empPromptWithWorkspace = opts.workspaceContext
@@ -769,7 +781,7 @@ export function spawnAgent(prompt, opts = {}) {
769
781
  fs.mkdirSync(dotClaudeDir, { recursive: true });
770
782
  fs.writeFileSync(join(dotClaudeDir, 'CLAUDE.md'), empPromptWithWorkspace);
771
783
  try {
772
- fs.symlinkSync(settings.workingDir, join(tmpDir, 'workspace'), 'dir');
784
+ fs.symlinkSync(settings["workingDir"], join(tmpDir, 'workspace'), 'dir');
773
785
  }
774
786
  catch {
775
787
  // Non-fatal: the absolute Project root in Workspace Context remains authoritative.
@@ -794,7 +806,7 @@ export function spawnAgent(prompt, opts = {}) {
794
806
  resolve({ text: '', code: 127 });
795
807
  if (mainManaged)
796
808
  processQueue();
797
- cleanupEmployeeTmpDir(spawnCwd, settings.workingDir, agentLabel);
809
+ cleanupEmployeeTmpDir(spawnCwd, settings["workingDir"], agentLabel);
798
810
  return { child: null, promise: resultPromise };
799
811
  }
800
812
  if (cli === 'copilot') {
@@ -806,7 +818,7 @@ export function spawnAgent(prompt, opts = {}) {
806
818
  if (cli === 'gemini' && sysPrompt) {
807
819
  const tmpSysFile = join(os.tmpdir(), `jaw-gemini-sys-${agentLabel}.md`);
808
820
  fs.writeFileSync(tmpSysFile, sysPrompt);
809
- spawnEnv.GEMINI_SYSTEM_MD = tmpSysFile;
821
+ spawnEnv["GEMINI_SYSTEM_MD"] = tmpSysFile;
810
822
  }
811
823
  // ─── Copilot ACP branch ──────────────────────
812
824
  if (cli === 'copilot') {
@@ -842,6 +854,9 @@ export function spawnAgent(prompt, opts = {}) {
842
854
  const acp = new AcpClient({ model, workDir: spawnCwd, permissions, env: spawnEnv });
843
855
  acp.spawn();
844
856
  const child = acp.proc;
857
+ if (!child) {
858
+ throw new Error('Copilot ACP process was not created');
859
+ }
845
860
  if (mainManaged)
846
861
  activeProcess = child;
847
862
  // Phase 7-3: detect duplicate spawn for same agentLabel. claimWorker guards
@@ -850,8 +865,9 @@ export function spawnAgent(prompt, opts = {}) {
850
865
  console.warn(`[spawn:dup] activeProcesses already has child for ${agentLabel} — orphaning previous reference`);
851
866
  }
852
867
  activeProcesses.set(agentLabel, child);
853
- broadcast('agent_status', { running: true, agentId: agentLabel, cli, ...empTag });
854
- if (mainManaged)
868
+ if (!opts.internal)
869
+ broadcast('agent_status', { running: true, agentId: agentLabel, cli, ...empTag });
870
+ if (mainManaged && !opts.internal)
855
871
  beginLiveRun(liveScope, cli);
856
872
  // ─── DIFF-C: ACP error guard — prevent uncaught EventEmitter crash ───
857
873
  let acpSettled = false; // guard: error→exit can fire sequentially
@@ -859,7 +875,7 @@ export function spawnAgent(prompt, opts = {}) {
859
875
  if (acpSettled)
860
876
  return;
861
877
  acpSettled = true;
862
- cleanupEmployeeTmpDir(spawnCwd, settings.workingDir, agentLabel);
878
+ cleanupEmployeeTmpDir(spawnCwd, settings["workingDir"], agentLabel);
863
879
  opts.lifecycle?.onExit?.(null);
864
880
  const msg = `Copilot ACP spawn failed: ${err.message}`;
865
881
  console.error(`[acp:error] ${msg}`);
@@ -875,16 +891,20 @@ export function spawnAgent(prompt, opts = {}) {
875
891
  processQueue();
876
892
  });
877
893
  if (mainManaged && !opts.internal && !opts._skipInsert) {
878
- insertMessage.run('user', prompt, cli, model, settings.workingDir || null);
894
+ insertMessage.run('user', prompt, cli, model, settings["workingDir"] || null);
879
895
  }
880
- broadcast('agent_status', { status: 'running', cli, agentId: agentLabel, ...empTag });
896
+ if (!opts.internal)
897
+ broadcast('agent_status', { status: 'running', cli, agentId: agentLabel, ...empTag }, traceAudience);
898
+ const traceRunId = startTraceRun({ cli, model, workingDir: settings["workingDir"] || null, agentLabel, audience: traceAudience });
881
899
  const ctx = {
882
900
  fullText: '', traceLog: [], toolLog: [], seenToolKeys: new Set(),
883
901
  hasClaudeStreamEvents: false, sessionId: null, cost: null,
884
902
  turns: null, duration: null, tokens: null, stderrBuf: '',
885
903
  thinkingBuf: '',
886
904
  liveScope: effectiveLiveScope,
887
- parentLiveScope: isEmployee ? liveScope : null,
905
+ parentLiveScope: parentLiveScopeForChild,
906
+ traceRunId,
907
+ traceAudience,
888
908
  };
889
909
  // Flush accumulated 💭 thinking buffer as a single merged event
890
910
  function flushThinking() {
@@ -896,12 +916,13 @@ export function spawnAgent(prompt, opts = {}) {
896
916
  const label = singleLine.length > 120 ? `${singleLine.slice(0, 119)}…` : singleLine;
897
917
  console.log(` 💭 ${label}`);
898
918
  const tool = { icon: '💭', label, toolType: 'thinking', detail: merged };
919
+ stampTraceTool(tool, ctx, 'thinking');
899
920
  ctx.toolLog.push(tool);
900
921
  if (ctx.liveScope)
901
922
  replaceLiveRunTools(ctx.liveScope, ctx.toolLog);
902
923
  if (ctx.parentLiveScope)
903
924
  appendLiveRunTool(ctx.parentLiveScope, { ...tool, isEmployee: true });
904
- broadcast('agent_tool', { agentId: agentLabel, ...tool, ...empTag });
925
+ broadcast('agent_tool', { agentId: agentLabel, ...tool, ...empTag }, traceAudience);
905
926
  }
906
927
  ctx.thinkingBuf = '';
907
928
  }
@@ -912,6 +933,8 @@ export function spawnAgent(prompt, opts = {}) {
912
933
  acp.on('session/update', (params) => {
913
934
  if (replayMode)
914
935
  return; // 리플레이 중 모든 이벤트 무시
936
+ const update = asCliEventRecord(asCliEventRecord(params)["update"]);
937
+ appendTraceEvent({ runId: ctx.traceRunId, source: 'acp_raw', eventType: fieldString(update.sessionUpdate, 'session/update'), raw: params });
915
938
  const parsed = extractFromAcpUpdate(params, ctx);
916
939
  if (!parsed)
917
940
  return;
@@ -928,12 +951,13 @@ export function spawnAgent(prompt, opts = {}) {
928
951
  const key = `${parsedTool.icon}:${parsedTool.label}:${parsedTool.stepRef || ''}:${parsedTool.status || ''}`;
929
952
  if (!ctx.seenToolKeys.has(key)) {
930
953
  ctx.seenToolKeys.add(key);
954
+ stampTraceTool(parsedTool, ctx, parsedTool.toolType || 'tool');
931
955
  ctx.toolLog.push(parsedTool);
932
956
  if (ctx.liveScope)
933
957
  replaceLiveRunTools(ctx.liveScope, ctx.toolLog);
934
958
  if (ctx.parentLiveScope)
935
959
  appendLiveRunTool(ctx.parentLiveScope, { ...parsedTool, isEmployee: true });
936
- broadcast('agent_tool', { agentId: agentLabel, ...parsedTool, ...empTag });
960
+ broadcast('agent_tool', { agentId: agentLabel, ...parsedTool, ...empTag }, traceAudience);
937
961
  // Reset heartbeat gate on actually visible broadcast (not 💭)
938
962
  lastVisibleBroadcastTs = Date.now();
939
963
  heartbeatSent = false;
@@ -950,34 +974,39 @@ export function spawnAgent(prompt, opts = {}) {
950
974
  });
951
975
  // [P2-3.14] session/cancelled → route through extractFromAcpUpdate for UI notification
952
976
  acp.on('session/cancelled', (params) => {
977
+ appendTraceEvent({ runId: ctx.traceRunId, source: 'acp_raw', eventType: 'session/cancelled', raw: params });
953
978
  const parsed = extractFromAcpUpdate({
954
979
  update: { sessionUpdate: 'session_cancelled', ...(params || {}) },
955
980
  });
956
981
  if (parsed?.tool) {
982
+ stampTraceTool(parsed.tool, ctx, parsed.tool.toolType || 'tool');
957
983
  ctx.toolLog.push(parsed.tool);
958
984
  if (ctx.liveScope)
959
985
  replaceLiveRunTools(ctx.liveScope, ctx.toolLog);
960
986
  if (ctx.parentLiveScope)
961
987
  appendLiveRunTool(ctx.parentLiveScope, { ...parsed.tool, isEmployee: true });
962
- broadcast('agent_tool', { agentId: agentLabel, ...parsed.tool, ...empTag });
988
+ broadcast('agent_tool', { agentId: agentLabel, ...parsed.tool, ...empTag }, traceAudience);
963
989
  }
964
990
  });
965
991
  // [P2-3.15] session/request_permission → audit record in toolLog
966
992
  acp.on('session/request_permission', (params) => {
993
+ appendTraceEvent({ runId: ctx.traceRunId, source: 'acp_raw', eventType: 'session/request_permission', raw: params });
967
994
  const parsed = extractFromAcpUpdate({
968
995
  update: { sessionUpdate: 'request_permission', ...(params || {}) },
969
996
  });
970
997
  if (parsed?.tool) {
998
+ stampTraceTool(parsed.tool, ctx, parsed.tool.toolType || 'tool');
971
999
  ctx.toolLog.push(parsed.tool);
972
1000
  if (ctx.liveScope)
973
1001
  replaceLiveRunTools(ctx.liveScope, ctx.toolLog);
974
1002
  if (ctx.parentLiveScope)
975
1003
  appendLiveRunTool(ctx.parentLiveScope, { ...parsed.tool, isEmployee: true });
976
- broadcast('agent_tool', { agentId: agentLabel, ...parsed.tool, ...empTag });
1004
+ broadcast('agent_tool', { agentId: agentLabel, ...parsed.tool, ...empTag }, traceAudience);
977
1005
  }
978
1006
  });
979
1007
  // stderr_activity → stderrBuf accumulation + conditional heartbeat
980
1008
  acp.on('stderr_activity', (text) => {
1009
+ appendTraceEvent({ runId: ctx.traceRunId, source: 'stderr', eventType: 'stderr_activity', raw: text });
981
1010
  // Accumulate stderr for diagnostics (capped)
982
1011
  if (ctx.stderrBuf.length < 4000) {
983
1012
  ctx.stderrBuf += text + '\n';
@@ -993,7 +1022,7 @@ export function spawnAgent(prompt, opts = {}) {
993
1022
  icon: '⏳',
994
1023
  label: 'working... (no visible progress)',
995
1024
  ...empTag,
996
- });
1025
+ }, traceAudience);
997
1026
  }
998
1027
  });
999
1028
  // Run ACP flow
@@ -1001,7 +1030,7 @@ export function spawnAgent(prompt, opts = {}) {
1001
1030
  (async () => {
1002
1031
  try {
1003
1032
  const initResult = await acp.initialize();
1004
- if (process.env.DEBUG)
1033
+ if (process.env["DEBUG"])
1005
1034
  console.log('[acp:init]', JSON.stringify(initResult).slice(0, 200));
1006
1035
  replayMode = true; // Phase 17.2: mute during session load
1007
1036
  let loadSessionOk = false;
@@ -1030,23 +1059,23 @@ export function spawnAgent(prompt, opts = {}) {
1030
1059
  ctx.toolLog = [];
1031
1060
  ctx.seenToolKeys.clear();
1032
1061
  ctx.thinkingBuf = ''; // Phase 17.2: clear replay thinking too
1033
- if (mainManaged)
1062
+ if (mainManaged && !opts.internal)
1034
1063
  beginLiveRun(liveScope, cli);
1035
1064
  // If loadSession failed (or not resuming), inject history into prompt
1036
1065
  const needsHistoryFallback = isResume && !loadSessionOk;
1037
- const fallbackHistory = needsHistoryFallback ? buildHistoryBlock(prompt, settings.workingDir) : '';
1066
+ const fallbackHistory = needsHistoryFallback && !opts._skipHistory ? buildHistoryBlock(prompt, settings["workingDir"]) : '';
1038
1067
  const acpPrompt = needsHistoryFallback
1039
1068
  ? withHistoryPrompt(prompt, fallbackHistory)
1040
1069
  : (isResume ? prompt : withHistoryPrompt(prompt, historyBlock));
1041
1070
  const { promise: promptPromise } = acp.prompt(acpPrompt);
1042
1071
  const promptResult = await promptPromise;
1043
1072
  promptCompleted = true;
1044
- if (process.env.DEBUG)
1073
+ if (process.env["DEBUG"])
1045
1074
  console.log('[acp:prompt:result]', JSON.stringify(promptResult).slice(0, 200));
1046
1075
  // Save session BEFORE shutdown — acp.shutdown() causes SIGTERM (code=null),
1047
1076
  // which skips the exit handler's code===0 gate, losing session continuity.
1048
1077
  const persistedAcpSessionId = ctx.sessionId;
1049
- if (persistedAcpSessionId && persistMainSession({
1078
+ if (persistedAcpSessionId && persistMainSession(stripUndefined({
1050
1079
  ownerGeneration,
1051
1080
  forceNew,
1052
1081
  employeeSessionId: empSid,
@@ -1056,7 +1085,7 @@ export function spawnAgent(prompt, opts = {}) {
1056
1085
  model,
1057
1086
  resumeKey,
1058
1087
  effort: cfg.effort || '',
1059
- })) {
1088
+ }))) {
1060
1089
  console.log(`[jaw:session] saved ${cli} session=${persistedAcpSessionId.slice(0, 12)}... (pre-shutdown)`);
1061
1090
  }
1062
1091
  await acp.shutdown();
@@ -1071,7 +1100,7 @@ export function spawnAgent(prompt, opts = {}) {
1071
1100
  if (acpSettled)
1072
1101
  return; // error handler already resolved
1073
1102
  acpSettled = true;
1074
- cleanupEmployeeTmpDir(spawnCwd, settings.workingDir, agentLabel);
1103
+ cleanupEmployeeTmpDir(spawnCwd, settings["workingDir"], agentLabel);
1075
1104
  opts.lifecycle?.onExit?.(code ?? null);
1076
1105
  // [I2] Consume per-process kill reason
1077
1106
  const acpKillReason = consumeKillReason(acp.proc?.pid);
@@ -1139,8 +1168,9 @@ export function spawnAgent(prompt, opts = {}) {
1139
1168
  console.warn(`[spawn:dup] activeProcesses already has child for ${agentLabel} — orphaning previous reference`);
1140
1169
  }
1141
1170
  activeProcesses.set(agentLabel, child);
1142
- broadcast('agent_status', { running: true, agentId: agentLabel, cli, ...empTag });
1143
- if (mainManaged)
1171
+ if (!opts.internal)
1172
+ broadcast('agent_status', { running: true, agentId: agentLabel, cli, ...empTag });
1173
+ if (mainManaged && !opts.internal)
1144
1174
  beginLiveRun(liveScope, cli);
1145
1175
  // ─── DIFF-A: error guard — prevent uncaught ENOENT crash ───
1146
1176
  let stdSettled = false; // guard: error→close can fire sequentially
@@ -1157,7 +1187,7 @@ export function spawnAgent(prompt, opts = {}) {
1157
1187
  if (stdSettled)
1158
1188
  return;
1159
1189
  stdSettled = true;
1160
- cleanupEmployeeTmpDir(spawnCwd, settings.workingDir, agentLabel);
1190
+ cleanupEmployeeTmpDir(spawnCwd, settings["workingDir"], agentLabel);
1161
1191
  opts.lifecycle?.onExit?.(null);
1162
1192
  const msg = err.code === 'ENOENT'
1163
1193
  ? `CLI '${cli}' 실행 실패 (ENOENT). 설치/경로를 확인하세요.`
@@ -1175,7 +1205,7 @@ export function spawnAgent(prompt, opts = {}) {
1175
1205
  processQueue();
1176
1206
  });
1177
1207
  if (mainManaged && !opts.internal && !opts._skipInsert) {
1178
- insertMessage.run('user', prompt, cli, model, settings.workingDir || null);
1208
+ insertMessage.run('user', prompt, cli, model, settings["workingDir"] || null);
1179
1209
  }
1180
1210
  if (cli === 'claude') {
1181
1211
  child.stdin.write(withHistoryPrompt(prompt, historyBlock));
@@ -1187,7 +1217,9 @@ export function spawnAgent(prompt, opts = {}) {
1187
1217
  child.stdin.write(codexStdin);
1188
1218
  }
1189
1219
  child.stdin.end();
1190
- broadcast('agent_status', { status: 'running', cli, agentId: agentLabel, ...empTag });
1220
+ if (!opts.internal)
1221
+ broadcast('agent_status', { status: 'running', cli, agentId: agentLabel, ...empTag }, traceAudience);
1222
+ const traceRunId = startTraceRun({ cli, model, workingDir: settings["workingDir"] || null, agentLabel, audience: traceAudience });
1191
1223
  const ctx = {
1192
1224
  fullText: '',
1193
1225
  traceLog: [],
@@ -1201,14 +1233,41 @@ export function spawnAgent(prompt, opts = {}) {
1201
1233
  tokens: null,
1202
1234
  stderrBuf: '',
1203
1235
  hasActiveSubAgent: false,
1204
- showReasoning: settings.showReasoning === true,
1236
+ showReasoning: settings["showReasoning"] === true,
1205
1237
  outputTextStarted: false,
1206
1238
  liveScope: effectiveLiveScope,
1207
- parentLiveScope: isEmployee ? liveScope : null,
1239
+ parentLiveScope: parentLiveScopeForChild,
1240
+ traceRunId,
1241
+ traceAudience,
1208
1242
  geminiResultSeen: false,
1209
- opencodeSpawnAudit: opencodeSpawnAudit,
1243
+ ...(opencodeSpawnAudit ? { opencodeSpawnAudit: opencodeSpawnAudit } : {}),
1210
1244
  };
1211
1245
  let geminiWatchdog = null;
1246
+ // ─── Subprocess stall watchdog (Phase 1: #178 OAuth2 stall recovery) ───
1247
+ const rawAgentTimeoutCfg = settings["agentTimeout"];
1248
+ const agentTimeoutCfg = rawAgentTimeoutCfg && typeof rawAgentTimeoutCfg === 'object'
1249
+ ? rawAgentTimeoutCfg
1250
+ : {};
1251
+ const watchdogConfig = {};
1252
+ if (typeof agentTimeoutCfg['firstProgressMs'] === 'number')
1253
+ watchdogConfig.firstProgressMs = agentTimeoutCfg['firstProgressMs'];
1254
+ if (typeof agentTimeoutCfg['idleMs'] === 'number')
1255
+ watchdogConfig.idleMs = agentTimeoutCfg['idleMs'];
1256
+ if (typeof agentTimeoutCfg['absoluteMs'] === 'number')
1257
+ watchdogConfig.absoluteMs = agentTimeoutCfg['absoluteMs'];
1258
+ const stallWatchdog = attachWatchdog(child, agentLabel, (reason) => {
1259
+ console.log(`[jaw:watchdog] killing ${agentLabel} — ${reason}`);
1260
+ ctx.stallReason = reason;
1261
+ if (child.pid) {
1262
+ killProcessTree(child.pid, 'SIGTERM');
1263
+ setTimeout(() => {
1264
+ try {
1265
+ killProcessTree(child.pid, 'SIGKILL');
1266
+ }
1267
+ catch { /* already dead */ }
1268
+ }, 5_000);
1269
+ }
1270
+ }, watchdogConfig);
1212
1271
  let buffer = '';
1213
1272
  const recordOpencodeEvent = (line, event) => {
1214
1273
  if (cli !== 'opencode')
@@ -1217,6 +1276,62 @@ export function spawnAgent(prompt, opts = {}) {
1217
1276
  ctx.opencodeLastEventType = typeof event?.type === 'string' ? event.type : 'unknown';
1218
1277
  ctx.opencodeLastEventAt = Date.now();
1219
1278
  };
1279
+ const dispatchNdjsonLine = (line) => {
1280
+ let raw;
1281
+ try {
1282
+ raw = JSON.parse(line);
1283
+ }
1284
+ catch {
1285
+ appendTraceEvent({ runId: ctx.traceRunId, source: 'cli_raw', eventType: 'malformed_json', raw: line });
1286
+ return;
1287
+ }
1288
+ appendTraceEvent({
1289
+ runId: ctx.traceRunId,
1290
+ source: 'cli_raw',
1291
+ eventType: fieldString(asCliEventRecord(raw).type, '<no-type>'),
1292
+ raw,
1293
+ });
1294
+ const event = discriminate(cli, raw);
1295
+ if (!event) {
1296
+ const type = fieldString(asCliEventRecord(raw).type, '<no-type>');
1297
+ ctx.traceLog.push(`[cli:unknown-event] cli=${cli} type=${type} preview=${JSON.stringify(raw).slice(0, 200)}`);
1298
+ return;
1299
+ }
1300
+ recordOpencodeEvent(line, event);
1301
+ if (process.env["DEBUG"]) {
1302
+ console.log(`[jaw:event:${agentLabel}] ${cli} type=${event.type}`);
1303
+ console.log(`[jaw:raw:${agentLabel}] ${line.slice(0, 300)}`);
1304
+ }
1305
+ logEventSummary(agentLabel, cli, event, ctx);
1306
+ if (!ctx.sessionId)
1307
+ ctx.sessionId = extractSessionId(cli, event);
1308
+ extractFromEvent(cli, event, ctx, agentLabel, empTag);
1309
+ // Gemini watchdog: AFTER extractFromEvent sets geminiResultSeen
1310
+ if (cli === 'gemini' && ctx.geminiResultSeen && !geminiWatchdog) {
1311
+ geminiWatchdog = setTimeout(() => {
1312
+ console.warn(`[jaw:gemini-watchdog] ${agentLabel} — result seen but close not received after 10s, killing`);
1313
+ try {
1314
+ child.kill('SIGTERM');
1315
+ }
1316
+ catch { /* already dead */ }
1317
+ }, 10000);
1318
+ }
1319
+ // Sub-agent wait: keep stall timer alive
1320
+ if (ctx.hasActiveSubAgent) {
1321
+ opts.lifecycle?.onActivity?.('heartbeat');
1322
+ }
1323
+ const outputChunk = extractOutputChunk(cli, event, ctx);
1324
+ if (outputChunk) {
1325
+ if (ctx.liveScope)
1326
+ appendLiveRunText(ctx.liveScope, outputChunk);
1327
+ broadcast('agent_output', {
1328
+ agentId: agentLabel,
1329
+ cli,
1330
+ text: outputChunk,
1331
+ ...empTag,
1332
+ }, (opts.internal || isEmployee) ? 'internal' : 'public');
1333
+ }
1334
+ };
1220
1335
  if (cli === 'opencode') {
1221
1336
  opencodeIdleTimer = setInterval(() => {
1222
1337
  const idleMs = Date.now() - lastOpencodeIoAt;
@@ -1237,55 +1352,20 @@ export function spawnAgent(prompt, opts = {}) {
1237
1352
  for (const line of lines) {
1238
1353
  if (!line.trim())
1239
1354
  continue;
1240
- try {
1241
- const event = JSON.parse(line);
1242
- recordOpencodeEvent(line, event);
1243
- if (process.env.DEBUG) {
1244
- console.log(`[jaw:event:${agentLabel}] ${cli} type=${event.type}`);
1245
- console.log(`[jaw:raw:${agentLabel}] ${line.slice(0, 300)}`);
1246
- }
1247
- logEventSummary(agentLabel, cli, event, ctx);
1248
- if (!ctx.sessionId)
1249
- ctx.sessionId = extractSessionId(cli, event);
1250
- extractFromEvent(cli, event, ctx, agentLabel, empTag);
1251
- // Gemini watchdog: AFTER extractFromEvent sets geminiResultSeen
1252
- if (cli === 'gemini' && ctx.geminiResultSeen && !geminiWatchdog) {
1253
- geminiWatchdog = setTimeout(() => {
1254
- console.warn(`[jaw:gemini-watchdog] ${agentLabel} — result seen but close not received after 10s, killing`);
1255
- try {
1256
- child.kill('SIGTERM');
1257
- }
1258
- catch { /* already dead */ }
1259
- }, 10000);
1260
- }
1261
- // Sub-agent wait: keep stall timer alive
1262
- if (ctx.hasActiveSubAgent) {
1263
- opts.lifecycle?.onActivity?.('heartbeat');
1264
- }
1265
- const outputChunk = extractOutputChunk(cli, event, ctx);
1266
- if (outputChunk) {
1267
- if (ctx.liveScope)
1268
- appendLiveRunText(ctx.liveScope, outputChunk);
1269
- broadcast('agent_output', {
1270
- agentId: agentLabel,
1271
- cli,
1272
- text: outputChunk,
1273
- ...empTag,
1274
- }, isEmployee ? 'internal' : 'public');
1275
- }
1276
- }
1277
- catch { /* non-JSON line */ }
1355
+ dispatchNdjsonLine(line);
1278
1356
  }
1279
1357
  });
1280
1358
  child.stderr.on('data', (chunk) => {
1281
1359
  opts.lifecycle?.onActivity?.('stderr');
1282
1360
  lastOpencodeIoAt = Date.now();
1283
1361
  const text = chunk.toString().trim();
1362
+ appendTraceEvent({ runId: ctx.traceRunId, source: 'stderr', eventType: 'stderr', raw: text });
1284
1363
  console.error(`[jaw:stderr:${agentLabel}] ${text}`);
1285
1364
  ctx.stderrBuf += text + '\n';
1286
1365
  });
1287
1366
  child.on('close', (code) => {
1288
1367
  clearOpencodeIdleTimer();
1368
+ stallWatchdog.stop();
1289
1369
  if (geminiWatchdog) {
1290
1370
  clearTimeout(geminiWatchdog);
1291
1371
  geminiWatchdog = null;
@@ -1294,25 +1374,11 @@ export function spawnAgent(prompt, opts = {}) {
1294
1374
  return; // error handler already resolved
1295
1375
  // [I1] Flush residual NDJSON buffer — last event may lack trailing newline
1296
1376
  if (buffer.trim()) {
1297
- try {
1298
- const lastEvent = JSON.parse(buffer);
1299
- recordOpencodeEvent(buffer, lastEvent);
1300
- logEventSummary(agentLabel, cli, lastEvent, ctx);
1301
- if (!ctx.sessionId)
1302
- ctx.sessionId = extractSessionId(cli, lastEvent);
1303
- extractFromEvent(cli, lastEvent, ctx, agentLabel, empTag);
1304
- const outputChunk = extractOutputChunk(cli, lastEvent, ctx);
1305
- if (outputChunk) {
1306
- if (ctx.liveScope)
1307
- appendLiveRunText(ctx.liveScope, outputChunk);
1308
- broadcast('agent_output', { agentId: agentLabel, cli, text: outputChunk, ...empTag }, isEmployee ? 'internal' : 'public');
1309
- }
1310
- }
1311
- catch { /* incomplete JSON — discard */ }
1377
+ dispatchNdjsonLine(buffer);
1312
1378
  buffer = '';
1313
1379
  }
1314
1380
  flushClaudeBuffers(ctx, agentLabel, empTag); // flush any pending thinking/input buffers
1315
- cleanupEmployeeTmpDir(spawnCwd, settings.workingDir, agentLabel);
1381
+ cleanupEmployeeTmpDir(spawnCwd, settings["workingDir"], agentLabel);
1316
1382
  opts.lifecycle?.onExit?.(code ?? null);
1317
1383
  // [I2] Consume per-process kill reason
1318
1384
  const stdKillReason = consumeKillReason(child.pid);