synabun 2.0.10 → 2.1.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 (517) hide show
  1. package/CHANGELOG.md +86 -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 +2 -2
  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 +17 -8
  11. package/lib/desktop-app.js +7 -1
  12. package/lib/external-tools.js +1 -1
  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 +228 -0
  24. package/lib/virustotal.mjs +192 -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/codex-config-heal.d.ts +6 -2
  37. package/mcp-server/dist/services/codex-config-heal.d.ts.map +1 -1
  38. package/mcp-server/dist/services/codex-config-heal.js +81 -28
  39. package/mcp-server/dist/services/codex-config-heal.js.map +1 -1
  40. package/mcp-server/dist/services/memory-judge-backfill.d.ts +6 -0
  41. package/mcp-server/dist/services/memory-judge-backfill.d.ts.map +1 -1
  42. package/mcp-server/dist/services/memory-judge-backfill.js +7 -1
  43. package/mcp-server/dist/services/memory-judge-backfill.js.map +1 -1
  44. package/mcp-server/dist/services/neural-interface.d.ts +16 -10
  45. package/mcp-server/dist/services/neural-interface.d.ts.map +1 -1
  46. package/mcp-server/dist/services/neural-interface.js +67 -11
  47. package/mcp-server/dist/services/neural-interface.js.map +1 -1
  48. package/mcp-server/dist/services/server-instructions.d.ts +7 -2
  49. package/mcp-server/dist/services/server-instructions.d.ts.map +1 -1
  50. package/mcp-server/dist/services/server-instructions.js +20 -62
  51. package/mcp-server/dist/services/server-instructions.js.map +1 -1
  52. package/mcp-server/dist/services/tool-catalog.d.ts +120 -0
  53. package/mcp-server/dist/services/tool-catalog.d.ts.map +1 -0
  54. package/mcp-server/dist/services/tool-catalog.js +339 -0
  55. package/mcp-server/dist/services/tool-catalog.js.map +1 -0
  56. package/mcp-server/dist/services/tool-list-refresh-barrier.d.ts +12 -0
  57. package/mcp-server/dist/services/tool-list-refresh-barrier.d.ts.map +1 -0
  58. package/mcp-server/dist/services/tool-list-refresh-barrier.js +40 -0
  59. package/mcp-server/dist/services/tool-list-refresh-barrier.js.map +1 -0
  60. package/mcp-server/dist/services/tool-list.d.ts +108 -0
  61. package/mcp-server/dist/services/tool-list.d.ts.map +1 -0
  62. package/mcp-server/dist/services/tool-list.js +334 -0
  63. package/mcp-server/dist/services/tool-list.js.map +1 -0
  64. package/mcp-server/dist/services/tool-runtime.d.ts +161 -0
  65. package/mcp-server/dist/services/tool-runtime.d.ts.map +1 -0
  66. package/mcp-server/dist/services/tool-runtime.js +400 -0
  67. package/mcp-server/dist/services/tool-runtime.js.map +1 -0
  68. package/mcp-server/dist/services/whiteboard-geometry.d.ts +26 -2
  69. package/mcp-server/dist/services/whiteboard-geometry.d.ts.map +1 -1
  70. package/mcp-server/dist/services/whiteboard-geometry.js +91 -8
  71. package/mcp-server/dist/services/whiteboard-geometry.js.map +1 -1
  72. package/mcp-server/dist/tools/agents.d.ts +10 -10
  73. package/mcp-server/dist/tools/agents.d.ts.map +1 -1
  74. package/mcp-server/dist/tools/agents.js +22 -13
  75. package/mcp-server/dist/tools/agents.js.map +1 -1
  76. package/mcp-server/dist/tools/browser-batch.d.ts +3 -3
  77. package/mcp-server/dist/tools/image-tools.d.ts +1 -1
  78. package/mcp-server/dist/tools/image-tools.js +1 -1
  79. package/mcp-server/dist/tools/skill-tools.d.ts +505 -0
  80. package/mcp-server/dist/tools/skill-tools.d.ts.map +1 -0
  81. package/mcp-server/dist/tools/skill-tools.js +639 -0
  82. package/mcp-server/dist/tools/skill-tools.js.map +1 -0
  83. package/mcp-server/dist/tools/skill.d.ts +7 -0
  84. package/mcp-server/dist/tools/skill.d.ts.map +1 -0
  85. package/mcp-server/dist/tools/skill.js +11 -0
  86. package/mcp-server/dist/tools/skill.js.map +1 -0
  87. package/mcp-server/dist/tools/tool-groups.d.ts +68 -0
  88. package/mcp-server/dist/tools/tool-groups.d.ts.map +1 -0
  89. package/mcp-server/dist/tools/tool-groups.js +147 -0
  90. package/mcp-server/dist/tools/tool-groups.js.map +1 -0
  91. package/mcp-server/dist/tools/whiteboard-format.d.ts.map +1 -1
  92. package/mcp-server/dist/tools/whiteboard-format.js +7 -4
  93. package/mcp-server/dist/tools/whiteboard-format.js.map +1 -1
  94. package/mcp-server/dist/tools/whiteboard-tools.d.ts +64 -13
  95. package/mcp-server/dist/tools/whiteboard-tools.d.ts.map +1 -1
  96. package/mcp-server/dist/tools/whiteboard-tools.js +30 -5
  97. package/mcp-server/dist/tools/whiteboard-tools.js.map +1 -1
  98. package/mcp-server/package-lock.json +2 -2
  99. package/mcp-server/package.json +1 -1
  100. package/mcp-server/src/http.ts +75 -12
  101. package/mcp-server/src/index.ts +147 -154
  102. package/mcp-server/src/preload.ts +12 -12
  103. package/mcp-server/src/services/codex-config-heal.ts +80 -29
  104. package/mcp-server/src/services/memory-judge-backfill.ts +7 -1
  105. package/mcp-server/src/services/neural-interface.ts +79 -20
  106. package/mcp-server/src/services/server-instructions.ts +27 -63
  107. package/mcp-server/src/services/tool-catalog.ts +403 -0
  108. package/mcp-server/src/services/tool-list-refresh-barrier.ts +33 -0
  109. package/mcp-server/src/services/tool-list.ts +410 -0
  110. package/mcp-server/src/services/tool-runtime.ts +457 -0
  111. package/mcp-server/src/services/whiteboard-geometry.ts +94 -9
  112. package/mcp-server/src/tools/agents.ts +22 -14
  113. package/mcp-server/src/tools/image-tools.ts +1 -1
  114. package/mcp-server/src/tools/skill-tools.ts +589 -0
  115. package/mcp-server/src/tools/skill.ts +13 -0
  116. package/mcp-server/src/tools/tool-groups.ts +164 -0
  117. package/mcp-server/src/tools/whiteboard-format.ts +9 -3
  118. package/mcp-server/src/tools/whiteboard-tools.ts +39 -5
  119. package/neural-interface/i18n/en.json +3463 -200
  120. package/neural-interface/i18n/pt-BR.json +3411 -151
  121. package/neural-interface/lib/assistant-api.js +127 -28
  122. package/neural-interface/lib/assistant-brains/claude.js +4 -3
  123. package/neural-interface/lib/assistant-brains/codex-browser-policy-hook.mjs +12 -2
  124. package/neural-interface/lib/assistant-brains/codex-route-gate-hook.mjs +32 -9
  125. package/neural-interface/lib/assistant-brains/codex.js +9 -5
  126. package/neural-interface/lib/assistant-brains/opencode.js +120 -54
  127. package/neural-interface/lib/assistant-brains/opencode2-browser-policy/index.js +28 -13
  128. package/neural-interface/lib/assistant-brains/opencode2-route-gate/index.js +59 -19
  129. package/neural-interface/lib/assistant-catalog.js +6 -7
  130. package/neural-interface/lib/assistant-dispatch.js +871 -156
  131. package/neural-interface/lib/assistant-envelope.js +3 -1
  132. package/neural-interface/lib/assistant-persona.js +80 -11
  133. package/neural-interface/lib/assistant-plan-permissions.js +10 -9
  134. package/neural-interface/lib/assistant-route-gate-codex.js +3 -0
  135. package/neural-interface/lib/assistant-route-gate.js +6 -4
  136. package/neural-interface/lib/assistant-router.js +13 -8
  137. package/neural-interface/lib/assistant-runtime.js +56 -18
  138. package/neural-interface/lib/assistant-task-prompt.js +78 -14
  139. package/neural-interface/lib/assistant-tools.js +51 -0
  140. package/neural-interface/lib/backup-service.js +620 -3
  141. package/neural-interface/lib/backup-zip-reader.js +10 -5
  142. package/neural-interface/lib/backup-zip-writer.js +257 -0
  143. package/neural-interface/lib/browser-execution.js +10 -2
  144. package/neural-interface/lib/browser-guard-cdp.js +83 -0
  145. package/neural-interface/lib/browser-network-guard.js +284 -0
  146. package/neural-interface/lib/browser-policy-roots.js +64 -0
  147. package/neural-interface/lib/browser-tool-policy.js +186 -31
  148. package/neural-interface/lib/claude-agent-bridge.js +4 -2
  149. package/neural-interface/lib/claude-hooks-status.js +103 -0
  150. package/neural-interface/lib/claude-temporary.js +5 -11
  151. package/neural-interface/lib/cli-install.js +18 -138
  152. package/neural-interface/lib/cli-resolver.js +4 -1
  153. package/neural-interface/lib/cli-update-planner.js +32 -31
  154. package/neural-interface/lib/cloudflared/tunnel.js +42 -2
  155. package/neural-interface/lib/codex-mcp-approvals.js +11 -0
  156. package/neural-interface/lib/codex-worker-app-server.js +172 -0
  157. package/neural-interface/lib/confined-fs.js +30 -3
  158. package/neural-interface/lib/crash-notice-api.js +98 -0
  159. package/neural-interface/lib/editor-completion-opencode.js +68 -68
  160. package/neural-interface/lib/exec-loop-command.js +4 -8
  161. package/neural-interface/lib/http-guards.js +8 -2
  162. package/neural-interface/lib/install-details.js +4 -1
  163. package/neural-interface/lib/mcp-agent-servers.js +67 -0
  164. package/neural-interface/lib/mcp-client-config.js +0 -29
  165. package/neural-interface/lib/mcp-external-servers.js +323 -0
  166. package/neural-interface/lib/{mcp-profile-refresh-coordinator.js → mcp-tools-refresh-coordinator.js} +4 -4
  167. package/neural-interface/lib/morelogin.js +30 -0
  168. package/neural-interface/lib/native-loop-providers.js +547 -47
  169. package/neural-interface/lib/native-loop-runtime.js +268 -41
  170. package/neural-interface/lib/opencode-config.js +557 -0
  171. package/neural-interface/lib/opencode-db-schema.js +17 -34
  172. package/neural-interface/lib/opencode-history.js +48 -218
  173. package/neural-interface/lib/opencode-mcp-ready.js +108 -0
  174. package/neural-interface/lib/opencode-native-boundary.js +44 -0
  175. package/neural-interface/lib/opencode-protocol.js +249 -112
  176. package/neural-interface/lib/opencode-runtime-config.js +32 -22
  177. package/neural-interface/lib/opencode-serve-records.js +39 -21
  178. package/neural-interface/lib/opencode-v2-client.js +48 -153
  179. package/neural-interface/lib/opencode-v2-ws-requests.js +36 -210
  180. package/neural-interface/lib/opencode-worker-data.js +27 -0
  181. package/neural-interface/lib/opencode2-client.js +73 -37
  182. package/neural-interface/lib/opencode2-proxy.js +23 -63
  183. package/neural-interface/lib/opencode2-translate.js +51 -2
  184. package/neural-interface/lib/owner-authority.js +249 -0
  185. package/neural-interface/lib/page-session.js +275 -0
  186. package/neural-interface/lib/peer-identity.js +763 -0
  187. package/neural-interface/lib/request-gate.js +17 -2
  188. package/neural-interface/lib/rulesets/api.js +1 -1
  189. package/neural-interface/lib/rulesets/fs-safe.js +1 -1
  190. package/neural-interface/lib/rulesets/installer.js +92 -27
  191. package/neural-interface/lib/rulesets/json-edit.js +1 -1
  192. package/neural-interface/lib/session-cache-builder.js +17 -30
  193. package/neural-interface/lib/session-title-generator.js +58 -36
  194. package/neural-interface/lib/skills/api-v2.js +495 -0
  195. package/neural-interface/lib/skills/bundle.js +418 -0
  196. package/neural-interface/lib/skills/catalog.js +294 -0
  197. package/neural-interface/lib/skills/creation-api.js +191 -0
  198. package/neural-interface/lib/skills/creation-brief.js +247 -0
  199. package/neural-interface/lib/skills/creation-sources.js +267 -0
  200. package/neural-interface/lib/skills/creation.js +843 -0
  201. package/neural-interface/lib/skills/deploy.js +564 -0
  202. package/neural-interface/lib/skills/digest.js +119 -0
  203. package/neural-interface/lib/skills/discover.js +111 -0
  204. package/neural-interface/lib/skills/draft-confinement.js +214 -0
  205. package/neural-interface/lib/skills/eval-confinement.js +397 -0
  206. package/neural-interface/lib/skills/eval-sandbox.js +280 -0
  207. package/neural-interface/lib/skills/eval-trace.js +119 -0
  208. package/neural-interface/lib/skills/evals-api.js +212 -0
  209. package/neural-interface/lib/skills/evals.js +1573 -0
  210. package/neural-interface/lib/skills/export.js +200 -0
  211. package/neural-interface/lib/skills/frontmatter.js +64 -0
  212. package/neural-interface/lib/skills/health.js +75 -0
  213. package/neural-interface/lib/skills/json-edit.js +165 -0
  214. package/neural-interface/lib/skills/known-bridge-digests.json +387 -0
  215. package/neural-interface/lib/skills/known-bridges.js +96 -0
  216. package/neural-interface/lib/skills/library.js +823 -0
  217. package/neural-interface/lib/skills/local-store.js +21 -0
  218. package/neural-interface/lib/skills/migration.js +433 -0
  219. package/neural-interface/lib/skills/operations.js +45 -0
  220. package/neural-interface/lib/skills/ownership.js +427 -0
  221. package/neural-interface/lib/skills/packages.js +88 -0
  222. package/neural-interface/lib/skills/reviews.js +212 -0
  223. package/neural-interface/lib/skills/revision.js +80 -0
  224. package/neural-interface/lib/skills/roots.js +262 -0
  225. package/neural-interface/lib/skills/runtime-checks.js +355 -0
  226. package/neural-interface/lib/skills/scan-assets.js +252 -0
  227. package/neural-interface/lib/skills/scan-context.js +26 -0
  228. package/neural-interface/lib/skills/scan-shell.js +324 -0
  229. package/neural-interface/lib/skills/scan.js +364 -0
  230. package/neural-interface/lib/skills/scanners.js +54 -0
  231. package/neural-interface/lib/skills/service.js +522 -0
  232. package/neural-interface/lib/skills/telemetry.js +113 -0
  233. package/neural-interface/lib/sqlite-integrity-worker.js +22 -0
  234. package/neural-interface/lib/tool-lists.js +124 -0
  235. package/neural-interface/lib/whatsapp/bridge.js +6 -3
  236. package/neural-interface/lib/worker-confinement.js +1192 -0
  237. package/neural-interface/lib/worker-guard-setting.js +56 -0
  238. package/neural-interface/lib/worker-mcp-channel.js +175 -0
  239. package/neural-interface/lib/worker-relay-ports.js +227 -0
  240. package/neural-interface/lib/worker-resume.js +229 -0
  241. package/neural-interface/lib/worker-sandbox.js +299 -0
  242. package/neural-interface/package-lock.json +18 -12
  243. package/neural-interface/package.json +2 -2
  244. package/neural-interface/public/index.html +3 -1
  245. package/neural-interface/public/index2d.html +19 -11
  246. package/neural-interface/public/onboarding.html +2 -2
  247. package/neural-interface/public/shared/account-menu.js +8 -5
  248. package/neural-interface/public/shared/agent-runtime-options.js +35 -19
  249. package/neural-interface/public/shared/api.js +1527 -1336
  250. package/neural-interface/public/shared/app-frame.js +192 -0
  251. package/neural-interface/public/shared/assistant/asst-agents-dock.js +33 -2
  252. package/neural-interface/public/shared/assistant/asst-ask-styles.js +270 -0
  253. package/neural-interface/public/shared/assistant/asst-ask-tail.js +118 -0
  254. package/neural-interface/public/shared/assistant/asst-ask.js +397 -0
  255. package/neural-interface/public/shared/assistant/asst-brain-picker.js +49 -35
  256. package/neural-interface/public/shared/assistant/asst-control.js +157 -26
  257. package/neural-interface/public/shared/assistant/asst-followups-card.js +383 -0
  258. package/neural-interface/public/shared/assistant/asst-followups.js +417 -0
  259. package/neural-interface/public/shared/assistant/asst-limit-dock.js +40 -0
  260. package/neural-interface/public/shared/assistant/asst-limit-wait.js +294 -0
  261. package/neural-interface/public/shared/assistant/asst-limit.js +168 -0
  262. package/neural-interface/public/shared/assistant/asst-mascot.js +49 -12
  263. package/neural-interface/public/shared/assistant/asst-menu.js +7 -6
  264. package/neural-interface/public/shared/assistant/asst-panel.js +106 -11
  265. package/neural-interface/public/shared/assistant/asst-rack-styles.js +66 -49
  266. package/neural-interface/public/shared/assistant/asst-render.js +401 -77
  267. package/neural-interface/public/shared/assistant/asst-route.js +83 -12
  268. package/neural-interface/public/shared/assistant/asst-scenes.js +2 -0
  269. package/neural-interface/public/shared/assistant/asst-sidepanel.js +67 -4
  270. package/neural-interface/public/shared/assistant/asst-slash.js +9 -7
  271. package/neural-interface/public/shared/assistant/asst-state.js +11 -15
  272. package/neural-interface/public/shared/assistant/asst-stop.js +127 -0
  273. package/neural-interface/public/shared/assistant/asst-styles.js +59 -21
  274. package/neural-interface/public/shared/assistant/asst-tool-kinds.js +156 -16
  275. package/neural-interface/public/shared/automation-context.js +5 -2
  276. package/neural-interface/public/shared/cc-dropdown.js +89 -19
  277. package/neural-interface/public/shared/cdx/cdx-context-menu.js +10 -9
  278. package/neural-interface/public/shared/cdx/cdx-copy.js +16 -0
  279. package/neural-interface/public/shared/cdx/cdx-output-model.js +22 -1
  280. package/neural-interface/public/shared/cdx/cdx-output.js +8 -7
  281. package/neural-interface/public/shared/cdx/cdx-panel.js +45 -149
  282. package/neural-interface/public/shared/cdx/cdx-protocol.js +28 -1
  283. package/neural-interface/public/shared/cdx/cdx-render.js +47 -29
  284. package/neural-interface/public/shared/cdx/cdx-requests.js +3 -3
  285. package/neural-interface/public/shared/cdx/cdx-skill-hints.js +54 -0
  286. package/neural-interface/public/shared/cdx/cdx-styles.js +11 -3
  287. package/neural-interface/public/shared/cdx/cdx-tabs.js +52 -39
  288. package/neural-interface/public/shared/cdx/cdx-ws.js +0 -1
  289. package/neural-interface/public/shared/cli-install-view.js +4 -8
  290. package/neural-interface/public/shared/cli-status.js +2 -2
  291. package/neural-interface/public/shared/constants.js +2 -2
  292. package/neural-interface/public/shared/context-menu-areas.js +34 -0
  293. package/neural-interface/public/shared/context-menu-logic.js +243 -0
  294. package/neural-interface/public/shared/context-menu-model.js +366 -0
  295. package/neural-interface/public/shared/context-menu.js +372 -0
  296. package/neural-interface/public/shared/cp/cp-context-menu.js +10 -9
  297. package/neural-interface/public/shared/crash-notice-view.js +168 -0
  298. package/neural-interface/public/shared/desktop-update-view.js +20 -0
  299. package/neural-interface/public/shared/editor/editor-panel-logic.js +2 -2
  300. package/neural-interface/public/shared/html-shell.js +9 -11
  301. package/neural-interface/public/shared/i18n.js +2 -0
  302. package/neural-interface/public/shared/ocp-v2/ocp-v2-approvals.js +7 -7
  303. package/neural-interface/public/shared/ocp-v2/ocp-v2-binding.js +4 -4
  304. package/neural-interface/public/shared/ocp-v2/ocp-v2-changes-logic.js +3 -101
  305. package/neural-interface/public/shared/ocp-v2/ocp-v2-childpanel.js +2 -0
  306. package/neural-interface/public/shared/ocp-v2/ocp-v2-compact-button.js +1 -3
  307. package/neural-interface/public/shared/ocp-v2/ocp-v2-composer-logic.js +2 -6
  308. package/neural-interface/public/shared/ocp-v2/ocp-v2-context-menu.js +11 -11
  309. package/neural-interface/public/shared/ocp-v2/ocp-v2-context-model.js +0 -3
  310. package/neural-interface/public/shared/ocp-v2/ocp-v2-events.js +8 -4
  311. package/neural-interface/public/shared/ocp-v2/ocp-v2-manager.js +7 -7
  312. package/neural-interface/public/shared/ocp-v2/ocp-v2-outcome-notifications.js +16 -0
  313. package/neural-interface/public/shared/ocp-v2/ocp-v2-panel.js +47 -252
  314. package/neural-interface/public/shared/ocp-v2/ocp-v2-plan.js +1 -2
  315. package/neural-interface/public/shared/ocp-v2/ocp-v2-projectbar.js +95 -202
  316. package/neural-interface/public/shared/ocp-v2/ocp-v2-render.js +6 -21
  317. package/neural-interface/public/shared/ocp-v2/ocp-v2-send.js +4 -4
  318. package/neural-interface/public/shared/ocp-v2/ocp-v2-session-actions.js +8 -61
  319. package/neural-interface/public/shared/ocp-v2/ocp-v2-sessions-logic.js +2 -91
  320. package/neural-interface/public/shared/ocp-v2/ocp-v2-slash-hints.js +16 -15
  321. package/neural-interface/public/shared/ocp-v2/ocp-v2-state.js +8 -21
  322. package/neural-interface/public/shared/ocp-v2/ocp-v2-status-logic.js +1 -99
  323. package/neural-interface/public/shared/ocp-v2/ocp-v2-status.js +5 -35
  324. package/neural-interface/public/shared/ocp-v2/ocp-v2-styles.js +0 -21
  325. package/neural-interface/public/shared/ocp-v2/{ocp-v2-profile-inheritance.js → ocp-v2-tools-inheritance.js} +16 -16
  326. package/neural-interface/public/shared/ocp-v2/ocp-v2-ws.js +14 -47
  327. package/neural-interface/public/shared/page-session.js +96 -0
  328. package/neural-interface/public/shared/registry.js +5 -3
  329. package/neural-interface/public/shared/retired-2d.js +3 -0
  330. package/neural-interface/public/shared/schedules-view.js +195 -61
  331. package/neural-interface/public/shared/settings/settings-claude-hooks.js +135 -0
  332. package/neural-interface/public/shared/settings/settings-data.js +3 -1
  333. package/neural-interface/public/shared/settings/settings-ia.js +6 -6
  334. package/neural-interface/public/shared/settings/settings-opencode.js +89 -0
  335. package/neural-interface/public/shared/settings/settings-skill-folders-pane.js +265 -0
  336. package/neural-interface/public/shared/settings/settings-skill-folders.js +130 -0
  337. package/neural-interface/public/shared/settings/settings-worker-guard.js +72 -0
  338. package/neural-interface/public/shared/skills/ss-args.js +96 -0
  339. package/neural-interface/public/shared/skills/ss-creation.js +219 -0
  340. package/neural-interface/public/shared/skills/ss-dialog.js +130 -0
  341. package/neural-interface/public/shared/skills/ss-doc.js +173 -0
  342. package/neural-interface/public/shared/skills/ss-eval-adapters.js +269 -0
  343. package/neural-interface/public/shared/skills/ss-eval-grade.js +359 -0
  344. package/neural-interface/public/shared/skills/ss-eval-optimise.js +153 -0
  345. package/neural-interface/public/shared/skills/ss-eval-plan.js +315 -0
  346. package/neural-interface/public/shared/skills/ss-evals.js +417 -0
  347. package/neural-interface/public/shared/skills/ss-form.js +159 -0
  348. package/neural-interface/public/shared/skills/ss-frontmatter.js +376 -0
  349. package/neural-interface/public/shared/skills/ss-ids.js +32 -0
  350. package/neural-interface/public/shared/skills/ss-lint.js +141 -0
  351. package/neural-interface/public/shared/skills/ss-presets.js +117 -0
  352. package/neural-interface/public/shared/skills/ss-profiles.js +475 -0
  353. package/neural-interface/public/shared/skills/ss-resources.js +165 -0
  354. package/neural-interface/public/shared/skills/ss-review-view.js +190 -0
  355. package/neural-interface/public/shared/skills/ss-tabs.js +79 -0
  356. package/neural-interface/public/shared/skills/ss-unicode.js +135 -0
  357. package/neural-interface/public/shared/skills/studio/sx-actions.js +222 -0
  358. package/neural-interface/public/shared/skills/studio/sx-cm.js +101 -0
  359. package/neural-interface/public/shared/skills/studio/sx-create-ai-view.js +749 -0
  360. package/neural-interface/public/shared/skills/studio/sx-create-ai.js +236 -0
  361. package/neural-interface/public/shared/skills/studio/sx-create-view.js +254 -0
  362. package/neural-interface/public/shared/skills/studio/sx-create.js +126 -0
  363. package/neural-interface/public/shared/skills/studio/sx-diff-view.js +43 -0
  364. package/neural-interface/public/shared/skills/studio/sx-diff.js +133 -0
  365. package/neural-interface/public/shared/skills/studio/sx-docs.js +480 -0
  366. package/neural-interface/public/shared/skills/studio/sx-dom.js +229 -0
  367. package/neural-interface/public/shared/skills/studio/sx-edit-view.js +848 -0
  368. package/neural-interface/public/shared/skills/studio/sx-editor-model.js +193 -0
  369. package/neural-interface/public/shared/skills/studio/sx-errors.js +22 -0
  370. package/neural-interface/public/shared/skills/studio/sx-geometry.js +82 -0
  371. package/neural-interface/public/shared/skills/studio/sx-import.js +262 -0
  372. package/neural-interface/public/shared/skills/studio/sx-inspector.js +308 -0
  373. package/neural-interface/public/shared/skills/studio/sx-install-flow.js +279 -0
  374. package/neural-interface/public/shared/skills/studio/sx-install.js +296 -0
  375. package/neural-interface/public/shared/skills/studio/sx-library-view.js +639 -0
  376. package/neural-interface/public/shared/skills/studio/sx-library.js +475 -0
  377. package/neural-interface/public/shared/skills/studio/sx-main.js +681 -0
  378. package/neural-interface/public/shared/skills/studio/sx-operations-view.js +98 -0
  379. package/neural-interface/public/shared/skills/studio/sx-operations.js +11 -0
  380. package/neural-interface/public/shared/skills/studio/sx-plan.js +158 -0
  381. package/neural-interface/public/shared/skills/studio/sx-publish-view.js +621 -0
  382. package/neural-interface/public/shared/skills/studio/sx-review-view.js +369 -0
  383. package/neural-interface/public/shared/skills/studio/sx-review.js +148 -0
  384. package/neural-interface/public/shared/skills/studio/sx-scan.js +35 -0
  385. package/neural-interface/public/shared/skills/studio/sx-snippets.js +96 -0
  386. package/neural-interface/public/shared/skills/studio/sx-subject.js +248 -0
  387. package/neural-interface/public/shared/skills/studio/sx-test-view.js +994 -0
  388. package/neural-interface/public/shared/skills/studio/sx-test.js +328 -0
  389. package/neural-interface/public/shared/skills/studio/sx-versions-view.js +241 -0
  390. package/neural-interface/public/shared/skills/studio/sx-workspace-view.js +425 -0
  391. package/neural-interface/public/shared/styleguide/sg-panel.js +4 -2
  392. package/neural-interface/public/shared/styles.css +1525 -1779
  393. package/neural-interface/public/shared/synabun-mascot.js +1115 -9
  394. package/neural-interface/public/shared/tool-list-picker.js +55 -0
  395. package/neural-interface/public/shared/tool-list-storage.js +24 -0
  396. package/neural-interface/public/shared/tool-list-view.js +112 -0
  397. package/neural-interface/public/shared/tour/tour-actor.js +268 -0
  398. package/neural-interface/public/shared/tour/tour-beats.js +336 -0
  399. package/neural-interface/public/shared/tour/tour-engine.js +884 -0
  400. package/neural-interface/public/shared/tour/tour-ink.js +390 -0
  401. package/neural-interface/public/shared/tour/tour-stage.js +440 -0
  402. package/neural-interface/public/shared/tour/tour-state.js +40 -0
  403. package/neural-interface/public/shared/tour/tour-tips.js +99 -0
  404. package/neural-interface/public/shared/tour/tour.css +144 -0
  405. package/neural-interface/public/shared/ui-automation-studio.js +91 -128
  406. package/neural-interface/public/shared/ui-claude-panel.js +77 -5
  407. package/neural-interface/public/shared/ui-command-runner.js +6 -3
  408. package/neural-interface/public/shared/ui-context-menu.js +295 -0
  409. package/neural-interface/public/shared/ui-cost-widget.js +57 -59
  410. package/neural-interface/public/shared/ui-crash-notice.js +187 -0
  411. package/neural-interface/public/shared/ui-detail.js +15 -3
  412. package/neural-interface/public/shared/ui-image-gallery.js +50 -47
  413. package/neural-interface/public/shared/ui-keybinds.js +26 -1
  414. package/neural-interface/public/shared/ui-menubar.js +8 -18
  415. package/neural-interface/public/shared/ui-native-loop-router-state.js +5 -0
  416. package/neural-interface/public/shared/ui-native-loop-router.js +7 -1
  417. package/neural-interface/public/shared/ui-navbar.js +4 -24
  418. package/neural-interface/public/shared/ui-panels.js +96 -65
  419. package/neural-interface/public/shared/ui-schedules-studio.js +507 -423
  420. package/neural-interface/public/shared/ui-sessions.js +5 -3
  421. package/neural-interface/public/shared/ui-settings.js +594 -462
  422. package/neural-interface/public/shared/ui-sidepanel-sessions.js +1 -1
  423. package/neural-interface/public/shared/ui-sidepanel-state.js +23 -12
  424. package/neural-interface/public/shared/ui-sidepanel-windows.js +16 -11
  425. package/neural-interface/public/shared/ui-skills.js +33 -2830
  426. package/neural-interface/public/shared/ui-styleguide.js +5 -2
  427. package/neural-interface/public/shared/ui-sync.js +15 -5
  428. package/neural-interface/public/shared/ui-terminal.js +124 -180
  429. package/neural-interface/public/shared/ui-tool-updates.js +3 -1
  430. package/neural-interface/public/shared/ui-tooltip.js +10 -5
  431. package/neural-interface/public/shared/ui-trash.js +6 -4
  432. package/neural-interface/public/shared/ui-tutorial-layout.js +3 -117
  433. package/neural-interface/public/shared/ui-tutorial-preview.js +103 -0
  434. package/neural-interface/public/shared/ui-tutorial-steps.js +3 -65
  435. package/neural-interface/public/shared/ui-tutorial.css +47 -100
  436. package/neural-interface/public/shared/ui-tutorial.js +285 -509
  437. package/neural-interface/public/shared/ui-update.js +38 -2
  438. package/neural-interface/public/shared/ui-whiteboard.js +311 -58
  439. package/neural-interface/public/shared/ui-worker-end.js +4 -0
  440. package/neural-interface/public/shared/ui-workspaces.js +3 -2
  441. package/neural-interface/public/shared/view-variant.js +66 -0
  442. package/neural-interface/public/shared/whatsapp/wa-view.js +1 -1
  443. package/neural-interface/public/shared/whiteboard-list.js +172 -0
  444. package/neural-interface/public/shared/worker-end.js +10 -3
  445. package/neural-interface/public/shared/worker-restart.js +12 -0
  446. package/neural-interface/public/sidepanel-session.html +1 -1
  447. package/neural-interface/public/variant/2d/background.js +2 -1
  448. package/neural-interface/public/variant/2d/context-menu.js +8 -2
  449. package/neural-interface/public/variant/2d/graph.js +42 -20
  450. package/neural-interface/public/variant/2d/hulls.js +14 -9
  451. package/neural-interface/public/variant/2d/lasso.js +11 -7
  452. package/neural-interface/public/variant/2d/main.js +32 -1
  453. package/neural-interface/public/variant/2d/minimap.js +11 -13
  454. package/neural-interface/public/variant/3d/main.js +69 -6
  455. package/neural-interface/public/variant/3d/map-controls.js +24 -9
  456. package/neural-interface/public/vendor/caveat/OFL.txt +93 -0
  457. package/neural-interface/public/vendor/caveat/caveat-latin-400-normal.woff2 +0 -0
  458. package/neural-interface/public/vendor/caveat/caveat-latin-700-normal.woff2 +0 -0
  459. package/neural-interface/public/vendor/caveat/caveat.css +17 -0
  460. package/neural-interface/public/vendor/caveat/manifest.json +12 -0
  461. package/neural-interface/public/vendor/yaml/LICENSE +13 -0
  462. package/neural-interface/public/vendor/yaml/manifest.json +4 -0
  463. package/neural-interface/public/vendor/yaml/yaml-2.9.1.min.js +137 -0
  464. package/neural-interface/scripts/build-vendor.mjs +32 -0
  465. package/neural-interface/server.js +3934 -2454
  466. package/neural-interface/templates/rulesets/core.md +1 -1
  467. package/neural-interface/templates/rulesets/legacy-hashes.json +18 -0
  468. package/neural-interface/templates/rulesets/manifest.json +8 -8
  469. package/npm-shrinkwrap.json +18 -12
  470. package/package.json +16 -3
  471. package/postinstall.js +9 -4
  472. package/preuninstall.js +1 -1
  473. package/setup.js +97 -322
  474. package/skills/skill-forge/SKILL.md +177 -0
  475. package/skills/skill-forge/evals/evals.json +54 -0
  476. package/skills/skill-forge/references/package.md +105 -0
  477. package/skills/skill-forge/references/review-and-recovery.md +63 -0
  478. package/skills/skill-forge/references/runtime-profiles.md +20 -0
  479. package/skills/skill-forge/references/sources-and-capabilities.md +51 -0
  480. package/skills/synabun/SKILL.md +10 -7
  481. package/skills/synabun/modules/audit.md +1 -5
  482. package/skills/synabun/modules/changelog.md +1 -5
  483. package/skills/synabun/modules/idea.md +1 -1
  484. package/skills/synabun/modules/memorize.md +6 -9
  485. package/skills/synabun/modules/schedule.md +4 -4
  486. package/mcp-server/dist/services/profiles.d.ts +0 -120
  487. package/mcp-server/dist/services/profiles.d.ts.map +0 -1
  488. package/mcp-server/dist/services/profiles.js +0 -387
  489. package/mcp-server/dist/services/profiles.js.map +0 -1
  490. package/mcp-server/dist/tools/leonardo-browser-tools.d.ts +0 -97
  491. package/mcp-server/dist/tools/leonardo-browser-tools.d.ts.map +0 -1
  492. package/mcp-server/dist/tools/leonardo-browser-tools.js +0 -228
  493. package/mcp-server/dist/tools/leonardo-browser-tools.js.map +0 -1
  494. package/mcp-server/dist/tools/leonardo.d.ts +0 -13
  495. package/mcp-server/dist/tools/leonardo.d.ts.map +0 -1
  496. package/mcp-server/dist/tools/leonardo.js +0 -21
  497. package/mcp-server/dist/tools/leonardo.js.map +0 -1
  498. package/mcp-server/dist/tools/profile.d.ts +0 -17
  499. package/mcp-server/dist/tools/profile.d.ts.map +0 -1
  500. package/mcp-server/dist/tools/profile.js +0 -114
  501. package/mcp-server/dist/tools/profile.js.map +0 -1
  502. package/mcp-server/src/services/profiles.ts +0 -428
  503. package/mcp-server/src/tools/leonardo-browser-tools.ts +0 -291
  504. package/mcp-server/src/tools/leonardo.ts +0 -30
  505. package/mcp-server/src/tools/profile.ts +0 -122
  506. package/neural-interface/lib/assistant-brains/opencode-browser-policy.js +0 -47
  507. package/neural-interface/lib/assistant-brains/opencode-route-gate.js +0 -62
  508. package/neural-interface/lib/mcp-profile-servers.js +0 -120
  509. package/neural-interface/public/shared/ui-tutorial-draw.js +0 -311
  510. package/skills/leonardo/SKILL.md +0 -168
  511. package/skills/leonardo/icon.svg +0 -1
  512. package/skills/leonardo/modules/browser-guide.md +0 -378
  513. package/skills/leonardo/modules/image-prompter.md +0 -283
  514. package/skills/leonardo/modules/model-advisor.md +0 -100
  515. package/skills/leonardo/modules/prompt-library.md +0 -110
  516. package/skills/leonardo/modules/style-guide.md +0 -186
  517. package/skills/leonardo/modules/video-prompter.md +0 -317
