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
@@ -0,0 +1,159 @@
1
+ // @ts-check
2
+ /**
3
+ * G10 mirror — cli-jaw claim audit.
4
+ *
5
+ * cli-jaw is a multi-CLI agent runtime that talks to local Chrome via the
6
+ * `agbrowse` skill. cli-jaw itself does NOT operate hosted/cloud browsers,
7
+ * does NOT expose remote CDP, does NOT bypass CAPTCHA/Cloudflare/stealth,
8
+ * and does NOT publish benchmark leaderboard scores.
9
+ *
10
+ * This script enforces those positioning boundaries on cli-jaw's own claim
11
+ * surfaces (READMEs, capability truth table). Wired through
12
+ * `scripts/release-gates.mjs` as `gate:no-cloud-claims` and mirrors
13
+ * `agbrowse/web-ai/claim-audit.mjs`.
14
+ */
15
+ import fs from 'node:fs';
16
+ import path from 'node:path';
17
+
18
+ const TARGETS = [
19
+ { file: 'README.md', sectionMode: 'ready' },
20
+ { file: 'README.ko.md', sectionMode: 'ready' },
21
+ { file: 'README.ja.md', sectionMode: 'ready' },
22
+ { file: 'README.zh-CN.md', sectionMode: 'ready' },
23
+ { file: 'structure/CAPABILITY_TRUTH_TABLE.md', sectionMode: 'ready' },
24
+ ];
25
+
26
+ const FORBIDDEN = [
27
+ { term: 'hosted browser', re: /hosted\s+browser/i, why: 'cli-jaw delegates to local Chrome via agbrowse only' },
28
+ { term: 'cloud browser', re: /cloud\s+browser/i, why: 'no managed/cloud browser runtime' },
29
+ { term: 'cloud runtime', re: /cloud\s+runtime/i, why: 'no managed/cloud runtime' },
30
+ { term: 'cloud agent', re: /cloud\s+agent/i, why: 'no hosted agent service' },
31
+ { term: 'remote CDP', re: /remote[-\s]+cdp/i, why: 'remote CDP is deferred upstream (agbrowse docs/EXTERNAL_CDP.md)' },
32
+ { term: 'external CDP', re: /external[-\s]+cdp/i, why: 'external CDP is deferred upstream' },
33
+ { term: 'stealth', re: /\bstealth\b/i, why: 'no stealth/anti-detection support' },
34
+ { term: 'CAPTCHA bypass', re: /captcha\s+bypass/i, why: 'no CAPTCHA bypass' },
35
+ { term: 'Cloudflare bypass', re: /cloudflare\s+bypass/i, why: 'no Cloudflare bypass' },
36
+ { term: 'leaderboard', re: /leaderboard/i, why: 'no benchmark leaderboard claim' },
37
+ ];
38
+
39
+ const EXPERIMENTAL_HEADERS = [
40
+ /experimental/i,
41
+ /deferred/i,
42
+ /out\s+of\s+scope/i,
43
+ /forbidden/i,
44
+ /not\s+implemented/i,
45
+ /known\s+gaps/i,
46
+ /comparison\s+rules/i,
47
+ /mirror\s+rules/i,
48
+ /known\s+limitations/i,
49
+ /comparison(\s+(boundary|vs|with|against|table))?/i,
50
+ /^current\s+positioning/i,
51
+ /^positioning/i,
52
+ /support\s+labels?/i,
53
+ /public\s+claim\s+gate/i,
54
+ /^status$/i,
55
+ /^phase\s+status/i,
56
+ /claim[-\s]*audit/i,
57
+ /boundary/i,
58
+ ];
59
+
60
+ const NEGATION_MARKERS = [
61
+ /\bno\b/i,
62
+ /\bnot\b/i,
63
+ /\bdeferred\b/i,
64
+ /\bdeferral\b/i,
65
+ /\bdo(?:es)?\s+not\b/i,
66
+ /\bwon['’]t\b/i,
67
+ /\bnever\b/i,
68
+ /\bout\s+of\s+scope\b/i,
69
+ /\bexperimental\b/i,
70
+ /\bforbidden\b/i,
71
+ /\bdeprecated\b/i,
72
+ /\bn\/?a\b/i,
73
+ /\bpending\b/i,
74
+ /\bdeliberately\b/i,
75
+ /\bdoes\s+not\s+offer\b/i,
76
+ ];
77
+
78
+ /**
79
+ * @param {string} text
80
+ * @returns {Array<{ start: number, end: number, head: string, isExperimental: boolean }>}
81
+ */
82
+ function partitionSections(text) {
83
+ const lines = text.split('\n');
84
+ const sections = [];
85
+ let cur = { start: 0, head: '(prologue)', isExperimental: false };
86
+ for (let i = 0; i < lines.length; i += 1) {
87
+ const m = /^#{1,6}\s+(.+?)\s*$/.exec(lines[i]);
88
+ if (m) {
89
+ sections.push({ start: cur.start, end: i, head: cur.head, isExperimental: cur.isExperimental });
90
+ const head = m[1];
91
+ const isExp = EXPERIMENTAL_HEADERS.some((re) => re.test(head));
92
+ cur = { start: i + 1, head, isExperimental: isExp };
93
+ }
94
+ }
95
+ sections.push({ start: cur.start, end: lines.length, head: cur.head, isExperimental: cur.isExperimental });
96
+ return sections;
97
+ }
98
+
99
+ /**
100
+ * @param {{ repoRoot: string }} opts
101
+ */
102
+ export function auditClaims({ repoRoot }) {
103
+ const offending = [];
104
+ const scanned = [];
105
+ for (const target of TARGETS) {
106
+ const abs = path.join(repoRoot, target.file);
107
+ if (!fs.existsSync(abs)) continue;
108
+ scanned.push(target.file);
109
+ const text = fs.readFileSync(abs, 'utf8');
110
+ const sections = partitionSections(text);
111
+ const lines = text.split('\n');
112
+ for (let i = 0; i < lines.length; i += 1) {
113
+ const line = lines[i];
114
+ const trimmed = line.trim();
115
+ if (trimmed.startsWith('```') || trimmed.startsWith('//')) continue;
116
+ const sec = sections.find((s) => i >= s.start && i < s.end);
117
+ if (target.sectionMode === 'ready' && sec && sec.isExperimental) continue;
118
+ const lineHasNegation = NEGATION_MARKERS.some((re) => re.test(line));
119
+ let paragraphHasNegation = false;
120
+ for (let j = i - 1, scannedBack = 0; j >= 0 && scannedBack < 3; j -= 1) {
121
+ const back = lines[j].trim();
122
+ if (!back) continue;
123
+ scannedBack += 1;
124
+ if (NEGATION_MARKERS.some((re) => re.test(back))) {
125
+ paragraphHasNegation = true;
126
+ break;
127
+ }
128
+ }
129
+ for (const f of FORBIDDEN) {
130
+ if (f.re.test(line)) {
131
+ if (lineHasNegation || paragraphHasNegation) continue;
132
+ offending.push({
133
+ file: target.file,
134
+ line: i + 1,
135
+ term: f.term,
136
+ why: f.why,
137
+ section: sec ? sec.head : '(unknown)',
138
+ });
139
+ }
140
+ }
141
+ }
142
+ }
143
+ return { ok: offending.length === 0, scanned, offending };
144
+ }
145
+
146
+ export function formatClaimAuditReport(report) {
147
+ const lines = [];
148
+ lines.push(`claim-audit: scanned ${report.scanned.length} file(s)`);
149
+ for (const f of report.scanned) lines.push(` - ${f}`);
150
+ if (report.ok) {
151
+ lines.push('result: PASS — no forbidden cloud/stealth/external-CDP claims in non-experimental sections');
152
+ } else {
153
+ lines.push(`result: FAIL — ${report.offending.length} offending hit(s)`);
154
+ for (const o of report.offending) {
155
+ lines.push(` ${o.file}:${o.line} [${o.term}] section="${o.section}" reason=${o.why}`);
156
+ }
157
+ }
158
+ return lines.join('\n');
159
+ }
@@ -199,11 +199,11 @@ function main(): void {
199
199
  for (const [k, v] of Object.entries(skill)) {
200
200
  ordered[k] = v;
201
201
  if (k === 'name') {
202
- ordered.name_ko = skill.name_ko;
203
- ordered.name_en = skill.name_en;
202
+ ordered["name_ko"] = skill.name_ko;
203
+ ordered["name_en"] = skill.name_en;
204
204
  } else if (k === 'description') {
205
- ordered.desc_ko = skill.desc_ko;
206
- ordered.desc_en = skill.desc_en;
205
+ ordered["desc_ko"] = skill.desc_ko;
206
+ ordered["desc_en"] = skill.desc_en;
207
207
  }
208
208
  }
209
209
  newSkills[skillId] = ordered as Skill;
@@ -139,7 +139,7 @@ if [ "$OS" = "darwin" ]; then
139
139
  fi
140
140
  fi
141
141
 
142
- # ── Verify checksum (best-effort) ──
142
+ # ── Verify checksum when available ──
143
143
  if command -v shasum &>/dev/null || command -v sha256sum &>/dev/null; then
144
144
  EXPECTED=$(curl -fsSL "$CHECKSUM_URL" 2>/dev/null | grep "$ASSET" | awk '{print $1}')
145
145
  if [ -n "$EXPECTED" ]; then
@@ -151,7 +151,7 @@ if command -v shasum &>/dev/null || command -v sha256sum &>/dev/null; then
151
151
  if [ "$EXPECTED" = "$ACTUAL" ]; then
152
152
  ok "Checksum verified"
153
153
  else
154
- warn "Checksum mismatch (expected: ${EXPECTED:0:12}…, got: ${ACTUAL:0:12}…)"
154
+ fail "Checksum mismatch (expected: ${EXPECTED:0:12}…, got: ${ACTUAL:0:12}…)"
155
155
  fi
156
156
  fi
157
157
  fi
@@ -251,7 +251,8 @@ main() {
251
251
  echo ""
252
252
  echo -e "${DIM} Tip: Authenticate at least one AI engine:${NC}"
253
253
  echo -e "${DIM} gh auth login # GitHub Copilot (free)${NC}"
254
- echo -e "${DIM} claude auth # Anthropic Claude${NC}"
254
+ echo -e "${DIM} claude auth login # Anthropic Claude${NC}"
255
+ echo -e "${DIM} claude auth status # Verify Claude login${NC}"
255
256
  echo -e "${DIM} codex login # OpenAI Codex${NC}"
256
257
  echo ""
257
258
  }
@@ -0,0 +1,347 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Phase 22 named release gates for cli-jaw.
4
+ *
5
+ * Each gate has a NAME, a CHECK function, and prints PASS / FAIL.
6
+ * Usage:
7
+ * node scripts/release-gates.mjs # run all gates
8
+ * node scripts/release-gates.mjs <gate-name> # run one gate
9
+ *
10
+ * Wired through package.json as `gate:<name>`.
11
+ */
12
+ import { spawnSync } from 'node:child_process';
13
+ import fs from 'node:fs';
14
+ import path from 'node:path';
15
+ import { fileURLToPath } from 'node:url';
16
+ import { auditClaims, formatClaimAuditReport } from './claim-audit.mjs';
17
+
18
+ const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
19
+
20
+ function run(cmd, args, opts = {}) {
21
+ return spawnSync(cmd, args, {
22
+ cwd: repoRoot,
23
+ stdio: opts.stdio || 'pipe',
24
+ encoding: 'utf8',
25
+ ...opts,
26
+ });
27
+ }
28
+
29
+ function readFile(rel) {
30
+ return fs.readFileSync(path.join(repoRoot, rel), 'utf8');
31
+ }
32
+
33
+ const FORBIDDEN_IN_READY = [
34
+ /external[-\s]?cdp/i,
35
+ /remote[-\s]?cdp/i,
36
+ /hosted browser/i,
37
+ /browser_type_ref/,
38
+ /browser_navigate/,
39
+ /browser_screenshot/,
40
+ /browser_back/,
41
+ /browser_forward/,
42
+ /browser_reload/,
43
+ /browser_wait_for/,
44
+ /browser_extract_text/,
45
+ ];
46
+
47
+ const GATES = {
48
+ 'typecheck': {
49
+ description: 'tsc --noEmit (server + frontend) clean',
50
+ check() {
51
+ const tasks = ['typecheck', 'typecheck:frontend'];
52
+ for (const t of tasks) {
53
+ const r = run('npm', ['run', t, '--silent']);
54
+ if (r.status !== 0) {
55
+ return { ok: false, detail: `${t} failed:\n${(r.stderr || r.stdout || '').slice(-2000)}` };
56
+ }
57
+ }
58
+ return { ok: true, detail: `tsc clean for: ${tasks.join(', ')}` };
59
+ },
60
+ },
61
+ 'tests': {
62
+ description: 'browser web-ai unit tests pass (mirror parity)',
63
+ check() {
64
+ const targets = [
65
+ 'tests/unit/browser-web-ai-target-resolver.test.ts',
66
+ 'tests/unit/browser-web-ai-answer-artifact.test.ts',
67
+ 'tests/unit/browser-web-ai-source-audit.test.ts',
68
+ 'tests/unit/browser-web-ai-cli-contract.test.ts',
69
+ 'tests/unit/release-gates.test.ts',
70
+ ].filter((p) => fs.existsSync(path.join(repoRoot, p)));
71
+ if (targets.length === 0) {
72
+ return { ok: false, detail: 'no Phase 22 mirror tests found' };
73
+ }
74
+ const args = [
75
+ 'tsx', '--import', './tests/setup/test-home.ts',
76
+ '--experimental-test-module-mocks', '--test',
77
+ ...targets,
78
+ ];
79
+ const r = run('npx', args);
80
+ if (r.status !== 0) {
81
+ return { ok: false, detail: `tests failed:\n${(r.stdout || r.stderr || '').slice(-2000)}` };
82
+ }
83
+ return { ok: true, detail: `passed ${targets.length} suite(s): ${targets.join(', ')}` };
84
+ },
85
+ },
86
+ 'truth-table-fresh': {
87
+ description: 'CAPABILITY_TRUTH_TABLE.md edited within 7 days OR matches code refs',
88
+ check() {
89
+ const rel = 'structure/CAPABILITY_TRUTH_TABLE.md';
90
+ const abs = path.join(repoRoot, rel);
91
+ if (!fs.existsSync(abs)) return { ok: false, detail: `${rel} missing` };
92
+ const stat = fs.statSync(abs);
93
+ const ageDays = (Date.now() - stat.mtimeMs) / (1000 * 60 * 60 * 24);
94
+ if (ageDays <= 7) return { ok: true, detail: `truth table ${ageDays.toFixed(2)}d old` };
95
+ const text = readFile(rel);
96
+ const required = ['action-intent', 'target-resolver', 'answer-artifact', 'source-audit'];
97
+ for (const term of required) {
98
+ if (!text.includes(term)) {
99
+ return { ok: false, detail: `truth table stale (${ageDays.toFixed(1)}d) and missing ${term}` };
100
+ }
101
+ }
102
+ return { ok: true, detail: `truth table ${ageDays.toFixed(1)}d old but matches required terms` };
103
+ },
104
+ },
105
+ 'mcp-scope-frozen': {
106
+ description: 'cli-jaw exposes no browser MCP tool surface (agbrowse owns 2 frozen tools)',
107
+ check() {
108
+ // cli-jaw must NOT register browser_* MCP tools — agbrowse is the
109
+ // sole source. Scan src/ for any new declarative MCP tool entries
110
+ // named browser_*.
111
+ const offenders = [];
112
+ const srcDir = path.join(repoRoot, 'src');
113
+ const stack = [srcDir];
114
+ while (stack.length) {
115
+ const dir = stack.pop();
116
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
117
+ const full = path.join(dir, entry.name);
118
+ if (entry.isDirectory()) {
119
+ stack.push(full);
120
+ continue;
121
+ }
122
+ if (!/\.(ts|mts|mjs|js|cjs)$/.test(entry.name)) continue;
123
+ const text = fs.readFileSync(full, 'utf8');
124
+ // any hint of a registered MCP browser_* tool definition
125
+ if (/['"]browser_(snapshot|click_ref|type_ref|navigate|back|forward|reload|wait_for|screenshot|extract_text)['"]\s*:\s*{/.test(text)) {
126
+ offenders.push(path.relative(repoRoot, full));
127
+ }
128
+ }
129
+ }
130
+ if (offenders.length > 0) {
131
+ return { ok: false, detail: `cli-jaw must not register browser MCP tools; offenders:\n${offenders.join('\n')}` };
132
+ }
133
+ return { ok: true, detail: 'cli-jaw registers no browser MCP tools (agbrowse owns the frozen scope)' };
134
+ },
135
+ },
136
+ 'no-experimental-in-readme-ready-section': {
137
+ description: 'README "ready" claims do not include external CDP or unimplemented MCP tools',
138
+ check() {
139
+ const files = ['README.md', 'README.ko.md', 'README.ja.md', 'README.zh-CN.md', 'structure/CAPABILITY_TRUTH_TABLE.md']
140
+ .filter((p) => fs.existsSync(path.join(repoRoot, p)));
141
+ const offending = [];
142
+ for (const rel of files) {
143
+ const text = readFile(rel);
144
+ const sections = text.split(/\n##\s+/);
145
+ for (const sec of sections) {
146
+ const head = sec.split('\n', 1)[0].toLowerCase();
147
+ const isReady = head.includes('ready') || head.includes('production') || head.includes('supported') || head.includes('feature');
148
+ const isExperimentalSection = head.includes('experimental') || head.includes('deferred') || head.includes('out of scope') || head.includes('forbidden') || head.includes('mirror rules');
149
+ if (!isReady || isExperimentalSection) continue;
150
+ for (const pat of FORBIDDEN_IN_READY) {
151
+ if (pat.test(sec)) {
152
+ offending.push(`${rel} :: ${head} :: ${pat}`);
153
+ }
154
+ }
155
+ }
156
+ }
157
+ if (offending.length > 0) {
158
+ return { ok: false, detail: `forbidden terms in ready sections:\n${offending.join('\n')}` };
159
+ }
160
+ return { ok: true, detail: `${files.length} README/truth-table file(s) clean of experimental terms in ready sections` };
161
+ },
162
+ },
163
+ 'no-cloud-claims': {
164
+ description: 'no hosted/cloud/stealth/external-CDP/leaderboard claims outside experimental sections (G10 mirror)',
165
+ check() {
166
+ const report = auditClaims({ repoRoot });
167
+ return { ok: report.ok, detail: formatClaimAuditReport(report) };
168
+ },
169
+ },
170
+ 'observe-actions-fixtures': {
171
+ description: 'observe-actions module loads and produces ranked candidates from a fixture snapshot (G02 mirror)',
172
+ async check() {
173
+ try {
174
+ const { spawnSync } = await import('node:child_process');
175
+ const path = await import('node:path');
176
+ const tsxBin = path.resolve(repoRoot, 'node_modules/.bin/tsx');
177
+ const fixtureScript = `import { buildObserveActions, formatObserveActions } from '${path.resolve(repoRoot, 'src/browser/web-ai/observe-actions.ts').replace(/\\\\/g, '/')}';\nconst r = buildObserveActions({ snapshotId: 'gate-fixture', url: null, refs: { '@e1': { role: 'button', name: 'Sign in' }, '@e2': { role: 'textbox', name: 'Email' }, '@e3': { role: 'link', name: 'Forgot password?' } } }, 'click sign in');\nif (!r || !Array.isArray(r.candidates) || r.candidates.length < 3) { console.error('candidates<3'); process.exit(2); }\nif (r.candidates[0].ref !== '@e1' || r.candidates[0].action !== 'click') { console.error('rank-fail'); process.exit(3); }\nif (!r.candidates.every(c => c.args.snapshotId === 'gate-fixture')) { console.error('snapId-missing'); process.exit(4); }\nconst t = formatObserveActions(r); if (!t || typeof t !== 'string') { console.error('format-fail'); process.exit(5); }\nconsole.log('OK ' + r.candidates.length);`;
178
+ const res = spawnSync(tsxBin, ['--eval', fixtureScript], { encoding: 'utf8' });
179
+ if (res.status !== 0) {
180
+ return { ok: false, detail: `observe-actions fixture failed: status=${res.status} stderr=${(res.stderr || '').trim()} stdout=${(res.stdout || '').trim()}` };
181
+ }
182
+ return { ok: true, detail: `observe-actions fixture: ${(res.stdout || '').trim()}` };
183
+ } catch (err) {
184
+ return { ok: false, detail: `observe-actions fixture threw: ${(err && err.message) || err}` };
185
+ }
186
+ },
187
+ },
188
+ 'observation-bundle-fixtures': {
189
+ description: 'observation-bundle module emits ObservationBundleV1 from a fixture (G06 mirror)',
190
+ async check() {
191
+ try {
192
+ const { spawnSync } = await import('node:child_process');
193
+ const path = await import('node:path');
194
+ const tsxBin = path.resolve(repoRoot, 'node_modules/.bin/tsx');
195
+ const modPath = path.resolve(repoRoot, 'src/browser/web-ai/observation-bundle.ts').replace(/\\\\/g, '/');
196
+ const fixtureScript = `import { buildObservationBundle, OBSERVATION_BUNDLE_SCHEMA_VERSION } from '${modPath}';\nconst b = buildObservationBundle({ url: 'https://x.test/', viewport: { width: 800, height: 600 }, snapshotNodes: [{ ref: '@e1', role: 'button', name: 'Go' }, { ref: '...', role: 'note', name: 't' }], boxes: { '@e1': { x: 1, y: 2, width: 10, height: 20 } }, textSummary: 'hello' });\nif (b.schemaVersion !== OBSERVATION_BUNDLE_SCHEMA_VERSION) { console.error('schema-mismatch'); process.exit(2); }\nif (b.refs.length !== 1) { console.error('ref-filter-fail'); process.exit(3); }\nif (!b.refs[0].box || b.refs[0].box.width !== 10) { console.error('box-attach-fail'); process.exit(4); }\nif (b.stats.refCount !== 1 || b.stats.boxCount !== 1 || b.stats.textChars !== 5) { console.error('stats-fail'); process.exit(5); }\nconsole.log('OK refs=' + b.stats.refCount + ' boxes=' + b.stats.boxCount + ' text=' + b.stats.textChars + 'ch');`;
197
+ const res = spawnSync(tsxBin, ['--eval', fixtureScript], { encoding: 'utf8' });
198
+ if (res.status !== 0) {
199
+ return { ok: false, detail: `observation-bundle fixture failed: status=${res.status} stderr=${(res.stderr || '').trim()} stdout=${(res.stdout || '').trim()}` };
200
+ }
201
+ return { ok: true, detail: `observation-bundle fixture: ${(res.stdout || '').trim()}` };
202
+ } catch (err) {
203
+ return { ok: false, detail: `observation-bundle fixture threw: ${(err && err.message) || err}` };
204
+ }
205
+ },
206
+ },
207
+ 'browser-primitives-catalog': {
208
+ description: 'action-breadth catalog exposes the agreed primitive set (G03 mirror)',
209
+ async check() {
210
+ try {
211
+ const { spawnSync } = await import('node:child_process');
212
+ const path = await import('node:path');
213
+ const tsxBin = path.resolve(repoRoot, 'node_modules/.bin/tsx');
214
+ const modPath = path.resolve(repoRoot, 'src/browser/web-ai/action-breadth.ts').replace(/\\\\/g, '/');
215
+ const fixtureScript = `import { BROWSER_PRIMITIVES, listPrimitiveCommands, BROWSER_PRIMITIVE_SCHEMA_VERSION, auditPrimitiveCoverage } from '${modPath}';\nif (BROWSER_PRIMITIVE_SCHEMA_VERSION !== 'browser-primitives-v1') { console.error('schema-mismatch'); process.exit(2); }\nif (BROWSER_PRIMITIVES.length < 18) { console.error('too-few'); process.exit(3); }\nconst cmds = new Set(listPrimitiveCommands());\nfor (const c of ['select','check','uncheck','upload','drag','scroll','wait-for']) { if (!cmds.has(c)) { console.error('missing:'+c); process.exit(4); } }\nconst fake = [...BROWSER_PRIMITIVES].map(p => 'case ' + JSON.stringify(p.command) + ':').join('\\n');\nconst r = auditPrimitiveCoverage(fake);\nif (!r.ok || r.missing.length !== 0) { console.error('audit-fail'); process.exit(5); }\nconsole.log('OK ' + BROWSER_PRIMITIVES.length + ' primitives');`;
216
+ const res = spawnSync(tsxBin, ['--eval', fixtureScript], { encoding: 'utf8' });
217
+ if (res.status !== 0) {
218
+ return { ok: false, detail: `action-breadth fixture failed: status=${res.status} stderr=${(res.stderr || '').trim()} stdout=${(res.stdout || '').trim()}` };
219
+ }
220
+ return { ok: true, detail: `action-breadth fixture: ${(res.stdout || '').trim()}` };
221
+ } catch (err) {
222
+ return { ok: false, detail: `action-breadth gate threw: ${(err && err.message) || err}` };
223
+ }
224
+ },
225
+ },
226
+ 'action-memory-safe-replay': {
227
+ description: 'action-memory cache returns hit only when DOM signature matches (G07 mirror)',
228
+ async check() {
229
+ try {
230
+ const { spawnSync } = await import('node:child_process');
231
+ const path = await import('node:path');
232
+ const tsxBin = path.resolve(repoRoot, 'node_modules/.bin/tsx');
233
+ const modPath = path.resolve(repoRoot, 'src/browser/web-ai/action-memory.ts').replace(/\\\\/g, '/');
234
+ const fixtureScript = `import { createActionMemory, validateMemoryHit, ACTION_MEMORY_SCHEMA_VERSION } from '${modPath}';\nif (ACTION_MEMORY_SCHEMA_VERSION !== 'action-memory-v1') { console.error('schema-mismatch'); process.exit(2); }\nconst m = createActionMemory();\nm.put({ origin: 'https://x.test', intentId: 'i', signature: 'sig-A', ref: '@e1', hits: 0, validations: { ok: 0, fail: 0 }, lastGoodAt: '' });\nconst hit = m.get('https://x.test', 'i', 'sig-A');\nif (!hit || hit.ref !== '@e1') { console.error('miss-on-match'); process.exit(3); }\nif (m.get('https://x.test', 'i', 'sig-B') !== null) { console.error('hit-on-drift'); process.exit(4); }\nif (validateMemoryHit(hit, 'sig-B') !== null) { console.error('validate-allowed-drift'); process.exit(5); }\nm.clear();\nif (m.size() !== 0) { console.error('clear-failed'); process.exit(6); }\nconsole.log('OK hit-on-match miss-on-drift clear');`;
235
+ const res = spawnSync(tsxBin, ['--eval', fixtureScript], { encoding: 'utf8' });
236
+ if (res.status !== 0) {
237
+ return { ok: false, detail: `action-memory fixture failed: status=${res.status} stderr=${(res.stderr || '').trim()} stdout=${(res.stdout || '').trim()}` };
238
+ }
239
+ return { ok: true, detail: `action-memory: ${(res.stdout || '').trim()}` };
240
+ } catch (err) {
241
+ return { ok: false, detail: `action-memory gate threw: ${(err && err.message) || err}` };
242
+ }
243
+ },
244
+ },
245
+ 'model-adapter-frozen': {
246
+ description: 'G09 mirror: cli-jaw must not implement an API model adapter or claim parity (negative-parity)',
247
+ async check() {
248
+ try {
249
+ // Truth-table must declare the deferred (frozen) row.
250
+ const truth = readFile('structure/CAPABILITY_TRUTH_TABLE.md');
251
+ const g09Line = truth.match(/^[^\n]*G09[^\n]+model[- ]adapter[^\n]+/im)?.[0] || '';
252
+ if (!g09Line) {
253
+ return { ok: false, detail: 'CAPABILITY_TRUTH_TABLE.md missing G09 model-adapter row' };
254
+ }
255
+ if (!/(deferred|frozen)/i.test(g09Line)) {
256
+ return { ok: false, detail: `G09 row must be marked deferred/frozen, got: ${g09Line.slice(0, 200)}` };
257
+ }
258
+
259
+ // package.json must NOT depend on provider SDKs.
260
+ const pkg = JSON.parse(readFile('package.json'));
261
+ const allDeps = { ...(pkg.dependencies || {}), ...(pkg.devDependencies || {}), ...(pkg.peerDependencies || {}) };
262
+ const sdkDenylist = ['openai', '@anthropic-ai/sdk', '@google/generative-ai', '@google/genai', 'ai'];
263
+ for (const name of Object.keys(allDeps)) {
264
+ if (sdkDenylist.includes(name) || name.startsWith('@ai-sdk/')) {
265
+ return { ok: false, detail: `forbidden provider SDK dep: ${name}` };
266
+ }
267
+ }
268
+
269
+ // Source scan limited to browser/web-ai surface (cli-jaw's
270
+ // broader memory/quota system has unrelated OpenAI integration
271
+ // that pre-dates and is independent of the agbrowse G09 freeze).
272
+ const scanRoots = ['src/browser'];
273
+ /** @type {Array<{file:string, hit:string}>} */
274
+ const violations = [];
275
+ const cmdAliasRe = /\b(api-query|model-query|--api\b|--transport\s+api|--mode\s+api)\b/;
276
+ const envRe = /\b(OPENAI_API_KEY|ANTHROPIC_API_KEY|GEMINI_API_KEY|GOOGLE_API_KEY|MODEL_ADAPTER_[A-Z_]+|AI_SDK_[A-Z_]+)\b/;
277
+ const importRe = /from\s+['"](openai|@anthropic-ai\/sdk|@google\/generative-ai|@google\/genai|@ai-sdk\/[^'"]+|ai)['"]/;
278
+ const dirDenylist = ['src/browser/web-ai/model-adapter', 'src/model-adapter', 'src/api-client'];
279
+ for (const dirRel of dirDenylist) {
280
+ if (fs.existsSync(path.join(repoRoot, dirRel))) {
281
+ return { ok: false, detail: `forbidden path exists: ${dirRel}/` };
282
+ }
283
+ }
284
+ /** @param {string} dirAbs */
285
+ function walk(dirAbs) {
286
+ if (!fs.existsSync(dirAbs)) return;
287
+ for (const entry of fs.readdirSync(dirAbs, { withFileTypes: true })) {
288
+ if (entry.name === 'node_modules' || entry.name.startsWith('.')) continue;
289
+ const abs = path.join(dirAbs, entry.name);
290
+ if (entry.isDirectory()) { walk(abs); continue; }
291
+ if (!/\.(mjs|cjs|js|ts|tsx|json|md)$/.test(entry.name)) continue;
292
+ const rel = path.relative(repoRoot, abs);
293
+ if (rel.endsWith('release-gates.mjs')) continue;
294
+ if (rel.endsWith('CAPABILITY_TRUTH_TABLE.md')) continue;
295
+ const text = fs.readFileSync(abs, 'utf8');
296
+ if (cmdAliasRe.test(text)) violations.push({ file: rel, hit: 'forbidden api-query/--api/--transport api alias' });
297
+ if (envRe.test(text)) violations.push({ file: rel, hit: 'forbidden API key/MODEL_ADAPTER_/AI_SDK_ env var' });
298
+ if (importRe.test(text)) violations.push({ file: rel, hit: 'forbidden provider SDK import' });
299
+ }
300
+ }
301
+ for (const root of scanRoots) walk(path.join(repoRoot, root));
302
+ if (violations.length) {
303
+ const sample = violations.slice(0, 5).map(v => `${v.file}: ${v.hit}`).join('; ');
304
+ return { ok: false, detail: `${violations.length} negative-parity violation(s): ${sample}` };
305
+ }
306
+
307
+ return { ok: true, detail: 'cli-jaw mirror clean: deferred row present, no SDK deps, no api-* drift' };
308
+ } catch (err) {
309
+ return { ok: false, detail: `model-adapter-frozen mirror gate threw: ${(err && err.message) || err}` };
310
+ }
311
+ },
312
+ },
313
+ };
314
+
315
+ function printResult(name, result) {
316
+ const status = result.ok ? 'PASS' : 'FAIL';
317
+ process.stdout.write(`[${status}] gate:${name} — ${GATES[name].description}\n`);
318
+ if (result.detail) process.stdout.write(` ${result.detail.replace(/\n/g, '\n ')}\n`);
319
+ }
320
+
321
+ async function main() {
322
+ const target = process.argv[2];
323
+ const names = target ? [target] : Object.keys(GATES);
324
+ let failed = 0;
325
+ for (const name of names) {
326
+ if (!GATES[name]) {
327
+ process.stdout.write(`[FAIL] gate:${name} — unknown gate\n`);
328
+ failed += 1;
329
+ continue;
330
+ }
331
+ let result;
332
+ try {
333
+ result = await GATES[name].check();
334
+ } catch (err) {
335
+ result = { ok: false, detail: `threw: ${err.message}` };
336
+ }
337
+ printResult(name, result);
338
+ if (!result.ok) failed += 1;
339
+ }
340
+ process.stdout.write(failed === 0 ? `\nAll ${names.length} gate(s) passed.\n` : `\n${failed}/${names.length} gate(s) FAILED.\n`);
341
+ process.exit(failed === 0 ? 0 : 1);
342
+ }
343
+
344
+ main().catch((err) => {
345
+ process.stderr.write(`release-gates threw: ${err.stack || err}\n`);
346
+ process.exit(1);
347
+ });
@@ -138,6 +138,9 @@ npm run build:frontend
138
138
 
139
139
  run_electron_release_checks
140
140
 
141
+ echo "🛡️ Running release gates (gate:all)..."
142
+ npm run gate:all
143
+
141
144
  echo "🧪 Verifying npm package contents..."
142
145
  npm pack --dry-run >/dev/null
143
146
 
@@ -120,6 +120,10 @@ git tag "v$VERSION"
120
120
  git push origin master
121
121
  git push origin "v$VERSION"
122
122
 
123
+ # ─── Release gates ────────────────────────────────────
124
+ echo "🛡️ Running release gates (gate:all)..."
125
+ npm run gate:all
126
+
123
127
  # ─── npm publish ───────────────────────────────────────
124
128
  echo "🚀 Publishing to npm..."
125
129
  npm publish --access public
@@ -4,6 +4,8 @@ import { dirname, join } from 'path';
4
4
  import { spawn } from 'child_process';
5
5
  import { buildArgs } from '../../src/agent/args.js';
6
6
  import { extractFromEvent, extractOutputChunk } from '../../src/agent/events.js';
7
+ import type { SpawnContext } from '../../src/types/agent.js';
8
+ import type { CliEventRecord } from '../../src/types/cli-events.js';
7
9
  import {
8
10
  applyCliEnvDefaults,
9
11
  ensureOpencodeAlwaysAllowPermissions,
@@ -169,14 +171,14 @@ function classify(result: Omit<RunResult, 'classification' | 'pass'>): RunResult
169
171
  return 'PASS';
170
172
  }
171
173
 
172
- function parseEvents(stdout: string): { events: any[]; parseErrors: string[]; eventTypes: Record<string, number> } {
173
- const events: any[] = [];
174
+ function parseEvents(stdout: string): { events: CliEventRecord[]; parseErrors: string[]; eventTypes: Record<string, number> } {
175
+ const events: CliEventRecord[] = [];
174
176
  const parseErrors: string[] = [];
175
177
  const eventTypes: Record<string, number> = {};
176
178
  for (const line of stdout.split(/\r?\n/)) {
177
179
  if (!line.trim()) continue;
178
180
  try {
179
- const parsed = JSON.parse(line);
181
+ const parsed = JSON.parse(line) as CliEventRecord;
180
182
  events.push(parsed);
181
183
  const type = typeof parsed.type === 'string' ? parsed.type : 'unknown';
182
184
  eventTypes[type] = (eventTypes[type] || 0) + 1;
@@ -187,12 +189,19 @@ function parseEvents(stdout: string): { events: any[]; parseErrors: string[]; ev
187
189
  return { events, parseErrors, eventTypes };
188
190
  }
189
191
 
190
- function replayParser(events: any[]): { fullTextLength: number; liveTextLength: number } {
191
- const ctx: any = {
192
+ function replayParser(events: CliEventRecord[]): { fullTextLength: number; liveTextLength: number } {
193
+ const ctx: SpawnContext = {
192
194
  fullText: '',
193
195
  traceLog: [],
194
196
  toolLog: [],
195
197
  seenToolKeys: new Set<string>(),
198
+ hasClaudeStreamEvents: false,
199
+ sessionId: null,
200
+ cost: null,
201
+ turns: null,
202
+ duration: null,
203
+ tokens: null,
204
+ stderrBuf: '',
196
205
  pendingOutputChunk: '',
197
206
  opencodePreToolText: '',
198
207
  opencodePostToolText: '',