synabun 2.0.9 → 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 (679) hide show
  1. package/CHANGELOG.md +115 -0
  2. package/README.md +25 -2
  3. package/THIRD-PARTY-LICENSES.md +68 -4
  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/launcher.mjs +9 -3
  10. package/lib/claude-hooks.js +172 -18
  11. package/lib/client-config-repair.js +17 -8
  12. package/lib/desktop-app.js +7 -1
  13. package/lib/external-tools.js +1 -1
  14. package/lib/first-launch-protection.js +57 -12
  15. package/lib/mcp-dist.js +176 -0
  16. package/lib/release-npm-ci.mjs +138 -0
  17. package/lib/release-publish.mjs +91 -0
  18. package/lib/release-scan.mjs +50 -0
  19. package/lib/server-crash-record.js +123 -0
  20. package/lib/server-exit.js +318 -0
  21. package/lib/server-supervisor.js +508 -0
  22. package/lib/start-launcher.js +43 -5
  23. package/lib/tools-cli.js +45 -0
  24. package/lib/update-snapshot.js +228 -0
  25. package/lib/virustotal.mjs +192 -0
  26. package/lib/windows-crash-event.js +269 -0
  27. package/mcp-server/dist/http.d.ts +20 -1
  28. package/mcp-server/dist/http.d.ts.map +1 -1
  29. package/mcp-server/dist/http.js +59 -12
  30. package/mcp-server/dist/http.js.map +1 -1
  31. package/mcp-server/dist/index.d.ts +33 -27
  32. package/mcp-server/dist/index.d.ts.map +1 -1
  33. package/mcp-server/dist/index.js +128 -143
  34. package/mcp-server/dist/index.js.map +1 -1
  35. package/mcp-server/dist/preload.js +1 -1
  36. package/mcp-server/dist/preload.js.map +1 -1
  37. package/mcp-server/dist/services/codex-config-heal.d.ts +6 -2
  38. package/mcp-server/dist/services/codex-config-heal.d.ts.map +1 -1
  39. package/mcp-server/dist/services/codex-config-heal.js +81 -28
  40. package/mcp-server/dist/services/codex-config-heal.js.map +1 -1
  41. package/mcp-server/dist/services/memory-judge-backfill.d.ts +6 -0
  42. package/mcp-server/dist/services/memory-judge-backfill.d.ts.map +1 -1
  43. package/mcp-server/dist/services/memory-judge-backfill.js +7 -1
  44. package/mcp-server/dist/services/memory-judge-backfill.js.map +1 -1
  45. package/mcp-server/dist/services/neural-interface.d.ts +16 -10
  46. package/mcp-server/dist/services/neural-interface.d.ts.map +1 -1
  47. package/mcp-server/dist/services/neural-interface.js +67 -11
  48. package/mcp-server/dist/services/neural-interface.js.map +1 -1
  49. package/mcp-server/dist/services/server-instructions.d.ts +7 -2
  50. package/mcp-server/dist/services/server-instructions.d.ts.map +1 -1
  51. package/mcp-server/dist/services/server-instructions.js +20 -62
  52. package/mcp-server/dist/services/server-instructions.js.map +1 -1
  53. package/mcp-server/dist/services/tool-catalog.d.ts +120 -0
  54. package/mcp-server/dist/services/tool-catalog.d.ts.map +1 -0
  55. package/mcp-server/dist/services/tool-catalog.js +339 -0
  56. package/mcp-server/dist/services/tool-catalog.js.map +1 -0
  57. package/mcp-server/dist/services/tool-list-refresh-barrier.d.ts +12 -0
  58. package/mcp-server/dist/services/tool-list-refresh-barrier.d.ts.map +1 -0
  59. package/mcp-server/dist/services/tool-list-refresh-barrier.js +40 -0
  60. package/mcp-server/dist/services/tool-list-refresh-barrier.js.map +1 -0
  61. package/mcp-server/dist/services/tool-list.d.ts +108 -0
  62. package/mcp-server/dist/services/tool-list.d.ts.map +1 -0
  63. package/mcp-server/dist/services/tool-list.js +334 -0
  64. package/mcp-server/dist/services/tool-list.js.map +1 -0
  65. package/mcp-server/dist/services/tool-runtime.d.ts +161 -0
  66. package/mcp-server/dist/services/tool-runtime.d.ts.map +1 -0
  67. package/mcp-server/dist/services/tool-runtime.js +400 -0
  68. package/mcp-server/dist/services/tool-runtime.js.map +1 -0
  69. package/mcp-server/dist/services/whiteboard-geometry.d.ts +26 -2
  70. package/mcp-server/dist/services/whiteboard-geometry.d.ts.map +1 -1
  71. package/mcp-server/dist/services/whiteboard-geometry.js +91 -8
  72. package/mcp-server/dist/services/whiteboard-geometry.js.map +1 -1
  73. package/mcp-server/dist/tools/agents.d.ts +10 -10
  74. package/mcp-server/dist/tools/agents.d.ts.map +1 -1
  75. package/mcp-server/dist/tools/agents.js +22 -13
  76. package/mcp-server/dist/tools/agents.js.map +1 -1
  77. package/mcp-server/dist/tools/browser-batch.d.ts +3 -3
  78. package/mcp-server/dist/tools/image-tools.d.ts +1 -1
  79. package/mcp-server/dist/tools/image-tools.js +1 -1
  80. package/mcp-server/dist/tools/skill-tools.d.ts +505 -0
  81. package/mcp-server/dist/tools/skill-tools.d.ts.map +1 -0
  82. package/mcp-server/dist/tools/skill-tools.js +639 -0
  83. package/mcp-server/dist/tools/skill-tools.js.map +1 -0
  84. package/mcp-server/dist/tools/skill.d.ts +7 -0
  85. package/mcp-server/dist/tools/skill.d.ts.map +1 -0
  86. package/mcp-server/dist/tools/skill.js +11 -0
  87. package/mcp-server/dist/tools/skill.js.map +1 -0
  88. package/mcp-server/dist/tools/tool-groups.d.ts +68 -0
  89. package/mcp-server/dist/tools/tool-groups.d.ts.map +1 -0
  90. package/mcp-server/dist/tools/tool-groups.js +147 -0
  91. package/mcp-server/dist/tools/tool-groups.js.map +1 -0
  92. package/mcp-server/dist/tools/whiteboard-format.d.ts.map +1 -1
  93. package/mcp-server/dist/tools/whiteboard-format.js +7 -4
  94. package/mcp-server/dist/tools/whiteboard-format.js.map +1 -1
  95. package/mcp-server/dist/tools/whiteboard-tools.d.ts +64 -13
  96. package/mcp-server/dist/tools/whiteboard-tools.d.ts.map +1 -1
  97. package/mcp-server/dist/tools/whiteboard-tools.js +30 -5
  98. package/mcp-server/dist/tools/whiteboard-tools.js.map +1 -1
  99. package/mcp-server/package-lock.json +2 -2
  100. package/mcp-server/package.json +1 -1
  101. package/mcp-server/src/http.ts +75 -12
  102. package/mcp-server/src/index.ts +147 -154
  103. package/mcp-server/src/preload.ts +12 -12
  104. package/mcp-server/src/services/codex-config-heal.ts +80 -29
  105. package/mcp-server/src/services/memory-judge-backfill.ts +7 -1
  106. package/mcp-server/src/services/neural-interface.ts +79 -20
  107. package/mcp-server/src/services/server-instructions.ts +27 -63
  108. package/mcp-server/src/services/tool-catalog.ts +403 -0
  109. package/mcp-server/src/services/tool-list-refresh-barrier.ts +33 -0
  110. package/mcp-server/src/services/tool-list.ts +410 -0
  111. package/mcp-server/src/services/tool-runtime.ts +457 -0
  112. package/mcp-server/src/services/whiteboard-geometry.ts +94 -9
  113. package/mcp-server/src/tools/agents.ts +22 -14
  114. package/mcp-server/src/tools/image-tools.ts +1 -1
  115. package/mcp-server/src/tools/skill-tools.ts +589 -0
  116. package/mcp-server/src/tools/skill.ts +13 -0
  117. package/mcp-server/src/tools/tool-groups.ts +164 -0
  118. package/mcp-server/src/tools/whiteboard-format.ts +9 -3
  119. package/mcp-server/src/tools/whiteboard-tools.ts +39 -5
  120. package/neural-interface/i18n/en.json +3680 -206
  121. package/neural-interface/i18n/pt-BR.json +3628 -157
  122. package/neural-interface/lib/account-usage.js +5 -3
  123. package/neural-interface/lib/app-controls-api.js +161 -0
  124. package/neural-interface/lib/assistant-api.js +148 -35
  125. package/neural-interface/lib/assistant-brains/claude.js +4 -3
  126. package/neural-interface/lib/assistant-brains/codex-browser-policy-hook.mjs +12 -2
  127. package/neural-interface/lib/assistant-brains/codex-route-gate-hook.mjs +32 -9
  128. package/neural-interface/lib/assistant-brains/codex.js +9 -5
  129. package/neural-interface/lib/assistant-brains/opencode.js +122 -44
  130. package/neural-interface/lib/assistant-brains/opencode2-browser-policy/index.js +59 -0
  131. package/neural-interface/lib/assistant-brains/opencode2-route-gate/index.js +97 -0
  132. package/neural-interface/lib/assistant-catalog.js +23 -9
  133. package/neural-interface/lib/assistant-dispatch.js +874 -156
  134. package/neural-interface/lib/assistant-envelope.js +22 -2
  135. package/neural-interface/lib/assistant-persona.js +80 -11
  136. package/neural-interface/lib/assistant-plan-permissions.js +10 -9
  137. package/neural-interface/lib/assistant-route-gate-codex.js +3 -0
  138. package/neural-interface/lib/assistant-route-gate.js +6 -4
  139. package/neural-interface/lib/assistant-router.js +13 -8
  140. package/neural-interface/lib/assistant-runtime.js +183 -26
  141. package/neural-interface/lib/assistant-task-prompt.js +78 -14
  142. package/neural-interface/lib/assistant-tools.js +51 -0
  143. package/neural-interface/lib/backup-service.js +620 -3
  144. package/neural-interface/lib/backup-zip-reader.js +10 -5
  145. package/neural-interface/lib/backup-zip-writer.js +257 -0
  146. package/neural-interface/lib/browser-execution.js +10 -2
  147. package/neural-interface/lib/browser-guard-cdp.js +83 -0
  148. package/neural-interface/lib/browser-network-guard.js +284 -0
  149. package/neural-interface/lib/browser-policy-roots.js +64 -0
  150. package/neural-interface/lib/browser-tool-policy.js +186 -31
  151. package/neural-interface/lib/claude-agent-bridge.js +4 -2
  152. package/neural-interface/lib/claude-hooks-status.js +103 -0
  153. package/neural-interface/lib/claude-model-catalog.js +64 -14
  154. package/neural-interface/lib/claude-temporary.js +5 -11
  155. package/neural-interface/lib/cli-install.js +18 -138
  156. package/neural-interface/lib/cli-resolver.js +4 -1
  157. package/neural-interface/lib/cli-update-planner.js +32 -31
  158. package/neural-interface/lib/cloudflared/tunnel.js +42 -2
  159. package/neural-interface/lib/codex-mcp-approvals.js +11 -0
  160. package/neural-interface/lib/codex-settings-schema.js +109 -47
  161. package/neural-interface/lib/codex-worker-app-server.js +172 -0
  162. package/neural-interface/lib/confined-fs.js +30 -3
  163. package/neural-interface/lib/crash-notice-api.js +98 -0
  164. package/neural-interface/lib/editor-completion-opencode.js +164 -67
  165. package/neural-interface/lib/exec-loop-command.js +4 -1
  166. package/neural-interface/lib/http-guards.js +8 -2
  167. package/neural-interface/lib/install-details.js +4 -1
  168. package/neural-interface/lib/launch-cache.js +293 -0
  169. package/neural-interface/lib/login-start.js +524 -0
  170. package/neural-interface/lib/mcp-agent-servers.js +67 -0
  171. package/neural-interface/lib/mcp-client-config.js +0 -29
  172. package/neural-interface/lib/mcp-external-servers.js +323 -0
  173. package/neural-interface/lib/{mcp-profile-refresh-coordinator.js → mcp-tools-refresh-coordinator.js} +4 -4
  174. package/neural-interface/lib/morelogin.js +30 -0
  175. package/neural-interface/lib/native-loop-providers.js +565 -50
  176. package/neural-interface/lib/native-loop-runtime.js +287 -41
  177. package/neural-interface/lib/opencode-config.js +557 -0
  178. package/neural-interface/lib/opencode-db-schema.js +58 -0
  179. package/neural-interface/lib/opencode-history.js +49 -204
  180. package/neural-interface/lib/opencode-mcp-ready.js +108 -0
  181. package/neural-interface/lib/opencode-native-boundary.js +44 -0
  182. package/neural-interface/lib/opencode-protocol.js +310 -0
  183. package/neural-interface/lib/opencode-provider-view.js +81 -0
  184. package/neural-interface/lib/opencode-runtime-config.js +32 -15
  185. package/neural-interface/lib/opencode-serve-records.js +624 -0
  186. package/neural-interface/lib/opencode-v2-client.js +53 -131
  187. package/neural-interface/lib/opencode-v2-ws-requests.js +35 -195
  188. package/neural-interface/lib/opencode-worker-activity.js +229 -0
  189. package/neural-interface/lib/opencode-worker-data.js +27 -0
  190. package/neural-interface/lib/opencode2-client.js +796 -0
  191. package/neural-interface/lib/opencode2-proxy.js +76 -0
  192. package/neural-interface/lib/opencode2-translate.js +1057 -0
  193. package/neural-interface/lib/owner-authority.js +249 -0
  194. package/neural-interface/lib/page-session.js +275 -0
  195. package/neural-interface/lib/peer-identity.js +763 -0
  196. package/neural-interface/lib/process-identity.js +361 -0
  197. package/neural-interface/lib/request-gate.js +17 -2
  198. package/neural-interface/lib/rulesets/api.js +1 -1
  199. package/neural-interface/lib/rulesets/fs-safe.js +1 -1
  200. package/neural-interface/lib/rulesets/installer.js +92 -27
  201. package/neural-interface/lib/rulesets/json-edit.js +1 -1
  202. package/neural-interface/lib/session-cache-builder.js +18 -10
  203. package/neural-interface/lib/session-title-generator.js +58 -18
  204. package/neural-interface/lib/skills/api-v2.js +495 -0
  205. package/neural-interface/lib/skills/bundle.js +418 -0
  206. package/neural-interface/lib/skills/catalog.js +294 -0
  207. package/neural-interface/lib/skills/creation-api.js +191 -0
  208. package/neural-interface/lib/skills/creation-brief.js +247 -0
  209. package/neural-interface/lib/skills/creation-sources.js +267 -0
  210. package/neural-interface/lib/skills/creation.js +843 -0
  211. package/neural-interface/lib/skills/deploy.js +564 -0
  212. package/neural-interface/lib/skills/digest.js +119 -0
  213. package/neural-interface/lib/skills/discover.js +111 -0
  214. package/neural-interface/lib/skills/draft-confinement.js +214 -0
  215. package/neural-interface/lib/skills/eval-confinement.js +397 -0
  216. package/neural-interface/lib/skills/eval-sandbox.js +280 -0
  217. package/neural-interface/lib/skills/eval-trace.js +119 -0
  218. package/neural-interface/lib/skills/evals-api.js +212 -0
  219. package/neural-interface/lib/skills/evals.js +1573 -0
  220. package/neural-interface/lib/skills/export.js +200 -0
  221. package/neural-interface/lib/skills/frontmatter.js +64 -0
  222. package/neural-interface/lib/skills/health.js +75 -0
  223. package/neural-interface/lib/skills/json-edit.js +165 -0
  224. package/neural-interface/lib/skills/known-bridge-digests.json +387 -0
  225. package/neural-interface/lib/skills/known-bridges.js +96 -0
  226. package/neural-interface/lib/skills/library.js +823 -0
  227. package/neural-interface/lib/skills/local-store.js +21 -0
  228. package/neural-interface/lib/skills/migration.js +433 -0
  229. package/neural-interface/lib/skills/operations.js +45 -0
  230. package/neural-interface/lib/skills/ownership.js +427 -0
  231. package/neural-interface/lib/skills/packages.js +88 -0
  232. package/neural-interface/lib/skills/reviews.js +212 -0
  233. package/neural-interface/lib/skills/revision.js +80 -0
  234. package/neural-interface/lib/skills/roots.js +262 -0
  235. package/neural-interface/lib/skills/runtime-checks.js +355 -0
  236. package/neural-interface/lib/skills/scan-assets.js +252 -0
  237. package/neural-interface/lib/skills/scan-context.js +26 -0
  238. package/neural-interface/lib/skills/scan-shell.js +324 -0
  239. package/neural-interface/lib/skills/scan.js +364 -0
  240. package/neural-interface/lib/skills/scanners.js +54 -0
  241. package/neural-interface/lib/skills/service.js +522 -0
  242. package/neural-interface/lib/skills/telemetry.js +113 -0
  243. package/neural-interface/lib/sqlite-integrity-worker.js +22 -0
  244. package/neural-interface/lib/style-guide/api.js +4 -3
  245. package/neural-interface/lib/tool-lists.js +124 -0
  246. package/neural-interface/lib/untrusted-file-headers.js +27 -0
  247. package/neural-interface/lib/whatsapp/bridge.js +6 -3
  248. package/neural-interface/lib/worker-confinement.js +1192 -0
  249. package/neural-interface/lib/worker-guard-setting.js +56 -0
  250. package/neural-interface/lib/worker-mcp-channel.js +175 -0
  251. package/neural-interface/lib/worker-relay-ports.js +227 -0
  252. package/neural-interface/lib/worker-resume.js +229 -0
  253. package/neural-interface/lib/worker-sandbox.js +299 -0
  254. package/neural-interface/package-lock.json +1354 -50
  255. package/neural-interface/package.json +6 -2
  256. package/neural-interface/public/index.html +5 -3
  257. package/neural-interface/public/index2d.html +19 -11
  258. package/neural-interface/public/onboarding.html +2 -2
  259. package/neural-interface/public/shared/account-menu.js +8 -5
  260. package/neural-interface/public/shared/agent-runtime-options.js +76 -16
  261. package/neural-interface/public/shared/api.js +1527 -1336
  262. package/neural-interface/public/shared/app-frame.js +192 -0
  263. package/neural-interface/public/shared/assistant/asst-agents-dock.js +205 -19
  264. package/neural-interface/public/shared/assistant/asst-api.js +11 -3
  265. package/neural-interface/public/shared/assistant/asst-ask-styles.js +270 -0
  266. package/neural-interface/public/shared/assistant/asst-ask-tail.js +118 -0
  267. package/neural-interface/public/shared/assistant/asst-ask.js +397 -0
  268. package/neural-interface/public/shared/assistant/asst-brain-picker.js +241 -112
  269. package/neural-interface/public/shared/assistant/asst-composer.js +1 -1
  270. package/neural-interface/public/shared/assistant/asst-control.js +157 -26
  271. package/neural-interface/public/shared/assistant/asst-followups-card.js +383 -0
  272. package/neural-interface/public/shared/assistant/asst-followups.js +417 -0
  273. package/neural-interface/public/shared/assistant/asst-hosts.js +49 -2
  274. package/neural-interface/public/shared/assistant/asst-limit-dock.js +40 -0
  275. package/neural-interface/public/shared/assistant/asst-limit-wait.js +294 -0
  276. package/neural-interface/public/shared/assistant/asst-limit.js +168 -0
  277. package/neural-interface/public/shared/assistant/asst-mascot.js +49 -12
  278. package/neural-interface/public/shared/assistant/asst-menu.js +84 -12
  279. package/neural-interface/public/shared/assistant/asst-panel.js +303 -44
  280. package/neural-interface/public/shared/assistant/asst-rack-styles.js +93 -58
  281. package/neural-interface/public/shared/assistant/asst-redact.js +186 -0
  282. package/neural-interface/public/shared/assistant/asst-render.js +770 -100
  283. package/neural-interface/public/shared/assistant/asst-route.js +83 -12
  284. package/neural-interface/public/shared/assistant/asst-run-stage.js +231 -0
  285. package/neural-interface/public/shared/assistant/asst-sanitize.js +193 -3
  286. package/neural-interface/public/shared/assistant/asst-scene-styles.js +273 -0
  287. package/neural-interface/public/shared/assistant/asst-scenes.js +530 -0
  288. package/neural-interface/public/shared/assistant/asst-sidepanel-styles.js +3 -15
  289. package/neural-interface/public/shared/assistant/asst-sidepanel.js +67 -4
  290. package/neural-interface/public/shared/assistant/asst-slash.js +9 -7
  291. package/neural-interface/public/shared/assistant/asst-state.js +25 -15
  292. package/neural-interface/public/shared/assistant/asst-stop.js +127 -0
  293. package/neural-interface/public/shared/assistant/asst-styles.js +102 -21
  294. package/neural-interface/public/shared/assistant/asst-tool-kinds.js +165 -13
  295. package/neural-interface/public/shared/automation-context.js +5 -2
  296. package/neural-interface/public/shared/cc-dropdown.js +550 -0
  297. package/neural-interface/public/shared/cdx/cdx-context-menu.js +10 -9
  298. package/neural-interface/public/shared/cdx/cdx-copy.js +16 -0
  299. package/neural-interface/public/shared/cdx/cdx-output-model.js +22 -1
  300. package/neural-interface/public/shared/cdx/cdx-output.js +8 -7
  301. package/neural-interface/public/shared/cdx/cdx-panel.js +58 -150
  302. package/neural-interface/public/shared/cdx/cdx-protocol.js +28 -1
  303. package/neural-interface/public/shared/cdx/cdx-render.js +62 -32
  304. package/neural-interface/public/shared/cdx/cdx-requests.js +3 -3
  305. package/neural-interface/public/shared/cdx/cdx-skill-hints.js +54 -0
  306. package/neural-interface/public/shared/cdx/cdx-styles.js +15 -3
  307. package/neural-interface/public/shared/cdx/cdx-tabs.js +201 -74
  308. package/neural-interface/public/shared/cdx/cdx-ws.js +0 -1
  309. package/neural-interface/public/shared/cli-install-view.js +4 -8
  310. package/neural-interface/public/shared/cli-status.js +2 -2
  311. package/neural-interface/public/shared/constants.js +2 -2
  312. package/neural-interface/public/shared/context-menu-areas.js +34 -0
  313. package/neural-interface/public/shared/context-menu-logic.js +243 -0
  314. package/neural-interface/public/shared/context-menu-model.js +366 -0
  315. package/neural-interface/public/shared/context-menu.js +372 -0
  316. package/neural-interface/public/shared/cp/cp-context-menu.js +10 -9
  317. package/neural-interface/public/shared/cp/cp-markdown.js +4 -57
  318. package/neural-interface/public/shared/crash-notice-view.js +168 -0
  319. package/neural-interface/public/shared/data-cache.js +223 -0
  320. package/neural-interface/public/shared/desktop-bridge.js +11 -0
  321. package/neural-interface/public/shared/desktop-titlebar-view.js +78 -1
  322. package/neural-interface/public/shared/desktop-titlebar.js +214 -28
  323. package/neural-interface/public/shared/desktop-update-view.js +35 -5
  324. package/neural-interface/public/shared/editor/editor-panel-logic.js +2 -2
  325. package/neural-interface/public/shared/file-links.js +73 -8
  326. package/neural-interface/public/shared/html-shell.js +78 -86
  327. package/neural-interface/public/shared/i18n.js +2 -0
  328. package/neural-interface/public/shared/launch-prefetch.js +59 -0
  329. package/neural-interface/public/shared/ocp-v2/ocp-v2-approvals.js +7 -7
  330. package/neural-interface/public/shared/ocp-v2/ocp-v2-binding.js +4 -4
  331. package/neural-interface/public/shared/ocp-v2/ocp-v2-caps.js +3 -2
  332. package/neural-interface/public/shared/ocp-v2/ocp-v2-changes-logic.js +3 -101
  333. package/neural-interface/public/shared/ocp-v2/ocp-v2-childpanel.js +9 -2
  334. package/neural-interface/public/shared/ocp-v2/ocp-v2-compact-button.js +1 -3
  335. package/neural-interface/public/shared/ocp-v2/ocp-v2-composer-logic.js +2 -6
  336. package/neural-interface/public/shared/ocp-v2/ocp-v2-context-menu.js +11 -11
  337. package/neural-interface/public/shared/ocp-v2/ocp-v2-context-model.js +0 -3
  338. package/neural-interface/public/shared/ocp-v2/ocp-v2-events.js +8 -4
  339. package/neural-interface/public/shared/ocp-v2/ocp-v2-manager.js +7 -7
  340. package/neural-interface/public/shared/ocp-v2/ocp-v2-modelpicker.js +54 -17
  341. package/neural-interface/public/shared/ocp-v2/ocp-v2-outcome-notifications.js +16 -0
  342. package/neural-interface/public/shared/ocp-v2/ocp-v2-panel.js +140 -254
  343. package/neural-interface/public/shared/ocp-v2/ocp-v2-plan.js +1 -2
  344. package/neural-interface/public/shared/ocp-v2/ocp-v2-projectbar.js +97 -203
  345. package/neural-interface/public/shared/ocp-v2/ocp-v2-providers.js +11 -9
  346. package/neural-interface/public/shared/ocp-v2/ocp-v2-rehydrate.js +15 -4
  347. package/neural-interface/public/shared/ocp-v2/ocp-v2-render.js +7 -22
  348. package/neural-interface/public/shared/ocp-v2/ocp-v2-send-logic.js +401 -0
  349. package/neural-interface/public/shared/ocp-v2/ocp-v2-send.js +20 -13
  350. package/neural-interface/public/shared/ocp-v2/ocp-v2-session-actions.js +8 -61
  351. package/neural-interface/public/shared/ocp-v2/ocp-v2-sessions-logic.js +53 -82
  352. package/neural-interface/public/shared/ocp-v2/ocp-v2-slash-hints.js +16 -15
  353. package/neural-interface/public/shared/ocp-v2/ocp-v2-state.js +8 -21
  354. package/neural-interface/public/shared/ocp-v2/ocp-v2-status-logic.js +1 -99
  355. package/neural-interface/public/shared/ocp-v2/ocp-v2-status.js +5 -35
  356. package/neural-interface/public/shared/ocp-v2/ocp-v2-styles.js +48 -40
  357. package/neural-interface/public/shared/ocp-v2/{ocp-v2-profile-inheritance.js → ocp-v2-tools-inheritance.js} +16 -16
  358. package/neural-interface/public/shared/ocp-v2/ocp-v2-ws.js +205 -62
  359. package/neural-interface/public/shared/opencode-providers.js +39 -0
  360. package/neural-interface/public/shared/page-session.js +96 -0
  361. package/neural-interface/public/shared/registry.js +5 -3
  362. package/neural-interface/public/shared/retired-2d.js +3 -0
  363. package/neural-interface/public/shared/schedules-view.js +452 -0
  364. package/neural-interface/public/shared/settings/settings-app-pane.js +335 -0
  365. package/neural-interface/public/shared/settings/settings-app.js +243 -0
  366. package/neural-interface/public/shared/settings/settings-claude-hooks.js +135 -0
  367. package/neural-interface/public/shared/settings/settings-data.js +90 -0
  368. package/neural-interface/public/shared/settings/settings-ia.js +23 -6
  369. package/neural-interface/public/shared/settings/settings-opencode.js +89 -0
  370. package/neural-interface/public/shared/settings/settings-skill-folders-pane.js +265 -0
  371. package/neural-interface/public/shared/settings/settings-skill-folders.js +130 -0
  372. package/neural-interface/public/shared/settings/settings-worker-guard.js +72 -0
  373. package/neural-interface/public/shared/sidepanel-session-status.js +49 -0
  374. package/neural-interface/public/shared/skills/ss-args.js +96 -0
  375. package/neural-interface/public/shared/skills/ss-creation.js +219 -0
  376. package/neural-interface/public/shared/skills/ss-dialog.js +130 -0
  377. package/neural-interface/public/shared/skills/ss-doc.js +173 -0
  378. package/neural-interface/public/shared/skills/ss-eval-adapters.js +269 -0
  379. package/neural-interface/public/shared/skills/ss-eval-grade.js +359 -0
  380. package/neural-interface/public/shared/skills/ss-eval-optimise.js +153 -0
  381. package/neural-interface/public/shared/skills/ss-eval-plan.js +315 -0
  382. package/neural-interface/public/shared/skills/ss-evals.js +417 -0
  383. package/neural-interface/public/shared/skills/ss-form.js +159 -0
  384. package/neural-interface/public/shared/skills/ss-frontmatter.js +376 -0
  385. package/neural-interface/public/shared/skills/ss-ids.js +32 -0
  386. package/neural-interface/public/shared/skills/ss-lint.js +141 -0
  387. package/neural-interface/public/shared/skills/ss-presets.js +117 -0
  388. package/neural-interface/public/shared/skills/ss-profiles.js +475 -0
  389. package/neural-interface/public/shared/skills/ss-resources.js +165 -0
  390. package/neural-interface/public/shared/skills/ss-review-view.js +190 -0
  391. package/neural-interface/public/shared/skills/ss-tabs.js +79 -0
  392. package/neural-interface/public/shared/skills/ss-unicode.js +135 -0
  393. package/neural-interface/public/shared/skills/studio/sx-actions.js +222 -0
  394. package/neural-interface/public/shared/skills/studio/sx-cm.js +101 -0
  395. package/neural-interface/public/shared/skills/studio/sx-create-ai-view.js +749 -0
  396. package/neural-interface/public/shared/skills/studio/sx-create-ai.js +236 -0
  397. package/neural-interface/public/shared/skills/studio/sx-create-view.js +254 -0
  398. package/neural-interface/public/shared/skills/studio/sx-create.js +126 -0
  399. package/neural-interface/public/shared/skills/studio/sx-diff-view.js +43 -0
  400. package/neural-interface/public/shared/skills/studio/sx-diff.js +133 -0
  401. package/neural-interface/public/shared/skills/studio/sx-docs.js +480 -0
  402. package/neural-interface/public/shared/skills/studio/sx-dom.js +229 -0
  403. package/neural-interface/public/shared/skills/studio/sx-edit-view.js +848 -0
  404. package/neural-interface/public/shared/skills/studio/sx-editor-model.js +193 -0
  405. package/neural-interface/public/shared/skills/studio/sx-errors.js +22 -0
  406. package/neural-interface/public/shared/skills/studio/sx-geometry.js +82 -0
  407. package/neural-interface/public/shared/skills/studio/sx-import.js +262 -0
  408. package/neural-interface/public/shared/skills/studio/sx-inspector.js +308 -0
  409. package/neural-interface/public/shared/skills/studio/sx-install-flow.js +279 -0
  410. package/neural-interface/public/shared/skills/studio/sx-install.js +296 -0
  411. package/neural-interface/public/shared/skills/studio/sx-library-view.js +639 -0
  412. package/neural-interface/public/shared/skills/studio/sx-library.js +475 -0
  413. package/neural-interface/public/shared/skills/studio/sx-main.js +681 -0
  414. package/neural-interface/public/shared/skills/studio/sx-operations-view.js +98 -0
  415. package/neural-interface/public/shared/skills/studio/sx-operations.js +11 -0
  416. package/neural-interface/public/shared/skills/studio/sx-plan.js +158 -0
  417. package/neural-interface/public/shared/skills/studio/sx-publish-view.js +621 -0
  418. package/neural-interface/public/shared/skills/studio/sx-review-view.js +369 -0
  419. package/neural-interface/public/shared/skills/studio/sx-review.js +148 -0
  420. package/neural-interface/public/shared/skills/studio/sx-scan.js +35 -0
  421. package/neural-interface/public/shared/skills/studio/sx-snippets.js +96 -0
  422. package/neural-interface/public/shared/skills/studio/sx-subject.js +248 -0
  423. package/neural-interface/public/shared/skills/studio/sx-test-view.js +994 -0
  424. package/neural-interface/public/shared/skills/studio/sx-test.js +328 -0
  425. package/neural-interface/public/shared/skills/studio/sx-versions-view.js +241 -0
  426. package/neural-interface/public/shared/skills/studio/sx-workspace-view.js +425 -0
  427. package/neural-interface/public/shared/styleguide/sg-panel.js +4 -2
  428. package/neural-interface/public/shared/styles.css +2065 -2150
  429. package/neural-interface/public/shared/synabun-mascot.js +1115 -9
  430. package/neural-interface/public/shared/tool-list-picker.js +55 -0
  431. package/neural-interface/public/shared/tool-list-storage.js +24 -0
  432. package/neural-interface/public/shared/tool-list-view.js +112 -0
  433. package/neural-interface/public/shared/tour/tour-actor.js +268 -0
  434. package/neural-interface/public/shared/tour/tour-beats.js +336 -0
  435. package/neural-interface/public/shared/tour/tour-engine.js +884 -0
  436. package/neural-interface/public/shared/tour/tour-ink.js +390 -0
  437. package/neural-interface/public/shared/tour/tour-stage.js +440 -0
  438. package/neural-interface/public/shared/tour/tour-state.js +40 -0
  439. package/neural-interface/public/shared/tour/tour-tips.js +99 -0
  440. package/neural-interface/public/shared/tour/tour.css +144 -0
  441. package/neural-interface/public/shared/ui-assistant.js +27 -5
  442. package/neural-interface/public/shared/ui-automation-studio.js +155 -152
  443. package/neural-interface/public/shared/ui-bookmarks.js +2 -1
  444. package/neural-interface/public/shared/ui-claude-panel.js +153 -13
  445. package/neural-interface/public/shared/ui-codex-panel.js +1 -0
  446. package/neural-interface/public/shared/ui-command-runner.js +6 -3
  447. package/neural-interface/public/shared/ui-context-menu.js +295 -0
  448. package/neural-interface/public/shared/ui-cost-widget.js +57 -59
  449. package/neural-interface/public/shared/ui-crash-notice.js +187 -0
  450. package/neural-interface/public/shared/ui-detail.js +21 -9
  451. package/neural-interface/public/shared/ui-file-links.js +1 -0
  452. package/neural-interface/public/shared/ui-image-gallery.js +56 -52
  453. package/neural-interface/public/shared/ui-invite.js +18 -2
  454. package/neural-interface/public/shared/ui-keybinds.js +26 -1
  455. package/neural-interface/public/shared/ui-link.js +9 -9
  456. package/neural-interface/public/shared/ui-menubar.js +229 -40
  457. package/neural-interface/public/shared/ui-native-loop-router-state.js +5 -0
  458. package/neural-interface/public/shared/ui-native-loop-router.js +9 -1
  459. package/neural-interface/public/shared/ui-navbar.js +4 -24
  460. package/neural-interface/public/shared/ui-opencode-panel-v2.js +1 -0
  461. package/neural-interface/public/shared/ui-panels.js +96 -65
  462. package/neural-interface/public/shared/ui-schedules-studio.js +2267 -953
  463. package/neural-interface/public/shared/ui-sessions.js +20 -7
  464. package/neural-interface/public/shared/ui-settings.js +679 -496
  465. package/neural-interface/public/shared/ui-sidebar.js +4 -4
  466. package/neural-interface/public/shared/ui-sidepanel-session-entry.js +13 -0
  467. package/neural-interface/public/shared/ui-sidepanel-sessions.js +56 -5
  468. package/neural-interface/public/shared/ui-sidepanel-state.js +23 -12
  469. package/neural-interface/public/shared/ui-sidepanel-tray.js +84 -8
  470. package/neural-interface/public/shared/ui-sidepanel-windows.js +16 -11
  471. package/neural-interface/public/shared/ui-skills.js +42 -2781
  472. package/neural-interface/public/shared/ui-styleguide.js +5 -2
  473. package/neural-interface/public/shared/ui-sync.js +22 -5
  474. package/neural-interface/public/shared/ui-terminal.js +159 -199
  475. package/neural-interface/public/shared/ui-tool-updates.js +3 -1
  476. package/neural-interface/public/shared/ui-tooltip.js +10 -5
  477. package/neural-interface/public/shared/ui-trash.js +14 -5
  478. package/neural-interface/public/shared/ui-tutorial-layout.js +3 -117
  479. package/neural-interface/public/shared/ui-tutorial-preview.js +103 -0
  480. package/neural-interface/public/shared/ui-tutorial-steps.js +3 -61
  481. package/neural-interface/public/shared/ui-tutorial.css +47 -100
  482. package/neural-interface/public/shared/ui-tutorial.js +285 -499
  483. package/neural-interface/public/shared/ui-update.js +121 -16
  484. package/neural-interface/public/shared/ui-whiteboard.js +313 -59
  485. package/neural-interface/public/shared/ui-worker-end.js +4 -0
  486. package/neural-interface/public/shared/ui-workspaces.js +3 -2
  487. package/neural-interface/public/shared/view-variant.js +66 -0
  488. package/neural-interface/public/shared/whatsapp/wa-view.js +1 -1
  489. package/neural-interface/public/shared/whiteboard-list.js +172 -0
  490. package/neural-interface/public/shared/worker-end.js +10 -3
  491. package/neural-interface/public/shared/worker-restart.js +12 -0
  492. package/neural-interface/public/sidepanel-session.html +1 -1
  493. package/neural-interface/public/variant/2d/background.js +2 -1
  494. package/neural-interface/public/variant/2d/context-menu.js +8 -2
  495. package/neural-interface/public/variant/2d/graph.js +42 -20
  496. package/neural-interface/public/variant/2d/hulls.js +14 -9
  497. package/neural-interface/public/variant/2d/lasso.js +11 -7
  498. package/neural-interface/public/variant/2d/main.js +36 -2
  499. package/neural-interface/public/variant/2d/minimap.js +11 -13
  500. package/neural-interface/public/variant/3d/main.js +72 -6
  501. package/neural-interface/public/variant/3d/map-controls.js +24 -9
  502. package/neural-interface/public/vendor/caveat/OFL.txt +93 -0
  503. package/neural-interface/public/vendor/caveat/caveat-latin-400-normal.woff2 +0 -0
  504. package/neural-interface/public/vendor/caveat/caveat-latin-700-normal.woff2 +0 -0
  505. package/neural-interface/public/vendor/caveat/caveat.css +17 -0
  506. package/neural-interface/public/vendor/caveat/manifest.json +12 -0
  507. package/neural-interface/public/vendor/highlight/LICENSE +29 -0
  508. package/neural-interface/public/vendor/highlight/github-dark-dimmed-11.12.0.min.css +9 -0
  509. package/neural-interface/public/vendor/highlight/highlight-11.12.0.min.js +1262 -0
  510. package/neural-interface/public/vendor/highlight/manifest.json +5 -0
  511. package/neural-interface/public/vendor/html2canvas/LICENSE +22 -0
  512. package/neural-interface/public/vendor/html2canvas/html2canvas-1.4.1.min.js +20 -0
  513. package/neural-interface/public/vendor/html2canvas/manifest.json +4 -0
  514. package/neural-interface/public/vendor/marked/LICENSE.md +44 -0
  515. package/neural-interface/public/vendor/marked/manifest.json +4 -0
  516. package/neural-interface/public/vendor/marked/marked-14.1.4.esm.js +2502 -0
  517. package/neural-interface/public/vendor/mermaid/LICENSE +21 -0
  518. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/abnfDiagram-PAR5IXJI.mjs +1 -0
  519. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/architecture-7GRP2DOG-M7G3SWCO.mjs +1 -0
  520. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/architectureDiagram-2PNWDENW.mjs +36 -0
  521. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/blockDiagram-PUWGUBOA.mjs +129 -0
  522. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/c4Diagram-3NLNHZP5.mjs +38 -0
  523. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-2NMSUPJH.mjs +1 -0
  524. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-32MCUW2P.mjs +206 -0
  525. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-3NPNU5GP.mjs +1 -0
  526. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-3SMGFRGC.mjs +1 -0
  527. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-4CAJECRU.mjs +14 -0
  528. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-4OADUZ5Q.mjs +10 -0
  529. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-5IMINLNL.mjs +1 -0
  530. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-5IQCK5RY.mjs +3 -0
  531. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-5MVFYWFU.mjs +1 -0
  532. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-AQ6EADP3.mjs +1 -0
  533. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-AZZRMDJM.mjs +15 -0
  534. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-CLS4B6BI.mjs +168 -0
  535. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-DZP67EKU.mjs +70 -0
  536. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-EICP7K5X.mjs +1 -0
  537. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-GDY2UAB4.mjs +1 -0
  538. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-H7VHZCWX.mjs +1 -0
  539. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-IJBDOHL6.mjs +1 -0
  540. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-JFFVMJIA.mjs +1 -0
  541. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-JQRUD6KW.mjs +1 -0
  542. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-JZGDI5JK.mjs +1 -0
  543. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-KD6SPIPN.mjs +2 -0
  544. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-NF366YI6.mjs +231 -0
  545. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-NUDPKBEF.mjs +32 -0
  546. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-OJINMHTS.mjs +1 -0
  547. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-Q6NGPIAH.mjs +2 -0
  548. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-QJSWEUOL.mjs +132 -0
  549. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-R7JDMUKV.mjs +1 -0
  550. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-RCXAM2GK.mjs +1 -0
  551. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-RT4MAWR3.mjs +1 -0
  552. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-SFMINX4W.mjs +1 -0
  553. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-SLDQ463B.mjs +88 -0
  554. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-STOV2HOB.mjs +1 -0
  555. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-T5OCTHI4.mjs +1 -0
  556. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-TCEHX7R3.mjs +1 -0
  557. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-VQC2EELJ.mjs +1 -0
  558. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-VRZKL3EH.mjs +1 -0
  559. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-VTHDQ7BV.mjs +1 -0
  560. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-VY2OSTJR.mjs +2 -0
  561. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-WUBWJARI.mjs +1 -0
  562. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-YBMQ5JGJ.mjs +2 -0
  563. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-YDMLL4PJ.mjs +1 -0
  564. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-Z6V44ARX.mjs +62 -0
  565. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZJJ7VQJP.mjs +339 -0
  566. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZNLK7HRR.mjs +1 -0
  567. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZQN7UHIL.mjs +1 -0
  568. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZS6VBONO.mjs +174 -0
  569. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZUNWM646.mjs +1 -0
  570. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/classDiagram-FGAMPOII.mjs +1 -0
  571. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/classDiagram-v2-AI5RJEK4.mjs +1 -0
  572. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/cose-bilkent-Q72C2OJ3.mjs +1 -0
  573. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/cynefin-OW5HDTMX-6OCTWOGG.mjs +1 -0
  574. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/cynefinDiagram-2OOWUY4M.mjs +62 -0
  575. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/dagre-MPVFI544.mjs +4 -0
  576. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-AE4NWXFW.mjs +24 -0
  577. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-BUJID5UG.mjs +41 -0
  578. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-C44CZ5NI.mjs +24 -0
  579. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-EYOLEXXS.mjs +30 -0
  580. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-P7B6PWOJ.mjs +3 -0
  581. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/ebnfDiagram-FTPZ3PV6.mjs +1 -0
  582. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/erDiagram-H3ERR26V.mjs +99 -0
  583. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/eventmodeling-NTZA5JFV-WKSWQHFS.mjs +1 -0
  584. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/flowDiagram-YHGXBVSY.mjs +1 -0
  585. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/ganttDiagram-RWFTB7ED.mjs +292 -0
  586. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/gitGraph-4MIJSDKK-JH2HKYUO.mjs +1 -0
  587. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/gitGraphDiagram-MAR6GKOP.mjs +106 -0
  588. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/info-A6RAGUB7-3TX3OFWW.mjs +1 -0
  589. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/infoDiagram-LV547AFH.mjs +2 -0
  590. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/ishikawaDiagram-PUJQGNDS.mjs +70 -0
  591. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/journeyDiagram-EW5QJT4W.mjs +139 -0
  592. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/kanban-definition-JSQERAZB.mjs +89 -0
  593. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/katex-CZ4GXH2S.mjs +257 -0
  594. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/mindmap-definition-VBJCLQLM.mjs +96 -0
  595. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/packet-AYTQ26CC-MKII6P3Y.mjs +1 -0
  596. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/pegDiagram-7WILOQTJ.mjs +1 -0
  597. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/pie-WAS4IAKB-6B4OPMJ5.mjs +1 -0
  598. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/pieDiagram-EFA7CBSB.mjs +39 -0
  599. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/quadrantDiagram-WARVYA7P.mjs +7 -0
  600. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/radar-RG4KPBEZ-UPTR3XUL.mjs +1 -0
  601. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroad-74A4TZTK-MEFUPFMS.mjs +1 -0
  602. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroad-abnf-HS5TGJTU-R5YG2S5D.mjs +1 -0
  603. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroad-ebnf-LZEXJU2U-G5QEX2L6.mjs +1 -0
  604. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroad-peg-WCYAUIDC-H5I2ZRY2.mjs +1 -0
  605. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroadDiagram-5NIQVNLQ.mjs +1 -0
  606. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/requirementDiagram-SXREGOKZ.mjs +84 -0
  607. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/sankeyDiagram-VV74M2VP.mjs +40 -0
  608. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/sequenceDiagram-52ZFIFDL.mjs +162 -0
  609. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/sizeCapture-FGA5AGYP.mjs +1 -0
  610. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/stateDiagram-3QAKPIVI.mjs +1 -0
  611. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/stateDiagram-v2-HN2P4RDZ.mjs +1 -0
  612. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/swimlanes-QLVP42QD.mjs +1 -0
  613. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/swimlanesDiagram-JKPDBFCN.mjs +8 -0
  614. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/timeline-definition-GS45XAXW.mjs +120 -0
  615. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/treeView-Q6P3EWNA-ZRJGANNQ.mjs +1 -0
  616. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/treemap-WGGIJYW6-K64VN5AS.mjs +1 -0
  617. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/vennDiagram-QIQU2ZRJ.mjs +34 -0
  618. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/wardley-WFR3VGLG-D67OWCCH.mjs +1 -0
  619. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/wardleyDiagram-U6YNM66N.mjs +78 -0
  620. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/xychartDiagram-XJAZEDNM.mjs +7 -0
  621. package/neural-interface/public/vendor/mermaid/manifest.json +4 -0
  622. package/neural-interface/public/vendor/mermaid/mermaid-11.17.2.esm.min.mjs +14 -0
  623. package/neural-interface/public/vendor/yaml/LICENSE +13 -0
  624. package/neural-interface/public/vendor/yaml/manifest.json +4 -0
  625. package/neural-interface/public/vendor/yaml/yaml-2.9.1.min.js +137 -0
  626. package/neural-interface/scripts/build-vendor.mjs +116 -3
  627. package/neural-interface/server.js +4834 -2541
  628. package/neural-interface/templates/rulesets/core.md +1 -1
  629. package/neural-interface/templates/rulesets/legacy-hashes.json +18 -0
  630. package/neural-interface/templates/rulesets/manifest.json +8 -8
  631. package/npm-shrinkwrap.json +18 -12
  632. package/package.json +16 -3
  633. package/postinstall.js +9 -4
  634. package/preuninstall.js +1 -1
  635. package/setup.js +97 -322
  636. package/skills/skill-forge/SKILL.md +177 -0
  637. package/skills/skill-forge/evals/evals.json +54 -0
  638. package/skills/skill-forge/references/package.md +105 -0
  639. package/skills/skill-forge/references/review-and-recovery.md +63 -0
  640. package/skills/skill-forge/references/runtime-profiles.md +20 -0
  641. package/skills/skill-forge/references/sources-and-capabilities.md +51 -0
  642. package/skills/synabun/SKILL.md +10 -7
  643. package/skills/synabun/modules/audit.md +1 -5
  644. package/skills/synabun/modules/changelog.md +1 -5
  645. package/skills/synabun/modules/idea.md +1 -1
  646. package/skills/synabun/modules/memorize.md +6 -9
  647. package/skills/synabun/modules/schedule.md +5 -5
  648. package/mcp-server/dist/services/profiles.d.ts +0 -120
  649. package/mcp-server/dist/services/profiles.d.ts.map +0 -1
  650. package/mcp-server/dist/services/profiles.js +0 -387
  651. package/mcp-server/dist/services/profiles.js.map +0 -1
  652. package/mcp-server/dist/tools/leonardo-browser-tools.d.ts +0 -97
  653. package/mcp-server/dist/tools/leonardo-browser-tools.d.ts.map +0 -1
  654. package/mcp-server/dist/tools/leonardo-browser-tools.js +0 -228
  655. package/mcp-server/dist/tools/leonardo-browser-tools.js.map +0 -1
  656. package/mcp-server/dist/tools/leonardo.d.ts +0 -13
  657. package/mcp-server/dist/tools/leonardo.d.ts.map +0 -1
  658. package/mcp-server/dist/tools/leonardo.js +0 -21
  659. package/mcp-server/dist/tools/leonardo.js.map +0 -1
  660. package/mcp-server/dist/tools/profile.d.ts +0 -17
  661. package/mcp-server/dist/tools/profile.d.ts.map +0 -1
  662. package/mcp-server/dist/tools/profile.js +0 -114
  663. package/mcp-server/dist/tools/profile.js.map +0 -1
  664. package/mcp-server/src/services/profiles.ts +0 -428
  665. package/mcp-server/src/tools/leonardo-browser-tools.ts +0 -291
  666. package/mcp-server/src/tools/leonardo.ts +0 -30
  667. package/mcp-server/src/tools/profile.ts +0 -122
  668. package/neural-interface/lib/assistant-brains/opencode-browser-policy.js +0 -47
  669. package/neural-interface/lib/assistant-brains/opencode-route-gate.js +0 -62
  670. package/neural-interface/lib/mcp-profile-servers.js +0 -120
  671. package/neural-interface/public/shared/ui-tutorial-draw.js +0 -311
  672. package/skills/leonardo/SKILL.md +0 -168
  673. package/skills/leonardo/icon.svg +0 -1
  674. package/skills/leonardo/modules/browser-guide.md +0 -378
  675. package/skills/leonardo/modules/image-prompter.md +0 -283
  676. package/skills/leonardo/modules/model-advisor.md +0 -100
  677. package/skills/leonardo/modules/prompt-library.md +0 -110
  678. package/skills/leonardo/modules/style-guide.md +0 -186
  679. package/skills/leonardo/modules/video-prompter.md +0 -317