@@ -1,3 +1,5 @@
1
+ import { workerRestart } from '../worker-restart.js';
2
+ import { t } from '../i18n.js';
1
3
  import { hostedSidepanelId, sidepanelHost } from '../ui-sidepanel-runtime.js';
2
4
  // ─────────────────────────────────────────────────────────────────────────────
3
5
  // OpenCode V2 — Panel container
@@ -10,20 +12,21 @@ import { hostedSidepanelId, sidepanelHost } from '../ui-sidepanel-runtime.js';
10
12
 
11
13
  import { state, emit, on } from '../state.js';
12
14
  import { storage } from '../storage.js';
15
+ import { frameRect } from '../app-frame.js';
13
16
  import { fetchProjects } from '../api.js';
14
17
  import { injectStyles } from './ocp-v2-styles.js';
15
18
  import { connect, api, hasSessionStore, onSessionCompacted, onEvent, onReconnect, supports, isDescendantSession } from './ocp-v2-ws.js';
16
19
  import {
17
- menuSessions, pickReusableEmptySession, shareView, SHARE_CONFIRM_TEXT, createPendingRenames, createStoppedShares,
20
+ menuSessions, pickReusableEmptySession, createPendingRenames,
18
21
  sessionBusyFromEvent, sessionBusyFromStatus, tabPillState, automationTurnPhase,
19
22
  } from './ocp-v2-sessions-logic.js';
