synabun 2.0.10 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (656) hide show
  1. package/CHANGELOG.md +207 -0
  2. package/README.md +25 -2
  3. package/THIRD-PARTY-LICENSES.md +22 -0
  4. package/bin/synabun.js +71 -24
  5. package/docs/whatsapp.md +13 -13
  6. package/hooks/claude-code/pre-websearch.mjs +12 -1
  7. package/hooks/claude-code/shared.mjs +5 -0
  8. package/hooks/claude-code/stop.mjs +1 -1
  9. package/lib/claude-hooks.js +172 -18
  10. package/lib/client-config-repair.js +30 -17
  11. package/lib/desktop-app.js +7 -1
  12. package/lib/external-tools.js +7 -6
  13. package/lib/first-launch-protection.js +57 -12
  14. package/lib/mcp-dist.js +176 -0
  15. package/lib/release-npm-ci.mjs +138 -0
  16. package/lib/release-publish.mjs +91 -0
  17. package/lib/release-scan.mjs +50 -0
  18. package/lib/server-crash-record.js +123 -0
  19. package/lib/server-exit.js +318 -0
  20. package/lib/server-supervisor.js +508 -0
  21. package/lib/start-launcher.js +37 -4
  22. package/lib/tools-cli.js +45 -0
  23. package/lib/update-snapshot.js +302 -0
  24. package/lib/virustotal.mjs +203 -0
  25. package/lib/windows-crash-event.js +269 -0
  26. package/mcp-server/dist/http.d.ts +20 -1
  27. package/mcp-server/dist/http.d.ts.map +1 -1
  28. package/mcp-server/dist/http.js +59 -12
  29. package/mcp-server/dist/http.js.map +1 -1
  30. package/mcp-server/dist/index.d.ts +33 -27
  31. package/mcp-server/dist/index.d.ts.map +1 -1
  32. package/mcp-server/dist/index.js +128 -143
  33. package/mcp-server/dist/index.js.map +1 -1
  34. package/mcp-server/dist/preload.js +1 -1
  35. package/mcp-server/dist/preload.js.map +1 -1
  36. package/mcp-server/dist/services/budget-judgments.d.ts +1 -1
  37. package/mcp-server/dist/services/budget-judgments.d.ts.map +1 -1
  38. package/mcp-server/dist/services/budget-judgments.js +5 -3
  39. package/mcp-server/dist/services/budget-judgments.js.map +1 -1
  40. package/mcp-server/dist/services/codex-config-heal.d.ts +6 -2
  41. package/mcp-server/dist/services/codex-config-heal.d.ts.map +1 -1
  42. package/mcp-server/dist/services/codex-config-heal.js +81 -28
  43. package/mcp-server/dist/services/codex-config-heal.js.map +1 -1
  44. package/mcp-server/dist/services/identity.d.ts +2 -2
  45. package/mcp-server/dist/services/identity.js +2 -2
  46. package/mcp-server/dist/services/memory-judge-backfill.d.ts +6 -0
  47. package/mcp-server/dist/services/memory-judge-backfill.d.ts.map +1 -1
  48. package/mcp-server/dist/services/memory-judge-backfill.js +7 -1
  49. package/mcp-server/dist/services/memory-judge-backfill.js.map +1 -1
  50. package/mcp-server/dist/services/memory-sessions.d.ts +1 -1
  51. package/mcp-server/dist/services/memory-sessions.d.ts.map +1 -1
  52. package/mcp-server/dist/services/memory-sessions.js +28 -2
  53. package/mcp-server/dist/services/memory-sessions.js.map +1 -1
  54. package/mcp-server/dist/services/neural-interface.d.ts +18 -11
  55. package/mcp-server/dist/services/neural-interface.d.ts.map +1 -1
  56. package/mcp-server/dist/services/neural-interface.js +67 -11
  57. package/mcp-server/dist/services/neural-interface.js.map +1 -1
  58. package/mcp-server/dist/services/server-instructions.d.ts +7 -2
  59. package/mcp-server/dist/services/server-instructions.d.ts.map +1 -1
  60. package/mcp-server/dist/services/server-instructions.js +22 -63
  61. package/mcp-server/dist/services/server-instructions.js.map +1 -1
  62. package/mcp-server/dist/services/tool-catalog.d.ts +120 -0
  63. package/mcp-server/dist/services/tool-catalog.d.ts.map +1 -0
  64. package/mcp-server/dist/services/tool-catalog.js +339 -0
  65. package/mcp-server/dist/services/tool-catalog.js.map +1 -0
  66. package/mcp-server/dist/services/tool-list-refresh-barrier.d.ts +12 -0
  67. package/mcp-server/dist/services/tool-list-refresh-barrier.d.ts.map +1 -0
  68. package/mcp-server/dist/services/tool-list-refresh-barrier.js +40 -0
  69. package/mcp-server/dist/services/tool-list-refresh-barrier.js.map +1 -0
  70. package/mcp-server/dist/services/tool-list.d.ts +108 -0
  71. package/mcp-server/dist/services/tool-list.d.ts.map +1 -0
  72. package/mcp-server/dist/services/tool-list.js +334 -0
  73. package/mcp-server/dist/services/tool-list.js.map +1 -0
  74. package/mcp-server/dist/services/tool-runtime.d.ts +161 -0
  75. package/mcp-server/dist/services/tool-runtime.d.ts.map +1 -0
  76. package/mcp-server/dist/services/tool-runtime.js +400 -0
  77. package/mcp-server/dist/services/tool-runtime.js.map +1 -0
  78. package/mcp-server/dist/services/typesafe-config.js +1 -1
  79. package/mcp-server/dist/services/typesafe-config.js.map +1 -1
  80. package/mcp-server/dist/services/whiteboard-geometry.d.ts +26 -2
  81. package/mcp-server/dist/services/whiteboard-geometry.d.ts.map +1 -1
  82. package/mcp-server/dist/services/whiteboard-geometry.js +91 -8
  83. package/mcp-server/dist/services/whiteboard-geometry.js.map +1 -1
  84. package/mcp-server/dist/tools/agents.d.ts +14 -14
  85. package/mcp-server/dist/tools/agents.d.ts.map +1 -1
  86. package/mcp-server/dist/tools/agents.js +29 -19
  87. package/mcp-server/dist/tools/agents.js.map +1 -1
  88. package/mcp-server/dist/tools/browser-batch.d.ts +3 -3
  89. package/mcp-server/dist/tools/choice.d.ts +6 -0
  90. package/mcp-server/dist/tools/choice.d.ts.map +1 -1
  91. package/mcp-server/dist/tools/choice.js +18 -13
  92. package/mcp-server/dist/tools/choice.js.map +1 -1
  93. package/mcp-server/dist/tools/git-tools.js +2 -2
  94. package/mcp-server/dist/tools/git-tools.js.map +1 -1
  95. package/mcp-server/dist/tools/image-tools.d.ts +1 -1
  96. package/mcp-server/dist/tools/image-tools.js +1 -1
  97. package/mcp-server/dist/tools/morelogin.d.ts.map +1 -1
  98. package/mcp-server/dist/tools/morelogin.js +9 -6
  99. package/mcp-server/dist/tools/morelogin.js.map +1 -1
  100. package/mcp-server/dist/tools/skill-tools.d.ts +505 -0
  101. package/mcp-server/dist/tools/skill-tools.d.ts.map +1 -0
  102. package/mcp-server/dist/tools/skill-tools.js +642 -0
  103. package/mcp-server/dist/tools/skill-tools.js.map +1 -0
  104. package/mcp-server/dist/tools/skill.d.ts +7 -0
  105. package/mcp-server/dist/tools/skill.d.ts.map +1 -0
  106. package/mcp-server/dist/tools/skill.js +11 -0
  107. package/mcp-server/dist/tools/skill.js.map +1 -0
  108. package/mcp-server/dist/tools/tool-groups.d.ts +68 -0
  109. package/mcp-server/dist/tools/tool-groups.d.ts.map +1 -0
  110. package/mcp-server/dist/tools/tool-groups.js +147 -0
  111. package/mcp-server/dist/tools/tool-groups.js.map +1 -0
  112. package/mcp-server/dist/tools/whiteboard-format.d.ts.map +1 -1
  113. package/mcp-server/dist/tools/whiteboard-format.js +7 -4
  114. package/mcp-server/dist/tools/whiteboard-format.js.map +1 -1
  115. package/mcp-server/dist/tools/whiteboard-tools.d.ts +64 -13
  116. package/mcp-server/dist/tools/whiteboard-tools.d.ts.map +1 -1
  117. package/mcp-server/dist/tools/whiteboard-tools.js +30 -5
  118. package/mcp-server/dist/tools/whiteboard-tools.js.map +1 -1
  119. package/mcp-server/package-lock.json +2 -2
  120. package/mcp-server/package.json +1 -1
  121. package/mcp-server/src/http.ts +75 -12
  122. package/mcp-server/src/index.ts +147 -154
  123. package/mcp-server/src/preload.ts +12 -12
  124. package/mcp-server/src/services/budget-judgments.ts +5 -3
  125. package/mcp-server/src/services/codex-config-heal.ts +80 -29
  126. package/mcp-server/src/services/identity.ts +2 -2
  127. package/mcp-server/src/services/memory-judge-backfill.ts +7 -1
  128. package/mcp-server/src/services/memory-sessions.ts +24 -3
  129. package/mcp-server/src/services/neural-interface.ts +81 -21
  130. package/mcp-server/src/services/server-instructions.ts +29 -64
  131. package/mcp-server/src/services/tool-catalog.ts +403 -0
  132. package/mcp-server/src/services/tool-list-refresh-barrier.ts +33 -0
  133. package/mcp-server/src/services/tool-list.ts +410 -0
  134. package/mcp-server/src/services/tool-runtime.ts +457 -0
  135. package/mcp-server/src/services/typesafe-config.ts +1 -1
  136. package/mcp-server/src/services/whiteboard-geometry.ts +94 -9
  137. package/mcp-server/src/tools/agents.ts +29 -20
  138. package/mcp-server/src/tools/choice.ts +17 -12
  139. package/mcp-server/src/tools/git-tools.ts +2 -2
  140. package/mcp-server/src/tools/image-tools.ts +1 -1
  141. package/mcp-server/src/tools/morelogin.ts +6 -4
  142. package/mcp-server/src/tools/skill-tools.ts +592 -0
  143. package/mcp-server/src/tools/skill.ts +13 -0
  144. package/mcp-server/src/tools/tool-groups.ts +164 -0
  145. package/mcp-server/src/tools/whiteboard-format.ts +9 -3
  146. package/mcp-server/src/tools/whiteboard-tools.ts +39 -5
  147. package/neural-interface/i18n/en.json +3953 -228
  148. package/neural-interface/i18n/pt-BR.json +3901 -179
  149. package/neural-interface/lib/agent-sandbox-elevation.js +6 -0
  150. package/neural-interface/lib/antigravity/acp-client-host.js +554 -0
  151. package/neural-interface/lib/antigravity/acp-connection.js +299 -0
  152. package/neural-interface/lib/antigravity/bypass.js +100 -0
  153. package/neural-interface/lib/antigravity/catalog.js +273 -0
  154. package/neural-interface/lib/antigravity/home.js +260 -0
  155. package/neural-interface/lib/antigravity/migrate-gemini.js +139 -0
  156. package/neural-interface/lib/antigravity/panel-bridge.js +1058 -0
  157. package/neural-interface/lib/antigravity/policy-hook.mjs +78 -0
  158. package/neural-interface/lib/antigravity/policy.js +74 -0
  159. package/neural-interface/lib/antigravity/tool-call.js +178 -0
  160. package/neural-interface/lib/antigravity/transcripts.js +252 -0
  161. package/neural-interface/lib/antigravity/usage.js +43 -0
  162. package/neural-interface/lib/assistant-api.js +128 -28
  163. package/neural-interface/lib/assistant-brains/antigravity.js +423 -0
  164. package/neural-interface/lib/assistant-brains/claude.js +4 -3
  165. package/neural-interface/lib/assistant-brains/codex-browser-policy-hook.mjs +12 -2
  166. package/neural-interface/lib/assistant-brains/codex-route-gate-hook.mjs +32 -9
  167. package/neural-interface/lib/assistant-brains/codex.js +9 -5
  168. package/neural-interface/lib/assistant-brains/opencode.js +120 -54
  169. package/neural-interface/lib/assistant-brains/opencode2-browser-policy/index.js +28 -13
  170. package/neural-interface/lib/assistant-brains/opencode2-route-gate/index.js +59 -19
  171. package/neural-interface/lib/assistant-budget-planner.js +7 -3
  172. package/neural-interface/lib/assistant-budget-split.js +42 -15
  173. package/neural-interface/lib/assistant-catalog.js +81 -15
  174. package/neural-interface/lib/assistant-config.js +6 -3
  175. package/neural-interface/lib/assistant-dispatch.js +1073 -200
  176. package/neural-interface/lib/assistant-envelope.js +156 -2
  177. package/neural-interface/lib/assistant-evidence.js +80 -0
  178. package/neural-interface/lib/assistant-hidden-models.js +7 -5
  179. package/neural-interface/lib/assistant-persona.js +93 -19
  180. package/neural-interface/lib/assistant-plan-permissions.js +25 -9
  181. package/neural-interface/lib/assistant-route-gate-codex.js +3 -0
  182. package/neural-interface/lib/assistant-route-gate.js +6 -4
  183. package/neural-interface/lib/assistant-router.js +245 -38
  184. package/neural-interface/lib/assistant-runtime.js +214 -30
  185. package/neural-interface/lib/assistant-task-prompt.js +87 -21
  186. package/neural-interface/lib/assistant-tools.js +51 -0
  187. package/neural-interface/lib/assistant-usage.js +29 -0
  188. package/neural-interface/lib/backup-service.js +626 -4
  189. package/neural-interface/lib/backup-zip-reader.js +10 -5
  190. package/neural-interface/lib/backup-zip-writer.js +257 -0
  191. package/neural-interface/lib/browser-execution.js +10 -2
  192. package/neural-interface/lib/browser-guard-cdp.js +84 -0
  193. package/neural-interface/lib/browser-network-guard.js +476 -0
  194. package/neural-interface/lib/browser-policy-roots.js +64 -0
  195. package/neural-interface/lib/browser-tool-policy.js +198 -38
  196. package/neural-interface/lib/claude-agent-bridge.js +11 -2
  197. package/neural-interface/lib/claude-history-cache.js +210 -0
  198. package/neural-interface/lib/claude-hooks-status.js +103 -0
  199. package/neural-interface/lib/claude-model-catalog.js +5 -1
  200. package/neural-interface/lib/claude-temporary.js +5 -11
  201. package/neural-interface/lib/cli-install-api.js +1 -1
  202. package/neural-interface/lib/cli-install.js +163 -154
  203. package/neural-interface/lib/cli-resolver.js +13 -3
  204. package/neural-interface/lib/cli-update-planner.js +52 -41
  205. package/neural-interface/lib/cloudflared/tunnel.js +42 -2
  206. package/neural-interface/lib/codex-mcp-approvals.js +11 -0
  207. package/neural-interface/lib/codex-rollout-reader.js +52 -0
  208. package/neural-interface/lib/codex-worker-app-server.js +191 -0
  209. package/neural-interface/lib/confined-fs.js +30 -3
  210. package/neural-interface/lib/crash-notice-api.js +98 -0
  211. package/neural-interface/lib/editor-completion-opencode.js +68 -68
  212. package/neural-interface/lib/editor-git-api.js +3 -20
  213. package/neural-interface/lib/exec-loop-command.js +13 -10
  214. package/neural-interface/lib/file-explorer-api.js +74 -40
  215. package/neural-interface/lib/file-explorer-watch.js +9 -3
  216. package/neural-interface/lib/git-bash/install.js +52 -6
  217. package/neural-interface/lib/git-bash/manager.js +59 -17
  218. package/neural-interface/lib/git-bash/pins.js +12 -0
  219. package/neural-interface/lib/git-read.js +2 -2
  220. package/neural-interface/lib/git-status-runner.js +390 -0
  221. package/neural-interface/lib/git-status-watchdog.js +40 -0
  222. package/neural-interface/lib/greeting/budgets.js +1 -0
  223. package/neural-interface/lib/greeting/engine.js +2 -2
  224. package/neural-interface/lib/greeting/sources.js +10 -12
  225. package/neural-interface/lib/greeting/writer.js +1 -1
  226. package/neural-interface/lib/http-guards.js +8 -2
  227. package/neural-interface/lib/install-details.js +4 -1
  228. package/neural-interface/lib/mcp-agent-servers.js +67 -0
  229. package/neural-interface/lib/mcp-client-config.js +35 -33
  230. package/neural-interface/lib/mcp-external-servers.js +332 -0
  231. package/neural-interface/lib/mcp-installer.js +2 -1
  232. package/neural-interface/lib/{mcp-profile-refresh-coordinator.js → mcp-tools-refresh-coordinator.js} +4 -4
  233. package/neural-interface/lib/memory-session-capture.js +17 -3
  234. package/neural-interface/lib/morelogin.js +177 -25
  235. package/neural-interface/lib/native-loop-providers.js +965 -66
  236. package/neural-interface/lib/native-loop-runtime.js +290 -42
  237. package/neural-interface/lib/opencode-config.js +557 -0
  238. package/neural-interface/lib/opencode-db-schema.js +17 -34
  239. package/neural-interface/lib/opencode-history.js +48 -218
  240. package/neural-interface/lib/opencode-mcp-ready.js +108 -0
  241. package/neural-interface/lib/opencode-native-boundary.js +53 -0
  242. package/neural-interface/lib/opencode-protocol.js +249 -112
  243. package/neural-interface/lib/opencode-runtime-config.js +32 -22
  244. package/neural-interface/lib/opencode-serve-records.js +39 -21
  245. package/neural-interface/lib/opencode-v2-client.js +48 -153
  246. package/neural-interface/lib/opencode-v2-ws-requests.js +36 -210
  247. package/neural-interface/lib/opencode-worker-data.js +27 -0
  248. package/neural-interface/lib/opencode2-client.js +73 -37
  249. package/neural-interface/lib/opencode2-proxy.js +23 -63
  250. package/neural-interface/lib/opencode2-translate.js +51 -2
  251. package/neural-interface/lib/owner-authority.js +249 -0
  252. package/neural-interface/lib/page-session.js +275 -0
  253. package/neural-interface/lib/path-confine.js +12 -9
  254. package/neural-interface/lib/peer-identity.js +793 -0
  255. package/neural-interface/lib/pty-host/core.js +28 -1
  256. package/neural-interface/lib/pty-host/lifetime.js +12 -0
  257. package/neural-interface/lib/pty-host/manager.js +12 -1
  258. package/neural-interface/lib/remote-policy.js +1 -1
  259. package/neural-interface/lib/request-gate.js +20 -2
  260. package/neural-interface/lib/rulesets/api.js +7 -6
  261. package/neural-interface/lib/rulesets/fs-safe.js +1 -1
  262. package/neural-interface/lib/rulesets/installer.js +180 -36
  263. package/neural-interface/lib/rulesets/json-edit.js +1 -1
  264. package/neural-interface/lib/rulesets/render.js +1 -1
  265. package/neural-interface/lib/session-cache-builder.js +81 -31
  266. package/neural-interface/lib/session-title-generator.js +58 -36
  267. package/neural-interface/lib/skills/api-v2.js +495 -0
  268. package/neural-interface/lib/skills/bundle.js +418 -0
  269. package/neural-interface/lib/skills/catalog.js +298 -0
  270. package/neural-interface/lib/skills/creation-api.js +191 -0
  271. package/neural-interface/lib/skills/creation-brief.js +247 -0
  272. package/neural-interface/lib/skills/creation-sources.js +285 -0
  273. package/neural-interface/lib/skills/creation.js +843 -0
  274. package/neural-interface/lib/skills/deploy.js +569 -0
  275. package/neural-interface/lib/skills/digest.js +119 -0
  276. package/neural-interface/lib/skills/discover.js +111 -0
  277. package/neural-interface/lib/skills/draft-confinement.js +216 -0
  278. package/neural-interface/lib/skills/eval-confinement.js +399 -0
  279. package/neural-interface/lib/skills/eval-sandbox.js +280 -0
  280. package/neural-interface/lib/skills/eval-trace.js +135 -0
  281. package/neural-interface/lib/skills/evals-api.js +212 -0
  282. package/neural-interface/lib/skills/evals.js +1573 -0
  283. package/neural-interface/lib/skills/export.js +203 -0
  284. package/neural-interface/lib/skills/frontmatter.js +64 -0
  285. package/neural-interface/lib/skills/health.js +75 -0
  286. package/neural-interface/lib/skills/json-edit.js +165 -0
  287. package/neural-interface/lib/skills/known-bridge-digests.json +441 -0
  288. package/neural-interface/lib/skills/known-bridges.js +96 -0
  289. package/neural-interface/lib/skills/library.js +823 -0
  290. package/neural-interface/lib/skills/local-store.js +21 -0
  291. package/neural-interface/lib/skills/migration.js +433 -0
  292. package/neural-interface/lib/skills/operations.js +45 -0
  293. package/neural-interface/lib/skills/ownership.js +427 -0
  294. package/neural-interface/lib/skills/packages.js +88 -0
  295. package/neural-interface/lib/skills/reviews.js +212 -0
  296. package/neural-interface/lib/skills/revision.js +80 -0
  297. package/neural-interface/lib/skills/roots.js +269 -0
  298. package/neural-interface/lib/skills/runtime-checks.js +358 -0
  299. package/neural-interface/lib/skills/scan-assets.js +252 -0
  300. package/neural-interface/lib/skills/scan-context.js +26 -0
  301. package/neural-interface/lib/skills/scan-shell.js +324 -0
  302. package/neural-interface/lib/skills/scan.js +364 -0
  303. package/neural-interface/lib/skills/scanners.js +54 -0
  304. package/neural-interface/lib/skills/service.js +530 -0
  305. package/neural-interface/lib/skills/telemetry.js +119 -0
  306. package/neural-interface/lib/sqlite-integrity-worker.js +22 -0
  307. package/neural-interface/lib/synabun-version.js +1 -1
  308. package/neural-interface/lib/system-activity.js +1 -1
  309. package/neural-interface/lib/tool-lists.js +124 -0
  310. package/neural-interface/lib/whatsapp/brain.js +7 -3
  311. package/neural-interface/lib/whatsapp/bridge.js +6 -3
  312. package/neural-interface/lib/whatsapp/cards.js +22 -9
  313. package/neural-interface/lib/whatsapp/config.js +1 -1
  314. package/neural-interface/lib/worker-confinement.js +1268 -0
  315. package/neural-interface/lib/worker-guard-setting.js +56 -0
  316. package/neural-interface/lib/worker-mcp-channel.js +175 -0
  317. package/neural-interface/lib/worker-question.js +74 -0
  318. package/neural-interface/lib/worker-relay-ports.js +227 -0
  319. package/neural-interface/lib/worker-resume.js +238 -0
  320. package/neural-interface/lib/worker-sandbox.js +329 -0
  321. package/neural-interface/package-lock.json +34 -12
  322. package/neural-interface/package.json +3 -2
  323. package/neural-interface/public/index.html +3 -1
  324. package/neural-interface/public/index2d.html +19 -11
  325. package/neural-interface/public/onboarding.html +3 -3
  326. package/neural-interface/public/shared/account-menu.js +8 -5
  327. package/neural-interface/public/shared/agent-runtime-options.js +125 -31
  328. package/neural-interface/public/shared/agy/agy-bypass.js +47 -0
  329. package/neural-interface/public/shared/agy/agy-client.js +266 -0
  330. package/neural-interface/public/shared/agy/agy-commands.js +120 -0
  331. package/neural-interface/public/shared/agy/agy-copy.js +326 -0
  332. package/neural-interface/public/shared/agy/agy-diff.js +161 -0
  333. package/neural-interface/public/shared/agy/agy-events.js +469 -0
  334. package/neural-interface/public/shared/agy/agy-greeting.js +26 -0
  335. package/neural-interface/public/shared/agy/agy-options.js +232 -0
  336. package/neural-interface/public/shared/agy/agy-panel.js +2543 -0
  337. package/neural-interface/public/shared/agy/agy-render.js +392 -0
  338. package/neural-interface/public/shared/agy/agy-setup.js +149 -0
  339. package/neural-interface/public/shared/agy/agy-styles.js +604 -0
  340. package/neural-interface/public/shared/agy/agy-tabs-logic.js +181 -0
  341. package/neural-interface/public/shared/api.js +1527 -1336
  342. package/neural-interface/public/shared/app-frame.js +192 -0
  343. package/neural-interface/public/shared/assistant/asst-agents-dock.js +36 -6
  344. package/neural-interface/public/shared/assistant/asst-api.js +1 -1
  345. package/neural-interface/public/shared/assistant/asst-ask-styles.js +270 -0
  346. package/neural-interface/public/shared/assistant/asst-ask-tail.js +118 -0
  347. package/neural-interface/public/shared/assistant/asst-ask.js +397 -0
  348. package/neural-interface/public/shared/assistant/asst-brain-picker.js +105 -44
  349. package/neural-interface/public/shared/assistant/asst-budget.js +5 -4
  350. package/neural-interface/public/shared/assistant/asst-control.js +205 -26
  351. package/neural-interface/public/shared/assistant/asst-followups-card.js +383 -0
  352. package/neural-interface/public/shared/assistant/asst-followups.js +417 -0
  353. package/neural-interface/public/shared/assistant/asst-hosts.js +16 -7
  354. package/neural-interface/public/shared/assistant/asst-limit-dock.js +45 -0
  355. package/neural-interface/public/shared/assistant/asst-limit-wait.js +327 -0
  356. package/neural-interface/public/shared/assistant/asst-limit.js +168 -0
  357. package/neural-interface/public/shared/assistant/asst-mascot.js +49 -12
  358. package/neural-interface/public/shared/assistant/asst-menu.js +7 -6
  359. package/neural-interface/public/shared/assistant/asst-panel.js +151 -19
  360. package/neural-interface/public/shared/assistant/asst-rack-styles.js +66 -49
  361. package/neural-interface/public/shared/assistant/asst-render.js +445 -82
  362. package/neural-interface/public/shared/assistant/asst-route.js +304 -53
  363. package/neural-interface/public/shared/assistant/asst-routes-editor.js +9 -8
  364. package/neural-interface/public/shared/assistant/asst-scenes.js +56 -1
  365. package/neural-interface/public/shared/assistant/asst-sidepanel.js +117 -10
  366. package/neural-interface/public/shared/assistant/asst-slash.js +17 -9
  367. package/neural-interface/public/shared/assistant/asst-state.js +87 -24
  368. package/neural-interface/public/shared/assistant/asst-stop.js +127 -0
  369. package/neural-interface/public/shared/assistant/asst-styles.js +93 -21
  370. package/neural-interface/public/shared/assistant/asst-tool-kinds.js +190 -23
  371. package/neural-interface/public/shared/assistant/asst-usage.js +2 -1
  372. package/neural-interface/public/shared/automation-context.js +5 -2
  373. package/neural-interface/public/shared/cc-dropdown.js +89 -19
  374. package/neural-interface/public/shared/cdx/cdx-context-menu.js +10 -9
  375. package/neural-interface/public/shared/cdx/cdx-copy.js +16 -0
  376. package/neural-interface/public/shared/cdx/cdx-output-model.js +22 -1
  377. package/neural-interface/public/shared/cdx/cdx-output.js +34 -10
  378. package/neural-interface/public/shared/cdx/cdx-panel.js +59 -151
  379. package/neural-interface/public/shared/cdx/cdx-preview.js +12 -0
  380. package/neural-interface/public/shared/cdx/cdx-protocol.js +39 -11
  381. package/neural-interface/public/shared/cdx/cdx-render.js +57 -38
  382. package/neural-interface/public/shared/cdx/cdx-requests.js +14 -4
  383. package/neural-interface/public/shared/cdx/cdx-skill-hints.js +54 -0
  384. package/neural-interface/public/shared/cdx/cdx-styles.js +15 -3
  385. package/neural-interface/public/shared/cdx/cdx-tabs.js +127 -44
  386. package/neural-interface/public/shared/cdx/cdx-ws.js +0 -1
  387. package/neural-interface/public/shared/cli-install-controller.js +218 -0
  388. package/neural-interface/public/shared/cli-install-view.js +11 -12
  389. package/neural-interface/public/shared/cli-status.js +11 -10
  390. package/neural-interface/public/shared/constants.js +5 -4
  391. package/neural-interface/public/shared/context-menu-areas.js +34 -0
  392. package/neural-interface/public/shared/context-menu-logic.js +243 -0
  393. package/neural-interface/public/shared/context-menu-model.js +367 -0
  394. package/neural-interface/public/shared/context-menu.js +372 -0
  395. package/neural-interface/public/shared/cp/cp-context-menu.js +10 -9
  396. package/neural-interface/public/shared/cp/cp-restore.js +162 -0
  397. package/neural-interface/public/shared/cp/cp-tool-cards.js +10 -3
  398. package/neural-interface/public/shared/crash-notice-view.js +168 -0
  399. package/neural-interface/public/shared/desktop-bridge.js +17 -0
  400. package/neural-interface/public/shared/desktop-titlebar-view.js +12 -0
  401. package/neural-interface/public/shared/desktop-titlebar.js +13 -4
  402. package/neural-interface/public/shared/desktop-update-view.js +21 -0
  403. package/neural-interface/public/shared/editor/editor-panel-logic.js +2 -2
  404. package/neural-interface/public/shared/explorer/fx-api.js +4 -4
  405. package/neural-interface/public/shared/explorer/fx-links.js +3 -3
  406. package/neural-interface/public/shared/explorer/fx-logic.js +1 -1
  407. package/neural-interface/public/shared/explorer/fx-main.js +48 -16
  408. package/neural-interface/public/shared/explorer/fx-tree.js +1 -0
  409. package/neural-interface/public/shared/greeting/greeting-card.js +2 -2
  410. package/neural-interface/public/shared/greeting/greeting-view.js +1 -0
  411. package/neural-interface/public/shared/html-shell.js +30 -15
  412. package/neural-interface/public/shared/i18n.js +2 -0
  413. package/neural-interface/public/shared/ocp-v2/ocp-v2-approvals.js +7 -7
  414. package/neural-interface/public/shared/ocp-v2/ocp-v2-binding.js +4 -4
  415. package/neural-interface/public/shared/ocp-v2/ocp-v2-changes-logic.js +3 -101
  416. package/neural-interface/public/shared/ocp-v2/ocp-v2-childpanel.js +2 -0
  417. package/neural-interface/public/shared/ocp-v2/ocp-v2-compact-button.js +1 -3
  418. package/neural-interface/public/shared/ocp-v2/ocp-v2-composer-logic.js +2 -6
  419. package/neural-interface/public/shared/ocp-v2/ocp-v2-context-menu.js +11 -11
  420. package/neural-interface/public/shared/ocp-v2/ocp-v2-context-model.js +0 -3
  421. package/neural-interface/public/shared/ocp-v2/ocp-v2-events.js +8 -4
  422. package/neural-interface/public/shared/ocp-v2/ocp-v2-manager.js +7 -7
  423. package/neural-interface/public/shared/ocp-v2/ocp-v2-outcome-notifications.js +16 -0
  424. package/neural-interface/public/shared/ocp-v2/ocp-v2-panel.js +74 -259
  425. package/neural-interface/public/shared/ocp-v2/ocp-v2-plan.js +1 -2
  426. package/neural-interface/public/shared/ocp-v2/ocp-v2-projectbar.js +95 -202
  427. package/neural-interface/public/shared/ocp-v2/ocp-v2-rehydrate.js +13 -4
  428. package/neural-interface/public/shared/ocp-v2/ocp-v2-render.js +13 -22
  429. package/neural-interface/public/shared/ocp-v2/ocp-v2-send.js +4 -4
  430. package/neural-interface/public/shared/ocp-v2/ocp-v2-session-actions.js +8 -61
  431. package/neural-interface/public/shared/ocp-v2/ocp-v2-sessions-logic.js +2 -91
  432. package/neural-interface/public/shared/ocp-v2/ocp-v2-slash-hints.js +16 -15
  433. package/neural-interface/public/shared/ocp-v2/ocp-v2-state.js +8 -21
  434. package/neural-interface/public/shared/ocp-v2/ocp-v2-status-logic.js +1 -99
  435. package/neural-interface/public/shared/ocp-v2/ocp-v2-status.js +5 -35
  436. package/neural-interface/public/shared/ocp-v2/ocp-v2-styles.js +17 -21
  437. package/neural-interface/public/shared/ocp-v2/{ocp-v2-profile-inheritance.js → ocp-v2-tools-inheritance.js} +16 -16
  438. package/neural-interface/public/shared/ocp-v2/ocp-v2-ws.js +60 -50
  439. package/neural-interface/public/shared/page-session.js +96 -0
  440. package/neural-interface/public/shared/provider-icons.js +4 -2
  441. package/neural-interface/public/shared/registry.js +5 -3
  442. package/neural-interface/public/shared/retired-2d.js +3 -0
  443. package/neural-interface/public/shared/schedules-view.js +195 -61
  444. package/neural-interface/public/shared/settings/settings-claude-hooks.js +135 -0
  445. package/neural-interface/public/shared/settings/settings-data.js +3 -1
  446. package/neural-interface/public/shared/settings/settings-ia.js +6 -6
  447. package/neural-interface/public/shared/settings/settings-opencode.js +89 -0
  448. package/neural-interface/public/shared/settings/settings-rules.js +2 -2
  449. package/neural-interface/public/shared/settings/settings-skill-folders-pane.js +265 -0
  450. package/neural-interface/public/shared/settings/settings-skill-folders.js +130 -0
  451. package/neural-interface/public/shared/settings/settings-worker-guard.js +72 -0
  452. package/neural-interface/public/shared/showcase-privacy.js +6 -1
  453. package/neural-interface/public/shared/sidepanel-session-status.js +3 -3
  454. package/neural-interface/public/shared/skills/ss-args.js +96 -0
  455. package/neural-interface/public/shared/skills/ss-creation.js +222 -0
  456. package/neural-interface/public/shared/skills/ss-dialog.js +133 -0
  457. package/neural-interface/public/shared/skills/ss-doc.js +173 -0
  458. package/neural-interface/public/shared/skills/ss-eval-adapters.js +269 -0
  459. package/neural-interface/public/shared/skills/ss-eval-grade.js +359 -0
  460. package/neural-interface/public/shared/skills/ss-eval-optimise.js +153 -0
  461. package/neural-interface/public/shared/skills/ss-eval-plan.js +315 -0
  462. package/neural-interface/public/shared/skills/ss-evals.js +417 -0
  463. package/neural-interface/public/shared/skills/ss-form.js +159 -0
  464. package/neural-interface/public/shared/skills/ss-frontmatter.js +376 -0
  465. package/neural-interface/public/shared/skills/ss-ids.js +32 -0
  466. package/neural-interface/public/shared/skills/ss-lint.js +149 -0
  467. package/neural-interface/public/shared/skills/ss-presets.js +117 -0
  468. package/neural-interface/public/shared/skills/ss-profiles.js +513 -0
  469. package/neural-interface/public/shared/skills/ss-resources.js +165 -0
  470. package/neural-interface/public/shared/skills/ss-review-view.js +190 -0
  471. package/neural-interface/public/shared/skills/ss-tabs.js +79 -0
  472. package/neural-interface/public/shared/skills/ss-unicode.js +135 -0
  473. package/neural-interface/public/shared/skills/studio/sx-actions.js +222 -0
  474. package/neural-interface/public/shared/skills/studio/sx-cm.js +101 -0
  475. package/neural-interface/public/shared/skills/studio/sx-create-ai-view.js +749 -0
  476. package/neural-interface/public/shared/skills/studio/sx-create-ai.js +237 -0
  477. package/neural-interface/public/shared/skills/studio/sx-create-view.js +254 -0
  478. package/neural-interface/public/shared/skills/studio/sx-create.js +126 -0
  479. package/neural-interface/public/shared/skills/studio/sx-diff-view.js +43 -0
  480. package/neural-interface/public/shared/skills/studio/sx-diff.js +133 -0
  481. package/neural-interface/public/shared/skills/studio/sx-docs.js +480 -0
  482. package/neural-interface/public/shared/skills/studio/sx-dom.js +230 -0
  483. package/neural-interface/public/shared/skills/studio/sx-edit-view.js +848 -0
  484. package/neural-interface/public/shared/skills/studio/sx-editor-model.js +193 -0
  485. package/neural-interface/public/shared/skills/studio/sx-errors.js +22 -0
  486. package/neural-interface/public/shared/skills/studio/sx-fixes-view.js +359 -0
  487. package/neural-interface/public/shared/skills/studio/sx-fixes.js +327 -0
  488. package/neural-interface/public/shared/skills/studio/sx-geometry.js +82 -0
  489. package/neural-interface/public/shared/skills/studio/sx-import.js +262 -0
  490. package/neural-interface/public/shared/skills/studio/sx-inspector.js +308 -0
  491. package/neural-interface/public/shared/skills/studio/sx-install-flow.js +282 -0
  492. package/neural-interface/public/shared/skills/studio/sx-install.js +313 -0
  493. package/neural-interface/public/shared/skills/studio/sx-library-view.js +748 -0
  494. package/neural-interface/public/shared/skills/studio/sx-library.js +479 -0
  495. package/neural-interface/public/shared/skills/studio/sx-main.js +690 -0
  496. package/neural-interface/public/shared/skills/studio/sx-operations-view.js +98 -0
  497. package/neural-interface/public/shared/skills/studio/sx-operations.js +11 -0
  498. package/neural-interface/public/shared/skills/studio/sx-plan.js +158 -0
  499. package/neural-interface/public/shared/skills/studio/sx-publish-view.js +621 -0
  500. package/neural-interface/public/shared/skills/studio/sx-review-view.js +369 -0
  501. package/neural-interface/public/shared/skills/studio/sx-review.js +148 -0
  502. package/neural-interface/public/shared/skills/studio/sx-scan.js +35 -0
  503. package/neural-interface/public/shared/skills/studio/sx-snippets.js +96 -0
  504. package/neural-interface/public/shared/skills/studio/sx-subject.js +249 -0
  505. package/neural-interface/public/shared/skills/studio/sx-test-view.js +994 -0
  506. package/neural-interface/public/shared/skills/studio/sx-test.js +328 -0
  507. package/neural-interface/public/shared/skills/studio/sx-versions-view.js +241 -0
  508. package/neural-interface/public/shared/skills/studio/sx-workspace-view.js +426 -0
  509. package/neural-interface/public/shared/state.js +1 -1
  510. package/neural-interface/public/shared/streaming-markdown.js +58 -0
  511. package/neural-interface/public/shared/styleguide/sg-panel.js +4 -2
  512. package/neural-interface/public/shared/styles.css +1822 -1756
  513. package/neural-interface/public/shared/synabun-mascot.js +1115 -9
  514. package/neural-interface/public/shared/text-cache.js +29 -0
  515. package/neural-interface/public/shared/tool-list-picker.js +55 -0
  516. package/neural-interface/public/shared/tool-list-storage.js +24 -0
  517. package/neural-interface/public/shared/tool-list-view.js +112 -0
  518. package/neural-interface/public/shared/topright-overflow-logic.js +54 -0
  519. package/neural-interface/public/shared/tour/tour-actor.js +268 -0
  520. package/neural-interface/public/shared/tour/tour-beats.js +336 -0
  521. package/neural-interface/public/shared/tour/tour-engine.js +884 -0
  522. package/neural-interface/public/shared/tour/tour-ink.js +390 -0
  523. package/neural-interface/public/shared/tour/tour-stage.js +440 -0
  524. package/neural-interface/public/shared/tour/tour-state.js +40 -0
  525. package/neural-interface/public/shared/tour/tour-tips.js +99 -0
  526. package/neural-interface/public/shared/tour/tour.css +144 -0
  527. package/neural-interface/public/shared/ui-antigravity-panel.js +19 -0
  528. package/neural-interface/public/shared/ui-assistant.js +2 -0
  529. package/neural-interface/public/shared/ui-automation-studio.js +111 -140
  530. package/neural-interface/public/shared/ui-claude-panel.js +376 -82
  531. package/neural-interface/public/shared/ui-cli-banner.js +23 -167
  532. package/neural-interface/public/shared/ui-command-runner.js +6 -3
  533. package/neural-interface/public/shared/ui-context-menu.js +295 -0
  534. package/neural-interface/public/shared/ui-cost-widget.js +57 -59
  535. package/neural-interface/public/shared/ui-crash-notice.js +187 -0
  536. package/neural-interface/public/shared/ui-detail.js +15 -3
  537. package/neural-interface/public/shared/ui-file-explorer.js +48 -6
  538. package/neural-interface/public/shared/ui-file-links.js +2 -2
  539. package/neural-interface/public/shared/ui-games.js +2 -2
  540. package/neural-interface/public/shared/ui-image-gallery.js +50 -47
  541. package/neural-interface/public/shared/ui-judgments.js +1 -1
  542. package/neural-interface/public/shared/ui-keybinds.js +33 -2
  543. package/neural-interface/public/shared/ui-link.js +3 -3
  544. package/neural-interface/public/shared/ui-menubar.js +10 -20
  545. package/neural-interface/public/shared/ui-native-loop-router-state.js +5 -0
  546. package/neural-interface/public/shared/ui-native-loop-router.js +11 -1
  547. package/neural-interface/public/shared/ui-navbar.js +49 -24
  548. package/neural-interface/public/shared/ui-notifications.js +1 -0
  549. package/neural-interface/public/shared/ui-panels.js +96 -65
  550. package/neural-interface/public/shared/ui-resume.js +9 -7
  551. package/neural-interface/public/shared/ui-schedules-studio.js +546 -431
  552. package/neural-interface/public/shared/ui-scroll-follow.js +16 -5
  553. package/neural-interface/public/shared/ui-sessions.js +27 -15
  554. package/neural-interface/public/shared/ui-settings.js +683 -526
  555. package/neural-interface/public/shared/ui-sidepanel-session-entry.js +9 -2
  556. package/neural-interface/public/shared/ui-sidepanel-sessions.js +4 -4
  557. package/neural-interface/public/shared/ui-sidepanel-state.js +23 -12
  558. package/neural-interface/public/shared/ui-sidepanel-tray.js +48 -7
  559. package/neural-interface/public/shared/ui-sidepanel-windows.js +18 -13
  560. package/neural-interface/public/shared/ui-skills.js +33 -2830
  561. package/neural-interface/public/shared/ui-styleguide.js +5 -2
  562. package/neural-interface/public/shared/ui-sync.js +15 -5
  563. package/neural-interface/public/shared/ui-terminal.js +270 -190
  564. package/neural-interface/public/shared/ui-tool-updates.js +6 -4
  565. package/neural-interface/public/shared/ui-tooltip.js +81 -51
  566. package/neural-interface/public/shared/ui-topright-overflow.js +233 -0
  567. package/neural-interface/public/shared/ui-trash.js +6 -4
  568. package/neural-interface/public/shared/ui-tutorial-layout.js +3 -117
  569. package/neural-interface/public/shared/ui-tutorial-preview.js +103 -0
  570. package/neural-interface/public/shared/ui-tutorial-steps.js +3 -65
  571. package/neural-interface/public/shared/ui-tutorial.css +47 -100
  572. package/neural-interface/public/shared/ui-tutorial.js +285 -509
  573. package/neural-interface/public/shared/ui-update.js +38 -2
  574. package/neural-interface/public/shared/ui-whiteboard.js +312 -59
  575. package/neural-interface/public/shared/ui-worker-end.js +5 -1
  576. package/neural-interface/public/shared/ui-workspaces.js +3 -2
  577. package/neural-interface/public/shared/view-variant.js +66 -0
  578. package/neural-interface/public/shared/whatsapp/wa-view.js +3 -3
  579. package/neural-interface/public/shared/whiteboard-list.js +172 -0
  580. package/neural-interface/public/shared/worker-end.js +10 -3
  581. package/neural-interface/public/shared/worker-questions.js +34 -0
  582. package/neural-interface/public/shared/worker-restart.js +12 -0
  583. package/neural-interface/public/sidepanel-session.html +2 -2
  584. package/neural-interface/public/variant/2d/background.js +2 -1
  585. package/neural-interface/public/variant/2d/context-menu.js +8 -2
  586. package/neural-interface/public/variant/2d/graph.js +42 -20
  587. package/neural-interface/public/variant/2d/hulls.js +14 -9
  588. package/neural-interface/public/variant/2d/lasso.js +11 -7
  589. package/neural-interface/public/variant/2d/main.js +32 -1
  590. package/neural-interface/public/variant/2d/minimap.js +11 -13
  591. package/neural-interface/public/variant/3d/main.js +69 -6
  592. package/neural-interface/public/variant/3d/map-controls.js +24 -9
  593. package/neural-interface/public/vendor/caveat/OFL.txt +93 -0
  594. package/neural-interface/public/vendor/caveat/caveat-latin-400-normal.woff2 +0 -0
  595. package/neural-interface/public/vendor/caveat/caveat-latin-700-normal.woff2 +0 -0
  596. package/neural-interface/public/vendor/caveat/caveat.css +17 -0
  597. package/neural-interface/public/vendor/caveat/manifest.json +12 -0
  598. package/neural-interface/public/vendor/yaml/LICENSE +13 -0
  599. package/neural-interface/public/vendor/yaml/manifest.json +4 -0
  600. package/neural-interface/public/vendor/yaml/yaml-2.9.1.min.js +137 -0
  601. package/neural-interface/scripts/build-vendor.mjs +32 -0
  602. package/neural-interface/server.js +4553 -2855
  603. package/neural-interface/templates/rulesets/README.md +1 -1
  604. package/neural-interface/templates/rulesets/core.md +1 -1
  605. package/neural-interface/templates/rulesets/legacy-hashes.json +23 -5
  606. package/neural-interface/templates/rulesets/manifest.json +8 -8
  607. package/npm-shrinkwrap.json +34 -12
  608. package/package.json +17 -3
  609. package/postinstall.js +9 -4
  610. package/preuninstall.js +1 -1
  611. package/setup.js +97 -322
  612. package/skills/skill-forge/SKILL.md +177 -0
  613. package/skills/skill-forge/evals/evals.json +54 -0
  614. package/skills/skill-forge/references/package.md +105 -0
  615. package/skills/skill-forge/references/review-and-recovery.md +63 -0
  616. package/skills/skill-forge/references/runtime-profiles.md +20 -0
  617. package/skills/skill-forge/references/sources-and-capabilities.md +51 -0
  618. package/skills/synabun/SKILL.md +10 -7
  619. package/skills/synabun/modules/audit.md +1 -5
  620. package/skills/synabun/modules/changelog.md +1 -5
  621. package/skills/synabun/modules/idea.md +1 -1
  622. package/skills/synabun/modules/memorize.md +6 -9
  623. package/skills/synabun/modules/schedule.md +6 -6
  624. package/mcp-server/dist/services/profiles.d.ts +0 -120
  625. package/mcp-server/dist/services/profiles.d.ts.map +0 -1
  626. package/mcp-server/dist/services/profiles.js +0 -387
  627. package/mcp-server/dist/services/profiles.js.map +0 -1
  628. package/mcp-server/dist/tools/leonardo-browser-tools.d.ts +0 -97
  629. package/mcp-server/dist/tools/leonardo-browser-tools.d.ts.map +0 -1
  630. package/mcp-server/dist/tools/leonardo-browser-tools.js +0 -228
  631. package/mcp-server/dist/tools/leonardo-browser-tools.js.map +0 -1
  632. package/mcp-server/dist/tools/leonardo.d.ts +0 -13
  633. package/mcp-server/dist/tools/leonardo.d.ts.map +0 -1
  634. package/mcp-server/dist/tools/leonardo.js +0 -21
  635. package/mcp-server/dist/tools/leonardo.js.map +0 -1
  636. package/mcp-server/dist/tools/profile.d.ts +0 -17
  637. package/mcp-server/dist/tools/profile.d.ts.map +0 -1
  638. package/mcp-server/dist/tools/profile.js +0 -114
  639. package/mcp-server/dist/tools/profile.js.map +0 -1
  640. package/mcp-server/src/services/profiles.ts +0 -428
  641. package/mcp-server/src/tools/leonardo-browser-tools.ts +0 -291
  642. package/mcp-server/src/tools/leonardo.ts +0 -30
  643. package/mcp-server/src/tools/profile.ts +0 -122
  644. package/neural-interface/lib/assistant-brains/opencode-browser-policy.js +0 -47
  645. package/neural-interface/lib/assistant-brains/opencode-route-gate.js +0 -62
  646. package/neural-interface/lib/mcp-profile-servers.js +0 -120
  647. package/neural-interface/public/shared/ui-tutorial-draw.js +0 -311
  648. package/skills/leonardo/SKILL.md +0 -168
  649. package/skills/leonardo/icon.svg +0 -1
  650. package/skills/leonardo/modules/browser-guide.md +0 -378
  651. package/skills/leonardo/modules/image-prompter.md +0 -283
  652. package/skills/leonardo/modules/model-advisor.md +0 -100
  653. package/skills/leonardo/modules/prompt-library.md +0 -110
  654. package/skills/leonardo/modules/style-guide.md +0 -186
  655. package/skills/leonardo/modules/video-prompter.md +0 -317
  656. /package/neural-interface/templates/rulesets/{gemini.md → antigravity.md} +0 -0
