synabun 2.0.10 → 2.2.0

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 (656) hide show
  1. package/CHANGELOG.md +207 -0
  2. package/README.md +25 -2
  3. package/THIRD-PARTY-LICENSES.md +22 -0
  4. package/bin/synabun.js +71 -24
  5. package/docs/whatsapp.md +13 -13
  6. package/hooks/claude-code/pre-websearch.mjs +12 -1
  7. package/hooks/claude-code/shared.mjs +5 -0
  8. package/hooks/claude-code/stop.mjs +1 -1
  9. package/lib/claude-hooks.js +172 -18
  10. package/lib/client-config-repair.js +30 -17
  11. package/lib/desktop-app.js +7 -1
  12. package/lib/external-tools.js +7 -6
  13. package/lib/first-launch-protection.js +57 -12
  14. package/lib/mcp-dist.js +176 -0
  15. package/lib/release-npm-ci.mjs +138 -0
  16. package/lib/release-publish.mjs +91 -0
  17. package/lib/release-scan.mjs +50 -0
  18. package/lib/server-crash-record.js +123 -0
  19. package/lib/server-exit.js +318 -0
  20. package/lib/server-supervisor.js +508 -0
  21. package/lib/start-launcher.js +37 -4
  22. package/lib/tools-cli.js +45 -0
  23. package/lib/update-snapshot.js +302 -0
  24. package/lib/virustotal.mjs +203 -0
  25. package/lib/windows-crash-event.js +269 -0
  26. package/mcp-server/dist/http.d.ts +20 -1
  27. package/mcp-server/dist/http.d.ts.map +1 -1
  28. package/mcp-server/dist/http.js +59 -12
  29. package/mcp-server/dist/http.js.map +1 -1
  30. package/mcp-server/dist/index.d.ts +33 -27
  31. package/mcp-server/dist/index.d.ts.map +1 -1
  32. package/mcp-server/dist/index.js +128 -143
  33. package/mcp-server/dist/index.js.map +1 -1
  34. package/mcp-server/dist/preload.js +1 -1
  35. package/mcp-server/dist/preload.js.map +1 -1
  36. package/mcp-server/dist/services/budget-judgments.d.ts +1 -1
  37. package/mcp-server/dist/services/budget-judgments.d.ts.map +1 -1
  38. package/mcp-server/dist/services/budget-judgments.js +5 -3
  39. package/mcp-server/dist/services/budget-judgments.js.map +1 -1
  40. package/mcp-server/dist/services/codex-config-heal.d.ts +6 -2
  41. package/mcp-server/dist/services/codex-config-heal.d.ts.map +1 -1
  42. package/mcp-server/dist/services/codex-config-heal.js +81 -28
  43. package/mcp-server/dist/services/codex-config-heal.js.map +1 -1
  44. package/mcp-server/dist/services/identity.d.ts +2 -2
  45. package/mcp-server/dist/services/identity.js +2 -2
  46. package/mcp-server/dist/services/memory-judge-backfill.d.ts +6 -0
  47. package/mcp-server/dist/services/memory-judge-backfill.d.ts.map +1 -1
  48. package/mcp-server/dist/services/memory-judge-backfill.js +7 -1
  49. package/mcp-server/dist/services/memory-judge-backfill.js.map +1 -1
  50. package/mcp-server/dist/services/memory-sessions.d.ts +1 -1
  51. package/mcp-server/dist/services/memory-sessions.d.ts.map +1 -1
  52. package/mcp-server/dist/services/memory-sessions.js +28 -2
  53. package/mcp-server/dist/services/memory-sessions.js.map +1 -1
  54. package/mcp-server/dist/services/neural-interface.d.ts +18 -11
  55. package/mcp-server/dist/services/neural-interface.d.ts.map +1 -1
  56. package/mcp-server/dist/services/neural-interface.js +67 -11
  57. package/mcp-server/dist/services/neural-interface.js.map +1 -1
  58. package/mcp-server/dist/services/server-instructions.d.ts +7 -2
  59. package/mcp-server/dist/services/server-instructions.d.ts.map +1 -1
  60. package/mcp-server/dist/services/server-instructions.js +22 -63
  61. package/mcp-server/dist/services/server-instructions.js.map +1 -1
  62. package/mcp-server/dist/services/tool-catalog.d.ts +120 -0
  63. package/mcp-server/dist/services/tool-catalog.d.ts.map +1 -0
  64. package/mcp-server/dist/services/tool-catalog.js +339 -0
  65. package/mcp-server/dist/services/tool-catalog.js.map +1 -0
  66. package/mcp-server/dist/services/tool-list-refresh-barrier.d.ts +12 -0
  67. package/mcp-server/dist/services/tool-list-refresh-barrier.d.ts.map +1 -0
  68. package/mcp-server/dist/services/tool-list-refresh-barrier.js +40 -0
  69. package/mcp-server/dist/services/tool-list-refresh-barrier.js.map +1 -0
  70. package/mcp-server/dist/services/tool-list.d.ts +108 -0
  71. package/mcp-server/dist/services/tool-list.d.ts.map +1 -0
  72. package/mcp-server/dist/services/tool-list.js +334 -0
  73. package/mcp-server/dist/services/tool-list.js.map +1 -0
  74. package/mcp-server/dist/services/tool-runtime.d.ts +161 -0
  75. package/mcp-server/dist/services/tool-runtime.d.ts.map +1 -0
  76. package/mcp-server/dist/services/tool-runtime.js +400 -0
  77. package/mcp-server/dist/services/tool-runtime.js.map +1 -0
  78. package/mcp-server/dist/services/typesafe-config.js +1 -1
  79. package/mcp-server/dist/services/typesafe-config.js.map +1 -1
  80. package/mcp-server/dist/services/whiteboard-geometry.d.ts +26 -2
  81. package/mcp-server/dist/services/whiteboard-geometry.d.ts.map +1 -1
  82. package/mcp-server/dist/services/whiteboard-geometry.js +91 -8
  83. package/mcp-server/dist/services/whiteboard-geometry.js.map +1 -1
  84. package/mcp-server/dist/tools/agents.d.ts +14 -14
  85. package/mcp-server/dist/tools/agents.d.ts.map +1 -1
  86. package/mcp-server/dist/tools/agents.js +29 -19
  87. package/mcp-server/dist/tools/agents.js.map +1 -1
  88. package/mcp-server/dist/tools/browser-batch.d.ts +3 -3
  89. package/mcp-server/dist/tools/choice.d.ts +6 -0
  90. package/mcp-server/dist/tools/choice.d.ts.map +1 -1
  91. package/mcp-server/dist/tools/choice.js +18 -13
  92. package/mcp-server/dist/tools/choice.js.map +1 -1
  93. package/mcp-server/dist/tools/git-tools.js +2 -2
  94. package/mcp-server/dist/tools/git-tools.js.map +1 -1
  95. package/mcp-server/dist/tools/image-tools.d.ts +1 -1
  96. package/mcp-server/dist/tools/image-tools.js +1 -1
  97. package/mcp-server/dist/tools/morelogin.d.ts.map +1 -1
  98. package/mcp-server/dist/tools/morelogin.js +9 -6
  99. package/mcp-server/dist/tools/morelogin.js.map +1 -1
  100. package/mcp-server/dist/tools/skill-tools.d.ts +505 -0
  101. package/mcp-server/dist/tools/skill-tools.d.ts.map +1 -0
  102. package/mcp-server/dist/tools/skill-tools.js +642 -0
  103. package/mcp-server/dist/tools/skill-tools.js.map +1 -0
  104. package/mcp-server/dist/tools/skill.d.ts +7 -0
  105. package/mcp-server/dist/tools/skill.d.ts.map +1 -0
  106. package/mcp-server/dist/tools/skill.js +11 -0
  107. package/mcp-server/dist/tools/skill.js.map +1 -0
  108. package/mcp-server/dist/tools/tool-groups.d.ts +68 -0
  109. package/mcp-server/dist/tools/tool-groups.d.ts.map +1 -0
  110. package/mcp-server/dist/tools/tool-groups.js +147 -0
  111. package/mcp-server/dist/tools/tool-groups.js.map +1 -0
  112. package/mcp-server/dist/tools/whiteboard-format.d.ts.map +1 -1
  113. package/mcp-server/dist/tools/whiteboard-format.js +7 -4
  114. package/mcp-server/dist/tools/whiteboard-format.js.map +1 -1
  115. package/mcp-server/dist/tools/whiteboard-tools.d.ts +64 -13
  116. package/mcp-server/dist/tools/whiteboard-tools.d.ts.map +1 -1
  117. package/mcp-server/dist/tools/whiteboard-tools.js +30 -5
  118. package/mcp-server/dist/tools/whiteboard-tools.js.map +1 -1
  119. package/mcp-server/package-lock.json +2 -2
  120. package/mcp-server/package.json +1 -1
  121. package/mcp-server/src/http.ts +75 -12
  122. package/mcp-server/src/index.ts +147 -154
  123. package/mcp-server/src/preload.ts +12 -12
  124. package/mcp-server/src/services/budget-judgments.ts +5 -3
  125. package/mcp-server/src/services/codex-config-heal.ts +80 -29
  126. package/mcp-server/src/services/identity.ts +2 -2
  127. package/mcp-server/src/services/memory-judge-backfill.ts +7 -1
  128. package/mcp-server/src/services/memory-sessions.ts +24 -3
  129. package/mcp-server/src/services/neural-interface.ts +81 -21
  130. package/mcp-server/src/services/server-instructions.ts +29 -64
  131. package/mcp-server/src/services/tool-catalog.ts +403 -0
  132. package/mcp-server/src/services/tool-list-refresh-barrier.ts +33 -0
  133. package/mcp-server/src/services/tool-list.ts +410 -0
  134. package/mcp-server/src/services/tool-runtime.ts +457 -0
  135. package/mcp-server/src/services/typesafe-config.ts +1 -1
  136. package/mcp-server/src/services/whiteboard-geometry.ts +94 -9
  137. package/mcp-server/src/tools/agents.ts +29 -20
  138. package/mcp-server/src/tools/choice.ts +17 -12
  139. package/mcp-server/src/tools/git-tools.ts +2 -2
  140. package/mcp-server/src/tools/image-tools.ts +1 -1
  141. package/mcp-server/src/tools/morelogin.ts +6 -4
  142. package/mcp-server/src/tools/skill-tools.ts +592 -0
  143. package/mcp-server/src/tools/skill.ts +13 -0
  144. package/mcp-server/src/tools/tool-groups.ts +164 -0
  145. package/mcp-server/src/tools/whiteboard-format.ts +9 -3
  146. package/mcp-server/src/tools/whiteboard-tools.ts +39 -5
  147. package/neural-interface/i18n/en.json +3953 -228
  148. package/neural-interface/i18n/pt-BR.json +3901 -179
  149. package/neural-interface/lib/agent-sandbox-elevation.js +6 -0
  150. package/neural-interface/lib/antigravity/acp-client-host.js +554 -0
  151. package/neural-interface/lib/antigravity/acp-connection.js +299 -0
  152. package/neural-interface/lib/antigravity/bypass.js +100 -0
  153. package/neural-interface/lib/antigravity/catalog.js +273 -0
  154. package/neural-interface/lib/antigravity/home.js +260 -0
  155. package/neural-interface/lib/antigravity/migrate-gemini.js +139 -0
  156. package/neural-interface/lib/antigravity/panel-bridge.js +1058 -0
  157. package/neural-interface/lib/antigravity/policy-hook.mjs +78 -0
  158. package/neural-interface/lib/antigravity/policy.js +74 -0
  159. package/neural-interface/lib/antigravity/tool-call.js +178 -0
  160. package/neural-interface/lib/antigravity/transcripts.js +252 -0
  161. package/neural-interface/lib/antigravity/usage.js +43 -0
  162. package/neural-interface/lib/assistant-api.js +128 -28
  163. package/neural-interface/lib/assistant-brains/antigravity.js +423 -0
  164. package/neural-interface/lib/assistant-brains/claude.js +4 -3
  165. package/neural-interface/lib/assistant-brains/codex-browser-policy-hook.mjs +12 -2
  166. package/neural-interface/lib/assistant-brains/codex-route-gate-hook.mjs +32 -9
  167. package/neural-interface/lib/assistant-brains/codex.js +9 -5
  168. package/neural-interface/lib/assistant-brains/opencode.js +120 -54
  169. package/neural-interface/lib/assistant-brains/opencode2-browser-policy/index.js +28 -13
  170. package/neural-interface/lib/assistant-brains/opencode2-route-gate/index.js +59 -19
  171. package/neural-interface/lib/assistant-budget-planner.js +7 -3
  172. package/neural-interface/lib/assistant-budget-split.js +42 -15
  173. package/neural-interface/lib/assistant-catalog.js +81 -15
  174. package/neural-interface/lib/assistant-config.js +6 -3
  175. package/neural-interface/lib/assistant-dispatch.js +1073 -200
  176. package/neural-interface/lib/assistant-envelope.js +156 -2
  177. package/neural-interface/lib/assistant-evidence.js +80 -0
  178. package/neural-interface/lib/assistant-hidden-models.js +7 -5
  179. package/neural-interface/lib/assistant-persona.js +93 -19
  180. package/neural-interface/lib/assistant-plan-permissions.js +25 -9
  181. package/neural-interface/lib/assistant-route-gate-codex.js +3 -0
  182. package/neural-interface/lib/assistant-route-gate.js +6 -4
  183. package/neural-interface/lib/assistant-router.js +245 -38
  184. package/neural-interface/lib/assistant-runtime.js +214 -30
  185. package/neural-interface/lib/assistant-task-prompt.js +87 -21
  186. package/neural-interface/lib/assistant-tools.js +51 -0
  187. package/neural-interface/lib/assistant-usage.js +29 -0
  188. package/neural-interface/lib/backup-service.js +626 -4
  189. package/neural-interface/lib/backup-zip-reader.js +10 -5
  190. package/neural-interface/lib/backup-zip-writer.js +257 -0
  191. package/neural-interface/lib/browser-execution.js +10 -2
  192. package/neural-interface/lib/browser-guard-cdp.js +84 -0
  193. package/neural-interface/lib/browser-network-guard.js +476 -0
  194. package/neural-interface/lib/browser-policy-roots.js +64 -0
  195. package/neural-interface/lib/browser-tool-policy.js +198 -38
  196. package/neural-interface/lib/claude-agent-bridge.js +11 -2
  197. package/neural-interface/lib/claude-history-cache.js +210 -0
  198. package/neural-interface/lib/claude-hooks-status.js +103 -0
  199. package/neural-interface/lib/claude-model-catalog.js +5 -1
  200. package/neural-interface/lib/claude-temporary.js +5 -11
  201. package/neural-interface/lib/cli-install-api.js +1 -1
  202. package/neural-interface/lib/cli-install.js +163 -154
  203. package/neural-interface/lib/cli-resolver.js +13 -3
  204. package/neural-interface/lib/cli-update-planner.js +52 -41
  205. package/neural-interface/lib/cloudflared/tunnel.js +42 -2
  206. package/neural-interface/lib/codex-mcp-approvals.js +11 -0
  207. package/neural-interface/lib/codex-rollout-reader.js +52 -0
  208. package/neural-interface/lib/codex-worker-app-server.js +191 -0
  209. package/neural-interface/lib/confined-fs.js +30 -3
  210. package/neural-interface/lib/crash-notice-api.js +98 -0
  211. package/neural-interface/lib/editor-completion-opencode.js +68 -68
  212. package/neural-interface/lib/editor-git-api.js +3 -20
  213. package/neural-interface/lib/exec-loop-command.js +13 -10
  214. package/neural-interface/lib/file-explorer-api.js +74 -40
  215. package/neural-interface/lib/file-explorer-watch.js +9 -3
  216. package/neural-interface/lib/git-bash/install.js +52 -6
  217. package/neural-interface/lib/git-bash/manager.js +59 -17
  218. package/neural-interface/lib/git-bash/pins.js +12 -0
  219. package/neural-interface/lib/git-read.js +2 -2
  220. package/neural-interface/lib/git-status-runner.js +390 -0
  221. package/neural-interface/lib/git-status-watchdog.js +40 -0
  222. package/neural-interface/lib/greeting/budgets.js +1 -0
  223. package/neural-interface/lib/greeting/engine.js +2 -2
  224. package/neural-interface/lib/greeting/sources.js +10 -12
  225. package/neural-interface/lib/greeting/writer.js +1 -1
  226. package/neural-interface/lib/http-guards.js +8 -2
  227. package/neural-interface/lib/install-details.js +4 -1
  228. package/neural-interface/lib/mcp-agent-servers.js +67 -0
  229. package/neural-interface/lib/mcp-client-config.js +35 -33
  230. package/neural-interface/lib/mcp-external-servers.js +332 -0
  231. package/neural-interface/lib/mcp-installer.js +2 -1
  232. package/neural-interface/lib/{mcp-profile-refresh-coordinator.js → mcp-tools-refresh-coordinator.js} +4 -4
  233. package/neural-interface/lib/memory-session-capture.js +17 -3
  234. package/neural-interface/lib/morelogin.js +177 -25
  235. package/neural-interface/lib/native-loop-providers.js +965 -66
  236. package/neural-interface/lib/native-loop-runtime.js +290 -42
  237. package/neural-interface/lib/opencode-config.js +557 -0
  238. package/neural-interface/lib/opencode-db-schema.js +17 -34
  239. package/neural-interface/lib/opencode-history.js +48 -218
  240. package/neural-interface/lib/opencode-mcp-ready.js +108 -0
  241. package/neural-interface/lib/opencode-native-boundary.js +53 -0
  242. package/neural-interface/lib/opencode-protocol.js +249 -112
  243. package/neural-interface/lib/opencode-runtime-config.js +32 -22
  244. package/neural-interface/lib/opencode-serve-records.js +39 -21
  245. package/neural-interface/lib/opencode-v2-client.js +48 -153
  246. package/neural-interface/lib/opencode-v2-ws-requests.js +36 -210
  247. package/neural-interface/lib/opencode-worker-data.js +27 -0
  248. package/neural-interface/lib/opencode2-client.js +73 -37
  249. package/neural-interface/lib/opencode2-proxy.js +23 -63
  250. package/neural-interface/lib/opencode2-translate.js +51 -2
  251. package/neural-interface/lib/owner-authority.js +249 -0
  252. package/neural-interface/lib/page-session.js +275 -0
  253. package/neural-interface/lib/path-confine.js +12 -9
  254. package/neural-interface/lib/peer-identity.js +793 -0
  255. package/neural-interface/lib/pty-host/core.js +28 -1
  256. package/neural-interface/lib/pty-host/lifetime.js +12 -0
  257. package/neural-interface/lib/pty-host/manager.js +12 -1
  258. package/neural-interface/lib/remote-policy.js +1 -1
  259. package/neural-interface/lib/request-gate.js +20 -2
  260. package/neural-interface/lib/rulesets/api.js +7 -6
  261. package/neural-interface/lib/rulesets/fs-safe.js +1 -1
  262. package/neural-interface/lib/rulesets/installer.js +180 -36
  263. package/neural-interface/lib/rulesets/json-edit.js +1 -1
  264. package/neural-interface/lib/rulesets/render.js +1 -1
  265. package/neural-interface/lib/session-cache-builder.js +81 -31
  266. package/neural-interface/lib/session-title-generator.js +58 -36
  267. package/neural-interface/lib/skills/api-v2.js +495 -0
  268. package/neural-interface/lib/skills/bundle.js +418 -0
  269. package/neural-interface/lib/skills/catalog.js +298 -0
  270. package/neural-interface/lib/skills/creation-api.js +191 -0
  271. package/neural-interface/lib/skills/creation-brief.js +247 -0
  272. package/neural-interface/lib/skills/creation-sources.js +285 -0
  273. package/neural-interface/lib/skills/creation.js +843 -0
  274. package/neural-interface/lib/skills/deploy.js +569 -0
  275. package/neural-interface/lib/skills/digest.js +119 -0
  276. package/neural-interface/lib/skills/discover.js +111 -0
  277. package/neural-interface/lib/skills/draft-confinement.js +216 -0
  278. package/neural-interface/lib/skills/eval-confinement.js +399 -0
  279. package/neural-interface/lib/skills/eval-sandbox.js +280 -0
  280. package/neural-interface/lib/skills/eval-trace.js +135 -0
  281. package/neural-interface/lib/skills/evals-api.js +212 -0
  282. package/neural-interface/lib/skills/evals.js +1573 -0
  283. package/neural-interface/lib/skills/export.js +203 -0
  284. package/neural-interface/lib/skills/frontmatter.js +64 -0
  285. package/neural-interface/lib/skills/health.js +75 -0
  286. package/neural-interface/lib/skills/json-edit.js +165 -0
  287. package/neural-interface/lib/skills/known-bridge-digests.json +441 -0
  288. package/neural-interface/lib/skills/known-bridges.js +96 -0
  289. package/neural-interface/lib/skills/library.js +823 -0
  290. package/neural-interface/lib/skills/local-store.js +21 -0
  291. package/neural-interface/lib/skills/migration.js +433 -0
  292. package/neural-interface/lib/skills/operations.js +45 -0
  293. package/neural-interface/lib/skills/ownership.js +427 -0
  294. package/neural-interface/lib/skills/packages.js +88 -0
  295. package/neural-interface/lib/skills/reviews.js +212 -0
  296. package/neural-interface/lib/skills/revision.js +80 -0
  297. package/neural-interface/lib/skills/roots.js +269 -0
  298. package/neural-interface/lib/skills/runtime-checks.js +358 -0
  299. package/neural-interface/lib/skills/scan-assets.js +252 -0
  300. package/neural-interface/lib/skills/scan-context.js +26 -0
  301. package/neural-interface/lib/skills/scan-shell.js +324 -0
  302. package/neural-interface/lib/skills/scan.js +364 -0
  303. package/neural-interface/lib/skills/scanners.js +54 -0
  304. package/neural-interface/lib/skills/service.js +530 -0
  305. package/neural-interface/lib/skills/telemetry.js +119 -0
  306. package/neural-interface/lib/sqlite-integrity-worker.js +22 -0
  307. package/neural-interface/lib/synabun-version.js +1 -1
  308. package/neural-interface/lib/system-activity.js +1 -1
  309. package/neural-interface/lib/tool-lists.js +124 -0
  310. package/neural-interface/lib/whatsapp/brain.js +7 -3
  311. package/neural-interface/lib/whatsapp/bridge.js +6 -3
  312. package/neural-interface/lib/whatsapp/cards.js +22 -9
  313. package/neural-interface/lib/whatsapp/config.js +1 -1
  314. package/neural-interface/lib/worker-confinement.js +1268 -0
  315. package/neural-interface/lib/worker-guard-setting.js +56 -0
  316. package/neural-interface/lib/worker-mcp-channel.js +175 -0
  317. package/neural-interface/lib/worker-question.js +74 -0
  318. package/neural-interface/lib/worker-relay-ports.js +227 -0
  319. package/neural-interface/lib/worker-resume.js +238 -0
  320. package/neural-interface/lib/worker-sandbox.js +329 -0
  321. package/neural-interface/package-lock.json +34 -12
  322. package/neural-interface/package.json +3 -2
  323. package/neural-interface/public/index.html +3 -1
  324. package/neural-interface/public/index2d.html +19 -11
  325. package/neural-interface/public/onboarding.html +3 -3
  326. package/neural-interface/public/shared/account-menu.js +8 -5
  327. package/neural-interface/public/shared/agent-runtime-options.js +125 -31
  328. package/neural-interface/public/shared/agy/agy-bypass.js +47 -0
  329. package/neural-interface/public/shared/agy/agy-client.js +266 -0
  330. package/neural-interface/public/shared/agy/agy-commands.js +120 -0
  331. package/neural-interface/public/shared/agy/agy-copy.js +326 -0
  332. package/neural-interface/public/shared/agy/agy-diff.js +161 -0
  333. package/neural-interface/public/shared/agy/agy-events.js +469 -0
  334. package/neural-interface/public/shared/agy/agy-greeting.js +26 -0
  335. package/neural-interface/public/shared/agy/agy-options.js +232 -0
  336. package/neural-interface/public/shared/agy/agy-panel.js +2543 -0
  337. package/neural-interface/public/shared/agy/agy-render.js +392 -0
  338. package/neural-interface/public/shared/agy/agy-setup.js +149 -0
  339. package/neural-interface/public/shared/agy/agy-styles.js +604 -0
  340. package/neural-interface/public/shared/agy/agy-tabs-logic.js +181 -0
  341. package/neural-interface/public/shared/api.js +1527 -1336
  342. package/neural-interface/public/shared/app-frame.js +192 -0
  343. package/neural-interface/public/shared/assistant/asst-agents-dock.js +36 -6
  344. package/neural-interface/public/shared/assistant/asst-api.js +1 -1
  345. package/neural-interface/public/shared/assistant/asst-ask-styles.js +270 -0
  346. package/neural-interface/public/shared/assistant/asst-ask-tail.js +118 -0
  347. package/neural-interface/public/shared/assistant/asst-ask.js +397 -0
  348. package/neural-interface/public/shared/assistant/asst-brain-picker.js +105 -44
  349. package/neural-interface/public/shared/assistant/asst-budget.js +5 -4
  350. package/neural-interface/public/shared/assistant/asst-control.js +205 -26
  351. package/neural-interface/public/shared/assistant/asst-followups-card.js +383 -0
  352. package/neural-interface/public/shared/assistant/asst-followups.js +417 -0
  353. package/neural-interface/public/shared/assistant/asst-hosts.js +16 -7
  354. package/neural-interface/public/shared/assistant/asst-limit-dock.js +45 -0
  355. package/neural-interface/public/shared/assistant/asst-limit-wait.js +327 -0
  356. package/neural-interface/public/shared/assistant/asst-limit.js +168 -0
  357. package/neural-interface/public/shared/assistant/asst-mascot.js +49 -12
  358. package/neural-interface/public/shared/assistant/asst-menu.js +7 -6
  359. package/neural-interface/public/shared/assistant/asst-panel.js +151 -19
  360. package/neural-interface/public/shared/assistant/asst-rack-styles.js +66 -49
  361. package/neural-interface/public/shared/assistant/asst-render.js +445 -82
  362. package/neural-interface/public/shared/assistant/asst-route.js +304 -53
  363. package/neural-interface/public/shared/assistant/asst-routes-editor.js +9 -8
  364. package/neural-interface/public/shared/assistant/asst-scenes.js +56 -1
  365. package/neural-interface/public/shared/assistant/asst-sidepanel.js +117 -10
  366. package/neural-interface/public/shared/assistant/asst-slash.js +17 -9
  367. package/neural-interface/public/shared/assistant/asst-state.js +87 -24
  368. package/neural-interface/public/shared/assistant/asst-stop.js +127 -0
  369. package/neural-interface/public/shared/assistant/asst-styles.js +93 -21
  370. package/neural-interface/public/shared/assistant/asst-tool-kinds.js +190 -23
  371. package/neural-interface/public/shared/assistant/asst-usage.js +2 -1
  372. package/neural-interface/public/shared/automation-context.js +5 -2
  373. package/neural-interface/public/shared/cc-dropdown.js +89 -19
  374. package/neural-interface/public/shared/cdx/cdx-context-menu.js +10 -9
  375. package/neural-interface/public/shared/cdx/cdx-copy.js +16 -0
  376. package/neural-interface/public/shared/cdx/cdx-output-model.js +22 -1
  377. package/neural-interface/public/shared/cdx/cdx-output.js +34 -10
  378. package/neural-interface/public/shared/cdx/cdx-panel.js +59 -151
  379. package/neural-interface/public/shared/cdx/cdx-preview.js +12 -0
  380. package/neural-interface/public/shared/cdx/cdx-protocol.js +39 -11
  381. package/neural-interface/public/shared/cdx/cdx-render.js +57 -38
  382. package/neural-interface/public/shared/cdx/cdx-requests.js +14 -4
  383. package/neural-interface/public/shared/cdx/cdx-skill-hints.js +54 -0
  384. package/neural-interface/public/shared/cdx/cdx-styles.js +15 -3
  385. package/neural-interface/public/shared/cdx/cdx-tabs.js +127 -44
  386. package/neural-interface/public/shared/cdx/cdx-ws.js +0 -1
  387. package/neural-interface/public/shared/cli-install-controller.js +218 -0
  388. package/neural-interface/public/shared/cli-install-view.js +11 -12
  389. package/neural-interface/public/shared/cli-status.js +11 -10
  390. package/neural-interface/public/shared/constants.js +5 -4
  391. package/neural-interface/public/shared/context-menu-areas.js +34 -0
  392. package/neural-interface/public/shared/context-menu-logic.js +243 -0
  393. package/neural-interface/public/shared/context-menu-model.js +367 -0
  394. package/neural-interface/public/shared/context-menu.js +372 -0
  395. package/neural-interface/public/shared/cp/cp-context-menu.js +10 -9
  396. package/neural-interface/public/shared/cp/cp-restore.js +162 -0
  397. package/neural-interface/public/shared/cp/cp-tool-cards.js +10 -3
  398. package/neural-interface/public/shared/crash-notice-view.js +168 -0
  399. package/neural-interface/public/shared/desktop-bridge.js +17 -0
  400. package/neural-interface/public/shared/desktop-titlebar-view.js +12 -0
  401. package/neural-interface/public/shared/desktop-titlebar.js +13 -4
  402. package/neural-interface/public/shared/desktop-update-view.js +21 -0
  403. package/neural-interface/public/shared/editor/editor-panel-logic.js +2 -2
  404. package/neural-interface/public/shared/explorer/fx-api.js +4 -4
  405. package/neural-interface/public/shared/explorer/fx-links.js +3 -3
  406. package/neural-interface/public/shared/explorer/fx-logic.js +1 -1
  407. package/neural-interface/public/shared/explorer/fx-main.js +48 -16
  408. package/neural-interface/public/shared/explorer/fx-tree.js +1 -0
  409. package/neural-interface/public/shared/greeting/greeting-card.js +2 -2
  410. package/neural-interface/public/shared/greeting/greeting-view.js +1 -0
  411. package/neural-interface/public/shared/html-shell.js +30 -15
  412. package/neural-interface/public/shared/i18n.js +2 -0
  413. package/neural-interface/public/shared/ocp-v2/ocp-v2-approvals.js +7 -7
  414. package/neural-interface/public/shared/ocp-v2/ocp-v2-binding.js +4 -4
  415. package/neural-interface/public/shared/ocp-v2/ocp-v2-changes-logic.js +3 -101
  416. package/neural-interface/public/shared/ocp-v2/ocp-v2-childpanel.js +2 -0
  417. package/neural-interface/public/shared/ocp-v2/ocp-v2-compact-button.js +1 -3
  418. package/neural-interface/public/shared/ocp-v2/ocp-v2-composer-logic.js +2 -6
  419. package/neural-interface/public/shared/ocp-v2/ocp-v2-context-menu.js +11 -11
  420. package/neural-interface/public/shared/ocp-v2/ocp-v2-context-model.js +0 -3
  421. package/neural-interface/public/shared/ocp-v2/ocp-v2-events.js +8 -4
  422. package/neural-interface/public/shared/ocp-v2/ocp-v2-manager.js +7 -7
  423. package/neural-interface/public/shared/ocp-v2/ocp-v2-outcome-notifications.js +16 -0
  424. package/neural-interface/public/shared/ocp-v2/ocp-v2-panel.js +74 -259
  425. package/neural-interface/public/shared/ocp-v2/ocp-v2-plan.js +1 -2
  426. package/neural-interface/public/shared/ocp-v2/ocp-v2-projectbar.js +95 -202
  427. package/neural-interface/public/shared/ocp-v2/ocp-v2-rehydrate.js +13 -4
  428. package/neural-interface/public/shared/ocp-v2/ocp-v2-render.js +13 -22
  429. package/neural-interface/public/shared/ocp-v2/ocp-v2-send.js +4 -4
  430. package/neural-interface/public/shared/ocp-v2/ocp-v2-session-actions.js +8 -61
  431. package/neural-interface/public/shared/ocp-v2/ocp-v2-sessions-logic.js +2 -91
  432. package/neural-interface/public/shared/ocp-v2/ocp-v2-slash-hints.js +16 -15
  433. package/neural-interface/public/shared/ocp-v2/ocp-v2-state.js +8 -21
  434. package/neural-interface/public/shared/ocp-v2/ocp-v2-status-logic.js +1 -99
  435. package/neural-interface/public/shared/ocp-v2/ocp-v2-status.js +5 -35
  436. package/neural-interface/public/shared/ocp-v2/ocp-v2-styles.js +17 -21
  437. package/neural-interface/public/shared/ocp-v2/{ocp-v2-profile-inheritance.js → ocp-v2-tools-inheritance.js} +16 -16
  438. package/neural-interface/public/shared/ocp-v2/ocp-v2-ws.js +60 -50
  439. package/neural-interface/public/shared/page-session.js +96 -0
  440. package/neural-interface/public/shared/provider-icons.js +4 -2
  441. package/neural-interface/public/shared/registry.js +5 -3
  442. package/neural-interface/public/shared/retired-2d.js +3 -0
  443. package/neural-interface/public/shared/schedules-view.js +195 -61
  444. package/neural-interface/public/shared/settings/settings-claude-hooks.js +135 -0
  445. package/neural-interface/public/shared/settings/settings-data.js +3 -1
  446. package/neural-interface/public/shared/settings/settings-ia.js +6 -6
  447. package/neural-interface/public/shared/settings/settings-opencode.js +89 -0
  448. package/neural-interface/public/shared/settings/settings-rules.js +2 -2
  449. package/neural-interface/public/shared/settings/settings-skill-folders-pane.js +265 -0
  450. package/neural-interface/public/shared/settings/settings-skill-folders.js +130 -0
  451. package/neural-interface/public/shared/settings/settings-worker-guard.js +72 -0
  452. package/neural-interface/public/shared/showcase-privacy.js +6 -1
  453. package/neural-interface/public/shared/sidepanel-session-status.js +3 -3
  454. package/neural-interface/public/shared/skills/ss-args.js +96 -0
  455. package/neural-interface/public/shared/skills/ss-creation.js +222 -0
  456. package/neural-interface/public/shared/skills/ss-dialog.js +133 -0
  457. package/neural-interface/public/shared/skills/ss-doc.js +173 -0
  458. package/neural-interface/public/shared/skills/ss-eval-adapters.js +269 -0
  459. package/neural-interface/public/shared/skills/ss-eval-grade.js +359 -0
  460. package/neural-interface/public/shared/skills/ss-eval-optimise.js +153 -0
  461. package/neural-interface/public/shared/skills/ss-eval-plan.js +315 -0
  462. package/neural-interface/public/shared/skills/ss-evals.js +417 -0
  463. package/neural-interface/public/shared/skills/ss-form.js +159 -0
  464. package/neural-interface/public/shared/skills/ss-frontmatter.js +376 -0
  465. package/neural-interface/public/shared/skills/ss-ids.js +32 -0
  466. package/neural-interface/public/shared/skills/ss-lint.js +149 -0
  467. package/neural-interface/public/shared/skills/ss-presets.js +117 -0
  468. package/neural-interface/public/shared/skills/ss-profiles.js +513 -0
  469. package/neural-interface/public/shared/skills/ss-resources.js +165 -0
  470. package/neural-interface/public/shared/skills/ss-review-view.js +190 -0
  471. package/neural-interface/public/shared/skills/ss-tabs.js +79 -0
  472. package/neural-interface/public/shared/skills/ss-unicode.js +135 -0
  473. package/neural-interface/public/shared/skills/studio/sx-actions.js +222 -0
  474. package/neural-interface/public/shared/skills/studio/sx-cm.js +101 -0
  475. package/neural-interface/public/shared/skills/studio/sx-create-ai-view.js +749 -0
  476. package/neural-interface/public/shared/skills/studio/sx-create-ai.js +237 -0
  477. package/neural-interface/public/shared/skills/studio/sx-create-view.js +254 -0
  478. package/neural-interface/public/shared/skills/studio/sx-create.js +126 -0
  479. package/neural-interface/public/shared/skills/studio/sx-diff-view.js +43 -0
  480. package/neural-interface/public/shared/skills/studio/sx-diff.js +133 -0
  481. package/neural-interface/public/shared/skills/studio/sx-docs.js +480 -0
  482. package/neural-interface/public/shared/skills/studio/sx-dom.js +230 -0
  483. package/neural-interface/public/shared/skills/studio/sx-edit-view.js +848 -0
  484. package/neural-interface/public/shared/skills/studio/sx-editor-model.js +193 -0
  485. package/neural-interface/public/shared/skills/studio/sx-errors.js +22 -0
  486. package/neural-interface/public/shared/skills/studio/sx-fixes-view.js +359 -0
  487. package/neural-interface/public/shared/skills/studio/sx-fixes.js +327 -0
  488. package/neural-interface/public/shared/skills/studio/sx-geometry.js +82 -0
  489. package/neural-interface/public/shared/skills/studio/sx-import.js +262 -0
  490. package/neural-interface/public/shared/skills/studio/sx-inspector.js +308 -0
  491. package/neural-interface/public/shared/skills/studio/sx-install-flow.js +282 -0
  492. package/neural-interface/public/shared/skills/studio/sx-install.js +313 -0
  493. package/neural-interface/public/shared/skills/studio/sx-library-view.js +748 -0
  494. package/neural-interface/public/shared/skills/studio/sx-library.js +479 -0
  495. package/neural-interface/public/shared/skills/studio/sx-main.js +690 -0
  496. package/neural-interface/public/shared/skills/studio/sx-operations-view.js +98 -0
  497. package/neural-interface/public/shared/skills/studio/sx-operations.js +11 -0
  498. package/neural-interface/public/shared/skills/studio/sx-plan.js +158 -0
  499. package/neural-interface/public/shared/skills/studio/sx-publish-view.js +621 -0
  500. package/neural-interface/public/shared/skills/studio/sx-review-view.js +369 -0
  501. package/neural-interface/public/shared/skills/studio/sx-review.js +148 -0
  502. package/neural-interface/public/shared/skills/studio/sx-scan.js +35 -0
  503. package/neural-interface/public/shared/skills/studio/sx-snippets.js +96 -0
  504. package/neural-interface/public/shared/skills/studio/sx-subject.js +249 -0
  505. package/neural-interface/public/shared/skills/studio/sx-test-view.js +994 -0
  506. package/neural-interface/public/shared/skills/studio/sx-test.js +328 -0
  507. package/neural-interface/public/shared/skills/studio/sx-versions-view.js +241 -0
  508. package/neural-interface/public/shared/skills/studio/sx-workspace-view.js +426 -0
  509. package/neural-interface/public/shared/state.js +1 -1
  510. package/neural-interface/public/shared/streaming-markdown.js +58 -0
  511. package/neural-interface/public/shared/styleguide/sg-panel.js +4 -2
  512. package/neural-interface/public/shared/styles.css +1822 -1756
  513. package/neural-interface/public/shared/synabun-mascot.js +1115 -9
  514. package/neural-interface/public/shared/text-cache.js +29 -0
  515. package/neural-interface/public/shared/tool-list-picker.js +55 -0
  516. package/neural-interface/public/shared/tool-list-storage.js +24 -0
  517. package/neural-interface/public/shared/tool-list-view.js +112 -0
  518. package/neural-interface/public/shared/topright-overflow-logic.js +54 -0
  519. package/neural-interface/public/shared/tour/tour-actor.js +268 -0
  520. package/neural-interface/public/shared/tour/tour-beats.js +336 -0
  521. package/neural-interface/public/shared/tour/tour-engine.js +884 -0
  522. package/neural-interface/public/shared/tour/tour-ink.js +390 -0
  523. package/neural-interface/public/shared/tour/tour-stage.js +440 -0
  524. package/neural-interface/public/shared/tour/tour-state.js +40 -0
  525. package/neural-interface/public/shared/tour/tour-tips.js +99 -0
  526. package/neural-interface/public/shared/tour/tour.css +144 -0
  527. package/neural-interface/public/shared/ui-antigravity-panel.js +19 -0
  528. package/neural-interface/public/shared/ui-assistant.js +2 -0
  529. package/neural-interface/public/shared/ui-automation-studio.js +111 -140
  530. package/neural-interface/public/shared/ui-claude-panel.js +376 -82
  531. package/neural-interface/public/shared/ui-cli-banner.js +23 -167
  532. package/neural-interface/public/shared/ui-command-runner.js +6 -3
  533. package/neural-interface/public/shared/ui-context-menu.js +295 -0
  534. package/neural-interface/public/shared/ui-cost-widget.js +57 -59
  535. package/neural-interface/public/shared/ui-crash-notice.js +187 -0
  536. package/neural-interface/public/shared/ui-detail.js +15 -3
  537. package/neural-interface/public/shared/ui-file-explorer.js +48 -6
  538. package/neural-interface/public/shared/ui-file-links.js +2 -2
  539. package/neural-interface/public/shared/ui-games.js +2 -2
  540. package/neural-interface/public/shared/ui-image-gallery.js +50 -47
  541. package/neural-interface/public/shared/ui-judgments.js +1 -1
  542. package/neural-interface/public/shared/ui-keybinds.js +33 -2
  543. package/neural-interface/public/shared/ui-link.js +3 -3
  544. package/neural-interface/public/shared/ui-menubar.js +10 -20
  545. package/neural-interface/public/shared/ui-native-loop-router-state.js +5 -0
  546. package/neural-interface/public/shared/ui-native-loop-router.js +11 -1
  547. package/neural-interface/public/shared/ui-navbar.js +49 -24
  548. package/neural-interface/public/shared/ui-notifications.js +1 -0
  549. package/neural-interface/public/shared/ui-panels.js +96 -65
  550. package/neural-interface/public/shared/ui-resume.js +9 -7
  551. package/neural-interface/public/shared/ui-schedules-studio.js +546 -431
  552. package/neural-interface/public/shared/ui-scroll-follow.js +16 -5
  553. package/neural-interface/public/shared/ui-sessions.js +27 -15
  554. package/neural-interface/public/shared/ui-settings.js +683 -526
  555. package/neural-interface/public/shared/ui-sidepanel-session-entry.js +9 -2
  556. package/neural-interface/public/shared/ui-sidepanel-sessions.js +4 -4
  557. package/neural-interface/public/shared/ui-sidepanel-state.js +23 -12
  558. package/neural-interface/public/shared/ui-sidepanel-tray.js +48 -7
  559. package/neural-interface/public/shared/ui-sidepanel-windows.js +18 -13
  560. package/neural-interface/public/shared/ui-skills.js +33 -2830
  561. package/neural-interface/public/shared/ui-styleguide.js +5 -2
  562. package/neural-interface/public/shared/ui-sync.js +15 -5
  563. package/neural-interface/public/shared/ui-terminal.js +270 -190
  564. package/neural-interface/public/shared/ui-tool-updates.js +6 -4
  565. package/neural-interface/public/shared/ui-tooltip.js +81 -51
  566. package/neural-interface/public/shared/ui-topright-overflow.js +233 -0
  567. package/neural-interface/public/shared/ui-trash.js +6 -4
  568. package/neural-interface/public/shared/ui-tutorial-layout.js +3 -117
  569. package/neural-interface/public/shared/ui-tutorial-preview.js +103 -0
  570. package/neural-interface/public/shared/ui-tutorial-steps.js +3 -65
  571. package/neural-interface/public/shared/ui-tutorial.css +47 -100
  572. package/neural-interface/public/shared/ui-tutorial.js +285 -509
  573. package/neural-interface/public/shared/ui-update.js +38 -2
  574. package/neural-interface/public/shared/ui-whiteboard.js +312 -59
  575. package/neural-interface/public/shared/ui-worker-end.js +5 -1
  576. package/neural-interface/public/shared/ui-workspaces.js +3 -2
  577. package/neural-interface/public/shared/view-variant.js +66 -0
  578. package/neural-interface/public/shared/whatsapp/wa-view.js +3 -3
  579. package/neural-interface/public/shared/whiteboard-list.js +172 -0
  580. package/neural-interface/public/shared/worker-end.js +10 -3
  581. package/neural-interface/public/shared/worker-questions.js +34 -0
  582. package/neural-interface/public/shared/worker-restart.js +12 -0
  583. package/neural-interface/public/sidepanel-session.html +2 -2
  584. package/neural-interface/public/variant/2d/background.js +2 -1
  585. package/neural-interface/public/variant/2d/context-menu.js +8 -2
  586. package/neural-interface/public/variant/2d/graph.js +42 -20
  587. package/neural-interface/public/variant/2d/hulls.js +14 -9
  588. package/neural-interface/public/variant/2d/lasso.js +11 -7
  589. package/neural-interface/public/variant/2d/main.js +32 -1
  590. package/neural-interface/public/variant/2d/minimap.js +11 -13
  591. package/neural-interface/public/variant/3d/main.js +69 -6
  592. package/neural-interface/public/variant/3d/map-controls.js +24 -9
  593. package/neural-interface/public/vendor/caveat/OFL.txt +93 -0
  594. package/neural-interface/public/vendor/caveat/caveat-latin-400-normal.woff2 +0 -0
  595. package/neural-interface/public/vendor/caveat/caveat-latin-700-normal.woff2 +0 -0
  596. package/neural-interface/public/vendor/caveat/caveat.css +17 -0
  597. package/neural-interface/public/vendor/caveat/manifest.json +12 -0
  598. package/neural-interface/public/vendor/yaml/LICENSE +13 -0
  599. package/neural-interface/public/vendor/yaml/manifest.json +4 -0
  600. package/neural-interface/public/vendor/yaml/yaml-2.9.1.min.js +137 -0
  601. package/neural-interface/scripts/build-vendor.mjs +32 -0
  602. package/neural-interface/server.js +4553 -2855
  603. package/neural-interface/templates/rulesets/README.md +1 -1
  604. package/neural-interface/templates/rulesets/core.md +1 -1
  605. package/neural-interface/templates/rulesets/legacy-hashes.json +23 -5
  606. package/neural-interface/templates/rulesets/manifest.json +8 -8
  607. package/npm-shrinkwrap.json +34 -12
  608. package/package.json +17 -3
  609. package/postinstall.js +9 -4
  610. package/preuninstall.js +1 -1
  611. package/setup.js +97 -322
  612. package/skills/skill-forge/SKILL.md +177 -0
  613. package/skills/skill-forge/evals/evals.json +54 -0
  614. package/skills/skill-forge/references/package.md +105 -0
  615. package/skills/skill-forge/references/review-and-recovery.md +63 -0
  616. package/skills/skill-forge/references/runtime-profiles.md +20 -0
  617. package/skills/skill-forge/references/sources-and-capabilities.md +51 -0
  618. package/skills/synabun/SKILL.md +10 -7
  619. package/skills/synabun/modules/audit.md +1 -5
  620. package/skills/synabun/modules/changelog.md +1 -5
  621. package/skills/synabun/modules/idea.md +1 -1
  622. package/skills/synabun/modules/memorize.md +6 -9
  623. package/skills/synabun/modules/schedule.md +6 -6
  624. package/mcp-server/dist/services/profiles.d.ts +0 -120
  625. package/mcp-server/dist/services/profiles.d.ts.map +0 -1
  626. package/mcp-server/dist/services/profiles.js +0 -387
  627. package/mcp-server/dist/services/profiles.js.map +0 -1
  628. package/mcp-server/dist/tools/leonardo-browser-tools.d.ts +0 -97
  629. package/mcp-server/dist/tools/leonardo-browser-tools.d.ts.map +0 -1
  630. package/mcp-server/dist/tools/leonardo-browser-tools.js +0 -228
  631. package/mcp-server/dist/tools/leonardo-browser-tools.js.map +0 -1
  632. package/mcp-server/dist/tools/leonardo.d.ts +0 -13
  633. package/mcp-server/dist/tools/leonardo.d.ts.map +0 -1
  634. package/mcp-server/dist/tools/leonardo.js +0 -21
  635. package/mcp-server/dist/tools/leonardo.js.map +0 -1
  636. package/mcp-server/dist/tools/profile.d.ts +0 -17
  637. package/mcp-server/dist/tools/profile.d.ts.map +0 -1
  638. package/mcp-server/dist/tools/profile.js +0 -114
  639. package/mcp-server/dist/tools/profile.js.map +0 -1
  640. package/mcp-server/src/services/profiles.ts +0 -428
  641. package/mcp-server/src/tools/leonardo-browser-tools.ts +0 -291
  642. package/mcp-server/src/tools/leonardo.ts +0 -30
  643. package/mcp-server/src/tools/profile.ts +0 -122
  644. package/neural-interface/lib/assistant-brains/opencode-browser-policy.js +0 -47
  645. package/neural-interface/lib/assistant-brains/opencode-route-gate.js +0 -62
  646. package/neural-interface/lib/mcp-profile-servers.js +0 -120
  647. package/neural-interface/public/shared/ui-tutorial-draw.js +0 -311
  648. package/skills/leonardo/SKILL.md +0 -168
  649. package/skills/leonardo/icon.svg +0 -1
  650. package/skills/leonardo/modules/browser-guide.md +0 -378
  651. package/skills/leonardo/modules/image-prompter.md +0 -283
  652. package/skills/leonardo/modules/model-advisor.md +0 -100
  653. package/skills/leonardo/modules/prompt-library.md +0 -110
  654. package/skills/leonardo/modules/style-guide.md +0 -186
  655. package/skills/leonardo/modules/video-prompter.md +0 -317
  656. /package/neural-interface/templates/rulesets/{gemini.md → antigravity.md} +0 -0