20
23
  import {
21
- forkSession, shareSession, unshareSession, undoLastTurn, restoreReverted,
24
+ forkSession, undoLastTurn, restoreReverted,
22
25
  loadSelectedSession, applySessionSelections, restoreDraftAttachments,
23
26
  readTranscriptExport, stopForNavigation, createSessionForNavigation, renameSession,
24
27
  navigateAfter, adoptReusableSession, landWithoutTabs, shouldNameCreatedSession, renameBox,
25
28
  } from './ocp-v2-session-actions.js';
26
- import { captureBinding, latestOnly, latestFor, createNavigation } from './ocp-v2-binding.js';
29
+ import { captureBinding, latestFor, createNavigation } from './ocp-v2-binding.js';
27
30
  import { createConfirmations } from './ocp-v2-confirm-logic.js';
28
31
  import { syncConfirmRow } from './ocp-v2-confirm.js';
29
32
  import { closeWithPromptsConfirm, prefilledDraft, samePrompts } from './ocp-v2-composer-logic.js';
@@ -42,7 +45,7 @@ import { createAutoAcceptControl } from './ocp-v2-autoaccept-button.js';
42
45
  import { mountTodoWidget } from './ocp-v2-session-widgets.js';
43
46
  import { mountChangesBar } from './ocp-v2-changes.js';
