synabun 2.0.0 → 2.0.7

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 (507) hide show
  1. package/CHANGELOG.md +97 -0
  2. package/NOTICE +5 -0
  3. package/README.md +2 -1
  4. package/THIRD-PARTY-LICENSES.md +59 -0
  5. package/benchmarks/fixtures/browser/README.md +1 -1
  6. package/benchmarks/fixtures/desktop/README.md +1 -1
  7. package/docs/whatsapp.md +153 -18
  8. package/hooks/claude-code/pre-compact.mjs +11 -0
  9. package/hooks/claude-code/prompt-submit.mjs +60 -184
  10. package/hooks/claude-code/session-start.mjs +73 -16
  11. package/hooks/claude-code/shared.mjs +26 -3
  12. package/hooks/claude-code/stop.mjs +5 -5
  13. package/lib/child-path.js +303 -0
  14. package/lib/claude-hooks.js +2 -1
  15. package/lib/data-home-migration.js +2 -0
  16. package/lib/desktop-app.js +265 -0
  17. package/lib/external-tools.js +7 -3
  18. package/lib/log-redact.js +102 -0
  19. package/lib/packaged-runtime.js +138 -11
  20. package/lib/start-launcher.js +88 -1
  21. package/mcp-server/dist/http.d.ts +3 -1
  22. package/mcp-server/dist/http.d.ts.map +1 -1
  23. package/mcp-server/dist/http.js +15 -4
  24. package/mcp-server/dist/http.js.map +1 -1
  25. package/mcp-server/dist/index.d.ts.map +1 -1
  26. package/mcp-server/dist/index.js +9 -6
  27. package/mcp-server/dist/index.js.map +1 -1
  28. package/mcp-server/dist/services/budget-judgments.d.ts +108 -0
  29. package/mcp-server/dist/services/budget-judgments.d.ts.map +1 -0
  30. package/mcp-server/dist/services/budget-judgments.js +153 -0
  31. package/mcp-server/dist/services/budget-judgments.js.map +1 -0
  32. package/mcp-server/dist/services/codex-config-heal.d.ts +5 -1
  33. package/mcp-server/dist/services/codex-config-heal.d.ts.map +1 -1
  34. package/mcp-server/dist/services/codex-config-heal.js +41 -4
  35. package/mcp-server/dist/services/codex-config-heal.js.map +1 -1
  36. package/mcp-server/dist/services/identity.d.ts +11 -0
  37. package/mcp-server/dist/services/identity.d.ts.map +1 -1
  38. package/mcp-server/dist/services/identity.js +24 -0
  39. package/mcp-server/dist/services/identity.js.map +1 -1
  40. package/mcp-server/dist/services/neural-interface.d.ts +13 -0
  41. package/mcp-server/dist/services/neural-interface.d.ts.map +1 -1
  42. package/mcp-server/dist/services/neural-interface.js +34 -2
  43. package/mcp-server/dist/services/neural-interface.js.map +1 -1
  44. package/mcp-server/dist/services/typesafe-config.d.ts +1 -1
  45. package/mcp-server/dist/services/typesafe-config.d.ts.map +1 -1
  46. package/mcp-server/dist/services/typesafe-config.js +4 -1
  47. package/mcp-server/dist/services/typesafe-config.js.map +1 -1
  48. package/mcp-server/dist/tools/agents.d.ts +10 -7
  49. package/mcp-server/dist/tools/agents.d.ts.map +1 -1
  50. package/mcp-server/dist/tools/agents.js +34 -13
  51. package/mcp-server/dist/tools/agents.js.map +1 -1
  52. package/mcp-server/dist/tools/whatsapp-send-file.d.ts +17 -0
  53. package/mcp-server/dist/tools/whatsapp-send-file.d.ts.map +1 -0
  54. package/mcp-server/dist/tools/whatsapp-send-file.js +44 -0
  55. package/mcp-server/dist/tools/whatsapp-send-file.js.map +1 -0
  56. package/mcp-server/dist/tui.js +2 -1
  57. package/mcp-server/dist/tui.js.map +1 -1
  58. package/mcp-server/dist/version.d.ts +5 -0
  59. package/mcp-server/dist/version.d.ts.map +1 -0
  60. package/mcp-server/dist/version.js +21 -0
  61. package/mcp-server/dist/version.js.map +1 -0
  62. package/mcp-server/package-lock.json +2 -2
  63. package/mcp-server/package.json +1 -3
  64. package/mcp-server/run.mjs +15 -9
  65. package/mcp-server/src/http.ts +18 -3
  66. package/mcp-server/src/index.ts +9 -6
  67. package/mcp-server/src/services/budget-judgments.ts +183 -0
  68. package/mcp-server/src/services/codex-config-heal.ts +35 -4
  69. package/mcp-server/src/services/identity.ts +27 -0
  70. package/mcp-server/src/services/neural-interface.ts +34 -2
  71. package/mcp-server/src/services/typesafe-config.ts +4 -1
  72. package/mcp-server/src/tools/agents.ts +33 -14
  73. package/mcp-server/src/tools/whatsapp-send-file.ts +51 -0
  74. package/mcp-server/src/tui.ts +2 -1
  75. package/mcp-server/src/version.ts +22 -0
  76. package/neural-interface/i18n/en.json +2126 -209
  77. package/neural-interface/i18n/pt-BR.json +2123 -207
  78. package/neural-interface/lib/account-usage.js +163 -0
  79. package/neural-interface/lib/assistant-api.js +316 -57
  80. package/neural-interface/lib/assistant-brains/claude.js +19 -2
  81. package/neural-interface/lib/assistant-brains/codex.js +3 -0
  82. package/neural-interface/lib/assistant-brains/opencode.js +17 -4
  83. package/neural-interface/lib/assistant-budget-planner.js +390 -0
  84. package/neural-interface/lib/assistant-budget-split.js +408 -0
  85. package/neural-interface/lib/assistant-budget.js +94 -95
  86. package/neural-interface/lib/assistant-catalog.js +179 -27
  87. package/neural-interface/lib/assistant-config.js +91 -14
  88. package/neural-interface/lib/assistant-dispatch.js +494 -138
  89. package/neural-interface/lib/assistant-hidden-models.js +393 -66
  90. package/neural-interface/lib/assistant-jev.js +26 -3
  91. package/neural-interface/lib/assistant-memory.js +24 -10
  92. package/neural-interface/lib/assistant-persona.js +73 -12
  93. package/neural-interface/lib/assistant-plan-permissions.js +8 -1
  94. package/neural-interface/lib/assistant-pricing.js +21 -6
  95. package/neural-interface/lib/assistant-route-accounts.js +14 -0
  96. package/neural-interface/lib/assistant-route-gate.js +19 -3
  97. package/neural-interface/lib/assistant-router.js +373 -42
  98. package/neural-interface/lib/assistant-runtime.js +488 -59
  99. package/neural-interface/lib/assistant-task-prompt.js +13 -3
  100. package/neural-interface/lib/assistant-test-density.js +142 -0
  101. package/neural-interface/lib/assistant-user-context-budgets.js +123 -0
  102. package/neural-interface/lib/assistant-user-context.js +908 -0
  103. package/neural-interface/lib/assistant-user-knowledge.js +328 -0
  104. package/neural-interface/lib/assistant-user-learn.js +404 -0
  105. package/neural-interface/lib/assistant-user-threads.js +226 -0
  106. package/neural-interface/lib/assistant-user-writer.js +183 -0
  107. package/neural-interface/lib/augmented-path.js +317 -53
  108. package/neural-interface/lib/browser-background-tab.js +134 -0
  109. package/neural-interface/lib/browser-screenshot.js +678 -61
  110. package/neural-interface/lib/claude-accounts.js +342 -31
  111. package/neural-interface/lib/claude-agent-bridge.js +123 -9
  112. package/neural-interface/lib/claude-executable.js +6 -1
  113. package/neural-interface/lib/claude-model-catalog.js +33 -5
  114. package/neural-interface/lib/claude-panel-auth.js +221 -0
  115. package/neural-interface/lib/claude-profile-api-key.js +62 -0
  116. package/neural-interface/lib/claude-temporary.js +46 -7
  117. package/neural-interface/lib/cli-install-api.js +137 -0
  118. package/neural-interface/lib/cli-install.js +797 -0
  119. package/neural-interface/lib/cli-path.js +130 -0
  120. package/neural-interface/lib/cli-resolver.js +744 -0
  121. package/neural-interface/lib/cli-update-planner.js +143 -7
  122. package/neural-interface/lib/cloudflared/install.js +533 -0
  123. package/neural-interface/lib/cloudflared/manager.js +545 -0
  124. package/neural-interface/lib/cloudflared/pins.js +115 -0
  125. package/neural-interface/lib/cloudflared/pins.json +63 -0
  126. package/neural-interface/lib/cloudflared/tunnel.js +265 -0
  127. package/neural-interface/lib/codex-account-auth.js +178 -0
  128. package/neural-interface/lib/codex-accounts.js +489 -0
  129. package/neural-interface/lib/codex-capabilities.js +2 -1
  130. package/neural-interface/lib/codex-compat-rpc.js +8 -2
  131. package/neural-interface/lib/codex-mcp-approvals.js +5 -1
  132. package/neural-interface/lib/codex-panel-auth.js +62 -0
  133. package/neural-interface/lib/codex-session-settings.js +1 -1
  134. package/neural-interface/lib/codex-settings-schema.js +120 -0
  135. package/neural-interface/lib/desktop/config.js +3 -0
  136. package/neural-interface/lib/editor-completion-endpoint.js +264 -0
  137. package/neural-interface/lib/editor-completion-opencode.js +436 -0
  138. package/neural-interface/lib/editor-completion.js +714 -0
  139. package/neural-interface/lib/editor-config.js +149 -0
  140. package/neural-interface/lib/editor-files-api.js +268 -0
  141. package/neural-interface/lib/editor-git-api.js +134 -0
  142. package/neural-interface/lib/file-explorer-api.js +1039 -0
  143. package/neural-interface/lib/file-explorer-system.js +355 -0
  144. package/neural-interface/lib/file-explorer-trash.ps1 +85 -0
  145. package/neural-interface/lib/file-explorer-watch.js +239 -0
  146. package/neural-interface/lib/git-bash/bzip2.js +339 -0
  147. package/neural-interface/lib/git-bash/claude-settings.js +73 -0
  148. package/neural-interface/lib/git-bash/extract-worker.js +34 -0
  149. package/neural-interface/lib/git-bash/install.js +529 -0
  150. package/neural-interface/lib/git-bash/licenses/COPYING +360 -0
  151. package/neural-interface/lib/git-bash/licenses/LGPL-2.1 +511 -0
  152. package/neural-interface/lib/git-bash/manager.js +268 -0
  153. package/neural-interface/lib/git-bash/pins.js +206 -0
  154. package/neural-interface/lib/git-bash/pins.json +34 -0
  155. package/neural-interface/lib/git-bash/resolver.js +194 -0
  156. package/neural-interface/lib/git-diff-api.js +103 -0
  157. package/neural-interface/lib/git-read.js +234 -0
  158. package/neural-interface/lib/greeting/api.js +89 -0
  159. package/neural-interface/lib/greeting/budgets.js +90 -0
  160. package/neural-interface/lib/greeting/engine.js +461 -0
  161. package/neural-interface/lib/greeting/facts.js +320 -0
  162. package/neural-interface/lib/greeting/sources.js +252 -0
  163. package/neural-interface/lib/greeting/writer.js +139 -0
  164. package/neural-interface/lib/http-guards.js +189 -13
  165. package/neural-interface/lib/install-details.js +145 -0
  166. package/neural-interface/lib/machine-names.js +88 -0
  167. package/neural-interface/lib/mcp-installer.js +14 -2
  168. package/neural-interface/lib/memory-api.js +31 -7
  169. package/neural-interface/lib/native-loop-providers.js +26 -8
  170. package/neural-interface/lib/native-loop-runtime.js +9 -4
  171. package/neural-interface/lib/os-path.js +319 -0
  172. package/neural-interface/lib/plugin-installer.js +4 -2
  173. package/neural-interface/lib/project-storage.js +5 -7
  174. package/neural-interface/lib/provider-panel-api-key-auth.js +92 -0
  175. package/neural-interface/lib/provider-panel-terminal-auth.js +95 -0
  176. package/neural-interface/lib/pty-host/core.js +2 -1
  177. package/neural-interface/lib/pty-host/manager.js +27 -2
  178. package/neural-interface/lib/remote-policy.js +20 -11
  179. package/neural-interface/lib/request-gate.js +589 -0
  180. package/neural-interface/lib/session-title-generator.js +4 -3
  181. package/neural-interface/lib/system-about.js +340 -0
  182. package/neural-interface/lib/system-activity.js +66 -0
  183. package/neural-interface/lib/terminal-env.js +11 -3
  184. package/neural-interface/lib/terminal-path.js +55 -0
  185. package/neural-interface/lib/ui-blob-api.js +108 -0
  186. package/neural-interface/lib/ui-blob-store.js +68 -0
  187. package/neural-interface/lib/virtual-socket.js +12 -1
  188. package/neural-interface/lib/whatsapp/baileys-adapter.js +165 -45
  189. package/neural-interface/lib/whatsapp/bridge.js +78 -34
  190. package/neural-interface/lib/whatsapp/commands.js +13 -14
  191. package/neural-interface/lib/whatsapp/config.js +134 -20
  192. package/neural-interface/lib/whatsapp/fake-baileys.js +99 -14
  193. package/neural-interface/lib/whatsapp/host-core.js +168 -35
  194. package/neural-interface/lib/whatsapp/inbound.js +5 -3
  195. package/neural-interface/lib/whatsapp/local-file.js +524 -0
  196. package/neural-interface/lib/whatsapp/manager.js +92 -32
  197. package/neural-interface/lib/whatsapp/paths.js +11 -1
  198. package/neural-interface/lib/whatsapp/protocol.js +65 -5
  199. package/neural-interface/lib/whatsapp/redact.js +63 -0
  200. package/neural-interface/lib/whatsapp/service.js +343 -91
  201. package/neural-interface/lib/whatsapp/transcription.js +463 -0
  202. package/neural-interface/package-lock.json +701 -2
  203. package/neural-interface/package.json +13 -2
  204. package/neural-interface/public/index.html +2 -0
  205. package/neural-interface/public/index2d.html +2 -0
  206. package/neural-interface/public/install-app.html +9 -6
  207. package/neural-interface/public/offline.html +19 -3
  208. package/neural-interface/public/onboarding.html +107 -2
  209. package/neural-interface/public/shared/account-i18n.js +7 -0
  210. package/neural-interface/public/shared/account-menu.js +539 -0
  211. package/neural-interface/public/shared/account-usage.js +19 -0
  212. package/neural-interface/public/shared/account-view.js +335 -0
  213. package/neural-interface/public/shared/agent-runtime-options.js +50 -14
  214. package/neural-interface/public/shared/assistant/asst-accounts.js +182 -184
  215. package/neural-interface/public/shared/assistant/asst-api.js +32 -2
  216. package/neural-interface/public/shared/assistant/asst-automation.js +286 -0
  217. package/neural-interface/public/shared/assistant/asst-brain-picker.js +430 -81
  218. package/neural-interface/public/shared/assistant/asst-budget.js +259 -303
  219. package/neural-interface/public/shared/assistant/asst-composer.js +11 -1
  220. package/neural-interface/public/shared/assistant/asst-mascot.js +140 -61
  221. package/neural-interface/public/shared/assistant/asst-menu.js +27 -11
  222. package/neural-interface/public/shared/assistant/asst-panel.js +198 -42
  223. package/neural-interface/public/shared/assistant/asst-render.js +197 -23
  224. package/neural-interface/public/shared/assistant/asst-route-models.js +108 -0
  225. package/neural-interface/public/shared/assistant/asst-route.js +95 -343
  226. package/neural-interface/public/shared/assistant/asst-routes-editor.js +534 -0
  227. package/neural-interface/public/shared/assistant/asst-sanitize.js +8 -1
  228. package/neural-interface/public/shared/assistant/asst-sidepanel.js +31 -9
  229. package/neural-interface/public/shared/assistant/asst-slash.js +1 -1
  230. package/neural-interface/public/shared/assistant/asst-state.js +186 -2
  231. package/neural-interface/public/shared/assistant/asst-styles.js +247 -11
  232. package/neural-interface/public/shared/blob-store.js +111 -22
  233. package/neural-interface/public/shared/cdx/cdx-commands.js +4 -1
  234. package/neural-interface/public/shared/cdx/cdx-features.js +22 -14
  235. package/neural-interface/public/shared/cdx/cdx-icons.js +2 -0
  236. package/neural-interface/public/shared/cdx/cdx-panel.js +80 -118
  237. package/neural-interface/public/shared/cdx/cdx-render.js +25 -89
  238. package/neural-interface/public/shared/cdx/cdx-settings.js +231 -0
  239. package/neural-interface/public/shared/cdx/cdx-styles.js +164 -107
  240. package/neural-interface/public/shared/cdx/cdx-tabs.js +348 -668
  241. package/neural-interface/public/shared/cdx/cdx-ws.js +2 -0
  242. package/neural-interface/public/shared/claude-account-view.js +3 -0
  243. package/neural-interface/public/shared/cli-install-view.js +392 -0
  244. package/neural-interface/public/shared/cli-status.js +282 -22
  245. package/neural-interface/public/shared/constants.js +6 -1
  246. package/neural-interface/public/shared/cp/cp-events.js +2 -1
  247. package/neural-interface/public/shared/cp/cp-rehydrate.js +2 -1
  248. package/neural-interface/public/shared/cp/cp-styles.js +61 -0
  249. package/neural-interface/public/shared/desktop-bridge.js +39 -0
  250. package/neural-interface/public/shared/desktop-titlebar-page.js +59 -0
  251. package/neural-interface/public/shared/desktop-titlebar-view.js +122 -0
  252. package/neural-interface/public/shared/desktop-titlebar.js +153 -0
  253. package/neural-interface/public/shared/desktop-update-view.js +462 -0
  254. package/neural-interface/public/shared/editor/editor-ai-logic.js +409 -0
  255. package/neural-interface/public/shared/editor/editor-ai.js +619 -0
  256. package/neural-interface/public/shared/editor/editor-commands.js +212 -0
  257. package/neural-interface/public/shared/editor/editor-compare.js +103 -0
  258. package/neural-interface/public/shared/editor/editor-completion-list.js +172 -0
  259. package/neural-interface/public/shared/editor/editor-doc.js +257 -0
  260. package/neural-interface/public/shared/editor/editor-git-logic.js +131 -0
  261. package/neural-interface/public/shared/editor/editor-git.js +95 -0
  262. package/neural-interface/public/shared/editor/editor-languages.js +156 -0
  263. package/neural-interface/public/shared/editor/editor-lint.js +229 -0
  264. package/neural-interface/public/shared/editor/editor-loader.js +51 -0
  265. package/neural-interface/public/shared/editor/editor-markdown.js +90 -0
  266. package/neural-interface/public/shared/editor/editor-menu.js +233 -0
  267. package/neural-interface/public/shared/editor/editor-minimap.js +371 -0
  268. package/neural-interface/public/shared/editor/editor-palette-logic.js +192 -0
  269. package/neural-interface/public/shared/editor/editor-palette.js +125 -0
  270. package/neural-interface/public/shared/editor/editor-panel-logic.js +288 -0
  271. package/neural-interface/public/shared/editor/editor-panel.js +2099 -0
  272. package/neural-interface/public/shared/editor/editor-prefs.js +224 -0
  273. package/neural-interface/public/shared/editor/editor-safety.js +500 -0
  274. package/neural-interface/public/shared/editor/editor-search.js +352 -0
  275. package/neural-interface/public/shared/editor/editor-statusbar.js +144 -0
  276. package/neural-interface/public/shared/editor/editor-tabs-logic.js +331 -0
  277. package/neural-interface/public/shared/editor/editor-tabs.js +233 -0
  278. package/neural-interface/public/shared/editor/editor-theme.js +244 -0
  279. package/neural-interface/public/shared/editor/editor-view.js +332 -0
  280. package/neural-interface/public/shared/explorer/fx-api.js +216 -0
  281. package/neural-interface/public/shared/explorer/fx-links.js +204 -0
  282. package/neural-interface/public/shared/explorer/fx-logic.js +537 -0
  283. package/neural-interface/public/shared/explorer/fx-main.js +865 -0
  284. package/neural-interface/public/shared/explorer/fx-names.js +87 -0
  285. package/neural-interface/public/shared/explorer/fx-ops.js +370 -0
  286. package/neural-interface/public/shared/explorer/fx-popups.js +490 -0
  287. package/neural-interface/public/shared/explorer/fx-tree.js +790 -0
  288. package/neural-interface/public/shared/file-links.js +339 -0
  289. package/neural-interface/public/shared/git-bash-view.js +145 -0
  290. package/neural-interface/public/shared/greeting/greeting-card.js +178 -0
  291. package/neural-interface/public/shared/greeting/greeting-view.js +148 -0
  292. package/neural-interface/public/shared/html-shell.js +161 -165
  293. package/neural-interface/public/shared/i18n.js +19 -1
  294. package/neural-interface/public/shared/install-details-view.js +86 -0
  295. package/neural-interface/public/shared/ocp-v2/ocp-v2-childpanel.js +4 -0
  296. package/neural-interface/public/shared/ocp-v2/ocp-v2-greeting.js +47 -0
  297. package/neural-interface/public/shared/ocp-v2/ocp-v2-panel.js +131 -17
  298. package/neural-interface/public/shared/ocp-v2/ocp-v2-render.js +7 -1
  299. package/neural-interface/public/shared/ocp-v2/ocp-v2-send.js +22 -0
  300. package/neural-interface/public/shared/ocp-v2/ocp-v2-styles.js +158 -0
  301. package/neural-interface/public/shared/ocp-v2/ocp-v2-ws.js +3 -2
  302. package/neural-interface/public/shared/pwa-install-page.js +32 -2
  303. package/neural-interface/public/shared/pwa-install.css +3 -3
  304. package/neural-interface/public/shared/pwa-install.js +100 -1
  305. package/neural-interface/public/shared/settings/settings-about-pane.js +271 -0
  306. package/neural-interface/public/shared/settings/settings-about.js +254 -0
  307. package/neural-interface/public/shared/settings/settings-code-editor-pane.js +412 -0
  308. package/neural-interface/public/shared/settings/settings-code-editor.js +328 -0
  309. package/neural-interface/public/shared/settings/settings-greeting.js +133 -0
  310. package/neural-interface/public/shared/settings/settings-ia.js +33 -4
  311. package/neural-interface/public/shared/settings/settings-user-context.js +154 -0
  312. package/neural-interface/public/shared/showcase-privacy.js +489 -0
  313. package/neural-interface/public/shared/start-bridge.js +238 -19
  314. package/neural-interface/public/shared/storage.js +30 -3
  315. package/neural-interface/public/shared/styles.css +1710 -770
  316. package/neural-interface/public/shared/synabun-mascot.js +68 -58
  317. package/neural-interface/public/shared/tunnel-view.js +167 -0
  318. package/neural-interface/public/shared/ui-claude-panel.js +369 -229
  319. package/neural-interface/public/shared/ui-cli-banner.js +355 -0
  320. package/neural-interface/public/shared/ui-detail.js +15 -0
  321. package/neural-interface/public/shared/ui-explorer.js +22 -0
  322. package/neural-interface/public/shared/ui-file-explorer.js +481 -2496
  323. package/neural-interface/public/shared/ui-file-links.js +103 -0
  324. package/neural-interface/public/shared/ui-git-bash.js +124 -0
  325. package/neural-interface/public/shared/ui-help.js +26 -0
  326. package/neural-interface/public/shared/ui-invite.js +126 -116
  327. package/neural-interface/public/shared/ui-judgments.js +10 -1
  328. package/neural-interface/public/shared/ui-keybinds.js +4 -0
  329. package/neural-interface/public/shared/ui-loading.js +187 -19
  330. package/neural-interface/public/shared/ui-menubar.js +25 -33
  331. package/neural-interface/public/shared/ui-native-loop-router-state.js +11 -0
  332. package/neural-interface/public/shared/ui-native-loop-router.js +15 -2
  333. package/neural-interface/public/shared/ui-navbar.js +48 -22
  334. package/neural-interface/public/shared/ui-provider-auth.js +104 -0
  335. package/neural-interface/public/shared/ui-provider-terminal-auth.js +223 -0
  336. package/neural-interface/public/shared/ui-sessions.js +9 -3
  337. package/neural-interface/public/shared/ui-settings.js +509 -490
  338. package/neural-interface/public/shared/ui-sidepanel-runtime.js +2 -1
  339. package/neural-interface/public/shared/ui-sidepanel-sessions.js +3 -1
  340. package/neural-interface/public/shared/ui-sync.js +22 -0
  341. package/neural-interface/public/shared/ui-terminal.js +40 -5
  342. package/neural-interface/public/shared/ui-tool-updates.js +5 -0
  343. package/neural-interface/public/shared/ui-tunnel.js +130 -0
  344. package/neural-interface/public/shared/ui-tutorial-steps.js +6 -2
  345. package/neural-interface/public/shared/ui-update.js +594 -5
  346. package/neural-interface/public/shared/ui-whatsapp.js +21 -6
  347. package/neural-interface/public/shared/ui-whiteboard.js +12 -0
  348. package/neural-interface/public/shared/ui-worker-end.js +245 -0
  349. package/neural-interface/public/shared/ui-workspaces.js +41 -27
  350. package/neural-interface/public/shared/whatsapp/wa-view.js +51 -8
  351. package/neural-interface/public/shared/worker-end.js +253 -0
  352. package/neural-interface/public/sw.js +2 -2
  353. package/neural-interface/public/variant/2d/main.js +10 -1
  354. package/neural-interface/public/variant/3d/main.js +10 -1
  355. package/neural-interface/public/vendor/codemirror/chunks/apl-CSDKT72Z.js +1 -0
  356. package/neural-interface/public/vendor/codemirror/chunks/asciiarmor-JYYPU5BM.js +1 -0
  357. package/neural-interface/public/vendor/codemirror/chunks/asn1-NRWCZDA6.js +1 -0
  358. package/neural-interface/public/vendor/codemirror/chunks/asterisk-5OU6D4ZQ.js +1 -0
  359. package/neural-interface/public/vendor/codemirror/chunks/brainfuck-ID4N4SYC.js +1 -0
  360. package/neural-interface/public/vendor/codemirror/chunks/chunk-4RZWGCS2.js +1 -0
  361. package/neural-interface/public/vendor/codemirror/chunks/chunk-ACTJM3JR.js +11 -0
  362. package/neural-interface/public/vendor/codemirror/chunks/chunk-S6BMAXLK.js +1 -0
  363. package/neural-interface/public/vendor/codemirror/chunks/chunk-TO2RDOHQ.js +3 -0
  364. package/neural-interface/public/vendor/codemirror/chunks/chunk-US2GMZZQ.js +13 -0
  365. package/neural-interface/public/vendor/codemirror/chunks/chunk-WYYO5ZAJ.js +1 -0
  366. package/neural-interface/public/vendor/codemirror/chunks/chunk-XALZTDJC.js +1 -0
  367. package/neural-interface/public/vendor/codemirror/chunks/chunk-YRNUTRDV.js +1 -0
  368. package/neural-interface/public/vendor/codemirror/chunks/chunk-Z3QOKH62.js +1 -0
  369. package/neural-interface/public/vendor/codemirror/chunks/clike-OWQBSOGL.js +1 -0
  370. package/neural-interface/public/vendor/codemirror/chunks/clojure-KV75UQWC.js +1 -0
  371. package/neural-interface/public/vendor/codemirror/chunks/cmake-GTEP5Y3C.js +1 -0
  372. package/neural-interface/public/vendor/codemirror/chunks/cobol-WCZ7QEGJ.js +1 -0
  373. package/neural-interface/public/vendor/codemirror/chunks/coffeescript-TGLBOT6B.js +1 -0
  374. package/neural-interface/public/vendor/codemirror/chunks/commonlisp-WVVI432V.js +1 -0
  375. package/neural-interface/public/vendor/codemirror/chunks/crystal-S6R6HLKQ.js +1 -0
  376. package/neural-interface/public/vendor/codemirror/chunks/css-PDA2RINP.js +1 -0
  377. package/neural-interface/public/vendor/codemirror/chunks/cypher-HL5QPL4C.js +1 -0
  378. package/neural-interface/public/vendor/codemirror/chunks/d-HHJH2HAJ.js +1 -0
  379. package/neural-interface/public/vendor/codemirror/chunks/diff-MN3A35BY.js +1 -0
  380. package/neural-interface/public/vendor/codemirror/chunks/dist-25SQLBVS.js +3 -0
  381. package/neural-interface/public/vendor/codemirror/chunks/dist-27ZGGJJS.js +1 -0
  382. package/neural-interface/public/vendor/codemirror/chunks/dist-4E52OJIF.js +1 -0
  383. package/neural-interface/public/vendor/codemirror/chunks/dist-6FT73XDC.js +2 -0
  384. package/neural-interface/public/vendor/codemirror/chunks/dist-BE6YGRMW.js +1 -0
  385. package/neural-interface/public/vendor/codemirror/chunks/dist-CJSGKW2O.js +1 -0
  386. package/neural-interface/public/vendor/codemirror/chunks/dist-CRPH2WLI.js +1 -0
  387. package/neural-interface/public/vendor/codemirror/chunks/dist-CTG7JEQN.js +1 -0
  388. package/neural-interface/public/vendor/codemirror/chunks/dist-I3FEVELX.js +1 -0
  389. package/neural-interface/public/vendor/codemirror/chunks/dist-IM5BBSWZ.js +1 -0
  390. package/neural-interface/public/vendor/codemirror/chunks/dist-KERUKTIF.js +1 -0
  391. package/neural-interface/public/vendor/codemirror/chunks/dist-LXTMWZAM.js +1 -0
  392. package/neural-interface/public/vendor/codemirror/chunks/dist-MABASSET.js +1 -0
  393. package/neural-interface/public/vendor/codemirror/chunks/dist-MJVBUZLL.js +3 -0
  394. package/neural-interface/public/vendor/codemirror/chunks/dist-MNB3WZVU.js +1 -0
  395. package/neural-interface/public/vendor/codemirror/chunks/dist-QYWXOE3U.js +7 -0
  396. package/neural-interface/public/vendor/codemirror/chunks/dist-TEBOFWLZ.js +1 -0
  397. package/neural-interface/public/vendor/codemirror/chunks/dist-UNXFROM3.js +1 -0
  398. package/neural-interface/public/vendor/codemirror/chunks/dist-XL2SLQO6.js +1 -0
  399. package/neural-interface/public/vendor/codemirror/chunks/dist-XO42Y3AP.js +6 -0
  400. package/neural-interface/public/vendor/codemirror/chunks/dist-Y2WWDWJK.js +1 -0
  401. package/neural-interface/public/vendor/codemirror/chunks/dist-YFEZKWMU.js +1 -0
  402. package/neural-interface/public/vendor/codemirror/chunks/dist-ZY7SWQO6.js +1 -0
  403. package/neural-interface/public/vendor/codemirror/chunks/dockerfile-3Y4R4NCH.js +1 -0
  404. package/neural-interface/public/vendor/codemirror/chunks/dtd-5343GJ4P.js +1 -0
  405. package/neural-interface/public/vendor/codemirror/chunks/dylan-FI2CXSW2.js +1 -0
  406. package/neural-interface/public/vendor/codemirror/chunks/ebnf-GNQ77YWA.js +1 -0
  407. package/neural-interface/public/vendor/codemirror/chunks/ecl-MRPUAE2L.js +1 -0
  408. package/neural-interface/public/vendor/codemirror/chunks/eiffel-DZROES27.js +1 -0
  409. package/neural-interface/public/vendor/codemirror/chunks/elm-4KICRFKQ.js +1 -0
  410. package/neural-interface/public/vendor/codemirror/chunks/erlang-3IHYC263.js +1 -0
  411. package/neural-interface/public/vendor/codemirror/chunks/factor-C6D3E5UK.js +1 -0
  412. package/neural-interface/public/vendor/codemirror/chunks/fcl-VYTWUJMI.js +1 -0
  413. package/neural-interface/public/vendor/codemirror/chunks/forth-ZBO2EH5M.js +1 -0
  414. package/neural-interface/public/vendor/codemirror/chunks/fortran-5NDCRWIK.js +1 -0
  415. package/neural-interface/public/vendor/codemirror/chunks/gas-SKRMOXFP.js +1 -0
  416. package/neural-interface/public/vendor/codemirror/chunks/gherkin-L45YXZLW.js +1 -0
  417. package/neural-interface/public/vendor/codemirror/chunks/groovy-GLPTLN44.js +1 -0
  418. package/neural-interface/public/vendor/codemirror/chunks/haskell-E7NF7P4Y.js +1 -0
  419. package/neural-interface/public/vendor/codemirror/chunks/haxe-K2NVDOB6.js +1 -0
  420. package/neural-interface/public/vendor/codemirror/chunks/http-Q6DRQIJB.js +1 -0
  421. package/neural-interface/public/vendor/codemirror/chunks/idl-MZYNJVLN.js +1 -0
  422. package/neural-interface/public/vendor/codemirror/chunks/javascript-6YRYK2HR.js +1 -0
  423. package/neural-interface/public/vendor/codemirror/chunks/julia-HXEL2T5G.js +1 -0
  424. package/neural-interface/public/vendor/codemirror/chunks/livescript-MV7CI2JZ.js +1 -0
  425. package/neural-interface/public/vendor/codemirror/chunks/lua-E36NHOOD.js +1 -0
  426. package/neural-interface/public/vendor/codemirror/chunks/mathematica-3XOZZCMC.js +1 -0
  427. package/neural-interface/public/vendor/codemirror/chunks/mbox-ODYGFKS7.js +1 -0
  428. package/neural-interface/public/vendor/codemirror/chunks/mirc-WB43AWF5.js +1 -0
  429. package/neural-interface/public/vendor/codemirror/chunks/mllike-ZT6ET7ZH.js +1 -0
  430. package/neural-interface/public/vendor/codemirror/chunks/modelica-LLMZPFGA.js +1 -0
  431. package/neural-interface/public/vendor/codemirror/chunks/mscgen-2OPNNYFH.js +1 -0
  432. package/neural-interface/public/vendor/codemirror/chunks/mumps-6P3HWJH6.js +1 -0
  433. package/neural-interface/public/vendor/codemirror/chunks/nginx-TCGKQTRW.js +1 -0
  434. package/neural-interface/public/vendor/codemirror/chunks/nsis-ATIGIXTJ.js +1 -0
  435. package/neural-interface/public/vendor/codemirror/chunks/ntriples-5PLBI5OV.js +1 -0
  436. package/neural-interface/public/vendor/codemirror/chunks/octave-QF2S3NL6.js +1 -0
  437. package/neural-interface/public/vendor/codemirror/chunks/oz-JFIVFFH2.js +1 -0
  438. package/neural-interface/public/vendor/codemirror/chunks/pascal-JG6SW76V.js +1 -0
  439. package/neural-interface/public/vendor/codemirror/chunks/perl-4B3IWVVO.js +1 -0
  440. package/neural-interface/public/vendor/codemirror/chunks/pig-ABEBH4MI.js +1 -0
  441. package/neural-interface/public/vendor/codemirror/chunks/powershell-H32XE7TL.js +1 -0
  442. package/neural-interface/public/vendor/codemirror/chunks/properties-NN644MMA.js +1 -0
  443. package/neural-interface/public/vendor/codemirror/chunks/protobuf-YKWQK2J3.js +1 -0
  444. package/neural-interface/public/vendor/codemirror/chunks/pug-RIYXEKFW.js +1 -0
  445. package/neural-interface/public/vendor/codemirror/chunks/puppet-JZQ5WPEV.js +1 -0
  446. package/neural-interface/public/vendor/codemirror/chunks/python-EBCGGHAC.js +1 -0
  447. package/neural-interface/public/vendor/codemirror/chunks/q-5UMH2YQY.js +1 -0
  448. package/neural-interface/public/vendor/codemirror/chunks/r-7XMGG453.js +1 -0
  449. package/neural-interface/public/vendor/codemirror/chunks/rpm-IEV7TSLR.js +1 -0
  450. package/neural-interface/public/vendor/codemirror/chunks/ruby-T4SPFPNM.js +1 -0
  451. package/neural-interface/public/vendor/codemirror/chunks/sas-GEDX67ET.js +1 -0
  452. package/neural-interface/public/vendor/codemirror/chunks/scheme-FTLOWKPC.js +1 -0
  453. package/neural-interface/public/vendor/codemirror/chunks/shell-HUFRKFSJ.js +1 -0
  454. package/neural-interface/public/vendor/codemirror/chunks/sieve-P5QUDVYO.js +1 -0
  455. package/neural-interface/public/vendor/codemirror/chunks/smalltalk-2SORJNQI.js +1 -0
  456. package/neural-interface/public/vendor/codemirror/chunks/solr-M22TGAR5.js +1 -0
  457. package/neural-interface/public/vendor/codemirror/chunks/sparql-4M3KL752.js +1 -0
  458. package/neural-interface/public/vendor/codemirror/chunks/spreadsheet-3K23LA4N.js +1 -0
  459. package/neural-interface/public/vendor/codemirror/chunks/sql-VHRFMUBI.js +1 -0
  460. package/neural-interface/public/vendor/codemirror/chunks/stex-QZDAQUY2.js +1 -0
  461. package/neural-interface/public/vendor/codemirror/chunks/stylus-7ZDKAKBD.js +1 -0
  462. package/neural-interface/public/vendor/codemirror/chunks/swift-WCLCLGMR.js +1 -0
  463. package/neural-interface/public/vendor/codemirror/chunks/tcl-JLMU6WOK.js +1 -0
  464. package/neural-interface/public/vendor/codemirror/chunks/textile-4CHDKZ4T.js +1 -0
  465. package/neural-interface/public/vendor/codemirror/chunks/tiddlywiki-DKMCZZQ4.js +1 -0
  466. package/neural-interface/public/vendor/codemirror/chunks/tiki-F4JIG36Q.js +1 -0
  467. package/neural-interface/public/vendor/codemirror/chunks/toml-BHMHTIM2.js +1 -0
  468. package/neural-interface/public/vendor/codemirror/chunks/troff-YQ2KV5NT.js +1 -0
  469. package/neural-interface/public/vendor/codemirror/chunks/ttcn-ZHRCVFJY.js +1 -0
  470. package/neural-interface/public/vendor/codemirror/chunks/ttcn-cfg-KJOVTY4X.js +1 -0
  471. package/neural-interface/public/vendor/codemirror/chunks/turtle-535P5N6I.js +1 -0
  472. package/neural-interface/public/vendor/codemirror/chunks/vb-76UMQHOT.js +1 -0
  473. package/neural-interface/public/vendor/codemirror/chunks/vbscript-CGNDTK6Z.js +1 -0
  474. package/neural-interface/public/vendor/codemirror/chunks/velocity-VSJDO5T5.js +1 -0
  475. package/neural-interface/public/vendor/codemirror/chunks/verilog-4T6ETXIP.js +1 -0
  476. package/neural-interface/public/vendor/codemirror/chunks/vhdl-T7FNAXUN.js +1 -0
  477. package/neural-interface/public/vendor/codemirror/chunks/webidl-P6MJSJ6J.js +1 -0
  478. package/neural-interface/public/vendor/codemirror/chunks/xquery-UOVILRGN.js +1 -0
  479. package/neural-interface/public/vendor/codemirror/chunks/yacas-CV2APROL.js +1 -0
  480. package/neural-interface/public/vendor/codemirror/chunks/z80-3KFNVM4M.js +1 -0
  481. package/neural-interface/public/vendor/codemirror/codemirror-6.43.14-75f05e67.min.js +2 -0
  482. package/neural-interface/public/vendor/codemirror/manifest.json +60 -0
  483. package/neural-interface/scripts/build-vendor.mjs +78 -2
  484. package/neural-interface/scripts/vendor-codemirror-entry.js +121 -0
  485. package/neural-interface/server.js +2085 -1629
  486. package/neural-interface/templates/rulesets/README.md +1 -1
  487. package/package.json +5 -8
  488. package/setup.js +53 -15
  489. package/benchmarks/browser-live-results.json +0 -79
  490. package/benchmarks/browser-v2-results.json +0 -258
  491. package/neural-interface/lib/codex-capabilities.d.ts +0 -41
  492. package/neural-interface/public/category-logos/claude.svg +0 -1
  493. package/neural-interface/public/category-logos/gemini-color.svg +0 -1
  494. package/neural-interface/public/category-logos/openai.svg +0 -1
  495. package/neural-interface/public/category-logos/synabun.png +0 -0
  496. package/neural-interface/public/claude.svg +0 -1
  497. package/neural-interface/public/gallery.svg +0 -6
  498. package/neural-interface/public/leonardoai.svg +0 -1
  499. package/neural-interface/public/mcp.svg +0 -4
  500. package/neural-interface/public/opencode-logo-dark-square.svg +0 -1
  501. package/neural-interface/public/pin-svgrepo-com.svg +0 -25
  502. package/neural-interface/public/sessionicon.svg +0 -8
  503. package/neural-interface/public/toolbar-album.svg +0 -8
  504. package/neural-interface/public/toolbar-question.svg +0 -6
  505. package/neural-interface/public/toolbar-sessions.svg +0 -6
  506. package/neural-interface/scripts/codex-protocol-fixture.mjs +0 -83
  507. package/skills/synabun/synabunicon.png +0 -0