@@ -1,12 +1,66 @@
1
- import { spawnSync } from 'node:child_process';
2
- import { mkdtempSync, readFileSync, rmSync, statSync } from 'node:fs';
1
+ import { execFile } from 'node:child_process';
2
+ import { mkdtemp, readFile, rm, stat } from 'node:fs/promises';
3
3
  import { tmpdir } from 'node:os';
4
4
  import { join } from 'node:path';
5
5
  // The probes run no command: always the Windows sandbox that needs no administrator (lib/agent-sandbox-elevation.js).
6
6
  import { CODEX_PROBE_SANDBOX_ARGS } from './agent-sandbox-elevation.js';
7
7
 
8
+ // The probes start Codex itself (a 300 MB binary on Windows) once per setting value: asynchronous, never
9
+ // more than two at a time, one run per binary for every caller, and kept per binary identity (path, mtime,
10
+ // size: an update is another binary) in memory and, through setCodexSettingsStore(), across restarts.
8
11
  const cache = new Map();
9
12
  const featureCache = new Map();
13
+ const inflight = new Map();
14
+ const latestSchema = new Map(); // codexBin → the schema of the binary as it was last read
15
+ let store = null;
16
+ const MAX_PROBES = 2;
17
+ let running = 0;
18
+ const waiting = [];
19
+
20
+ /** Where answers are kept across restarts: `{ get(key) → value | undefined, set(key, value) }` (lib/launch-cache.js). */
21
+ export function setCodexSettingsStore(next) {
22
+ store = next && typeof next.get === 'function' && typeof next.set === 'function' ? next : null;
23
+ }
24
+
25
+ function limited(job) {
26
+ return new Promise((resolve, reject) => {
27
+ waiting.push({ job, resolve, reject });
28
+ const pump = () => {
29
+ while (running < MAX_PROBES && waiting.length) {
30
+ const next = waiting.shift();
31
+ running += 1;
32
+ Promise.resolve().then(next.job).then(next.resolve, next.reject).finally(() => { running -= 1; pump(); });
33
+ }
34
+ };
35
+ pump();
36
+ });
37
+ }
38
+
39
+ // One Codex run: { status, stdout } (status null when it could not start or ran out of time).
40
+ function probe(codexBin, args, { env, timeout }) {
41
+ return limited(() => new Promise((resolve) => {
42
+ execFile(codexBin, args, { env, encoding: 'utf8', timeout, windowsHide: true, maxBuffer: 16 * 1024 * 1024 }, (error, stdout) => {
43
+ resolve({ status: error ? (typeof error.code === 'number' ? error.code : null) : 0, stdout: String(stdout || '') });
44
+ });
45
+ }));
46
+ }
47
+
48
+ // What was found for `key` before (this run, or the last one through the store), or undefined.
49
+ function known(memo, key) {
50
+ if (memo.has(key)) return memo.get(key);
51
+ try {
52
+ const kept = store?.get(key);
53
+ if (kept && typeof kept === 'object') { memo.set(key, kept); return kept; }
54
+ } catch { /* nothing kept */ }
55
+ return undefined;
56
+ }
57
+
58
+ function once(key, run) {
59
+ if (inflight.has(key)) return inflight.get(key);
60
+ const job = Promise.resolve().then(run).finally(() => inflight.delete(key));
61
+ inflight.set(key, job);
62
+ return job;
63
+ }
10
64
  export const CODEX_SETTINGS_KEYS = Object.freeze([
11
65
  'model', 'review_model', 'model_provider', 'approval_policy', 'sandbox_mode', 'personality',
12
66
  'service_tier', 'model_reasoning_effort', 'model_reasoning_summary', 'model_verbosity',
@@ -40,33 +94,38 @@ export function settingsSchemaFromProtocol(configSchema, threadSchema) {
40
94
  }
41
95
 
42
96
  /** Generate from the executable we actually launch; never use the global home. */
43
- export function readCodexSettingsSchema(codexBin) {
44
- const stamp = statSync(codexBin);
45
- const key = `${codexBin}:${stamp.mtimeMs}:${stamp.size}`;
46
- if (cache.has(key)) return cache.get(key);
47
- const home = mkdtempSync(join(tmpdir(), 'synabun-codex-schema-'));
48
- try {
49
- const out = join(home, 'schema');
50
- const run = spawnSync(codexBin, ['app-server', 'generate-json-schema', '--experimental', '--out', out, ...CODEX_PROBE_SANDBOX_ARGS], {
51
- env: { ...process.env, CODEX_HOME: home }, encoding: 'utf8', timeout: 15000, windowsHide: true,
52
- });
53
- if (run.error || run.status !== 0) throw new Error('Codex could not report its settings schema');
54
- const read = name => JSON.parse(readFileSync(join(out, 'v2', `${name}.json`), 'utf8'));
55
- const schema = settingsSchemaFromProtocol(read('ConfigReadResponse'), read('ThreadStartParams'));
56
- // Protocol enums can retain deprecated variants that the config loader
57
- // already rejects (0.162 still exports `untrusted`). Ask the loader too.
58
- // `features list` validates config locally and never runs a model or tool.
59
- for (const [fieldKey, field] of Object.entries(schema.fields)) {
60
- field.values = field.values.filter(value => {
61
- const check = spawnSync(codexBin, [...CODEX_PROBE_SANDBOX_ARGS, '-c', `${fieldKey}=${JSON.stringify(value)}`, 'features', 'list'], {
62
- env: { ...process.env, CODEX_HOME: home }, encoding: 'utf8', timeout: 5000, windowsHide: true,
63
- });
64
- return !check.error && check.status === 0;
65
- });
66
- }
67
- cache.set(key, schema);
68
- return schema;
69
- } finally { rmSync(home, { recursive: true, force: true }); }
97
+ export async function readCodexSettingsSchema(codexBin) {
98
+ const stamp = await stat(codexBin);
99
+ const key = `schema:${codexBin}:${stamp.mtimeMs}:${stamp.size}`;
100
+ const found = known(cache, key);
101
+ if (found) { latestSchema.set(codexBin, found); return found; }
102
+ return once(key, async () => {
103
+ const home = await mkdtemp(join(tmpdir(), 'synabun-codex-schema-'));
104
+ try {
105
+ const env = { ...process.env, CODEX_HOME: home };
106
+ const out = join(home, 'schema');
107
+ const run = await probe(codexBin, ['app-server', 'generate-json-schema', '--experimental', '--out', out, ...CODEX_PROBE_SANDBOX_ARGS], { env, timeout: 15000 });
108
+ if (run.status !== 0) throw new Error('Codex could not report its settings schema');
109
+ const read = async name => JSON.parse(await readFile(join(out, 'v2', `${name}.json`), 'utf8'));
110
+ const schema = settingsSchemaFromProtocol(await read('ConfigReadResponse'), await read('ThreadStartParams'));
111
+ // Protocol enums can retain deprecated variants that the config loader
112
+ // already rejects (0.162 still exports `untrusted`). Ask the loader too.
113
+ // `features list` validates config locally and never runs a model or tool.
114
+ for (const [fieldKey, field] of Object.entries(schema.fields)) {
115
+ const checks = await Promise.all(field.values.map(value => probe(codexBin, [...CODEX_PROBE_SANDBOX_ARGS, '-c', `${fieldKey}=${JSON.stringify(value)}`, 'features', 'list'], { env, timeout: 5000 })));
116
+ field.values = field.values.filter((_, index) => checks[index].status === 0);
117
+ }
118
+ cache.set(key, schema);
119
+ latestSchema.set(codexBin, schema);
120
+ try { store?.set(key, schema); } catch { /* kept in memory */ }
121
+ return schema;
122
+ } finally { await rm(home, { recursive: true, force: true }).catch(() => {}); }
123
+ });
124
+ }
125
+
126
+ /** The schema readCodexSettingsSchema() last gave for this binary, or null: never starts Codex. */
127
+ export function cachedCodexSettingsSchema(codexBin) {
128
+ return latestSchema.get(codexBin) || null;
70
129
  }
71
130
 
72
131
  export function validateCodexSettings(config, schema, features = []) {
@@ -99,24 +158,27 @@ export function validateCodexSettings(config, schema, features = []) {
99
158
 
100
159
  /** Some stable flags are now mandatory and ignore false (e.g. unified_exec).
101
160
  * Check both states with the local loader instead of offering a no-op switch. */
102
- export function readCodexFeatureSupport(codexBin, features) {
161
+ export async function readCodexFeatureSupport(codexBin, features) {
103
162
  const names = features.filter(f => ['stable', 'beta'].includes(f.stage) && /^[A-Za-z0-9_-]+$/.test(f.name)).map(f => f.name).sort();
104
- const stat = statSync(codexBin);
105
- const key = `${codexBin}:${stat.mtimeMs}:${stat.size}:${names.join(',')}`;
106
- if (featureCache.has(key)) return featureCache.get(key);
107
- const home = mkdtempSync(join(tmpdir(), 'synabun-feature-support-'));
108
- try {
109
- const states = [false, true].map(value => {
110
- const check = spawnSync(codexBin, [...CODEX_PROBE_SANDBOX_ARGS, '-c', `features={${names.map(name => `${name}=${value}`).join(',')}}`, 'features', 'list'], {
111
- env: { ...process.env, CODEX_HOME: home }, encoding: 'utf8', timeout: 10000, windowsHide: true,
112
- });
113
- if (check.error || check.status !== 0) throw new Error('Codex could not validate feature switches');
114
- return new Map(check.stdout.split('\n').map(line => {
115
- const parts = line.trim().split(/\s+/); return [parts[0], parts.at(-1)];
163
+ const stamp = await stat(codexBin);
164
+ const key = `features:${codexBin}:${stamp.mtimeMs}:${stamp.size}:${names.join(',')}`;
165
+ const found = known(featureCache, key);
166
+ if (found) return found;
167
+ return once(key, async () => {
168
+ const home = await mkdtemp(join(tmpdir(), 'synabun-feature-support-'));
169
+ try {
170
+ const env = { ...process.env, CODEX_HOME: home };
171
+ const states = await Promise.all([false, true].map(async value => {
172
+ const check = await probe(codexBin, [...CODEX_PROBE_SANDBOX_ARGS, '-c', `features={${names.map(name => `${name}=${value}`).join(',')}}`, 'features', 'list'], { env, timeout: 10000 });
173
+ if (check.status !== 0) throw new Error('Codex could not validate feature switches');
174
+ return new Map(check.stdout.split('\n').map(line => {
175
+ const parts = line.trim().split(/\s+/); return [parts[0], parts.at(-1)];
176
+ }));
116
177
  }));
117
- });
118
- const supported = Object.fromEntries(names.map(name => [name, states[0].get(name) === 'false' && states[1].get(name) === 'true']));
119
- featureCache.set(key, supported);
120
- return supported;
121
- } finally { rmSync(home, { recursive: true, force: true }); }
178
+ const supported = Object.fromEntries(names.map(name => [name, states[0].get(name) === 'false' && states[1].get(name) === 'true']));
179
+ featureCache.set(key, supported);
180
+ try { store?.set(key, supported); } catch { /* kept in memory */ }
181
+ return supported;
182
+ } finally { await rm(home, { recursive: true, force: true }).catch(() => {}); }
183
+ });
122
184
  }
@@ -0,0 +1,172 @@
1
+ // One app-server per dispatched worker. The SDK-shaped surface keeps the native
2
+ // worker's event/usage contract while thread/resume reopens its durable thread.
3
+ import { spawn, execFileSync } from 'node:child_process';
4
+ import { StringDecoder } from 'node:string_decoder';
5
+
6
+ const toml = (v) => Array.isArray(v) ? `[${v.map(toml).join(',')}]`
7
+ : v && typeof v === 'object' ? `{${Object.entries(v).filter(([, x]) => x != null).map(([k, x]) => `${JSON.stringify(k)}=${toml(x)}`).join(',')}}`
8
+ : JSON.stringify(v);
9
+
10
+ // Match the SDK's leaf overrides: pins/switches address only their intended
11
+ // fields and leave native command/url/env definitions in the native config.
12
+ // Codex splits override paths literally on dots (it does not parse TOML keys).
13
+ // Top-level keys may already be override paths; nested keys are literal segments.
14
+ export function codexWorkerConfigOverrides(config) {
15
+ const overrides = [];
16
+ const visit = (value, path) => {
17
+ if (value == null) return;
18
+ if (typeof value === 'object' && !Array.isArray(value)) {
19
+ for (const [key, child] of Object.entries(value)) {
20
+ if (path && /[.=\x00-\x1f\x7f]/.test(key)) throw new Error('Codex override paths cannot address this config key');
21
+ visit(child, path ? `${path}.${key}` : key);
22
+ }
23
+ } else overrides.push(`${path}=${toml(value)}`);
24
+ };
25
+ visit(config, '');
26
+ return overrides;
27
+ }
28
+
29
+ export class CodexWorkerAppServer {
30
+ constructor({ codexPathOverride, env, config = {}, configArgs = [], apiKey, signal, onProcess = () => {} }) {
31
+ this.pending = new Map();
32
+ this.seq = 0;
33
+ this.listener = null;
34
+ this.failure = null;
35
+ const args = [...configArgs];
36
+ for (const override of codexWorkerConfigOverrides(config)) args.push('-c', override);
37
+ // Run identity in the command line permits conservative orphan identification.
38
+ args.push('-c', `synabun_worker_run=${JSON.stringify(env.SYNABUN_TERMINAL_SESSION || '')}`, 'app-server');
39
+ this.proc = spawn(codexPathOverride, args, { env, stdio: ['pipe', 'pipe', 'pipe'], windowsHide: true });
40
+ this.exited = new Promise((r) => this.proc.once('close', r));
41
+ onProcess({ pid: this.proc.pid, startedAt: new Date().toISOString() });
42
+ let buffer = '';
43
+ const decoder = new StringDecoder('utf8');
44
+ this.proc.stdout.on('data', (chunk) => {
45
+ buffer += decoder.write(chunk);
46
+ let end;
47
+ while ((end = buffer.indexOf('\n')) >= 0) {
48
+ const line = buffer.slice(0, end); buffer = buffer.slice(end + 1);
49
+ let msg; try { msg = JSON.parse(line); } catch { continue; }
50
+ if (msg.id != null && !msg.method) {
51
+ const p = this.pending.get(msg.id); if (!p) continue;
52
+ this.pending.delete(msg.id); clearTimeout(p.timer);
53
+ msg.error ? p.reject(new Error(msg.error.message || 'Codex RPC failed')) : p.resolve(msg.result);
54
+ } else if (msg.id != null) {
55
+ // Workers have approvalPolicy never. Never grant an unexpected request.
56
+ this.write({ id: msg.id, error: { code: -32601, message: 'Unattended worker does not accept interactive requests' } });
57
+ } else this.listener?.(msg);
58
+ }
59
+ });
60
+ // Drain stderr without exposing credentials/config to the worker transcript.
61
+ this.proc.stderr.resume();
62
+ this.proc.on('error', (error) => this.fail(error));
63
+ this.proc.stdin.on('error', (error) => this.fail(error));
64
+ this.proc.on('close', (code, signal) => this.fail(new Error(`Codex app-server exited (${signal || code})`)));
65
+ this.ready = (async () => {
66
+ await this.rpc('initialize', { clientInfo: { name: 'synabun-worker', version: '1.0.0' }, capabilities: { experimentalApi: true } });
67
+ this.write({ method: 'initialized', params: {} });
68
+ if (apiKey) await this.rpc('account/login/start', { type: 'apiKey', apiKey });
69
+ })();
70
+ this.ready.catch(() => {});
71
+ this.startupSignal = signal;
72
+ this.cancelStartup = () => { this.dispose().catch(() => {}); };
73
+ signal?.addEventListener('abort', this.cancelStartup, { once: true });
74
+ if (signal?.aborted) this.cancelStartup();
75
+ }
76
+ write(value) { if (!this.proc.stdin.destroyed) this.proc.stdin.write(JSON.stringify(value) + '\n'); }
77
+ fail(error) {
78
+ this.failure = error;
79
+ for (const p of this.pending.values()) { clearTimeout(p.timer); p.reject(error); }
80
+ this.pending.clear();
81
+ this.listener?.({ method: 'synabun/exit', error });
82
+ }
83
+ rpc(method, params) {
84
+ if (this.failure) return Promise.reject(this.failure);
85
+ return new Promise((resolve, reject) => {
86
+ const id = ++this.seq;
87
+ const timer = setTimeout(() => { this.pending.delete(id); reject(new Error(`Codex ${method} timed out`)); }, 30_000);
88
+ this.pending.set(id, { resolve, reject, timer });
89
+ this.write({ id, method, params });
90
+ });
91
+ }
92
+ startThread(options) { return this.thread(null, options); }
93
+ resumeThread(id, options) { return this.thread(id, options); }
94
+ thread(id, options) {
95
+ const owner = this;
96
+ const sandboxPolicy = options.sandboxMode === 'read-only' ? { type: 'readOnly', networkAccess: !!options.networkAccessEnabled }
97
+ : options.sandboxMode === 'workspace-write' ? { type: 'workspaceWrite', writableRoots: [options.workingDirectory, ...(options.additionalDirectories || [])], networkAccess: !!options.networkAccessEnabled }
98
+ : { type: 'dangerFullAccess' };
99
+ const ready = this.ready.then(async () => {
100
+ const reply = await this.rpc(id ? 'thread/resume' : 'thread/start', {
101
+ ...(id ? { threadId: id } : {}), cwd: options.workingDirectory,
102
+ model: options.model || null, approvalPolicy: 'never', sandbox: options.sandboxMode,
103
+ config: { web_search: options.webSearchMode || 'disabled', sandbox_workspace_write: { network_access: !!options.networkAccessEnabled, writable_roots: options.additionalDirectories || [] } },
104
+ });
105
+ const actual = reply?.thread?.id;
106
+ if (!actual || (id && actual !== id)) throw new Error('Codex did not resume the requested thread');
107
+ id = actual;
108
+ });
109
+ ready.catch(() => {});
110
+ return {
111
+ get id() { return id; }, ready: () => ready,
112
+ async runStreamed(prompt, { signal, outputSchema } = {}) {
113
+ await ready;
114
+ const queue = []; const text = new Map(); let wake; let done = false; let failure; let turnId;
115
+ const push = (event) => { queue.push(event); wake?.(); };
116
+ const abort = () => {
117
+ failure = Object.assign(new Error('Codex turn aborted'), { name: 'AbortError' }); done = true; wake?.();
118
+ if (turnId) owner.rpc('turn/interrupt', { threadId: id, turnId }).catch(() => {});
119
+ };
120
+ owner.listener = (msg) => {
121
+ const p = msg.params || {};
122
+ if (p.threadId && p.threadId !== id) return;
123
+ if (msg.method === 'synabun/exit') { failure = msg.error; done = true; wake?.(); }
124
+ if (msg.method === 'item/agentMessage/delta') {
125
+ const value = (text.get(p.itemId) || '') + (p.delta || '');
126
+ text.set(p.itemId, value);
127
+ push({ type: 'item.updated', item: { id: p.itemId, type: 'agent_message', text: value } });
128
+ }
129
+ if (msg.method === 'item/started' || msg.method === 'item/completed') {
130
+ const item = p.item || {};
131
+ const types = { agentMessage: 'agent_message', commandExecution: 'command_execution', fileChange: 'file_change', mcpToolCall: 'mcp_tool_call', webSearch: 'web_search', reasoning: 'reasoning' };
132
+ push({ type: msg.method === 'item/started' ? 'item.started' : 'item.completed', item: { ...item, type: types[item.type] || item.type, aggregated_output: item.aggregatedOutput, exit_code: item.exitCode } });
133
+ }
134
+ if (msg.method === 'turn/completed') {
135
+ if (p.turn?.status === 'failed') push({ type: 'turn.failed', error: p.turn.error || { message: 'Codex turn failed' } });
136
+ else if (p.turn?.status === 'interrupted') failure = Object.assign(new Error('Codex turn interrupted'), { name: 'AbortError' });
137
+ else push({ type: 'turn.completed' }); // rollout meter is authoritative across resumes
138
+ done = true; wake?.();
139
+ }
140
+ };
141
+ signal?.addEventListener('abort', abort, { once: true });
142
+ try {
143
+ if (signal?.aborted) throw Object.assign(new Error('Codex turn aborted'), { name: 'AbortError' });
144
+ const reply = await owner.rpc('turn/start', { threadId: id, input: [{ type: 'text', text: String(prompt), text_elements: [] }], approvalPolicy: 'never', sandboxPolicy, effort: options.modelReasoningEffort || null, ...(outputSchema ? { outputSchema } : {}) });
145
+ turnId = reply?.turn?.id;
146
+ if (signal?.aborted) abort();
147
+ } catch (error) { owner.listener = null; signal?.removeEventListener('abort', abort); throw error; }
148
+ return { events: (async function* () {
149
+ try {
150
+ yield { type: 'thread.started', thread_id: id };
151
+ while (!done || queue.length) {
152
+ if (queue.length) yield queue.shift();
153
+ else await new Promise((r) => { wake = r; });
154
+ }
155
+ if (failure) throw failure;
156
+ } finally { owner.listener = null; signal?.removeEventListener('abort', abort); }
157
+ })() };
158
+ },
159
+ };
160
+ }
161
+ async dispose() {
162
+ this.startupSignal?.removeEventListener('abort', this.cancelStartup);
163
+ if (this.proc.exitCode !== null || this.proc.signalCode) return;
164
+ if (process.platform === 'win32') {
165
+ try { execFileSync('taskkill', ['/pid', String(this.proc.pid), '/T', '/F'], { timeout: 5000, stdio: 'ignore', windowsHide: true }); } catch {}
166
+ } else this.proc.kill('SIGTERM');
167
+ let timer;
168
+ await Promise.race([this.exited, new Promise((r) => { timer = setTimeout(r, 1500); })]);
169
+ clearTimeout(timer);
170
+ if (this.proc.exitCode === null && !this.proc.signalCode) this.proc.kill('SIGKILL');
171
+ }
172
+ }
@@ -19,7 +19,7 @@
19
19
  // sequence; it does not remove it.
20
20
 
21
21
  import {
22
- openSync, closeSync, fstatSync, lstatSync, readSync, writeSync, ftruncateSync, fsyncSync,
22
+ openSync, closeSync, fstatSync, fchmodSync, lstatSync, readSync, writeSync, ftruncateSync, fsyncSync,
23
23
  mkdirSync, readdirSync, rmSync, unlinkSync, renameSync, realpathSync, createReadStream, constants,
24
24
  } from 'node:fs';
25
25
  import { randomBytes } from 'node:crypto';
@@ -142,6 +142,17 @@ export function writeConfinedFile(base, path, data, { exclusive = false, mode =
142
142
  if (!st.isFile()) throw new PathConfineError(400, 'Not a regular file.');
143
143
  if (!created) ftruncateSync(fd, 0);
144
144
  writeAll(fd, data);
145
+ } catch (err) {
146
+ // A file this call created and could not fill (the disk filled, the data could not be had) is not left
147
+ // half written: it is removed while it is still the file that was opened.
148
+ if (created) {
149
+ try {
150
+ const mine = fstatSync(fd);
151
+ const now = lstatSync(real);
152
+ if (now.dev === mine.dev && now.ino === mine.ino) unlinkSync(real);
153
+ } catch { /* gone already, or no longer ours */ }
154
+ }
155
+ throw err;
145
156
  } finally { try { closeSync(fd); } catch {} }
146
157
  return real;
147
158
  }
@@ -173,14 +184,29 @@ export function removeConfinedEntry(base, path) {
173
184
  return true;
174
185
  }
175
186
 
187
+ /**
188
+ * What is at `path` itself, a link not followed: 'absent', 'file', 'dir', 'link' or 'other' (a FIFO, a
189
+ * socket, a device). Nothing is opened.
190
+ */
191
+ export function entryKind(path) {
192
+ let st;
193
+ try { st = lstatSync(String(path)); } catch { return 'absent'; }
194
+ if (st.isSymbolicLink()) return 'link';
195
+ if (st.isFile()) return 'file';
196
+ if (st.isDirectory()) return 'dir';
197
+ return 'other';
198
+ }
199
+
176
200
  /**
177
201
  * Replace `path` with `data` through a temporary file in the same folder:
178
202
  * created exclusively under an unpredictable name, never through a link, then
179
203
  * renamed over `path` (a rename replaces a link, it does not follow it).
180
204
  * `expect` is the file's state when it was read ({ dev, ino, mtimeMs, size }):
181
- * a file that changed since is not overwritten (409).
205
+ * a file that changed since is not overwritten (409). `exactMode`: the new
206
+ * file gets `mode` as it is, not narrowed by the process umask (a file that
207
+ * replaces another keeps the permissions that one had).
182
208
  */
183
- export function replaceFileAtomic(path, data, { mode = 0o600, expect = null } = {}) {
209
+ export function replaceFileAtomic(path, data, { mode = 0o600, expect = null, exactMode = false } = {}) {
184
210
  const dir = realPathOf(dirname(String(path)));
185
211
  const target = join(dir, basename(String(path)));
186
212
  const tmp = join(dir, `.${basename(target)}.${randomBytes(12).toString('hex')}.tmp`);
@@ -190,6 +216,7 @@ export function replaceFileAtomic(path, data, { mode = 0o600, expect = null } =
190
216
  try {
191
217
  const st = verifyOpened(fd, tmp);
192
218
  if (!st.isFile()) throw moved();
219
+ if (exactMode) fchmodSync(fd, mode & 0o7777);
193
220
  writeAll(fd, data);
194
221
  try { fsyncSync(fd); } catch {}
195
222
  } finally { try { closeSync(fd); } catch {} }
@@ -0,0 +1,98 @@
1
+ // ═══════════════════════════════════════════
2
+ // SynaBun — /api/system/crash-notice: the notice after an automatic restart
3
+ // ═══════════════════════════════════════════
4
+ //
5
+ // GET /api/system/crash-notice { ok, notice } null, or the crash the supervisor recovered from
6
+ // POST /api/system/crash-notice/dismiss { id } { ok, notice }: what is left (a newer crash's, or null)
7
+ //
8
+ // When the server crashes after it was up, its supervisor (lib/server-supervisor.js at the package root) starts
9
+ // it again and leaves DATA_HOME/data/server-crash.json (lib/server-crash-record.js) for it. The owner's pages ask
10
+ // for it when they load and every time their sync socket connects (a page that was open through the crash
11
+ // reconnects, it is not reloaded: public/shared/ui-crash-notice.js), and show it until the owner dismisses it. A
12
+ // dismissal removes the record, and every open tab and window drops the notice at once (`crash-notice:changed`
13
+ // on the sync socket); none shows it again after a reload. The next crash writes a new record, with a new id,
14
+ // which shows again. A record that cannot be removed (a read-only data folder) is kept dismissed in memory for
15
+ // the life of this server.
16
+ //
17
+ // The owner's only: /api/system is admin-only (lib/request-gate.js), and every route takes the owner's guard by
18
+ // itself (lib/http-guards.js ownerRouteGuard: this server's Host, its Origin on the write, no guest, no cross-site
19
+ // write) and refuses an agent's request (uiOnly: X-SynaBun-Terminal, -Role, -Assistant, -Desktop-Grant, as
20
+ // /api/system/app does). The dismissal is the owner's write from SynaBun's own page: X-SynaBun-UI: 1, a JSON body,
21
+ // and this boot's page secret (lib/page-session.js, as Skills Studio's owner writes), which a local process that
22
+ // merely leaves the agent headers out lacks; a tab that stayed open through the restart carries the previous boot's
23
+ // cookie, and the page's own recovery (public/shared/page-session.js) gets this boot's and sends the dismissal once
24
+ // more. A request names an id, never a path.
25
+
26
+ import { Router } from 'express';
27
+ import { clearCrashRecord, readCrashRecord } from '../../lib/server-crash-record.js';
28
+ import { sendGuardError, uiOnly } from './http-guards.js';
29
+
30
+ const ID = /^[0-9a-f]{16}$/;
31
+
32
+ /** What a page is shown of a record (already checked field by field when it was read), or null. */
33
+ export function crashNoticeOf(record) {
34
+ if (!record || typeof record !== 'object') return null;
35
+ const { v, ...notice } = record;
36
+ return notice;
37
+ }
38
+
39
+ /**
40
+ * @param {object} deps
41
+ * @param {string} deps.dataHome
42
+ * @param {import('express').RequestHandler} deps.guard the owner's guard (lib/http-guards.js ownerRouteGuard)
43
+ * @param {{ verify(req): boolean, require: import('express').RequestHandler }} [deps.pageSession] lib/page-session.js:
44
+ * the page secret a dismissal carries (server.js hands it in; without one, as in a unit test, none is asked)
45
+ * @param {(message: object) => void} [deps.broadcast] the owner's open pages (server.js broadcastSync keeps
46
+ * `crash-notice:` from invite guests)
47
+ * @param {() => Promise<{ tunnel?: 'unknown' }>} [deps.leftovers] what the crashed server may have left running that
48
+ * this one could not end (server.js: its cloudflared, sweepLeftoverTunnels): added to the notice
49
+ */
50
+ export function createCrashNoticeApi({
51
+ dataHome, guard, pageSession = null, broadcast = () => {}, log = () => {}, read = readCrashRecord, clear = clearCrashRecord,
52
+ leftovers = async () => ({}),
53
+ } = {}) {
54
+ if (!dataHome || typeof guard !== 'function') throw new Error('createCrashNoticeApi needs the data home and the owner\'s guard');
55
+ const router = Router();
56
+ // Dismissed while the record could not be removed: never shown again by this server.
57
+ const dismissed = new Set();
58
+ const current = () => {
59
+ const notice = crashNoticeOf(read(dataHome));
60
+ return notice && !dismissed.has(notice.id) ? notice : null;
61
+ };
62
+ // The notice as a page is shown it: the record, and what the crashed server may have left open.
63
+ const shown = async (notice) => {
64
+ if (!notice) return null;
65
+ let left = {};
66
+ try { left = await leftovers(); } catch { left = {}; }
67
+ return { ...notice, ...(left?.tunnel === 'unknown' ? { tunnel: 'unknown' } : {}) };
68
+ };
69
+
70
+ router.use(guard, uiOnly, (req, res, next) => { res.set('Cache-Control', 'no-store'); next(); });
71
+
72
+ router.get('/', async (req, res) => { res.json({ ok: true, notice: await shown(current()) }); });
73
+
74
+ router.post('/dismiss', (req, res, next) => {
75
+ if (req.get('x-synabun-ui') !== '1') return sendGuardError(res, 403, 'UI_HEADER_REQUIRED', 'A notice is dismissed from SynaBun\'s own page.');
76
+ // The page secret: what a local process that merely sends the page's headers lacks.
77
+ if (pageSession && !pageSession.verify(req)) return pageSession.require(req, res, next);
78
+ next();
79
+ }, async (req, res) => {
80
+ if (!req.is('application/json')) return res.status(415).json({ ok: false, code: 'JSON_REQUIRED', error: 'Send JSON.' });
81
+ const id = req.body?.id;
82
+ if (typeof id !== 'string' || !ID.test(id)) return res.status(400).json({ ok: false, code: 'BAD_REQUEST', error: 'Send { id } of the notice.' });
83
+ if (!clear(dataHome, { id })) {
84
+ const still = crashNoticeOf(read(dataHome));
85
+ if (still?.id === id) {
86
+ dismissed.add(id);
87
+ log(`[crash-notice] the record could not be removed; ${id} stays dismissed until the server restarts`);
88
+ }
89
+ } else {
90
+ log(`[crash-notice] dismissed ${id}`);
91
+ }
92
+ const notice = await shown(current());
93
+ try { broadcast({ type: 'crash-notice:changed', notice }); } catch {}
94
+ res.json({ ok: true, notice });
95
+ });
96
+
97
+ return router;
98
+ }