44
47
  import { mountEnvironmentPopover } from './ocp-v2-status.js';
45
- import { watchWorktree, newSessionPlan, checkoutOutcome } from './ocp-v2-changes-logic.js';
48
+ import { newSessionPlan, checkoutOutcome } from './ocp-v2-changes-logic.js';
46
49
  import { mountRenderer } from './ocp-v2-render.js';
47
50
  import { offerGreeting } from './ocp-v2-greeting.js';
48
51
  import { mountCompose, focusCompose, appendPathToCompose } from './ocp-v2-send.js';
@@ -108,6 +111,7 @@ const _sessionBusy = new Map();
108
111
  const _automationContinuedManually = new Set();
109
112
  const _automationManualSendInFlight = new Set();
110
113
  const _foreignActiveAutomationSessions = new Set();
114
+ const _workerRestarts = new Map();
111
115
  const _workerEnds = new Map(); // sessionId -> end card of the dispatched worker it belongs to (ui-worker-end.js)
112
116
  let _renderer = null;
113
117
  let _visible = false;
@@ -136,30 +140,20 @@ let _composer = null; // the primary panel's composer (mountCompose)
136
140
  let _cliBanner = null; // the CLI banner and send-block (ui-cli-banner.js)
137
141
  let _cliWasBlocked = false; // the banner held sends back last time it said (a change to usable heals the serve)