@@ -1,4 +1,5 @@
1
1
  import { capabilityAvailability, flattenNativeCatalog, reviewTarget } from './cdx-commands.js';
2
+ import { t } from '../i18n.js';
2
3
  import { knownCodexCapabilities } from './cdx-capabilities.js';
3
4
  import { codexReadableValue, parseCodexAttachmentPayload, codexGatewayState, codexVerificationState, codexHttpsHandoff } from './cdx-protocol.js';
4
5
 
@@ -333,23 +334,27 @@ export function updateCodexGateway(tab, value) {
333
334
  accountSecurityViews.get(tab)?.();
334
335
  }
335
336
 
336
- export async function mountCodexAccountSecurity({ host, request, tab, capabilities }) {
337
+ export async function mountCodexAccountSecurity({ host, experimentalHost = host, request, tab, capabilities }) {
338
+ const tr = (key, params) => t(`codexSettings.${key}`, params);
337
339
  const view = { error: message => { error.textContent = message; } };
338
340
  const error = element('div', 'cxp-settings-hint'); error.setAttribute('role', 'alert');
339
341
  const gateway = element('div', 'cxp-settings-section');
340
342
  const verification = element('div', 'cxp-settings-section');
341
- host.append(gateway, verification, error);
343
+ host.append(gateway, error);
344
+ experimentalHost.append(verification);
342
345
  const available = name => capabilityAvailability(knownCodexCapabilities(tab) || capabilities, name);
343
346
  const renderGateway = () => {
344
347
  if (!host.isConnected || tab.closed) { accountSecurityViews.delete(tab); return; }
345
348
  gateway.replaceChildren();
346
349
  if (!available('gateway_oauth_read').supported) return;
347
350
  const value = tab.gatewayOAuth || {};
351
+ gateway.hidden = !value.required;
352
+ if (!value.required) return;
348
353
  const state = codexGatewayState(value);
349
- gateway.append(element('div', 'cxp-settings-section-title', 'Gateway OAuth'));
350
- gateway.append(element('div', 'cxp-settings-hint', `${value.providerName || value.providerId || 'Provider'} · ${state.label}`));
354
+ gateway.append(element('div', 'cxp-settings-section-title', tr('gateway')));
355
+ gateway.append(element('div', 'cxp-settings-hint', `${value.providerName || value.providerId || tr('provider')} · ${tr(`gatewayStates.${value.status || 'notReady'}`)}`));
351
356
  const action = state.pending ? 'gateway_oauth_cancel' : 'gateway_oauth_login';
352
- gateway.append(button(state.pending ? 'Cancel' : 'Sign in', async () => {
357
+ gateway.append(button(tr(state.pending ? 'cancel' : 'signIn'), async () => {
353
358
  if (!available(action).supported) throw new Error(available(action).reason);
354
359
  await request(action, {});
355
360
  // Notification is authoritative; do not overwrite a completed login with a stale optimistic state.
@@ -360,10 +365,10 @@ export async function mountCodexAccountSecurity({ host, request, tab, capabiliti
360
365
  }, view, available(action)));
361
366
  if (!available(action).supported) gateway.append(element('div', 'cxp-settings-hint', available(action).reason));
362
367
  const handoff = codexHttpsHandoff(value.authUrl);
363
- if (value.authUrl && !handoff) gateway.append(element('div', 'cxp-settings-hint', 'Authorization URL is unavailable: HTTPS is required.'));
368
+ if (value.authUrl && !handoff) gateway.append(element('div', 'cxp-settings-hint', tr('httpsRequired')));
364
369
  if (handoff && state.pending) {
365
- gateway.append(element('div', 'cxp-settings-hint', `Continue sign-in at ${handoff.host}`));
366
- gateway.append(button(`Open ${handoff.host}`, () => {
370
+ gateway.append(element('div', 'cxp-settings-hint', tr('continueAt', { host: handoff.host })));
371
+ gateway.append(button(tr('openHost', { host: handoff.host }), () => {
367
372
  window.open(handoff.url, '_blank', 'noopener,noreferrer');
368
373
  }, view));
369
374
  }
@@ -386,12 +391,15 @@ export async function mountCodexAccountSecurity({ host, request, tab, capabiliti
386
391
  const response = await request('verification_status', {});
387
392
  if (!host.isConnected || tab.closed) return;
388
393
  const state = codexVerificationState(response.verification);
389
- verification.append(element('div', 'cxp-settings-section-title', 'User verification · Experimental'));
390
- verification.append(element('div', 'cxp-settings-hint', state.label));
391
- verification.append(element('div', 'cxp-settings-hint', 'Local device credential only; backend registration is managed by the verifier.'));
394
+ const reason = response.verification?.unavailableReason;
395
+ verification.hidden = !!reason && reason !== 'credentialMissing';
396
+ if (verification.hidden) return;
397
+ verification.append(element('div', 'cxp-settings-section-title', tr('verification')));
398
+ verification.append(element('div', 'cxp-settings-hint', tr(state.enrolled ? 'credentialReady' : 'credentialMissing')));
399
+ verification.append(element('div', 'cxp-settings-hint', tr('localCredential')));
392
400
  const action = state.enrolled ? 'verification_delete' : 'verification_enroll';
393
- const control = button(state.enrolled ? 'Remove' : 'Enroll', async () => {
394
- if (state.enrolled && !window.confirm('Remove the local user verification credential?')) return;
401
+ const control = button(tr(state.enrolled ? 'remove' : 'enroll'), async () => {
402
+ if (state.enrolled && !window.confirm(tr('removeCredential'))) return;
395
403
  await request(action, {}); await readVerification();
396
404
  }, view, available(action));
397
405
  if (state.enrolled) control.style.color = 'var(--cxp-danger)';
@@ -399,7 +407,7 @@ export async function mountCodexAccountSecurity({ host, request, tab, capabiliti
399
407
  if (!available(action).supported) verification.append(element('div', 'cxp-settings-hint', available(action).reason));
400
408
  } catch (failure) {
401
409
  if (available('verification_status').supported) {
402
- verification.append(element('div', 'cxp-settings-hint', `User verification unavailable: ${failure.message}`));
410
+ verification.append(element('div', 'cxp-settings-hint', tr('error', { message: failure.message })));
403
411
  }
404
412
  }
405
413
  }
@@ -41,6 +41,8 @@ export let windowId = hostedSidepanelId || sessionStorage.getItem('cxp-window-id
41
41
  // ── Storage Keys ──
42
42
  export const STOR = {
43
43
  threadId: 'synabun-codex-panel-thread',
44
+ // The account that thread belongs to (its rollout lives in that account's CODEX_HOME).
45
+ threadAccount: 'synabun-codex-panel-thread-account',
44
46
  title: 'synabun-codex-panel-title',
45
47
  project: 'synabun-codex-panel-project',
46
48
  projectThreads: 'synabun-codex-panel-project-threads',
@@ -4,9 +4,12 @@
4
4
  import { storage } from '../storage.js';
5
5
  import { state, emit, on } from '../state.js';
6
6
  import { registerSidepanel, setSidepanelVisible, sidepanelAcceptsKeyboard, openAnotherSidepanelSession } from '../ui-sidepanel-windows.js';
7
- import { subscribeCliStatus, recheckCliStatus, getCliDocUrl, getCliInstallCommand, getCliLabel } from '../cli-status.js';
7
+ import { mountCliBanner } from '../ui-cli-banner.js';
8
8
  import { nativeLoopWindowId } from '../ui-native-window-id.js';
9
9
  import { createStickyScrollController, getStickyScrollController } from '../ui-scroll-follow.js';
10
+ import { wireFileLinks } from '../ui-file-links.js';
11
+ import { trackWorkerEnd } from '../ui-worker-end.js';
12
+ import { isDispatchedRun } from '../worker-end.js';
10
13
  import { injectStyles } from './cdx-styles.js';
11
14
  import { mountContextMenu } from './cdx-context-menu.js';
12
15
  import { teardownMcpApps } from './cdx-mcp-app-host.js';
@@ -27,6 +30,7 @@ import {
27
30
  requestModelList, populateModelDropdown,
28
31
  setSessionLabel, renameActiveSession, promptNameNewSession, openSettingsPanel, renderSessionMenu,
29
32
  toggleAccountMenu,
33
+ mountCodexAccountMenu,
30
34
  contextMenuData, contextMenuReading, refreshContextMenuDetails,
31
35
  addImageFromFile, removeImage, renderImageStrip,
32
36
  addPathChip, removePathChip, renderPathStrip,
@@ -39,6 +43,7 @@ import {
39
43
  handleNotify,
40
44
  appendLocalUserMessage, hydrateCodexAutomationHistory,
41
45
  clearPlanHandoffState,
46
+ placeWorkerEnd,
42
47
  withTab,
43
48
  ensureProjectsLoaded,
44
49
  setActiveProject,
@@ -58,8 +63,7 @@ document.addEventListener('visibilitychange', () => {
58
63
  let _panel = null;
59
64
  let _visible = false;
60
65
  let _resizeBound = false;
61
- let _cliInstalled = null;
62
- let _cliUnsub = null;
66
+ let _cliBanner = null; // the CLI banner and send-block (ui-cli-banner.js)
63
67
 
64
68
  // ═══════════════════════════════════════════
65
69
  // Bound State (mirrors active tab — managed by cdx-tabs)
@@ -107,7 +111,6 @@ let _contextMenu = null;
107
111
  * monolith and are referenced by wireEvents / ensurePanel.
108
112
  *
109
113
  * Expected shape:
110
- * maybeOpenProjectFileLink(href, event) -> bool
111
114
  * flushCardBody(itemState)
112
115
  * resetThreadState(opts)
113
116
  * appendSystem(text, tone)
@@ -272,7 +275,6 @@ function buildPanel() {
272
275
  <button class="cxp-btn" id="cxp-slide" title="Slide panel"><svg viewBox="0 0 24 24"><polyline points="9 18 15 12 9 6"/></svg></button>
273
276
  </div>
274
277
  <div class="cxp-session-menu" id="cxp-session-menu"></div>
275
- <div class="cxp-account-menu" id="cxp-account-menu"></div>
276
278
  </div>
277
279
  <div class="cxp-messages-container" id="cxp-messages-container"></div>
278
280
  <div class="cxp-bottom">
@@ -403,122 +405,66 @@ function startupEmptyText() {
403
405
  }
404
406
 
405
407
  // ── CLI installation status (banner + send-block) ──
406
- let _cliInstallFailureForced = false;
407
- let _cliFailureReason = null;
408
-
409
- function ensureCliBannerEl() {
410
- if (!_panel) return null;
411
- const container = panelEl('#cxp-messages-container');
412
- if (!container || !container.parentNode) return null;
413
- let banner = container.parentNode.querySelector(':scope > .cxp-cli-banner');
414
- if (banner) { renderCliBannerContent(banner); return banner; }
415
- const url = getCliDocUrl('codex');
416
- banner = document.createElement('div');
417
- banner.className = 'cxp-cli-banner';
418
- banner.innerHTML = `
419
- <div class="cxp-cli-banner-icon">!</div>
420
- <div class="cxp-cli-banner-text">
421
- <div class="cxp-cli-banner-title"></div>
422
- <div class="cxp-cli-banner-body"></div>
423
- </div>
424
- <div class="cxp-cli-banner-actions">
425
- <a class="cxp-cli-banner-link" href="${url}" target="_blank" rel="noopener noreferrer">Install guide</a>
426
- <button class="cxp-cli-banner-recheck" type="button">Re-check</button>
427
- </div>
428
- `;
429
- container.parentNode.insertBefore(banner, container);
430
- const btn = banner.querySelector('.cxp-cli-banner-recheck');
431
- btn?.addEventListener('click', async () => {
432
- btn.disabled = true;
433
- btn.textContent = 'Checking…';
434
- try { await recheckCliStatus('codex'); }
435
- finally {
436
- if (btn.isConnected) {
437
- btn.disabled = false;
438
- btn.textContent = 'Re-check';
439
- }
440
- }
441
- });
442
- renderCliBannerContent(banner);
443
- return banner;
444
- }
445
-
446
- // Two very different situations reach this banner, and telling the user the
447
- // CLI is "not installed" when it is installed sends them off to reinstall
448
- // something that is already there. Distinguish them.
449
- function renderCliBannerContent(banner) {
450
- const titleEl = banner.querySelector('.cxp-cli-banner-title');
451
- const bodyEl = banner.querySelector('.cxp-cli-banner-body');
452
- if (!titleEl || !bodyEl) return;
453
- const label = getCliLabel('codex');
454
- bodyEl.replaceChildren();
455
-
456
- if (_cliInstalled === null) {
457
- titleEl.textContent = `${label} CLI not installed`;
458
- const cmd = getCliInstallCommand('codex');
459
- bodyEl.append('Run ');
460
- const code = document.createElement('code');
461
- code.textContent = cmd;
462
- bodyEl.append(code, ' or follow the install guide.');
463
- return;
464
- }
465
-
466
- titleEl.textContent = `${label} CLI failed to start`;
467
- bodyEl.append(`${label} v${_cliInstalled} is installed, but it could not be launched. `);
468
- if (_cliFailureReason) {
469
- const code = document.createElement('code');
470
- code.textContent = _cliFailureReason;
471
- bodyEl.append(code);
472
- } else {
473
- bodyEl.append('Check the CLI path in Settings, then re-check.');
408
+ // One controller (ui-cli-banner.js) draws the banner above the transcript while
409
+ // Codex is not usable: not installed (with Install, which runs OpenAI's own
410
+ // installer on the server), being installed, failed to install, or found but
411
+ // failed to start (with the error it gave). It toggles `cxp-cli-blocked` on the
412
+ // panel, which syncInputEnabled (cdx-tabs.js) reads to keep Send off. What it
413
+ // says is cli-install-view.js (`cliInstall.*` strings).
414
+ let _cliWasBlocked = false;
415
+
416
+ function cliBanner() {
417
+ if (!_cliBanner) {
418
+ _cliBanner = mountCliBanner({
419
+ toolKey: 'codex',
420
+ prefix: 'cxp',
421
+ panel: () => _panel,
422
+ anchor: () => panelEl('#cxp-messages-container'),
423
+ onBlockedChange: (blocked) => {
424
+ try { syncInputEnabled(); } catch {}
425
+ const usableAgain = _cliWasBlocked && !blocked;
426
+ _cliWasBlocked = blocked;
427
+ if (usableAgain) reconnectAfterCli();
428
+ },
429
+ });
474
430
  }
431
+ return _cliBanner;
475
432
  }
476
433
 
477
- function removeCliBannerEl() {
478
- if (!_panel) return;
479
- const container = panelEl('#cxp-messages-container');
480
- const banner = container?.parentNode?.querySelector(':scope > .cxp-cli-banner');
481
- banner?.remove();
434
+ // Codex was installed (or found again) after this tab's session could not start it: the tab connects again, so
435
+ // Send works without reopening the panel. A tab that is running, or one an automation owns, is left alone.
436
+ function reconnectAfterCli() {
437
+ const tab = activeTab();
438
+ if (!tab || tab.closed || tab.automationActive || tab.running) return;
439
+ if (tab.connected && tab.bootstrapped) return;
440
+ try {
441
+ if (tab.ws && tab.ws.readyState === WebSocket.OPEN) disconnectTab(tab);
442
+ connectTab(tab);
443
+ } catch (error) {
444
+ console.warn('[cdx-panel] reconnect after Codex became usable failed', error);
445
+ }
482
446
  }
483
447
 
484
448
  function refreshCliBanner() {
485
449
  if (!_panel) return;
486
- const missing = _cliInstalled === null || _cliInstallFailureForced;
487
- _panel.classList.toggle('cxp-cli-blocked', missing);
488
- if (missing) ensureCliBannerEl();
489
- else removeCliBannerEl();
450
+ cliBanner().refresh();
490
451
  try { syncInputEnabled(); } catch {}
491
452
  }
492
453
 
493
454
  export function isCdxCliInstalled() {
494
- return _cliInstalled !== null && !_cliInstallFailureForced;
455
+ return !cliBanner().blocked();
495
456
  }
496
457
 
458
+ // A session could not start Codex: "failed to start" with its words at once,
459
+ // then the server is asked again and its answer decides what stays. (The
460
+ // answer is read from the re-check itself: a spawn failure does not change
461
+ // the version, so a change-only notification would never clear the banner.)
497
462
  export function flagCdxCliInstallFailure(reason = null) {
498
- _cliInstallFailureForced = true;
499
- _cliFailureReason = reason ? String(reason).slice(0, 300) : null;
500
- refreshCliBanner();
501
- // Clear the latch from the value recheckCliStatus RETURNS. Relying on the
502
- // subscriber callback alone deadlocked: the callback only fired when the
503
- // version string changed, and a spawn failure does not change the version,
504
- // so the banner could never be dismissed — the Re-check button included.
505
- recheckCliStatus('codex')
506
- .then((info) => {
507
- if (!info?.installed) return;
508
- _cliInstallFailureForced = false;
509
- _cliFailureReason = null;
510
- refreshCliBanner();
511
- })
512
- .catch(() => {});
463
+ cliBanner().flagFailure(reason);
513
464
  }
514
465
 
515
466
  function ensureCliSubscription() {
516
- if (_cliUnsub) return;
517
- _cliUnsub = subscribeCliStatus('codex', (info) => {
518
- _cliInstalled = info?.installed || null;
519
- if (_cliInstalled) { _cliInstallFailureForced = false; _cliFailureReason = null; }
520
- refreshCliBanner();
521
- });
467
+ cliBanner();
522
468
  }
523
469
 
524
470
  // ═══════════════════════════════════════════
@@ -785,14 +731,18 @@ async function saveRecallProfile(profile) {
785
731
  // ═══════════════════════════════════════════
786
732
 
787
733
  function wireEvents() {
788
- // Project links retain their existing handling; card heads bind in cdx-render.
789
- const msgContainer = panelEl('#cxp-messages-container');
790
- if (msgContainer) {
791
- msgContainer.addEventListener('click', (e) => {
792
- const link = e.target.closest('a[href]');
793
- if (link && msgContainer.contains(link) && _host.maybeOpenProjectFileLink?.(link.getAttribute('href'), e)) return;
794
- });
795
- }
734
+ // File links open in the code editor (../ui-file-links.js, shared with the other panels): one listener for
735
+ // every tab's transcript, so stored and streaming messages behave alike. Card heads bind in cdx-render.
736
+ wireFileLinks(panelEl('#cxp-messages-container'), {
737
+ // A relative path is a path in the project of the tab on screen (a worker run's tab has the run's folder).
738
+ cwd: (link) => (allTabs().find((tab) => tab.messagesEl?.contains(link)) || activeTab())?.project || '',
739
+ textLinks: 'a.cxp-file-link',
740
+ // A path the editor does not open keeps what a click on it did: it is copied.
741
+ copyPath: (link, path) => navigator.clipboard.writeText(path).then(() => {
742
+ link.classList.add('cxp-file-link-copied');
743
+ setTimeout(() => link.classList.remove('cxp-file-link-copied'), 1500);
744
+ }),
745
+ });
796
746
 
797
747
  const input = panelEl('#cxp-input');
798
748
  const send = panelEl('#cxp-send');
@@ -899,7 +849,6 @@ function wireEvents() {
899
849
  },
900
850
  onOpen: () => {
901
851
  sessionMenu?.classList.remove('open');
902
- panelEl('#cxp-account-menu')?.classList.remove('open');
903
852
  panelEl('#cxp-effort-menu')?.classList.remove('open');
904
853
  refreshContextMenuDetails();
905
854
  },
@@ -909,8 +858,8 @@ function wireEvents() {
909
858
  // After this click has reached the document, whose handler closes the menu.
910
859
  onAccount: () => setTimeout(() => toggleAccountMenu(), 0),
911
860
  });
912
- // The account menu hangs under the header, which a floating window is moved by.
913
- panelEl('#cxp-account-menu')?.addEventListener('pointerdown', (event) => event.stopPropagation());
861
+ // The header account menu (account-menu.js, shared with the Claude panel): before the cog.
862
+ mountCodexAccountMenu(panelEl('.cxp-actions'), _panel);
914
863
  const slideBtn = panelEl('#cxp-slide');
915
864
  slideBtn?.addEventListener('click', () => setVisible(false));
916
865
  const changelogBtn = panelEl('#cxp-action-changelog');
@@ -1028,7 +977,6 @@ function wireEvents() {
1028
977
  });
1029
978
  document.addEventListener('click', (event) => {
1030
979
  if (!event.target.closest('.cxp-header')) sessionMenu?.classList.remove('open');
1031
- if (!event.target.closest('#cxp-account-menu')) panelEl('#cxp-account-menu')?.classList.remove('open');
1032
980
  if (!event.target.closest('.cxp-dropdown')) {
1033
981
  _panel?.querySelectorAll('.cxp-dropdown.open').forEach((node) => node.classList.remove('open'));
1034
982
  }
@@ -1274,6 +1222,19 @@ export async function attachCodexAutomation(run, {
1274
1222
  ensurePanel();
1275
1223
  await ensureProjectsLoaded();
1276
1224
  if (isCancelled()) return { ok: false, reason: 'dismissed' };
1225
+ const running = run.status === 'starting' || run.status === 'running';
1226
+ // The user continued this run's thread by hand after the run ended: the tab stays theirs. The
1227
+ // dock's Focus raises it; the run is let go again, and nothing in the tab changes.
1228
+ const own = allTabs().find((entry) => !entry.automationRunId && entry.releasedRunId === run.runId && entry.threadId === threadId);
1229
+ if (own && !running) {
1230
+ window.dispatchEvent(new CustomEvent('native-loop:dismissed', { detail: { runId: run.runId } }));
1231
+ if (focus) {
1232
+ if (!_visible) await toggleCodexPanel();
1233
+ const ownIdx = allTabs().indexOf(own);
1234
+ if (ownIdx >= 0) switchTab(ownIdx);
1235
+ }
1236
+ return { ok: true, tabId: own.id, released: true };
1237
+ }
1277
1238
  let tab = allTabs().find((entry) => entry.automationRunId === run.runId);
1278
1239
  if (!tab) {
1279
1240
  tab = createTab({
@@ -1291,7 +1252,6 @@ export async function attachCodexAutomation(run, {
1291
1252
  }, { autoSwitch: false });
1292
1253
  }
1293
1254
  if (!tab) return { ok: false, reason: 'tab_limit' };
1294
- const running = run.status === 'starting' || run.status === 'running';
1295
1255
  // A task-mode worker between turns (waiting for a follow-up) is alive, not working.
1296
1256
  const working = running && run.turnState !== 'idle' && run.turnState !== 'terminal';
1297
1257
  tab.automationRunId = run.runId;
@@ -1315,10 +1275,12 @@ export async function attachCodexAutomation(run, {
1315
1275
  return { ok: false, reason: 'dismissed' };
1316
1276
  }
1317
1277
  }
1318
- if (run.status === 'failed' && run.error && tab._automationLifecycleError !== run.error) {
1278
+ // (A dispatched worker's failure, with its reason, is on its end card.)
1279
+ if (run.status === 'failed' && run.error && !isDispatchedRun(run) && tab._automationLifecycleError !== run.error) {
1319
1280
  tab._automationLifecycleError = run.error;
1320
1281
  withTab(tab, () => appendSystem(run.error, 'error'));
1321
1282
  }
1283
+ trackWorkerEnd(run, { apply: (view) => { tab._workerEnd = view; placeWorkerEnd(tab); } });
1322
1284
  saveTabs();
1323
1285
  renderPills();
1324
1286
  if (focus) {
@@ -16,6 +16,7 @@ import { bindExpandableCard, setCardExpanded } from './cdx-cards.js';
16
16
  import { mountMcpAppCard } from './cdx-mcp-app-host.js';
17
17
  import { OUTPUT_LIMITS, boundedText, jsonAnswer, prettyJsonFences, readableStructuredValue, fileChangeDiffs, parseUnifiedDiff, deduplicateTurnDiff } from './cdx-output-model.js';
18
18
  import { renderReadableOutput, renderReadableBlock, cleanOutputBlocks, hydrateOutputControls, observeOutputBlocks, renderDiffView, restoreDiffViews } from './cdx-output.js';
19
+ import { fileLinkTitle, fillFileLinkCopy, isInsideRoots, parseFileLinkTarget } from '../file-links.js';
19
20
  export { setCardExpanded } from './cdx-cards.js';
20
21
 
21
22
  // ── Shared context (set by cdx-tabs via setRenderContext) ──
@@ -375,101 +376,45 @@ export function postProcessRenderedHtml(container) {
375
376
  // ═══════════════════════════════════════════
376
377
  // File Path Linking
377
378
  // ═══════════════════════════════════════════
379
+ // What a target means is decided in ../file-links.js, shared with the other panels; a click is taken by the
380
+ // one listener cdx-panel.js puts on the transcript (../ui-file-links.js), so links in a stored transcript
381
+ // work like fresh ones.
378
382
 
379
383
  export function normalizePathForCompare(path) {
380
384
  return String(path || '').replace(/\\/g, '/').replace(/\/+$/, '');
381
385
  }
382
386
 
383
- export function isProjectFilePath(path) {
384
- const normalized = normalizePathForCompare(path);
385
- if (!normalized.startsWith('/')) return false;
386
- const roots = new Set([
387
- normalizePathForCompare(_ctx.project),
388
- ...(_ctx.projects || []).map((entry) => normalizePathForCompare(entry?.path)).filter(Boolean),
389
- ]);
390
- for (const root of roots) {
391
- if (!root) continue;
392
- if (normalized === root || normalized.startsWith(`${root}/`)) return true;
393
- }
394
- return false;
387
+ // The folder a relative link is read from: the project of the tab the transcript belongs to.
388
+ function fileLinkWhere() {
389
+ return {
390
+ cwd: _ctx.boundTab?.project || _ctx.project || '',
391
+ origin: globalThis.location?.origin || '',
392
+ };
395
393
  }
396
394
 
397
- export function parseProjectFileTarget(rawTarget) {
398
- if (!rawTarget) return null;
399
- let raw = String(rawTarget).trim();
400
- if (!raw || raw === '#') return null;
401
- if (raw.startsWith('file://')) {
402
- try { raw = decodeURIComponent(new URL(raw).pathname || ''); }
403
- catch { raw = raw.replace(/^file:\/\//, ''); }
404
- }
405
-
406
- let pathPart = raw;
407
- let hash = '';
408
- if (/^[a-z]+:\/\//i.test(raw)) {
409
- try {
410
- const parsed = new URL(raw, window.location.origin);
411
- if (parsed.origin !== window.location.origin) return null;
412
- pathPart = parsed.pathname || '';
413
- hash = parsed.hash || '';
414
- } catch {
415
- return null;
416
- }
417
- } else {
418
- const hashIndex = raw.indexOf('#');
419
- if (hashIndex >= 0) {
420
- pathPart = raw.slice(0, hashIndex);
421
- hash = raw.slice(hashIndex);
422
- }
423
- }
424
-
425
- try { pathPart = decodeURIComponent(pathPart); } catch {}
426
- pathPart = normalizePathForCompare(pathPart);
427
-
428
- let line = null;
429
- let column = null;
430
- const suffixMatch = pathPart.match(/:(\d+)(?::(\d+))?$/);
431
- if (suffixMatch) {
432
- line = Number(suffixMatch[1]) || null;
433
- column = Number(suffixMatch[2]) || null;
434
- pathPart = normalizePathForCompare(pathPart.slice(0, suffixMatch.index));
435
- }
436
- if (!isProjectFilePath(pathPart)) return null;
437
- const hashMatch = hash.match(/^#L(\d+)(?:C(\d+))?$/i);
438
- if (hashMatch) {
439
- line = Number(hashMatch[1]) || line;
440
- column = Number(hashMatch[2]) || column;
441
- }
442
-
443
- return { filePath: pathPart, line, column };
395
+ export function isProjectFilePath(path) {
396
+ return isInsideRoots(path, [_ctx.boundTab?.project, _ctx.project, ...(_ctx.projects || []).map((entry) => entry?.path)]);
444
397
  }
445
398
 
446
- export function openProjectFileTarget(target) {
447
- if (!target?.filePath) return false;
448
- _ctx.emit('open-file-editor', {
449
- filePath: target.filePath,
450
- line: target.line || undefined,
451
- column: target.column || undefined,
452
- });
453
- return true;
399
+ // A link target that is a file of this tab's project or of a registered one, or null.
400
+ function projectFileTarget(rawTarget) {
401
+ const target = parseFileLinkTarget(rawTarget, fileLinkWhere());
402
+ return target?.path && isProjectFilePath(target.path) ? target : null;
454
403
  }
455
404
 
456
- export function maybeOpenProjectFileLink(rawTarget, event) {
457
- const target = parseProjectFileTarget(rawTarget);
458
- if (!target) return false;
459
- event?.preventDefault?.();
460
- return openProjectFileTarget(target);
405
+ function openInEditorTitle(target) {
406
+ const { key, params } = fileLinkTitle(target);
407
+ return _ctx.fileLinkText?.(key, params) || fillFileLinkCopy(key, params);
461
408
  }
462
409
 
463
410
  export function markProjectFileAnchors(container) {
464
411
  if (!container) return;
465
412
  container.querySelectorAll('a[href]').forEach((link) => {
466
- const target = parseProjectFileTarget(link.getAttribute('href'));
413
+ const target = projectFileTarget(link.getAttribute('href'));
467
414
  if (!target) return;
468
415
  link.classList.add('cxp-file-link');
469
- link.dataset.projectFilePath = target.filePath;
470
- link.title = target.line
471
- ? `Open in editor${target.column ? ` at line ${target.line}, column ${target.column}` : ` at line ${target.line}`}`
472
- : 'Open in editor';
416
+ link.dataset.projectFilePath = target.path;
417
+ link.title = openInEditorTitle(target);
473
418
  });
474
419
  }
475
420
 
@@ -497,19 +442,10 @@ export function linkifyFilePaths(container) {
497
442
  const link = document.createElement('a');
498
443
  link.className = 'cxp-file-link';
499
444
  link.textContent = pathStr;
500
- const target = parseProjectFileTarget(pathStr);
501
- link.title = target?.line
502
- ? `Open in editor${target.column ? ` at line ${target.line}, column ${target.column}` : ` at line ${target.line}`}`
503
- : target ? 'Open in editor' : 'Click to copy path';
445
+ const target = projectFileTarget(pathStr);
446
+ link.title = target ? openInEditorTitle(target) : 'Click to copy path';
504
447
  link.href = '#';
505
- link.addEventListener('click', (e) => {
506
- if (maybeOpenProjectFileLink(pathStr, e)) return;
507
- e.preventDefault();
508
- const cleanPath = pathStr.replace(/:\d+(:\d+)?$/, '');
509
- navigator.clipboard.writeText(cleanPath).catch(() => {});
510
- link.classList.add('cxp-file-link-copied');
511
- setTimeout(() => link.classList.remove('cxp-file-link-copied'), 1500);
512
- });
448
+ // The click is taken on the transcript (cdx-panel.js): the editor when it can open the path, else a copy.
513
449
  frag.appendChild(link);
514
450
  lastIndex = match.index + match[0].length;
515
451
  }