@@ -236,7 +236,10 @@ export function fileChangeDiffs(item = {}) {
236
236
  if (raw && (/^(?:diff --git |--- )/m.test(raw) || changes.length <= 1 && /^@@ /m.test(raw))) return parseUnifiedDiff(raw, changes.length === 1 ? changeInfo(changes[0]) : {});
237
237
  const files = changes.slice(0, OUTPUT_LIMITS.files).flatMap(change => {
238
238
  const info = changeInfo(change);
239
- const patch = change.diff || change.patch || change.content || change.output || '';
239
+ const patch = change.diff ?? change.patch ?? change.content ?? change.output;
240
+ if ((info.status === 'added' || info.status === 'deleted') && typeof patch === 'string') {
241
+ return [wholeFileDiff(patch, info)];
242
+ }
240
243
  if (!patch) return [{ ...info, lines: [], hunks: [], added: 0, removed: 0, raw: '', unavailable: true }];
241
244
  return parseUnifiedDiff(typeof patch === 'string' ? patch : readableStructuredValue(patch), info);
242
245
  });
@@ -244,6 +247,24 @@ export function fileChangeDiffs(item = {}) {
244
247
  return files;
245
248
  }
246
249
 
250
+ function wholeFileDiff(content, info) {
251
+ const added = info.status === 'added';
252
+ const text = content.replace(/\r\n/g, '\n');
253
+ const lines = text === '' ? [] : text.split('\n');
254
+ if (text.endsWith('\n')) lines.pop();
255
+ const sign = added ? '+' : '-';
256
+ const raw = `@@ -${added ? '0,0' : `1,${lines.length}`} +${added ? `1,${lines.length}` : '0,0'} @@\n`
257
+ + lines.map(line => `${sign}${line}\n`).join('')
258
+ + (text && !text.endsWith('\n') ? '\\n' : '');
259
+ const oversized = content.length > OUTPUT_LIMITS.input || lines.length > OUTPUT_LIMITS.diffLines;
260
+ return { ...info, lines: oversized ? [] : lines.map((text, i) => ({
261
+ kind: added ? 'add' : 'delete', sign, text,
262
+ oldLine: added ? null : i + 1, newLine: added ? i + 1 : null,
263
+ })), hunks: [{ oldStart: added ? 0 : 1, newStart: added ? 1 : 0 }],
264
+ added: added ? lines.length : 0, removed: added ? 0 : lines.length,
265
+ raw, oversized };
266
+ }
267
+
247
268
  function changeInfo(change) {
248
269
  const kind = typeof change.kind === 'object' ? change.kind : { type: change.kind || change.type };
249
270
  const moved = kind.move_path || kind.movePath || change.newPath;
@@ -1,3 +1,4 @@
1
+ import { cxpText } from './cdx-copy.js';
1
2
  import { OUTPUT_LIMITS, boundedText, cleanTerminal, jsonAnswer, looksLikeStreamingJson, isPreformattedText, structuredValueModel, readableStructuredValue, parseUnifiedDiff, hasOverlongRun, outputOverflows, displayDiffPath } from './cdx-output-model.js';
2
3
 
3
4
  const sources = new WeakMap();
@@ -5,7 +6,7 @@ const bound = new WeakSet();
5
6
  const diffStates = new WeakMap();
6
7
  const pending = new WeakMap();
7
8
  const cleaned = new WeakMap();
8
- const watched = new WeakSet();
9
+ const watched = new WeakMap(); // transcript -> teardown (including queued mutation work)
9
10
  const observer = typeof IntersectionObserver === 'function' ? new IntersectionObserver(entries => {
10
11
  for (const entry of entries) if (entry.isIntersecting) { pending.get(entry.target)?.(); observer.unobserve(entry.target); pending.delete(entry.target); }
11
12
  }, { rootMargin: '200px' }) : null;
@@ -22,6 +23,7 @@ const measurements = new WeakMap();
22
23
  const measurementQueue = new Set();
23
24
  let measurementFrame = false, capId = 0;
24
25
  function queueMeasurement(el) {
26
+ if (!measurements.has(el)) return;
25
27
  measurementQueue.add(el);
26
28
  if (measurementFrame) return;
27
29
  measurementFrame = true;
@@ -49,6 +51,7 @@ function measureChanges(el, update) {
49
51
  }
50
52
  function releaseMeasurements(root) {
51
53
  for (const el of [root, ...(root.querySelectorAll?.('*') || [])]) {
54
+ observer?.unobserve(el); pending.delete(el);
52
55
  sizeObserver?.unobserve(el); contentObservers.get(el)?.disconnect();
53
56
  contentObservers.delete(el); measurements.delete(el); measurementQueue.delete(el);
54
57
  }
@@ -193,7 +196,7 @@ export function hydrateOutputControls(container) {
193
196
  watchCaps(root);
194
197
  } else if (button.dataset.outputAction === 'copy') {
195
198
  const text = sources.get(root)?.text ?? root.dataset.original ?? diffStates.get(root)?.raw ?? root.querySelector('.cxp-diff-source')?.textContent ?? '';
196
- navigator.clipboard.writeText(text).then(() => { button.textContent = 'Copied'; setTimeout(() => { button.textContent = root.classList.contains('cxp-diff-view') ? 'Copy patch' : 'Copy'; }, 1500); }).catch(() => {});
199
+ navigator.clipboard.writeText(text).then(() => { button.textContent = 'Copied'; setTimeout(() => { button.textContent = root.classList.contains('cxp-diff-view') ? cxpText('copyPatch', 'Copy patch') : 'Copy'; }, 1500); }).catch(() => {});
197
200
  }
198
201
  event.stopPropagation();
199
202
  });
@@ -248,11 +251,13 @@ export function cleanOutputBlocks(container) {
248
251
  // Covers generic/legacy cards and request builders which assign pre.textContent
249
252
  // directly. Observe each transcript once; our own writes settle after one pass.
250
253
  export function observeOutputBlocks(container) {
251
- if (!container || watched.has(container) || typeof MutationObserver !== 'function') return;
252
- watched.add(container);
254
+ if (!container || typeof MutationObserver !== 'function') return;
255
+ if (watched.has(container)) return watched.get(container);
253
256
  let queued = false;
257
+ let disposed = false;
254
258
  const dirty = new Set();
255
259
  const watcher = new MutationObserver(records => {
260
+ if (disposed) return;
256
261
  for (const record of records) {
257
262
  for (const removed of record.removedNodes || []) if (removed.nodeType === 1 && !removed.isConnected) releaseMeasurements(removed);
258
263
  const target = record.target.nodeType === 1 ? record.target : record.target.parentElement;
@@ -264,6 +269,7 @@ export function observeOutputBlocks(container) {
264
269
  queued = true;
265
270
  queueMicrotask(() => {
266
271
  queued = false;
272
+ if (disposed) return;
267
273
  for (const root of dirty) {
268
274
  if (root.matches?.('pre, .cxp-card-pre') && !root.closest('.cxp-readable, .cxp-output-source, .cxp-diff-view') && !root.querySelector('.cxp-readable')) {
269
275
  const code = root.querySelector('code');
@@ -275,6 +281,24 @@ export function observeOutputBlocks(container) {
275
281
  });
276
282
  });
277
283
  watcher.observe(container, { childList: true, characterData: true, subtree: true });
284
+ const dispose = () => {
285
+ disposed = true;
286
+ watcher.disconnect();
287
+ dirty.clear();
288
+ watched.delete(container);
289
+ releaseMeasurements(container);
290
+ };
291
+ watched.set(container, dispose);
292
+ return dispose;
293
+ }
294
+
295
+ // Removing a whole transcript does not produce a mutation *inside* it. Both
296
+ // global observers must release its outputs and lazy diffs explicitly on close.
297
+ export function disposeOutputBlocks(container) {
298
+ if (!container) return;
299
+ const dispose = watched.get(container);
300
+ if (dispose) dispose();
301
+ else releaseMeasurements(container);
278
302
  }
279
303
 
280
304
  function diffRows(file, target, count) {
@@ -310,19 +334,19 @@ export function renderDiffView(container, files, { lazy = false, cwd = container
310
334
  if (!state) {
311
335
  state = { entries: new Map(), raw: '' }; diffStates.set(container, state);
312
336
  const controls = node('div', 'cxp-output-controls');
313
- const copy = node('button', 'cxp-output-control', 'Copy patch'); copy.type = 'button'; copy.dataset.outputAction = 'copy'; controls.append(copy);
337
+ const copy = node('button', 'cxp-output-control', cxpText('copyPatch', 'Copy patch')); copy.type = 'button'; copy.dataset.outputAction = 'copy'; controls.append(copy);
314
338
  const source = node('pre', 'cxp-diff-source'); source.hidden = true;
315
339
  if (summaryEl) controls.insertBefore(summaryEl, copy);
316
340
  else controls.insertBefore(node('div', 'cxp-card-meta'), copy);
317
341
  container.replaceChildren(controls, source); hydrateOutputControls(container);
318
342
  }
319
343
  const summary = container.querySelector('.cxp-output-controls .cxp-card-meta');
320
- if (summary && !summaryEl) summary.textContent = `${files.length} file change${files.length === 1 ? '' : 's'}`;
344
+ if (summary && !summaryEl) summary.textContent = cxpText(files.length === 1 ? 'oneFileChange' : 'fileChanges', files.length === 1 ? '1 file change' : '{count} file changes', { count: files.length });
321
345
  state.raw = files.map(file => file.raw || '').join('\n');
322
346
  let filesNote = container.querySelector('.cxp-diff-files-note');
323
347
  if (!filesNote) { filesNote = node('div', 'cxp-output-note cxp-diff-files-note'); container.append(filesNote); }
324
348
  filesNote.hidden = !files.some(file => file.filesTruncated);
325
- filesNote.textContent = 'Remaining files omitted: preview limited to 100 files.';
349
+ filesNote.textContent = cxpText('filesLimit', 'Remaining files omitted: preview limited to 100 files.');
326
350
  const serialized = files.map(file => file.raw?.startsWith('diff --git ') ? file.raw : `diff --git a/${file.oldPath || file.path} b/${file.path}\n${file.status === 'renamed' ? `rename from ${file.oldPath}\nrename to ${file.path}\n` : ''}--- ${file.status === 'added' ? '/dev/null' : `a/${file.oldPath || file.path}`}\n+++ ${file.status === 'deleted' ? '/dev/null' : `b/${file.path}`}\n${file.raw || ''}`).join('\n');
327
351
  container.querySelector('.cxp-diff-source').textContent = boundedText(serialized, OUTPUT_LIMITS.input);
328
352
  const retained = new Set();
@@ -341,11 +365,11 @@ export function renderDiffView(container, files, { lazy = false, cwd = container
341
365
  const f = entry.file;
342
366
  if (!f) return;
343
367
  entry.built = true;
344
- const message = f.binary ? 'Binary file; text diff unavailable.' : f.oversized ? 'Oversized patch; rendering omitted (200,000 characters / 2,000 lines per file limit). Raw patch is copyable.' : f.unavailable || !f.lines.length && !f.hunks.length && f.status !== 'renamed' ? 'Patch not supplied or not a unified diff.' : '';
368
+ const message = f.binary ? cxpText('binary', 'Binary file; text diff unavailable.') : f.oversized ? cxpText('oversized', 'Oversized patch; rendering omitted (200,000 characters / 2,000 lines per file limit). Raw patch is copyable.') : f.unavailable || !f.lines.length && !f.hunks.length && f.status !== 'renamed' ? cxpText('patchMissing', 'Patch not supplied or not a unified diff.') : '';
345
369
  entry.note.textContent = message; entry.note.hidden = !message;
346
370
  diffRows(f, entry.rows, message ? 0 : entry.full ? OUTPUT_LIMITS.diffLines : OUTPUT_LIMITS.diffPreview);
347
371
  entry.more.hidden = !!message || f.lines.length <= OUTPUT_LIMITS.diffPreview;
348
- entry.more.textContent = entry.full ? 'Show fewer lines' : `Show full diff (${f.lines.length} lines)`;
372
+ entry.more.textContent = entry.full ? cxpText('fewerLines', 'Show fewer lines') : cxpText('fullDiff', 'Show full diff ({count} lines)', { count: f.lines.length });
349
373
  watchCap(entry.rows);
350
374
  };
351
375
  entry.build = build;
@@ -361,7 +385,7 @@ export function renderDiffView(container, files, { lazy = false, cwd = container
361
385
  entry.path.title = file.status === 'renamed' ? `${file.oldPath} → ${file.path}` : file.path;
362
386
  measureChanges(entry.path, () => fitDiffPath(entry.path, entry.file, container.dataset.cwd));
363
387
  fitDiffPath(entry.path, file, cwd);
364
- entry.status.textContent = file.status;
388
+ entry.status.textContent = cxpText(`diff_${file.status}`, file.status);
365
389
  entry.stats.textContent = `+${file.added} −${file.removed}`;
366
390
  if (entry.built || !lazy || !observer) { if (entry.details.open || entry.built) entry.build(); }
367
391
  else { pending.set(entry.details, entry.build); observer.observe(entry.details); }
@@ -1,6 +1,11 @@
1
+ import { syncWorkerQuestions } from '../worker-questions.js';
2
+ import { handleServerRequest, resolveRequestCard } from './cdx-requests.js';
3
+ import { cxpText, cxpSessionLabel, setCodexTranslator } from './cdx-copy.js';
1
4
  // SynaBun — Codex Panel: DOM, Events & Lifecycle
2
5
  // ═══════════════════════════════════════════
3
6
 
7
+ import { workerRestart } from '../worker-restart.js';
8
+ import { t } from '../i18n.js';
4
9
  import { storage } from '../storage.js';
5
10
  import { state, emit, on } from '../state.js';
6
11
  import { registerSidepanel, setSidepanelVisible, sidepanelAcceptsKeyboard, openAnotherSidepanelSession } from '../ui-sidepanel-windows.js';
@@ -8,6 +13,7 @@ import { mountCliBanner } from '../ui-cli-banner.js';
8
13
  import { nativeLoopWindowId } from '../ui-native-window-id.js';
9
14
  import { createStickyScrollController, getStickyScrollController } from '../ui-scroll-follow.js';
10
15
  import { wireFileLinks } from '../ui-file-links.js';
16
+ import { frameRect } from '../app-frame.js';
11
17
  import { trackWorkerEnd } from '../ui-worker-end.js';
12
18
  import { isDispatchedRun } from '../worker-end.js';
13
19
  import { runAwaitsAnswer } from '../sidepanel-session-status.js';
@@ -255,6 +261,8 @@ export function panelEl(selector) {
255
261
  // buildPanel — DOM Construction
256
262
  // ═══════════════════════════════════════════
257
263
 
264
+ setCodexTranslator(t);
265
+
258
266
  function buildPanel() {
259
267
  const panel = document.createElement('div');
260
268
  panel.id = 'codex-panel';
@@ -262,18 +270,18 @@ function buildPanel() {
262
270
  panel.innerHTML = `
263
271
  <div class="cxp-resize-handle"></div>
264
272
  <div class="cxp-header">
265
- <button class="cxp-session-btn" id="cxp-session-btn" type="button" title="${esc(_sessionLabel)}">
266
- <span class="cxp-session-label" id="cxp-session-label">${esc(_sessionLabel)}</span>
273
+ <button class="cxp-session-btn" id="cxp-session-btn" type="button" title="${esc(cxpSessionLabel(_sessionLabel))}">
274
+ <span class="cxp-session-label" id="cxp-session-label">${esc(cxpSessionLabel(_sessionLabel))}</span>
267
275
  <span class="cxp-dd-arrow">&#x25BE;</span>
268
276
  </button>
269
- <button class="cxp-header-rename" id="cxp-header-rename" type="button" title="Rename session">
277
+ <button class="cxp-header-rename" id="cxp-header-rename" type="button" title="${cxpText('rename', 'Rename session')}">
270
278
  ${ICON_EDIT}
271
279
  </button>
272
280
  <div class="cxp-actions">
273
- <button class="cxp-btn" id="cxp-new" title="New Codex tab">${ICON_PLUS}</button>
274
- <button class="cxp-btn" id="cxp-minimize" title="Minimize to pill">${ICON_MINIMIZE}</button>
275
- <button class="cxp-btn cxp-btn-danger" id="cxp-close" title="Close current tab">${ICON_X}</button>
276
- <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>
281
+ <button class="cxp-btn" id="cxp-new" title="${cxpText('newTab', 'New Codex tab')}">${ICON_PLUS}</button>
282
+ <button class="cxp-btn" id="cxp-minimize" title="${cxpText('minimize', 'Minimize to pill')}">${ICON_MINIMIZE}</button>
283
+ <button class="cxp-btn cxp-btn-danger" id="cxp-close" title="${cxpText('closeTab', 'Close current tab')}">${ICON_X}</button>
284
+ <button class="cxp-btn" id="cxp-slide" title="${cxpText('slide', 'Slide panel')}"><svg viewBox="0 0 24 24"><polyline points="9 18 15 12 9 6"/></svg></button>
277
285
  </div>
278
286
  <div class="cxp-session-menu" id="cxp-session-menu"></div>
279
287
  </div>
@@ -290,28 +298,23 @@ function buildPanel() {
290
298
  <div class="cxp-queue-list" id="cxp-queue-list"></div>
291
299
  </div>
292
300
  <div class="cxp-projectbar">
293
- <div class="cxp-dropdown" id="cxp-project" data-placeholder="project..." data-tooltip="Project">
301
+ <div class="cxp-dropdown" id="cxp-project" data-placeholder="project..." data-tooltip="${cxpText('project', 'Project')}">
294
302
  <span class="cxp-dd-label">project...</span>
295
303
  <span class="cxp-dd-arrow">&#x25BE;</span>
296
304
  <div class="cxp-dd-menu"></div>
297
305
  </div>
298
- <div class="cxp-dropdown cxp-dropdown-sm" id="cxp-branch" data-placeholder="branch" data-tooltip="Branch">
306
+ <div class="cxp-dropdown cxp-dropdown-sm" id="cxp-branch" data-placeholder="branch" data-tooltip="${cxpText('branch', 'Branch')}">
299
307
  <span class="cxp-dd-label">branch</span>
300
308
  <span class="cxp-dd-arrow">&#x25BE;</span>
301
309
  <div class="cxp-dd-menu"></div>
302
310
  </div>
303
- <div class="cxp-dropdown cxp-dropdown-sm" id="cxp-profile" data-placeholder="profile" data-tooltip="Tool profile">
304
- <span class="cxp-dd-label">full</span>
305
- <span class="cxp-dd-arrow">&#x25BE;</span>
306
- <div class="cxp-dd-menu"></div>
307
- </div>
308
- <div class="cxp-dropdown cxp-dropdown-sm" id="cxp-recall" data-placeholder="recall" data-tooltip="Recall profile">
311
+ <div class="cxp-dropdown cxp-dropdown-sm" id="cxp-recall" data-placeholder="recall" data-tooltip="${cxpText('recallProfile', 'Recall profile')}">
309
312
  <span class="cxp-dd-label">recall</span>
310
313
  <span class="cxp-dd-arrow">&#x25BE;</span>
311
314
  <div class="cxp-dd-menu"></div>
312
315
  </div>
313
316
  <div class="cxp-projectbar-actions">
314
- <button class="cxp-bar-action" id="cxp-action-changelog" title="Generate changelog"><svg viewBox="0 0 16 16" width="12" height="12" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 1.5h8.5v13H4a1.5 1.5 0 01-1.5-1.5V3A1.5 1.5 0 014 1.5z"/><path d="M5.5 5h5M5.5 7.5h3M5.5 10h4"/></svg></button>
317
+ <button class="cxp-bar-action" id="cxp-action-changelog" title="${cxpText('changelog', 'Generate changelog')}"><svg viewBox="0 0 16 16" width="12" height="12" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 1.5h8.5v13H4a1.5 1.5 0 01-1.5-1.5V3A1.5 1.5 0 014 1.5z"/><path d="M5.5 5h5M5.5 7.5h3M5.5 10h4"/></svg></button>
315
318
  </div>
316
319
  </div>
317
320
  <div class="cxp-image-strip" id="cxp-image-strip" hidden></div>
@@ -319,11 +322,11 @@ function buildPanel() {
319
322
  <div class="cxp-input-wrap">
320
323
  <div class="cxp-input-shell">
321
324
  <input type="file" id="cxp-file-input" accept="image/*" multiple hidden />
322
- <textarea class="cxp-input" id="cxp-input" rows="1" placeholder="Message Codex…" spellcheck="false"></textarea>
323
- <button class="cxp-mic-btn" id="cxp-mic-btn" title="Hold to talk" hidden>
325
+ <textarea class="cxp-input" id="cxp-input" rows="1" placeholder="${cxpText('message', 'Message Codex…')}" spellcheck="false"></textarea>
326
+ <button class="cxp-mic-btn" id="cxp-mic-btn" title="${cxpText('talk', 'Hold to talk')}" hidden>
324
327
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><rect x="9" y="1" width="6" height="11" rx="3"/><path d="M5 10a7 7 0 0 0 14 0"/><path d="M12 17v4M8 21h8"/></svg>
325
328
  </button>
326
- <button class="cxp-send" id="cxp-send" disabled title="Send">
329
+ <button class="cxp-send" id="cxp-send" disabled title="${cxpText('send', 'Send')}">
327
330
  <svg class="cxp-send-icon" viewBox="0 0 24 24"><path d="M12 5v14"/><path d="m5 12 7-7 7 7"/></svg>
328
331
  <svg class="cxp-stop-icon" viewBox="0 0 24 24" style="display:none"><rect x="7" y="7" width="10" height="10" rx="2"/></svg>
329
332
  </button>
@@ -332,21 +335,21 @@ function buildPanel() {
332
335
  <div class="cxp-slash-hints" id="cxp-slash-hints" hidden></div>
333
336
  <div class="cxp-footer-toolbar">
334
337
  <div class="cxp-footer-left">
335
- <a class="cxp-brand-link" href="https://chatgpt.com/codex/settings/usage" target="_blank" rel="noopener noreferrer" title="Open Codex usage settings">
338
+ <a class="cxp-brand-link" href="https://chatgpt.com/codex/settings/usage" target="_blank" rel="noopener noreferrer" title="${cxpText('usage', 'Open Codex usage settings')}">
336
339
  <svg class="cxp-brand" viewBox="0 0 24 24" width="16" height="16" fill="currentColor"><path d="M22.282 9.821a5.985 5.985 0 0 0-.516-4.91 6.046 6.046 0 0 0-6.51-2.9A6.065 6.065 0 0 0 4.981 4.18a5.998 5.998 0 0 0-3.998 2.9 6.046 6.046 0 0 0 .743 7.097 5.98 5.98 0 0 0 .51 4.911 6.051 6.051 0 0 0 6.515 2.9A5.985 5.985 0 0 0 13.26 24a6.056 6.056 0 0 0 5.772-4.206 5.99 5.99 0 0 0 3.997-2.9 6.056 6.056 0 0 0-.747-7.073zM13.26 22.43a4.476 4.476 0 0 1-2.876-1.04l.141-.081 4.779-2.758a.795.795 0 0 0 .392-.681v-6.737l2.02 1.168a.071.071 0 0 1 .038.052v5.583a4.504 4.504 0 0 1-4.494 4.494zM3.6 18.304a4.47 4.47 0 0 1-.535-3.014l.142.085 4.783 2.759a.771.771 0 0 0 .78 0l5.843-3.369v2.332a.08.08 0 0 1-.033.062L9.74 19.95a4.5 4.5 0 0 1-6.14-1.646zM2.34 7.896a4.485 4.485 0 0 1 2.366-1.973V11.6a.766.766 0 0 0 .388.676l5.815 3.355-2.02 1.168a.076.076 0 0 1-.071 0l-4.83-2.786A4.504 4.504 0 0 1 2.34 7.872zm16.597 3.855l-5.833-3.387L15.119 7.2a.076.076 0 0 1 .071 0l4.83 2.791a4.494 4.494 0 0 1-.676 8.105v-5.678a.79.79 0 0 0-.407-.667zm2.01-3.023l-.141-.085-4.774-2.782a.776.776 0 0 0-.785 0L9.409 9.23V6.897a.066.066 0 0 1 .028-.061l4.83-2.787a4.5 4.5 0 0 1 6.68 4.66zm-12.64 4.135l-2.02-1.164a.08.08 0 0 1-.038-.057V6.075a4.5 4.5 0 0 1 7.375-3.453l-.142.08L8.704 5.46a.795.795 0 0 0-.393.681zm1.097-2.365l2.602-1.5 2.607 1.5v2.999l-2.597 1.5-2.607-1.5z"/></svg>
337
340
  </a>
338
- <button class="cxp-attach-btn" id="cxp-attach-btn" title="Attach images">
341
+ <button class="cxp-attach-btn" id="cxp-attach-btn" title="${cxpText('attach', 'Attach images')}">
339
342
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48"/></svg>
340
343
  </button>
341
344
  </div>
342
345
  <div class="cxp-footer-right">
343
346
  <div class="cxp-effort-wrap">
344
- <button class="cxp-toolbar-toggle" id="cxp-effort-toggle" title="Reasoning effort" data-effort="off" type="button">${ICON_BRAIN}<span class="cxp-btn-label">Effort</span><span class="cxp-effort-dots"><i></i><i></i><i></i><i></i><i></i></span></button>
347
+ <button class="cxp-toolbar-toggle" id="cxp-effort-toggle" title="${cxpText('effort', 'Reasoning effort')}" data-effort="off" type="button">${ICON_BRAIN}<span class="cxp-btn-label">${cxpText('effortLabel', 'Effort')}</span><span class="cxp-effort-dots"><i></i><i></i><i></i><i></i><i></i></span></button>
345
348
  <div class="cxp-effort-menu" id="cxp-effort-menu"></div>
346
349
  </div>
347
- <button class="cxp-toolbar-toggle" id="cxp-plan-toggle" title="Plan mode: off">${ICON_PLAN}<span class="cxp-btn-label">Plan</span></button>
348
- <button class="cxp-toolbar-toggle" id="cxp-autoaccept-toggle" title="Auto-accept: off">${ICON_SHIELD}<span class="cxp-btn-label">Auto</span></button>
349
- <button class="cxp-toolbar-toggle" id="cxp-context-toggle" type="button" aria-pressed="false" title="Context: provider default">${ICON_SPARK}<span class="cxp-btn-label">Default</span></button>
350
+ <button class="cxp-toolbar-toggle" id="cxp-plan-toggle" title="${cxpText('planOff', 'Plan mode: off')}">${ICON_PLAN}<span class="cxp-btn-label">${cxpText('plan', 'Plan')}</span></button>
351
+ <button class="cxp-toolbar-toggle" id="cxp-autoaccept-toggle" title="${cxpText('autoOff', 'Auto-accept: off')}">${ICON_SHIELD}<span class="cxp-btn-label">${cxpText('auto', 'Auto')}</span></button>
352
+ <button class="cxp-toolbar-toggle" id="cxp-context-toggle" type="button" aria-pressed="false" title="${cxpText('contextDefault', 'Context: provider default')}">${ICON_SPARK}<span class="cxp-btn-label">${cxpText('default', 'Default')}</span></button>
350
353
  <button class="cxp-toolbar-toggle" id="cxp-context-retry" type="button" hidden aria-label="Retry model capabilities" title="Reload model capabilities">Retry</button>
351
354
  <div class="cxp-dropdown" id="cxp-model" data-placeholder="model...">
352
355
  <span class="cxp-dd-label">model...</span>
@@ -518,7 +521,6 @@ function applyVisibility(nextVisible) {
518
521
  if (!_tabs.length) createTab({ project: storage.getItem(STOR.project) || '' });
519
522
  state.lastActivePanel = 'codex';
520
523
  updateActiveTabView();
521
- loadCurrentProfile();
522
524
  loadRecallProfile();
523
525
  panelEl('#cxp-input')?.focus();
524
526
  refreshCliBanner();
@@ -551,111 +553,6 @@ async function loadBranches(path) {
551
553
  } catch {}
552
554
  }
553
555
 
554
- // ═══════════════════════════════════════════
555
- // MCP Profile — live profile switching
556
- // ═══════════════════════════════════════════
557
-
558
- let _mcpProfiles = [];
559
- let _currentProfile = 'full';
560
- let _defaultMcpProfile = 'full';
561
-
562
- function mcpProfileItemsFromPresets(presets) {
563
- if (!presets || typeof presets !== 'object') return null;
564
- return Object.entries(presets).map(([value, p]) => ({
565
- value,
566
- label: p?.label || value,
567
- hint: `${p?.tools || '?'} tools`,
568
- }));
569
- }
570
-
571
- function applyMcpProfileState(profile, presets) {
572
- if (profile) _currentProfile = profile;
573
- const items = mcpProfileItemsFromPresets(presets);
574
- if (items) _mcpProfiles = items;
575
- const $profile = panelEl('#cxp-profile');
576
- if ($profile) populateProfileDropdown($profile);
577
- }
578
-
579
- async function loadCurrentProfile() {
580
- const $profile = panelEl('#cxp-profile');
581
- if (!$profile) return;
582
- try {
583
- const resp = await fetch('/api/mcp/profile');
584
- const data = await resp.json();
585
- if (data.ok) {
586
- _defaultMcpProfile = data.defaultProfile || data.profile || 'full';
587
- const tab = activeTab();
588
- if (tab && !tab.mcpProfile) {
589
- tab.mcpProfile = _defaultMcpProfile;
590
- saveTabs();
591
- }
592
- applyMcpProfileState(tab?.mcpProfile || _defaultMcpProfile, data.presets);
593
- return;
594
- }
595
- } catch {}
596
- populateProfileDropdown($profile);
597
- }
598
-
599
- function populateProfileDropdown($dd) {
600
- const menu = $dd.querySelector('.cxp-dd-menu');
601
- const label = $dd.querySelector('.cxp-dd-label');
602
- if (!menu || !label) return;
603
- menu.innerHTML = '';
604
- const matched = _mcpProfiles.find(p => p.value === _currentProfile);
605
- label.textContent = matched ? matched.label : _currentProfile;
606
- $dd.classList.add('has-value');
607
- $dd._value = _currentProfile;
608
- for (const p of _mcpProfiles) {
609
- const el = document.createElement('div');
610
- el.className = 'cxp-dd-item' + (p.value === _currentProfile ? ' selected' : '');
611
- el.dataset.value = p.value;
612
- el.innerHTML = `<span>${p.label}</span><span style="opacity:0.35;margin-left:auto;font-size:9px">${p.hint}</span>`;
613
- el.style.display = 'flex'; el.style.gap = '6px';
614
- el.addEventListener('click', async () => {
615
- if (p.value === _currentProfile) { $dd.classList.remove('open'); return; }
616
- const previous = _currentProfile;
617
- _currentProfile = p.value;
618
- $dd._value = p.value;
619
- label.textContent = p.label;
620
- $dd.classList.remove('open');
621
- menu.querySelectorAll('.cxp-dd-item').forEach(o => o.classList.remove('selected'));
622
- el.classList.add('selected');
623
- try {
624
- await updateMcpProfile(p.value);
625
- populateProfileDropdown($dd);
626
- } catch (err) {
627
- _currentProfile = previous;
628
- populateProfileDropdown($dd);
629
- _host.appendSystem?.(err.message || 'Could not switch MCP profile', 'error');
630
- }
631
- });
632
- menu.appendChild(el);
633
- }
634
- }
635
-
636
- async function updateMcpProfile(profile) {
637
- const tab = activeTab();
638
- if (!tab) throw new Error('No active Codex tab');
639
- if (tab.running || tab.startingThread || tab.automationActive) {
640
- throw new Error('Wait for the active Codex turn or automation to finish before changing its MCP profile.');
641
- }
642
- const result = await requestSocketPayload('mcp_profile_set', {
643
- profile,
644
- threadId: tab.threadId || null,
645
- cwd: tab.project || null,
646
- model: tab.model || null,
647
- contextMode: tab.contextMode === 'extended' ? 'extended' : 'default',
648
- });
649
- const effective = result?.profile || profile;
650
- tab.mcpProfile = effective;
651
- _currentProfile = effective;
652
- saveTabs();
653
- // This selector is tab-scoped. The shared default is changed only through
654
- // an explicit future-runtime/default control, never as a side effect of
655
- // restarting the active Codex app-server.
656
- return effective;
657
- }
658
-
659
556
  // ═══════════════════════════════════════════
660
557
  // Recall Profile — live recall preset switching
661
558
  // ═══════════════════════════════════════════
@@ -666,6 +563,7 @@ const RECALL_PROFILES_META = [
666
563
  { value: 'deep', label: 'Deep', hint: '10 results' },
667
564
  { value: 'custom', label: 'Custom', hint: 'custom' },
668
565
  ];
566
+ function recallLabel(p) { return cxpText(p.value, p.label); }
669
567
  const RECALL_PROFILE_DEFAULTS = {
670
568
  quick: { limit: 3, minImportance: 5, minScore: 0.45, maxChars: 300, includeSessions: 'never', recencyBoost: false },
671
569
  balanced: { limit: 5, minImportance: 0, minScore: 0.30, maxChars: 0, includeSessions: 'auto', recencyBoost: false },
@@ -690,20 +588,20 @@ function populateRecallDropdown($dd) {
690
588
  if (!menu || !label) return;
691
589
  menu.innerHTML = '';
692
590
  const matched = RECALL_PROFILES_META.find(p => p.value === _recallProfile);
693
- label.textContent = matched ? matched.label : _recallProfile;
591
+ label.textContent = matched ? recallLabel(matched) : _recallProfile;
694
592
  $dd.classList.add('has-value');
695
593
  $dd._value = _recallProfile;
696
594
  for (const p of RECALL_PROFILES_META) {
697
595
  const el = document.createElement('div');
698
596
  el.className = 'cxp-dd-item' + (p.value === _recallProfile ? ' selected' : '');
699
597
  el.dataset.value = p.value;
700
- el.innerHTML = `<span>${p.label}</span><span style="opacity:0.35;margin-left:auto;font-size:9px">${p.hint}</span>`;
598
+ el.innerHTML = `<span>${recallLabel(p)}</span><span style="opacity:0.35;margin-left:auto;font-size:9px">${p.hint}</span>`;
701
599
  el.style.display = 'flex'; el.style.gap = '6px';
702
600
  el.addEventListener('click', () => {
703
601
  if (p.value === _recallProfile) { $dd.classList.remove('open'); return; }
704
602
  _recallProfile = p.value;
705
603
  $dd._value = p.value;
706
- label.textContent = p.label;
604
+ label.textContent = recallLabel(p);
707
605
  $dd.classList.remove('open');
708
606
  menu.querySelectorAll('.cxp-dd-item').forEach(o => o.classList.remove('selected'));
709
607
  el.classList.add('selected');
@@ -841,6 +739,7 @@ function wireEvents() {
841
739
  // Context settings: the cog and its popover take the place of the context bar.
842
740
  _contextMenu?.destroy();
843
741
  _contextMenu = mountContextMenu(panelEl('.cxp-actions'), _panel, {
742
+ bounds: frameRect, // the popover stays in the app frame
844
743
  reading: contextMenuReading,
845
744
  data: () => {
846
745
  const data = contextMenuData();
@@ -911,6 +810,7 @@ function wireEvents() {
911
810
  try {
912
811
  const statusResponse = await fetch(`/api/git/status?path=${encodeURIComponent(project)}`);
913
812
  const status = statusResponse.ok ? await statusResponse.json() : null;
813
+ if (!status?.ok || !status.isGit || status.partial || status.stale || status.timedOut) throw new Error(status?.error || 'Git status is incomplete. Refresh before switching branches.');
914
814
  if (status?.changes?.length) {
915
815
  const confirmed = window.confirm(`Switch from ${previous || 'the current branch'} to ${branch} with ${status.changes.length} uncommitted change${status.changes.length === 1 ? '' : 's'}? Git will preserve them when possible.`);
916
816
  if (!confirmed) {
@@ -940,8 +840,6 @@ function wireEvents() {
940
840
  branchDd.classList.remove('cxp-dropdown--busy');
941
841
  }
942
842
  });
943
- const profileDd = panelEl('#cxp-profile');
944
- ddSetup(profileDd);
945
843
  const recallDd = panelEl('#cxp-recall');
946
844
  ddSetup(recallDd);
947
845
  loadRecallProfile();
@@ -1030,17 +928,14 @@ function wireEvents() {
1030
928
  // Initialize voice input
1031
929
  initVoiceInput();
1032
930
 
1033
- on('mcp:profile-changed', (msg = {}) => {
1034
- _defaultMcpProfile = msg.defaultProfile || msg.profile || _defaultMcpProfile;
1035
- applyMcpProfileState(activeTab()?.mcpProfile || _defaultMcpProfile, msg.presets);
1036
- });
1037
931
 
1038
932
  on('codex-panel:show', async (data) => {
1039
- setVisible(true);
1040
933
  if (data?.tabId) {
1041
934
  const idx = _tabs.findIndex((entry) => entry.id === data.tabId);
1042
935
  if (idx >= 0) switchTab(idx);
1043
936
  }
937
+ setVisible(true);
938
+ ensureProjectsLoaded().catch(() => {});
1044
939
  });
1045
940
 
1046
941
  const findPlanEditorTab = ({ source, tabId, planId, accountId, threadId } = {}) => {
@@ -1182,9 +1077,6 @@ function ensurePanel() {
1182
1077
  emit,
1183
1078
  on,
1184
1079
  loadBranches,
1185
- activeTabChanged: (tab) => {
1186
- applyMcpProfileState(tab?.mcpProfile || _defaultMcpProfile, null);
1187
- },
1188
1080
  contextMenuSync: () => _contextMenu?.sync(),
1189
1081
  });
1190
1082
 
@@ -1220,8 +1112,8 @@ export async function toggleCodexPanel() {
1220
1112
  setVisible(false);
1221
1113
  return;
1222
1114
  }
1223
- await ensureProjectsLoaded();
1224
1115
  setVisible(true);
1116
+ await ensureProjectsLoaded();
1225
1117
  }
1226
1118
 
1227
1119
  export async function attachCodexAutomation(run, {
@@ -1233,6 +1125,7 @@ export async function attachCodexAutomation(run, {
1233
1125
  await ensureProjectsLoaded();
1234
1126
  if (isCancelled()) return { ok: false, reason: 'dismissed' };
1235
1127
  const running = run.status === 'starting' || run.status === 'running';
1128
+ const restart = workerRestart(run);
1236
1129
  // The user continued this run's thread by hand after the run ended: the tab stays theirs. The
1237
1130
  // dock's Focus raises it; the run is let go again, and nothing in the tab changes.
1238
1131
  const own = allTabs().find((entry) => !entry.automationRunId && entry.releasedRunId === run.runId && entry.threadId === threadId);
@@ -1255,7 +1148,6 @@ export async function attachCodexAutomation(run, {
1255
1148
  accountId: run.accountId || 'default',
1256
1149
  model: run.model || '',
1257
1150
  effort: run.effort || 'off',
1258
- mcpProfile: run.mcpProfile || null,
1259
1151
  autoAccept: true,
1260
1152
  planMode: false,
1261
1153
  title: run.title || 'Automation',
@@ -1266,20 +1158,24 @@ export async function attachCodexAutomation(run, {
1266
1158
  // on a question needs you, like one with an approval card up (setRunning and renderPills repaint).
1267
1159
  const working = running && run.turnState !== 'idle' && run.turnState !== 'terminal';
1268
1160
  tab.automationRunId = run.runId;
1269
- tab.automationActive = running;
1161
+ tab.automationActive = restart.active;
1270
1162
  tab.automationAwaits = runAwaitsAnswer(run);
1271
1163
  tab.automationOwnerId = nativeLoopWindowId;
1272
1164
  tab.threadId = threadId;
1273
1165
  tab.project = run.cwd || tab.project;
1274
- tab.mcpProfile = run.mcpProfile || tab.mcpProfile || _defaultMcpProfile;
1275
- tab.sessionLabel = run.title || tab.sessionLabel || 'Automation';
1166
+ tab.automationTitle = run.title || tab.automationTitle || tab.sessionLabel || 'Automation';
1167
+ tab.sessionLabel = tab.automationTitle;
1276
1168
  tab._automationIteration = run.currentIteration;
1277
1169
  tab.planMode = false;
1278
- if (focus) applyMcpProfileState(tab.mcpProfile, null);
1279
1170
  clearPlanHandoffState(tab);
1280
1171
  withTab(tab, () => setRunning(working));
1281
1172
  // The router replays what it buffered right after this attach; when that
1282
1173
  // reaches back to the first prompt, history would only render it twice.
1174
+ if (restart.resumes > (tab._automationResumes || 0)) {
1175
+ tab._automationHydrated = false;
1176
+ tab._automationLiveEvents = false;
1177
+ }
1178
+ tab._automationResumes = restart.resumes;
1283
1179
  if (running && !tab._automationHydrated && !codexAutomationBufferCoversRun(bufferedEvents, bufferTruncated)) {
1284
1180
  await hydrateCodexAutomationHistory(tab);
1285
1181
  if (isCancelled() || tab.closed) {
@@ -1287,11 +1183,23 @@ export async function attachCodexAutomation(run, {
1287
1183
  return { ok: false, reason: 'dismissed' };
1288
1184
  }
1289
1185
  }
1186
+ if (restart.key && tab._restartStamp !== restart.stamp) {
1187
+ withTab(tab, () => appendSystem(t(restart.key)));
1188
+ tab._restartStamp = restart.stamp;
1189
+ }
1290
1190
  // (A dispatched worker's failure, with its reason, is on its end card.)
1291
1191
  if (run.status === 'failed' && run.error && !isDispatchedRun(run) && tab._automationLifecycleError !== run.error) {
1292
1192
  tab._automationLifecycleError = run.error;
1293
1193
  withTab(tab, () => appendSystem(run.error, 'error'));
1294
1194
  }
1195
+ withTab(tab, () => syncWorkerQuestions(tab, run, {
1196
+ open: (id, pending) => handleServerRequest({ requestId: id, method: pending.protocol?.method, params: pending.input || {}, threadId }),
1197
+ close: (id) => {
1198
+ resolveRequestCard(id, t('workerQuestion.resolved'));
1199
+ tab.heldServerRequests?.delete(String(id));
1200
+ tab.blockingServerRequests?.delete(String(id));
1201
+ },
1202
+ }));
1295
1203
  trackWorkerEnd(run, { apply: (view) => { tab._workerEnd = view; placeWorkerEnd(tab); } });
1296
1204
  saveTabs();
1297
1205
  renderPills();
@@ -1300,7 +1208,7 @@ export async function attachCodexAutomation(run, {
1300
1208
  const idx = allTabs().indexOf(tab);
1301
1209
  if (idx >= 0) switchTab(idx);
1302
1210
  }
1303
- if (!running && isActiveTab(tab) && _visible) connectTab(tab);
1211
+ if (!restart.active && isActiveTab(tab) && _visible) connectTab(tab);
1304
1212
  return { ok: true, tabId: tab.id };
1305
1213
  }
1306
1214
 
@@ -0,0 +1,12 @@
1
+ // The early Codex rollout preview (server.js sendEarlyCodexRolloutPreview): DOM-free decisions.
2
+
3
+ /** A bootstrap asks for the preview only for a saved thread of the tab on screen. */
4
+ export function codexWantsRolloutPreview(tab, shownTab, threadId) {
5
+ return !!threadId && !!tab && tab === shownTab;
6
+ }
7
+
8
+ /** A preview paints only for the thread shown, and only while nothing else (a stored snapshot) is on screen. */
9
+ export function rolloutPreviewApplies(msg, shownThread, transcriptSourceType) {
10
+ const previewFor = String(msg?.threadId || msg?.thread?.id || '');
11
+ return !transcriptSourceType && !!previewFor && previewFor === String(shownThread || '');
12
+ }