138
142
  // Where the panel goes. Every choice of the user (a tab, a session in the
139
- // menu, New session, a project, a worktree) begins an intent, and a navigation
143
+ // menu, New session, a project) begins an intent, and a navigation
140
144
  // binds the panel only while its intent is the latest one: a later choice wins
141
145
  // over an older one that is still in flight (ocp-v2-binding.js). What the
142
146
  // panel starts by itself (boot, the recovery, an automation asking for focus)
143
147
  // only observes: it never overtakes a choice of the user.
144
148
  const _nav = createNavigation(getDefaultStore());
145
- // What publishes or destroys is asked in the panel, in two steps, never with a
146
- // native dialog (ocp-v2-confirm-logic.js). `surface` says where the question
147
- // is drawn: 'menu' under its row of the session menu, 'panel' above the
148
- // compose box, 'dialog' in the naming dialog.
149
+ // What destroys is asked in the panel, in two steps, never with a native
150
+ // dialog (ocp-v2-confirm-logic.js). `surface` says where the question is
151
+ // drawn: 'menu' under its row of the session menu, 'panel' above the compose
152
+ // box.
149
153
  const _confirms = createConfirmations({ store: getDefaultStore() });
150
154
  let _confirmSlotEl = null;
151
155
  const _menuConfirmAnchors = new Map(); // question key -> the menu row it is asked under
152
156
  _confirms.onChange(() => { syncSessionMenuConfirm(); syncPanelConfirm(); });
153
- // Share links whose sharing this panel stopped. OpenCode goes on reporting
154
- // them (createStoppedShares in ocp-v2-sessions-logic.js), so the store takes
155
- // such a link out of any session info it is handed, and so do the session
156
- // menu and the tab cache. One list for every window, kept across reloads.
157
- const STOR_STOPPED_SHARES = 'opencode-v2-stopped-shares';
158
- const _stoppedShares = createStoppedShares({
159
- load: () => JSON.parse(storage.getItem(STOR_STOPPED_SHARES) || '{}'),
160
- save: (entries) => storage.setItem(STOR_STOPPED_SHARES, JSON.stringify(entries)),
161
- });
162
- getDefaultStore().setSessionInfoFilter?.((info) => _stoppedShares.clean(info));
163
157
 