@@ -0,0 +1,96 @@
1
+ // ═══════════════════════════════════════════
2
+ // SynaBun Neural Interface — Skills Studio 2.0: snippets
3
+ // ═══════════════════════════════════════════
4
+ //
5
+ // Pieces the editor inserts for you. A body snippet goes in at the caret, on lines of its own (never inside the
6
+ // frontmatter: a caret there inserts at the start of the body). A frontmatter snippet is keys, merged into the
7
+ // frontmatter through the same one-key patch as the form (ss-frontmatter.js patch): the keys already there, their
8
+ // comments and order stay. The words follow the runtimes as they are (SK-067, Q14): pre-approved tools run without
9
+ // asking and do not restrict other tools; a skill names its files by a path relative to its folder, or
10
+ // ${CLAUDE_SKILL_DIR} in Claude Code; nothing claims "five trigger phrases" make a skill fire. Names and
11
+ // descriptions are i18n keys (`skillsStudio.snippets.<id>`); the inserted text is the skill's own words, English.
12
+ // The user's own snippets (the presets of P0, ss-presets.js) are body snippets. No DOM and no imports.
13
+
14
+ /** @typedef {{ id: string, kind: 'body'|'frontmatter', types: string[], text?: string, patch?: object, group: string }} Snippet */
15
+
16
+ /** @type {Snippet[]} */
17
+ export const SNIPPETS = Object.freeze([
18
+ { id: 'role', kind: 'body', group: 'structure', types: ['skill', 'agent'], text: '## Role\n\nYou are [who]. Your job is to [what], for [whom].\n' },
19
+ { id: 'steps', kind: 'body', group: 'structure', types: ['skill', 'command', 'agent'], text: '## Steps\n\n1. Read what the user gave and check it is complete.\n2. Do the task.\n3. Check the result.\n4. Report what changed, briefly.\n' },
20
+ { id: 'constraints', kind: 'body', group: 'structure', types: [], text: '## Rules\n\n- Never change files outside the project.\n- Ask before deleting anything.\n- Say what you are about to do before you do it.\n' },
21
+ { id: 'output', kind: 'body', group: 'structure', types: [], text: '## Output\n\nAnswer with:\n\n1. A one-line summary.\n2. What you found, most important first.\n3. What to do next.\n' },
22
+ { id: 'examples', kind: 'body', group: 'structure', types: ['skill', 'agent'], text: '## Examples\n\n<example>\nuser: "[a request this skill should handle]"\nassistant: "[what a good answer does]"\n</example>\n' },
23
+ { id: 'context', kind: 'body', group: 'workflow', types: ['skill', 'command'], text: '## First, gather context\n\nBefore you change anything, read the files involved and look for how the project already does it.\n' },
24
+ { id: 'errors', kind: 'body', group: 'workflow', types: ['skill', 'command'], text: '## When something fails\n\nSay what failed and why, suggest the next step, and do not repeat the same attempt unchanged.\n' },
25
+ { id: 'input-check', kind: 'body', group: 'workflow', types: ['skill', 'command'], text: '## Input\n\nThe user\'s words are in $ARGUMENTS. If they are empty or unclear, ask before you start.\n' },
26
+ { id: 'confirm', kind: 'body', group: 'workflow', types: ['skill', 'command'], text: '## Before anything destructive\n\nList exactly what will be changed or removed and wait for a clear yes.\n' },
27
+ { id: 'scope', kind: 'body', group: 'workflow', types: ['skill', 'agent'], text: '## Scope\n\nThis covers: [what].\nIt does not cover: [what not]; say so and suggest the right tool.\n' },
28
+ { id: 'references', kind: 'body', group: 'files', types: ['skill'], text: '## References\n\nRead these only when the task needs them:\n\n- [references/guide.md](references/guide.md): [what it holds]\n' },
29
+ { id: 'variables', kind: 'body', group: 'files', types: ['skill', 'command'], text: '## Variables\n\n- $ARGUMENTS: what the user typed after the name.\n- ${CLAUDE_SKILL_DIR}: this skill\'s folder in Claude Code (elsewhere, use paths relative to this file).\n' },
30
+ { id: 'dynamic', kind: 'body', group: 'files', types: ['skill', 'command'], text: '## Current state\n\n- Branch: !`git branch --show-current`\n' },
31
+ { id: 'fm-tools-readonly', kind: 'frontmatter', group: 'frontmatter', types: ['skill'], patch: { 'allowed-tools': ['Read', 'Grep', 'Glob'] } },
32
+ { id: 'fm-agent-tools', kind: 'frontmatter', group: 'frontmatter', types: ['agent'], patch: { tools: 'Read, Grep, Glob' } },
33
+ { id: 'fm-manual', kind: 'frontmatter', group: 'frontmatter', types: ['skill'], patch: { 'disable-model-invocation': true } },
34
+ { id: 'fm-hint', kind: 'frontmatter', group: 'frontmatter', types: ['skill', 'command'], patch: { 'argument-hint': '[target]' } },
35
+ { id: 'fm-when', kind: 'frontmatter', group: 'frontmatter', types: ['skill'], patch: { when_to_use: 'Use when [the situation]. For example: "[a request]".' } },
36
+ { id: 'fm-fork', kind: 'frontmatter', group: 'frontmatter', types: ['skill'], patch: { context: 'fork', agent: 'Explore' } },
37
+ { id: 'fm-model', kind: 'frontmatter', group: 'frontmatter', types: ['agent'], patch: { model: 'sonnet' } },
38
+ ]);
39
+
40
+ export const SNIPPET_GROUPS = Object.freeze(['structure', 'workflow', 'files', 'frontmatter', 'custom']);
41
+
42
+ /** The snippets for a kind of artifact: the built-in ones that fit it, then the user's own. */
43
+ export function snippetsFor(type, custom = []) {
44
+ const builtIn = SNIPPETS.filter((s) => !s.types.length || s.types.includes(type));
45
+ // A preset comes from the synced UI state (or a file someone handed over): every field is taken as text.
46
+ const typesOf = (p) => (Array.isArray(p.types) ? p.types.filter((x) => typeof x === 'string') : []);
47
+ const own = (Array.isArray(custom) ? custom : []).filter((p) => p && typeof p.snippet === 'string' && p.id != null && (!typesOf(p).length || typesOf(p).includes(type)))
48
+ .map((p) => ({ id: `custom:${String(p.id)}`, kind: 'body', group: 'custom', types: typesOf(p), text: p.snippet, name: String(p.name ?? ''), description: typeof p.description === 'string' ? p.description : '', custom: true }));
49
+ // One snippet once: a preset that is a built-in's exact text is not listed twice.
50
+ const texts = new Set(builtIn.map((s) => s.text).filter(Boolean));
51
+ return [...builtIn, ...own.filter((s) => !texts.has(s.text))];
52
+ }
53
+
54
+ /** Where the body of a text starts (after its frontmatter), as an index. */
55
+ export function bodyStart(text) {
56
+ const s = String(text ?? '');
57
+ const bom = s.charCodeAt(0) === 0xFEFF ? 1 : 0;
58
+ const m = /^---[ \t]*\n[\s\S]*?\n---[ \t]*(?:\n|$)/.exec(s.slice(bom));
59
+ return m ? bom + m[0].length : bom;
60
+ }
61
+
62
+ /**
63
+ * Insert a snippet.
64
+ * @param {string} text the document ("\n" line breaks)
65
+ * @param {Snippet} snippet
66
+ * @param {{ caret?: number, fm?: { patch: (text: string, changes: object) => object } }} [o] `fm`: ss-frontmatter.js (frontmatter snippets)
67
+ * @returns {{ ok: true, text: string, caret: number, at: number } | { ok: false, reason: string }}
68
+ */
69
+ export function applySnippet(text, snippet, { caret = null, fm = null } = {}) {
70
+ const s = String(text ?? '');
71
+ if (snippet?.kind === 'frontmatter') {
72
+ if (!fm || typeof fm.patch !== 'function') return { ok: false, reason: 'no-parser' };
73
+ const result = fm.patch(s, snippet.patch || {});
74
+ if (!result.ok) return { ok: false, reason: result.reason || 'invalid' };
75
+ return { ok: true, text: result.text, caret: Math.min(caret ?? 0, result.text.length), at: 0, changed: result.changed !== false };
76
+ }
77
+ const piece = String(snippet?.text ?? '');
78
+ if (!piece.trim()) return { ok: false, reason: 'empty' };
79
+ const start = bodyStart(s);
80
+ let at = Number.isInteger(caret) ? Math.max(0, Math.min(caret, s.length)) : s.length;
81
+ if (at < start) at = start; // never inside the frontmatter
82
+ const before = s.slice(0, at);
83
+ const after = s.slice(at);
84
+ const pad = before.length > start && !before.endsWith('\n\n') ? (before.endsWith('\n') ? '\n' : '\n\n') : '';
85
+ const body = piece.endsWith('\n') ? piece : `${piece}\n`;
86
+ const trail = after.length && !after.startsWith('\n') ? '\n' : '';
87
+ const next = before + pad + body + trail + after;
88
+ return { ok: true, text: next, caret: before.length + pad.length + body.length, at: before.length + pad.length, changed: true };
89
+ }
90
+
91
+ /** Whether a snippet matches a search, through the words the view shows for it. */
92
+ export function snippetMatches(snippet, query, words = (s) => `${s.name || ''} ${s.description || ''}`) {
93
+ const q = String(query ?? '').trim().toLowerCase();
94
+ if (!q) return true;
95
+ return `${snippet.id} ${words(snippet)} ${snippet.kind === 'frontmatter' ? Object.keys(snippet.patch || {}).join(' ') : ''}`.toLowerCase().includes(q);
96
+ }
@@ -0,0 +1,249 @@
1
+ // ═══════════════════════════════════════════
2
+ // SynaBun Neural Interface — Skills Studio 2.0: what a Library row opens as
3
+ // ═══════════════════════════════════════════
4
+ //
5
+ // A row of the Library (sx-library.js) opens in one workspace, in one of four modes:
6
+ // library a skill in SynaBun's managed library: edits go to its draft (PATCH /v2/drafts), Versions lists its
7
+ // revisions, Publish installs one of them into the runtimes' folders (owner decision 2026-10-22:
8
+ // runtime folders are destinations, not edited in place);
9
+ // adopt a skill folder of the owner's that is not in the library yet: it opens as it is on disk, and the
10
+ // first save takes the folder into the library (POST /v2/skills { artifactId }) with the edit as its
11
+ // draft, so it reaches the folder again only through Publish;
12
+ // inplace an agent or a command (one file): the library holds skill folders only, so it is saved where it is,
13
+ // over the revision it was opened at (the P0 routes: PUT /api/skills-studio/artifact/:id);
14
+ // readonly what SynaBun does not write: a skill it ships, a plugin's, a Claude account's, a runtime's own
15
+ // (Codex system skills, managed settings), a folder no route can reach. A skill can be copied into the
16
+ // library ("Customize a copy").
17
+ // Also here: the P0 artifact id of an entry (when those routes can reach it), and the install targets a skill can
18
+ // be published to, read from the catalog's roots. No DOM; imports only ss-ids.js.
19
+
20
+ import { encodeArtifactId } from '../ss-ids.js';
21
+
22
+ const READ_ONLY_REASON = { synabun: 'bundled', plugin: 'plugin', account: 'account', system: 'system', shared: 'shared' };
23
+
24
+ /**
25
+ * The artifact id the P0 routes (/api/skills-studio/artifact/:id) take for an entry, encoded, or null when they
26
+ * cannot reach it: they read Claude Code's own folders only (~/.claude/skills|commands|agents of the default
27
+ * account, a registered project's .claude/…), and the bundled source.
28
+ */
29
+ export function v1IdFor(entry) {
30
+ if (!entry || typeof entry.path !== 'string' || !entry.path) return null;
31
+ const kind = entry.kind;
32
+ if (!['skill', 'command', 'agent'].includes(kind)) return null;
33
+ const bundled = entry.sourceKind === 'bundled' || entry.family === 'synabun';
34
+ const claudeOwn = entry.family === 'claude' && entry.sourceKind === 'native'
35
+ && (entry.scope === 'project' || (entry.scope === 'user' && (!entry.accountId || entry.accountId === 'default')));
36
+ if (!bundled && !claudeOwn) return null;
37
+ if (bundled && kind !== 'skill') return null;
38
+ return encodeArtifactId(`${kind}:${entry.path}`);
39
+ }
40
+
41
+ /** The entry of a row the P0 routes reach, when one of its locations is such (an account's link, a project's own). */
42
+ function addressableEntry(row) {
43
+ for (const e of [row.primary, ...(row.entries || [])]) if (e && v1IdFor(e)) return e;
44
+ return null;
45
+ }
46
+
47
+ /**
48
+ * What a row opens as.
49
+ * @param {object} row a row of sx-library.js buildRows()
50
+ * @param {{ guest?: boolean, caps?: Set<string> }} [o] caps: the service's capabilities (GET /v2/capabilities)
51
+ * @returns {{ mode: 'library'|'adopt'|'inplace'|'readonly', editable: boolean, reason: string|null,
52
+ * canCustomize: boolean, canAdopt: boolean, canPublish: boolean, hasVersions: boolean, v1Id: string|null,
53
+ * artifactId: string|null, skillId: string|null, readsFiles: 'library'|'v1'|'catalog'|'head' }}
54
+ */
55
+ export function subjectOf(row, { guest = false, caps = new Set() } = {}) {
56
+ const entry = row?.primary || null;
57
+ const skill = row?.skill || null;
58
+ const v1Entry = addressableEntry(row || {});
59
+ const v1Id = v1Entry ? v1IdFor(v1Entry) : null;
60
+ const catalogFiles = caps.has('catalog-file');
61
+ const out = {
62
+ mode: 'readonly', editable: false, reason: null, canCustomize: false, canAdopt: false, canPublish: false, hasVersions: false,
63
+ v1Id, artifactId: entry?.id || null, skillId: skill?.skillId || null,
64
+ readsFiles: v1Id ? 'v1' : catalogFiles ? 'catalog' : 'head',
65
+ };
66
+ if (!row) return out;
67
+ if (skill && row.source !== 'synabun') {
68
+ out.mode = 'library';
69
+ out.readsFiles = 'library';
70
+ out.hasVersions = true;
71
+ out.canPublish = !guest;
72
+ out.editable = !guest;
73
+ if (guest) out.reason = 'guest';
74
+ return out;
75
+ }
76
+ if (row.source === 'synabun') {
77
+ // What SynaBun ships: its library copy holds the versions (`upstream`); it is installed, never edited.
78
+ out.mode = 'readonly';
79
+ out.reason = 'bundled';
80
+ out.readsFiles = skill ? 'library' : out.readsFiles;
81
+ out.hasVersions = !!skill;
82
+ out.canPublish = !!skill && !guest;
83
+ out.canCustomize = !guest && row.kind === 'skill';
84
+ return out;
85
+ }
86
+ if (row.binary) {
87
+ out.reason = 'not-text';
88
+ out.canAdopt = false;
89
+ return out;
90
+ }
91
+ if (row.kind === 'skill') {
92
+ if (!row.readOnly && entry && (entry.scope === 'user' || entry.scope === 'project')) {
93
+ out.mode = 'adopt';
94
+ out.editable = !guest;
95
+ out.canAdopt = !guest;
96
+ out.reason = guest ? 'guest' : null;
97
+ return out;
98
+ }
99
+ out.reason = guest ? 'guest' : (READ_ONLY_REASON[row.source] || 'not-writable');
100
+ out.canCustomize = !guest && (out.readsFiles !== 'head');
101
+ return out;
102
+ }
103
+ // An agent or a command: saved where it is, through the routes that reach it.
104
+ if (!row.readOnly && v1Id) {
105
+ out.mode = 'inplace';
106
+ out.editable = !guest;
107
+ out.reason = guest ? 'guest' : null;
108
+ return out;
109
+ }
110
+ out.reason = guest ? 'guest' : (READ_ONLY_REASON[row.source] || (row.readOnly ? 'not-writable' : 'not-addressable'));
111
+ return out;
112
+ }
113
+
114
+ // ── Install targets ──
115
+
116
+ /** The key an install plan gives a target (lib/skills/deploy.js normalizeTarget). */
117
+ export function targetKey(t) {
118
+ const scope = t?.scope === 'project' ? 'project' : 'user';
119
+ return scope === 'project' ? `${t.runtime}:project:${t.projectPath}` : `${t.runtime}:user:${t?.accountId || 'default'}`;
120
+ }
121
+
122
+ /** A target as a request names it: only the fields a target has. */
123
+ export function wholeTarget(t) {
124
+ const out = { runtime: t.runtime };
125
+ if (t.scope === 'project') { out.scope = 'project'; out.projectPath = t.projectPath; } else out.scope = 'user';
126
+ if (t.accountId && t.accountId !== 'default') out.accountId = t.accountId;
127
+ return out;
128
+ }
129
+
130
+ /** The keys of a list of targets, each once, sorted: a selection as it can be compared with another. */
131
+ export const selectionKeys = (targets) => [...new Set((Array.isArray(targets) ? targets : []).map(targetKey))].sort();
132
+
133
+ /**
134
+ * Whether two asks of Publish are the same: one revision and exactly the same targets. A plan answers only what it
135
+ * was asked for: shown or installed for anything else (another version picked, a target ticked meanwhile), it would
136
+ * install what the owner no longer sees.
137
+ * @param {{ revisionId: string|null, targets: object[] }|null} a @param {{ revisionId: string|null, targets: object[] }|null} b
138
+ */
139
+ export function sameAsk(a, b) {
140
+ if (!a || !b || !a.revisionId || a.revisionId !== b.revisionId) return false;
141
+ const x = selectionKeys(a.targets); const y = selectionKeys(b.targets);
142
+ return x.length > 0 && x.length === y.length && x.every((k, i) => k === y[i]);
143
+ }
144
+
145
+ const RUNTIME_OF_FAMILY = { claude: 'claude', codex: 'codex', opencode: 'opencode', antigravity: 'antigravity', shared: 'agents' };
146
+
147
+ /**
148
+ * The targets a skill can be installed into: each runtime's own skills folder for each account, the shared
149
+ * ~/.agents/skills (only while the owner turned it on), and the folders of the projects asked for.
150
+ * @param {object} o
151
+ * @param {object[]} [o.roots] the catalog's roots (GET /catalog `roots`)
152
+ * @param {{ sharedAgentsRoot?: boolean }} [o.config]
153
+ * @param {{ path: string, label: string }[]} [o.projects] projects to offer targets for
154
+ * @returns {{ key, target, runtime, scope, accountId, projectPath, projectLabel, path, status, policy, shared, runtimes }[]}
155
+ * `runtimes`: every runtime that reads that folder (OpenCode reads Claude Code's; Codex's project folder is shared)
156
+ */
157
+ export function installTargets({ roots = [], config = {}, projects = [] } = {}) {
158
+ const out = [];
159
+ const seen = new Set();
160
+ const push = (t) => { if (seen.has(t.key)) return; seen.add(t.key); out.push(t); };
161
+ for (const root of Array.isArray(roots) ? roots : []) {
162
+ if (root?.kind !== 'skills' || !RUNTIME_OF_FAMILY[root.family]) continue;
163
+ if (root.sourceKind !== 'native' && root.sourceKind !== 'shared') continue;
164
+ const write = root.policy?.write;
165
+ if (write !== 'owner' && write !== 'owner-opt-in') continue;
166
+ const runtime = RUNTIME_OF_FAMILY[root.family];
167
+ if (root.scope === 'project') continue; // projects come from `projects`, one row per runtime
168
+ const accountId = root.accountId || 'default';
169
+ const target = { runtime, scope: 'user', ...(accountId !== 'default' ? { accountId } : {}) };
170
+ const readers = Array.isArray(root.runtimes) && root.runtimes.length ? root.runtimes.filter((r) => typeof r === 'string') : [runtime === 'agents' ? 'codex' : runtime, ...(runtime === 'agents' ? ['opencode'] : [])];
171
+ push({ key: targetKey(target), target, runtime, scope: 'user', accountId, projectPath: null, projectLabel: null, path: root.path, status: root.status, policy: root.policy || null, shared: runtime === 'agents', off: runtime === 'agents' && !config.sharedAgentsRoot, runtimes: readers });
172
+ }
173
+ for (const p of Array.isArray(projects) ? projects : []) {
174
+ if (!p?.path) continue;
175
+ for (const runtime of ['claude', 'codex', 'opencode']) {
176
+ const target = { runtime, scope: 'project', projectPath: p.path };
177
+ const sub = runtime === 'claude' ? '.claude/skills' : runtime === 'codex' ? '.agents/skills' : '.opencode/skills';
178
+ // Who reads a project's folders (lib/skills/roots.js): .claude/skills and .agents/skills are read by OpenCode too,
179
+ // .agents/skills by Antigravity as well (it has no project folder of its own).
180
+ const readers = runtime === 'opencode' ? ['opencode'] : runtime === 'codex' ? ['codex', 'opencode', 'antigravity'] : [runtime, 'opencode'];
181
+ push({ key: targetKey(target), target, runtime, scope: 'project', accountId: 'default', projectPath: p.path, projectLabel: p.label || p.path, path: `${p.path.replace(/[\\/]+$/, '')}/${sub}`, status: null, policy: null, shared: false, off: false, runtimes: readers });
182
+ }
183
+ }
184
+ const order = { claude: 0, codex: 1, opencode: 2, antigravity: 3, agents: 4 };
185
+ return out.sort((a, b) => (a.scope === b.scope ? 0 : a.scope === 'user' ? -1 : 1) || (a.projectLabel || '').localeCompare(b.projectLabel || '') || (order[a.runtime] - order[b.runtime]) || a.accountId.localeCompare(b.accountId));
186
+ }
187
+
188
+ /**
189
+ * What a target has of a skill now: an installation of the library (current or older than the revision shown), a
190
+ * folder of its name SynaBun did not install, an old bridge, or nothing.
191
+ * @param {object} t a target of installTargets()
192
+ * @param {object} o
193
+ * @param {object|null} o.skill the library skill (GET /skills summary)
194
+ * @param {object|null} o.row its Library row
195
+ * @param {string|null} [o.revisionId] the revision the Publish tab shows
196
+ */
197
+ export function targetState(t, { skill = null, row = null, revisionId = null } = {}) {
198
+ const install = (skill?.installations || []).find((i) => i.runtime === t.runtime && (i.scope || 'user') === t.scope
199
+ && (t.scope === 'project' ? i.projectPath === t.projectPath : (i.accountId || 'default') === t.accountId));
200
+ if (install) {
201
+ const current = revisionId ? install.sourceRevisionId === revisionId : !install.updateAvailable;
202
+ return { state: current ? 'installed' : 'outdated', installation: install, path: install.destination };
203
+ }
204
+ const name = row?.folderName || skill?.name || '';
205
+ const inFolder = (row?.entries || []).find((e) => e.kind === 'skill' && e.path && t.path && e.path.startsWith(`${t.path.replace(/[\\/]+$/, '')}/`) && e.path.slice(t.path.replace(/[\\/]+$/, '').length + 1) === name);
206
+ if (inFolder) return { state: 'present', installation: null, path: inFolder.path };
207
+ const bridge = (row?.bridges || []).find((b) => b.runtime === t.runtime && t.scope === 'user');
208
+ if (bridge) return { state: 'bridge', installation: null, path: bridge.entry?.path || null };
209
+ return { state: 'none', installation: null, path: null };
210
+ }
211
+
212
+ /**
213
+ * Targets checked to start with: where the skill is already, else the owner's assistants (Settings → Skills → My
214
+ * assistants; detected from what is installed and used when none were chosen), each in its own user folder for the
215
+ * default account: never everything. A folder another assistant reads too is counted for it: OpenCode reads Claude
216
+ * Code's skills folder, so with both among the assistants only Claude Code's is ticked (no second copy unless asked;
217
+ * `seenThrough` says which). Without any list: Claude Code.
218
+ * @param {object[]} targets installTargets()
219
+ * @param {{ skill?: object|null, row?: object|null, assistants?: string[]|null }} [o]
220
+ */
221
+ export function defaultTargets(targets, { skill = null, row = null, assistants = null } = {}) {
222
+ const there = targets.filter((t) => !t.off && ['installed', 'outdated', 'present'].includes(targetState(t, { skill, row }).state));
223
+ if (there.length) return new Set(there.map((t) => t.key));
224
+ const own = (runtime) => targets.find((t) => t.runtime === runtime && t.scope === 'user' && t.accountId === 'default' && !t.off) || null;
225
+ const wanted = Array.isArray(assistants) && assistants.length ? assistants.filter((r) => ['claude', 'codex', 'opencode', 'antigravity'].includes(r)) : ['claude'];
226
+ // Every assistant gets its own folder: a terminal OpenCode reads Claude Code's folder, but SynaBun's own OpenCode
227
+ // serves (the panel, an Assistant brain) start with OPENCODE_DISABLE_CLAUDE_CODE=1 and never see it (checked with
228
+ // opencode 2.1.4), so an OpenCode among the assistants is ticked for a real copy.
229
+ const picked = ['claude', 'codex', 'opencode', 'antigravity'].filter((runtime) => wanted.includes(runtime)).map(own).filter(Boolean);
230
+ if (!picked.length) { const claude = own('claude'); return new Set(claude ? [claude.key] : []); }
231
+ return new Set(picked.map((t) => t.key));
232
+ }
233
+
234
+ /**
235
+ * The runtime whose ticked (or installed) folder a terminal copy of this runtime reads too, in this scope: 'claude'
236
+ * for an OpenCode tile when Claude Code's folder is ticked or holds the skill (a terminal OpenCode reads it; SynaBun's
237
+ * own OpenCode serves do not, so this is a hint, never a reason to leave OpenCode out); else null.
238
+ * @param {string} runtime @param {object[]} targets @param {Set<string>} checked
239
+ * @param {{ scope?: string, skill?: object|null, row?: object|null }} [o]
240
+ */
241
+ export function seenThrough(runtime, targets, checked, { scope = 'user', skill = null, row = null } = {}) {
242
+ for (const t of targets) {
243
+ if (t.runtime === runtime || t.off || !(t.runtimes || []).includes(runtime)) continue;
244
+ const inScope = scope.startsWith('project:') ? t.scope === 'project' && t.projectPath === scope.slice(8) : t.scope === 'user' && t.accountId === 'default';
245
+ if (!inScope) continue;
246
+ if (checked?.has?.(t.key) || ['installed', 'outdated', 'present'].includes(targetState(t, { skill, row }).state)) return t.runtime;
247
+ }
248
+ return null;
249
+ }