164
158
  function forkClonedOpenCodePersistence() {
165
159
  try {
@@ -469,6 +463,7 @@ function buildPanel() {
469
463
  onAttachPath: (path) => appendPathToCompose(path),
470
464
  });
471
465
  _contextMenu = mountContextMenu(actions, panel, getDefaultStore(), {
466
+ bounds: frameRect, // the popover stays in the app frame
472
467
  compact: createCompactControl(getDefaultStore()),
473
468
  autoAccept: createAutoAcceptControl(getDefaultStore()),
474
469
  onManage: () => environment.open(),
@@ -585,10 +580,6 @@ function buildPanel() {
585
580
  const result = failIfRefused(await forkSession(getDefaultStore(), api), 'Fork failed');
586
581
  if (result?.ok) await openCreatedSession(result.session, { activate: !result.moved, nav });
587
582
  },
588
- // Asked every time, in the session menu: /share only opens the question
589
- // there, and its button publishes the transcript at a public URL.
590
- share: () => shareActiveSession(),
591
- unshare: () => stopSharingActiveSession(),
592
583
  };
593
584
  composer = _composer = mountCompose(compose, getDefaultStore(), {
594
585
  slashActions,
@@ -667,7 +658,6 @@ function buildPanel() {
667
658
  if (eventType !== 'session.updated' && eventType !== 'session.deleted' && eventType !== 'session.created') return;
668
659
  if (eventType === 'session.deleted') {
669
660
  const sid = ev?.info?.id || ev?.sessionID || ev?.sessionId;
670
- if (sid) _stoppedShares.resume(sid);
671
661
  if (sid && _tabSessionIds.includes(sid)) {
672
662
  handlePillClose(sid).catch((err) => console.warn('[ocp-v2-panel] close of a deleted session failed', err));
673
663
  }
@@ -894,7 +884,7 @@ function updateOpenCodeTitleLocally(sessionId, title) {
894
884
  ? active.sessionInfo
895
885
  : _tabInfoCache.get(sessionId);
896
886
  const updated = { ...(current || {}), id: sessionId, title };
897
- _tabInfoCache.set(sessionId, _stoppedShares.clean(updated));
887
+ _tabInfoCache.set(sessionId, updated);
898
888
  if (sessionId === active.sessionId) setSession(sessionId, updated);
899
889
  ensureTab(sessionId, updated);
900
890
  renderPill();
@@ -1088,8 +1078,6 @@ let _sessionMenuSearch = '';
1088
1078
  let _sessionMenuArchived = false;
1089
1079
  let _sessionMenuBodyEl = null;
1090
1080
  let _sessionMenuRefreshTimer = null;
1091
- let _sharePolicy = null; // OpenCode's `share` setting, read once per menu open
1092
- const _sharePolicyReads = latestOnly();
1093
1081
  // The list under the search box: the newest read wins, and only for the
1094
1082
  // filters (search text, archived or not) the menu still shows.
1095
1083
  const _sessionMenuReads = latestFor();
@@ -1159,20 +1147,6 @@ async function renderSessionMenu() {
1159
1147
  _sessionMenuEl.appendChild(_sessionMenuBodyEl);
1160
1148
  _menuConfirmAnchors.clear();
1161
1149
 
1162
- // Whether sharing is allowed at all (D2: hidden when the config disables it).
1163
- // The policy is the project's: an answer for an earlier opening of the menu,
1164
- // or for the session the panel has left, is not this menu's.
1165
- _sharePolicy = null;
1166
- const policyIsFresh = _sharePolicyReads.begin();
1167
- const policyAt = captureBinding(getDefaultStore());
1168
- api.sessionSharePolicy({ cwd: policyAt.cwd || undefined }).then((res) => {
1169
- if (!policyIsFresh() || !policyAt.isCurrent()) return;
1170
- if (!replyFailed(res)) {
1171
- _sharePolicy = res.data?.share || 'manual';
1172
- scheduleSessionMenuRefresh(0);
1173
- }
1174
- }).catch(() => {});
1175
-
1176
1150
  await refreshSessionMenuBody();
1177
1151
  setTimeout(() => input.focus(), 0);
1178
1152
  }
@@ -1210,8 +1184,7 @@ async function refreshSessionMenuBody() {
1210
1184
  const cwd = s.cwd || storage.getItem(STOR_PROJECT) || '';
1211
1185
  // Sessions of every project are listed, so one from another registered
1212
1186
  // project can be resumed; sub-agent sessions open from their parent instead.
1213
- // (A link whose sharing the panel stopped is not a share: the row says so.)
1214
- const all = menuSessions(sessions, { search }).slice(0, SESSION_MENU_LIMIT).map((row) => _stoppedShares.clean(row));
1187
+ const all = menuSessions(sessions, { search }).slice(0, SESSION_MENU_LIMIT);
1215
1188
 
1216
1189
  body.innerHTML = '';
1217
1190
  _menuConfirmAnchors.clear();
@@ -1256,82 +1229,14 @@ async function refreshSessionMenuBody() {
1256
1229
  syncSessionMenuConfirm();
1257
1230
  }
1258
1231
 
1259
- // Publishing is two steps, both in the panel. "Share session…" (or /share)
1260
- // only asks: the question under it says what becomes public, and its button
1261
- // shares. Nothing is published by one click, and never by a native dialog.
1262
- async function shareActiveSession() {
1263
- const sid = getState().sessionId;
1264
- if (!sid) return null;
1265
- if (!_sessionMenuEl?.classList.contains('open')) openSessionMenu();
1266
- const result = await shareSession(getDefaultStore(), api, () => _confirms.ask({
1267
- key: `share:${sid}`, surface: 'menu', text: SHARE_CONFIRM_TEXT, confirmLabel: 'Share publicly',
1268
- }), { stopped: _stoppedShares });
1269
- if (result && result.ok === false && !result.cancelled && !result.moved) pushError({ message: result.error || 'Share failed' });
1270
- if (result?.ok && result.url) {
1271
- try { await navigator.clipboard.writeText(result.url); } catch {}
1272
- if (_sessionMenuEl?.classList.contains('open')) scheduleSessionMenuRefresh(0);
1273
- else openSessionMenu();
1274
- }
1275
- return result;
1276
- }
1277
-
1278
- // Stop sharing: the link goes from everything the panel holds of that
1279
- // session (the store, the tab cache, the menu), also when the panel was on
1280
- // another session by the time OpenCode answered.
1281
- async function stopSharingActiveSession() {
1282
- const sid = getState().sessionId;
1283
- const result = await unshareSession(getDefaultStore(), api, { stopped: _stoppedShares });
1284
- if (result && result.ok === false && !result.moved) pushError({ message: result.error || 'Could not stop sharing' });
1285
- if (sid) forgetStoppedShare(sid);
1286
- return result;
1287
- }
1288
-
1289
- function forgetStoppedShare(sessionId) {
1290
- const cached = _tabInfoCache.get(sessionId);
1291
- if (cached) _tabInfoCache.set(sessionId, _stoppedShares.clean(cached));
1292
- const known = getState().knownSessions;
1293
- if (known?.has?.(sessionId)) known.set(sessionId, _stoppedShares.clean(known.get(sessionId)));
1294
- scheduleSessionMenuRefresh(0);
1295
- }
1296
-
1297
- // Share / export / fork for the session that is open.
1232
+ // Export / fork for the session that is open.
1298
1233
  function appendActiveSessionActions(body, s) {
1299
1234
  if (!s.sessionId) return;
1300
- const share = shareView(s.sessionInfo, _sharePolicy, supports);
1301
1235
  const report = (result, fallback) => {
1302
1236
  if (result && result.ok === false && !result.cancelled && !result.moved) pushError({ message: result.error || fallback });
1303
1237
  return result;
1304
1238
  };
1305
1239
 
1306
- // Asked every time, under this item: the click only opens the question.
1307
- // (The item is there while its question is armed, whatever the policy read
1308
- // says by then: /share asks before that read is back.)
1309
- const shareKey = `share:${s.sessionId}`;
1310
- if ((share.canShare && _sharePolicy) || _confirms.isArmed(shareKey)) {
1311
- const shareItem = menuItem('Share session…', () => {
1312
- shareActiveSession().catch((err) => pushError({ message: err?.message || 'Share failed' }));
1313
- }, { muted: true });
1314
- _menuConfirmAnchors.set(shareKey, shareItem);
1315
- body.appendChild(shareItem);
1316
- }
1317
- if (share.showLink) {
1318
- body.appendChild(menuItem('Copy share link', async () => {
1319
- // A failed copy is reported in the session whose link it was.
1320
- const at = captureBinding(getDefaultStore());
1321
- try { await navigator.clipboard.writeText(share.url); } catch (err) {
1322
- if (at.isCurrent()) pushError({ message: err?.message || 'Copy failed' });
1323
- }
1324
- }, { muted: true, meta: 'public' }));
1325
- const url = document.createElement('div');
1326
- url.className = 'ocpv2-session-share-url';
1327
- url.textContent = share.url;
1328
- body.appendChild(url);
1329
- }
1330
- if (share.canUnshare) {
1331
- body.appendChild(menuItem('Stop sharing', () => {
1332
- stopSharingActiveSession().catch((err) => pushError({ message: err?.message || 'Could not stop sharing' }));
1333
- }, { muted: true }));
1334
- }
1335
1240
  if (s.messageOrder.length) {
1336
1241
  body.appendChild(menuItem('Export transcript', () => {
1337
1242
  closeSessionMenu();
@@ -1371,7 +1276,7 @@ function buildSessionMenuItem(sess, s, cwd, { archived, filters }) {
1371
1276
  labelEl.textContent = title;
1372
1277
  item.appendChild(labelEl);
1373
1278
 
1374
- const meta = [projectName, sess.share?.url ? 'shared' : ''].filter(Boolean).join(' · ');
1279
+ const meta = projectName || '';
1375
1280
  if (meta) {
1376
1281
  const metaEl = document.createElement('span');
1377
1282
  metaEl.className = 'ocpv2-session-item-meta';
@@ -1567,7 +1472,7 @@ async function restoreSessionSelections(sid, info) {
1567
1472
  applySessionSelections(getDefaultStore(), full);
1568
1473
  // Fresh metadata too: keeps the title right after a switch.
1569
1474
  getDefaultStore().setSessionInfo(full);
1570
- _tabInfoCache.set(sid, _stoppedShares.clean({ ...(_tabInfoCache.get(sid) || {}), ...full }));
1475
+ _tabInfoCache.set(sid, { ...(_tabInfoCache.get(sid) || {}), ...full });
1571
1476
  if (!info) ensureTab(sid, full);
1572
1477
  });
1573
1478
  }
@@ -1689,7 +1594,7 @@ async function boot() {
1689
1594
  const info = byId.get(sid);
1690
1595
  if (info) {
1691
1596
  liveTabs.push(sid);
1692
- _tabInfoCache.set(sid, _stoppedShares.clean(info));
1597
+ _tabInfoCache.set(sid, info);
1693
1598
  ensureOpenCodeTitleState(sid, info, { manual: true });
1694
1599
  }
1695
1600
  }
@@ -1699,7 +1604,7 @@ async function boot() {
1699
1604
  if (!liveTabs.length && _pendingAutomationAttach?.sessionId) {
1700
1605
  const { sessionId, info } = _pendingAutomationAttach;
1701
1606
  liveTabs.push(sessionId);
1702
- _tabInfoCache.set(sessionId, _stoppedShares.clean(info || { id: sessionId }));
1607
+ _tabInfoCache.set(sessionId, info || { id: sessionId });
1703
1608
  ensureOpenCodeTitleState(sessionId, info, { manual: true });
1704
1609
  _tabSessionIds = [...liveTabs];
1705
1610
  saveTabSessions();
@@ -1959,14 +1864,6 @@ function promptNameNewSession(targetSessionId = null) {
1959
1864
  <label class="ocpv2-name-modal-label">Branch</label>
1960
1865
  <select class="ocpv2-name-modal-select" data-role="branch" disabled></select>
1961
1866
  </div>
1962
- <div class="ocpv2-name-modal-row ocpv2-name-modal-worktree" hidden>
1963
- <label class="ocpv2-name-modal-label">Worktree</label>
1964
- <label class="ocpv2-name-modal-check">
1965
- <input type="checkbox" data-role="worktree" />
1966
- <span>Run in a new git worktree</span>
1967
- </label>
1968
- </div>
1969
- <div class="ocpv2-name-modal-worktrees" hidden></div>
1970
1867
  <input type="text" class="ocpv2-name-modal-input" placeholder="Session name..." maxlength="120" />
1971
1868
  <div class="ocpv2-name-modal-actions">
1972
1869
  <button type="button" class="ocpv2-name-modal-btn skip">Skip</button>
@@ -1991,14 +1888,6 @@ function promptNameNewSession(targetSessionId = null) {
1991
1888
 
1992
1889
  let branchOriginal = null;
1993
1890
  let branchesKnown = false;
1994
- // A session in a new worktree starts from what the project has checked out
1995
- // now; the project's own checkout is never switched for it.
1996
- const syncBranchLock = () => {
1997
- const locked = !!worktreeCheck?.checked;
1998
- if (locked && branchOriginal) branchSel.value = branchOriginal;
1999
- branchSel.disabled = locked || !branchesKnown;
2000
- branchSel.title = locked ? 'A new worktree starts from the branch the project has checked out.' : '';
2001
- };
2002
1891
  let branchRequest = 0;
2003
1892
  async function refreshBranches(path) {
2004
1893
  const request = ++branchRequest;
@@ -2021,75 +1910,13 @@ function promptNameNewSession(targetSessionId = null) {
2021
1910
  if (branchOriginal) branchSel.value = branchOriginal;
2022
1911
  branchesKnown = true;
2023
1912
  }
2024
- syncBranchLock();
1913
+ branchSel.disabled = !branchesKnown;
2025
1914
  }
2026
1915
 
2027
- // Worktrees: an isolated checkout OpenCode creates for the session, so its
2028
- // edits stay out of the main working tree. Offered only when the server can.
2029
- const worktreeRow = overlay.querySelector('.ocpv2-name-modal-worktree');
2030
- const worktreeCheck = overlay.querySelector('input[data-role="worktree"]');
2031
- const worktreeList = overlay.querySelector('.ocpv2-name-modal-worktrees');
2032
- worktreeCheck?.addEventListener('change', syncBranchLock);
2033
1916
  refreshBranches(projectSel?.value || initialProject);
2034
- const worktreeReads = latestOnly();
2035
- // Removing a worktree is asked in the dialog, under its row.
2036
- const worktreeConfirmAnchors = new Map();
2037
- const dialogQuestion = (view) => view.surface === 'dialog';
2038
- const offWorktreeConfirm = _confirms.onChange(() => {
2039
- syncConfirmRow(_confirms, worktreeList, 'dialog', (key) => worktreeConfirmAnchors.get(key));
2040
- });
2041
- async function refreshWorktrees(path) {
2042
- // The rows are read again: a question about one of them is off.
2043
- _confirms.cancel(dialogQuestion);
2044
- worktreeConfirmAnchors.clear();
2045
- const canCreate = supports('worktree:create') && !!path;
2046
- worktreeRow.hidden = !canCreate;
2047
- if (!canCreate) worktreeCheck.checked = false;
2048
- syncBranchLock();
2049
- worktreeList.hidden = true;
2050
- worktreeList.textContent = '';
2051
- if (!path || !supports('worktree:list', 'worktree:remove')) return;
2052
- const latest = worktreeReads.begin();
2053
- const res = await api.worktreeList({ cwd: path }).catch(() => null);
2054
- // A newer read (another project picked, a worktree removed) owns the list.
2055
- if (!latest() || replyFailed(res) || !Array.isArray(res.data) || !res.data.length || projectSel?.value !== path) return;
2056
- worktreeList.hidden = false;
2057
- for (const tree of res.data) {
2058
- const row = document.createElement('div');
2059
- row.className = 'ocpv2-permission-more';
2060
- const name = document.createElement('code');
2061
- name.textContent = tree.branch ? `${tree.name} (${tree.branch})` : tree.name;
2062
- name.title = tree.directory;
2063
- const remove = document.createElement('button');
2064
- remove.type = 'button';
2065
- remove.className = 'ocpv2-permission-link';
2066
- remove.textContent = 'Remove';
2067
- remove.addEventListener('click', async () => {
2068
- // This click only asks; the button of the question removes it.
2069
- const key = `worktree-remove:${tree.directory}`;
2070
- worktreeConfirmAnchors.set(key, row);
2071
- const agreed = await _confirms.ask({
2072
- key, surface: 'dialog', confirmLabel: 'Remove worktree',
2073
- text: `Remove the worktree "${tree.name}"? Its directory and uncommitted changes are deleted.`,
2074
- });
2075
- if (!agreed) return;
2076
- const removed = await api.worktreeRemove({ cwd: path, directory: tree.directory }).catch((err) => ({ ok: false, error: err?.message }));
2077
- // The failure is about the worktree, not about a session: it is shown
2078
- // wherever the panel is. The list is this dialog's: it is read again
2079
- // only while the dialog is open and still on that project.
2080
- if (replyFailed(removed)) { pushError({ message: replyError(removed, 'Could not remove the worktree') }); return; }
2081
- if (done || projectSel?.value !== path) return;
2082
- refreshWorktrees(path);
2083
- });
2084
- row.append(name, remove);
2085
- worktreeList.appendChild(row);
2086
- }
2087
- }
2088
- refreshWorktrees(projectSel?.value || initialProject);
2089
1917
 
2090
1918
  projectSel?.addEventListener('change', () => {
2091
1919
  refreshBranches(projectSel.value);
2092
- refreshWorktrees(projectSel.value);
2093
1920
  });
2094
1921
 
2095
1922
  setTimeout(() => { input.focus(); input.select(); }, 10);
@@ -2098,8 +1925,6 @@ function promptNameNewSession(targetSessionId = null) {
2098
1925
  const close = () => {
2099
1926
  if (done) return;
2100
1927
  done = true;
2101
- offWorktreeConfirm();
2102
- _confirms.cancel(dialogQuestion);
2103
1928
  overlay.remove();
2104
1929
  };
2105
1930
 
@@ -2108,29 +1933,20 @@ function promptNameNewSession(targetSessionId = null) {
2108
1933
  const nextTitle = input.value.trim();
2109
1934
  const chosenProject = projectSel?.value || '';
2110
1935
  const chosenBranch = branchSel?.value || '';
2111
- const wantsWorktree = !!worktreeCheck?.checked && !!chosenProject;
2112
1936
  close();
2113
1937
  // Skip leaves the freshly-created session in place — same as Claude/Codex
2114
1938
  // where dismissing the rename modal keeps the empty new tab.
2115
1939
  if (cancel) return;
2116
1940
 
2117
1941
  const plan = newSessionPlan({
2118
- project: chosenProject, branch: chosenBranch, currentBranch: branchOriginal || '',
2119
- wantsWorktree, cwd: getState().cwd || '',
1942
+ project: chosenProject, branch: chosenBranch, currentBranch: branchOriginal || '', cwd: getState().cwd || '',
2120
1943
  });
2121
1944
  const projectChanged = plan.projectChanged;
2122
1945
  // What Save starts is a navigation of its own when it creates a session
2123
- // (in a worktree, in another project): it owns the panel from this click
2124
- // on, unless the user chooses something else while it waits. A Save that
2125
- // only names the session navigates nowhere and begins no intent.
2126
- const nav = (plan.worktree || projectChanged) ? _nav.begin() : null;
2127
-
2128
- // The worktree first: an isolated session never switches the branch of the
2129
- // project's own checkout.
2130
- if (plan.worktree) {
2131
- await startSessionInNewWorktree(chosenProject, nextTitle, nav);
2132
- return;
2133
- }
1946
+ // (in another project): it owns the panel from this click on, unless the
1947
+ // user chooses something else while it waits. A Save that only names the
1948
+ // session navigates nowhere and begins no intent.
1949
+ const nav = projectChanged ? _nav.begin() : null;
2134
1950
 
2135
1951
  if (plan.checkout) {
2136
1952
  // A session started after a failed switch would run on the wrong base.
@@ -2198,40 +2014,6 @@ function promptNameNewSession(targetSessionId = null) {
2198
2014
  });
2199
2015
  }
2200
2016
 
2201
- // "Run in a new git worktree": OpenCode creates the worktree (and runs the
2202
- // project's start command in it), then the session is created inside it. The
2203
- // project stays the remembered default; only this session lives in the worktree.
2204
- async function startSessionInNewWorktree(projectPath, title, nav = _nav.begin()) {
2205
- // Subscribe before creating: the ready event can beat the reply. Events are
2206
- // held until the reply names this worktree, so another creation finishing
2207
- // (or failing) first is not mistaken for this one.
2208
- const watch = watchWorktree(onEvent, { timeoutMs: 60_000 });
2209
- const created = await api.worktreeCreate({ cwd: projectPath }).catch((err) => ({ ok: false, error: err?.message }));
2210
- if (replyFailed(created) || !created.data?.directory) {
2211
- watch.cancel();
2212
- pushError({ message: replyError(created, 'Could not create the worktree') });
2213
- return;
2214
- }
2215
- watch.identify(created.data.name);
2216
- const state = await watch.result;
2217
- if (!state.ok) {
2218
- pushError({ message: state.error });
2219
- return;
2220
- }
2221
- // Up to a minute has passed. The session is created in the worktree either
2222
- // way; it takes the panel only when the user did not navigate meanwhile
2223
- // (`nav`), and is a tab otherwise.
2224
- if (nav.isCurrent()) {
2225
- const prevSid = getState().sessionId;
2226
- if (prevSid) ensureTab(prevSid, getState().sessionInfo);
2227
- }
2228
- try {
2229
- await startFreshSession({ title: title || undefined, cwd: created.data.directory, nav });
2230
- } catch (err) {
2231
- pushError({ message: err?.message || 'New session failed' });
2232
- }
2233
- }
2234
-
2235
2017
  async function closeCurrentSession() {
2236
2018
  // Update the UI first; server cleanup is best-effort and must not block the
2237
2019
  // only visible tab from closing.
@@ -2356,7 +2138,7 @@ function saveTabSessions() {
2356
2138
 
2357
2139
  function ensureTab(sessionId, info = null) {
2358
2140
  if (!sessionId) return;
2359
- if (info) _tabInfoCache.set(sessionId, _stoppedShares.clean(info));
2141
+ if (info) _tabInfoCache.set(sessionId, info);
2360
2142
  if (!_tabSessionIds.includes(sessionId)) {
2361
2143
  _tabSessionIds.push(sessionId);
2362
2144
  saveTabSessions();
@@ -2516,7 +2298,17 @@ async function closeTabByUser(sessionId, context) {
2516
2298
  // Assistant session that dispatched it.
2517
2299
  function workerEndCard(sessionId) {
2518
2300
  const view = sessionId ? _workerEnds.get(sessionId) : null;
2519
- if (!view) return null;
2301
+ if (!view) {
2302
+ const restart = _workerRestarts.get(sessionId);
2303
+ if (!restart?.key) return null;
2304
+ return { sig: restart.stamp, build: () => {
2305
+ const el = document.createElement('div');
2306
+ el.className = 'ocpv2-post-plan-card ocpv2-post-plan-body';
2307
+ el.setAttribute('role', 'status');
2308
+ el.textContent = t(restart.key);
2309
+ return el;
2310
+ } };
2311
+ }
2520
2312
  return {
2521
2313
  sig: view.sig,
2522
2314
  build: () => buildWorkerEndCard(view, {
@@ -2727,7 +2519,9 @@ export async function attachOpenCodeAutomation(run, { focus = !!run?.focus, isCa
2727
2519
  // Establish ownership before connect()/boot(): native provider events use a
2728
2520
  // separate socket and may report a Task child while this attach is awaiting.
2729
2521
  const previousRunId = _automationRunIds.get(sessionId);
2730
- const running = run.status === 'starting' || run.status === 'running';
2522
+ const restart = workerRestart(run);
2523
+ const running = restart.active;
2524
+ _workerRestarts.set(sessionId, restart);
2731
2525
  // The user continued this run's session by hand after the run ended: the tab stays theirs.
2732
2526
  const released = !running && previousRunId === run.runId
2733
2527
  && (_automationContinuedManually.has(sessionId) || _automationManualSendInFlight.has(sessionId));
@@ -2748,7 +2542,7 @@ export async function attachOpenCodeAutomation(run, { focus = !!run?.focus, isCa
2748
2542
  id: sessionId,
2749
2543
  title: run.title || 'Automation',
2750
2544
  directory: run.cwd || '',
2751
- mcpProfile: run.mcpProfile || null,
2545
+ tools: run.tools || null,
2752
2546
  time: { updated: Date.now() },
2753
2547
  };
2754
2548
  if (!_booted) _pendingAutomationAttach = { sessionId, info };
@@ -2778,16 +2572,17 @@ export async function attachOpenCodeAutomation(run, { focus = !!run?.focus, isCa
2778
2572
  if (!_visible) await showPrimaryOpencodePanel();
2779
2573
  await switchToSession(sessionId, info, { nav });
2780
2574
  } else if (getState().sessionId === sessionId) {
2781
- setRunning(running);
2575
+ setRunning(running && !restart.suspended);
2782
2576
  await rehydrateActiveSession().catch(() => {});
2783
2577
  }
2784
- if (getState().sessionId === sessionId) setRunning(running);
2578
+ if (getState().sessionId === sessionId) setRunning(running && !restart.suspended);
2579
+ _renderer?.render();
2785
2580
  // (A dispatched worker's failure, with its reason, is on its end card.)
2786
2581
  if (run.status === 'failed' && run.error && !isDispatchedRun(run) && getState().sessionId === sessionId
2787
2582
  && _tabInfoCache.get(sessionId)?._automationLifecycleError !== run.error) {
2788
2583
  const cachedInfo = _tabInfoCache.get(sessionId) || info;
2789
2584
  cachedInfo._automationLifecycleError = run.error;
2790
- _tabInfoCache.set(sessionId, _stoppedShares.clean(cachedInfo));
2585
+ _tabInfoCache.set(sessionId, cachedInfo);
2791
2586
  pushError({ message: run.error });
2792
2587
  }
2793
2588
  trackWorkerEnd(run, { apply: (view) => showWorkerEnd(sessionId, view) });
@@ -305,8 +305,7 @@ export async function handlePostPlanAction(action, store) {
305
305
  const res = await api.compact({
306
306
  sessionId: at.sessionId,
307
307
  cwd: at.cwd || undefined,
308
- mcpProfile: at.mcpProfile || undefined,
309
- model: at.model || undefined,
308
+ tools: at.tools || undefined,
310
309
  });
311
310
  // The compaction was that session's. On another binding there is no plan
312
311
  // card of it to relabel and nobody to tell about its failure.