synabun 2.0.10 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (517) hide show
  1. package/CHANGELOG.md +86 -0
  2. package/README.md +25 -2
  3. package/THIRD-PARTY-LICENSES.md +22 -0
  4. package/bin/synabun.js +71 -24
  5. package/docs/whatsapp.md +2 -2
  6. package/hooks/claude-code/pre-websearch.mjs +12 -1
  7. package/hooks/claude-code/shared.mjs +5 -0
  8. package/hooks/claude-code/stop.mjs +1 -1
  9. package/lib/claude-hooks.js +172 -18
  10. package/lib/client-config-repair.js +17 -8
  11. package/lib/desktop-app.js +7 -1
  12. package/lib/external-tools.js +1 -1
  13. package/lib/first-launch-protection.js +57 -12
  14. package/lib/mcp-dist.js +176 -0
  15. package/lib/release-npm-ci.mjs +138 -0
  16. package/lib/release-publish.mjs +91 -0
  17. package/lib/release-scan.mjs +50 -0
  18. package/lib/server-crash-record.js +123 -0
  19. package/lib/server-exit.js +318 -0
  20. package/lib/server-supervisor.js +508 -0
  21. package/lib/start-launcher.js +37 -4
  22. package/lib/tools-cli.js +45 -0
  23. package/lib/update-snapshot.js +228 -0
  24. package/lib/virustotal.mjs +192 -0
  25. package/lib/windows-crash-event.js +269 -0
  26. package/mcp-server/dist/http.d.ts +20 -1
  27. package/mcp-server/dist/http.d.ts.map +1 -1
  28. package/mcp-server/dist/http.js +59 -12
  29. package/mcp-server/dist/http.js.map +1 -1
  30. package/mcp-server/dist/index.d.ts +33 -27
  31. package/mcp-server/dist/index.d.ts.map +1 -1
  32. package/mcp-server/dist/index.js +128 -143
  33. package/mcp-server/dist/index.js.map +1 -1
  34. package/mcp-server/dist/preload.js +1 -1
  35. package/mcp-server/dist/preload.js.map +1 -1
  36. package/mcp-server/dist/services/codex-config-heal.d.ts +6 -2
  37. package/mcp-server/dist/services/codex-config-heal.d.ts.map +1 -1
  38. package/mcp-server/dist/services/codex-config-heal.js +81 -28
  39. package/mcp-server/dist/services/codex-config-heal.js.map +1 -1
  40. package/mcp-server/dist/services/memory-judge-backfill.d.ts +6 -0
  41. package/mcp-server/dist/services/memory-judge-backfill.d.ts.map +1 -1
  42. package/mcp-server/dist/services/memory-judge-backfill.js +7 -1
  43. package/mcp-server/dist/services/memory-judge-backfill.js.map +1 -1
  44. package/mcp-server/dist/services/neural-interface.d.ts +16 -10
  45. package/mcp-server/dist/services/neural-interface.d.ts.map +1 -1
  46. package/mcp-server/dist/services/neural-interface.js +67 -11
  47. package/mcp-server/dist/services/neural-interface.js.map +1 -1
  48. package/mcp-server/dist/services/server-instructions.d.ts +7 -2
  49. package/mcp-server/dist/services/server-instructions.d.ts.map +1 -1
  50. package/mcp-server/dist/services/server-instructions.js +20 -62
  51. package/mcp-server/dist/services/server-instructions.js.map +1 -1
  52. package/mcp-server/dist/services/tool-catalog.d.ts +120 -0
  53. package/mcp-server/dist/services/tool-catalog.d.ts.map +1 -0
  54. package/mcp-server/dist/services/tool-catalog.js +339 -0
  55. package/mcp-server/dist/services/tool-catalog.js.map +1 -0
  56. package/mcp-server/dist/services/tool-list-refresh-barrier.d.ts +12 -0
  57. package/mcp-server/dist/services/tool-list-refresh-barrier.d.ts.map +1 -0
  58. package/mcp-server/dist/services/tool-list-refresh-barrier.js +40 -0
  59. package/mcp-server/dist/services/tool-list-refresh-barrier.js.map +1 -0
  60. package/mcp-server/dist/services/tool-list.d.ts +108 -0
  61. package/mcp-server/dist/services/tool-list.d.ts.map +1 -0
  62. package/mcp-server/dist/services/tool-list.js +334 -0
  63. package/mcp-server/dist/services/tool-list.js.map +1 -0
  64. package/mcp-server/dist/services/tool-runtime.d.ts +161 -0
  65. package/mcp-server/dist/services/tool-runtime.d.ts.map +1 -0
  66. package/mcp-server/dist/services/tool-runtime.js +400 -0
  67. package/mcp-server/dist/services/tool-runtime.js.map +1 -0
  68. package/mcp-server/dist/services/whiteboard-geometry.d.ts +26 -2
  69. package/mcp-server/dist/services/whiteboard-geometry.d.ts.map +1 -1
  70. package/mcp-server/dist/services/whiteboard-geometry.js +91 -8
  71. package/mcp-server/dist/services/whiteboard-geometry.js.map +1 -1
  72. package/mcp-server/dist/tools/agents.d.ts +10 -10
  73. package/mcp-server/dist/tools/agents.d.ts.map +1 -1
  74. package/mcp-server/dist/tools/agents.js +22 -13
  75. package/mcp-server/dist/tools/agents.js.map +1 -1
  76. package/mcp-server/dist/tools/browser-batch.d.ts +3 -3
  77. package/mcp-server/dist/tools/image-tools.d.ts +1 -1
  78. package/mcp-server/dist/tools/image-tools.js +1 -1
  79. package/mcp-server/dist/tools/skill-tools.d.ts +505 -0
  80. package/mcp-server/dist/tools/skill-tools.d.ts.map +1 -0
  81. package/mcp-server/dist/tools/skill-tools.js +639 -0
  82. package/mcp-server/dist/tools/skill-tools.js.map +1 -0
  83. package/mcp-server/dist/tools/skill.d.ts +7 -0
  84. package/mcp-server/dist/tools/skill.d.ts.map +1 -0
  85. package/mcp-server/dist/tools/skill.js +11 -0
  86. package/mcp-server/dist/tools/skill.js.map +1 -0
  87. package/mcp-server/dist/tools/tool-groups.d.ts +68 -0
  88. package/mcp-server/dist/tools/tool-groups.d.ts.map +1 -0
  89. package/mcp-server/dist/tools/tool-groups.js +147 -0
  90. package/mcp-server/dist/tools/tool-groups.js.map +1 -0
  91. package/mcp-server/dist/tools/whiteboard-format.d.ts.map +1 -1
  92. package/mcp-server/dist/tools/whiteboard-format.js +7 -4
  93. package/mcp-server/dist/tools/whiteboard-format.js.map +1 -1
  94. package/mcp-server/dist/tools/whiteboard-tools.d.ts +64 -13
  95. package/mcp-server/dist/tools/whiteboard-tools.d.ts.map +1 -1
  96. package/mcp-server/dist/tools/whiteboard-tools.js +30 -5
  97. package/mcp-server/dist/tools/whiteboard-tools.js.map +1 -1
  98. package/mcp-server/package-lock.json +2 -2
  99. package/mcp-server/package.json +1 -1
  100. package/mcp-server/src/http.ts +75 -12
  101. package/mcp-server/src/index.ts +147 -154
  102. package/mcp-server/src/preload.ts +12 -12
  103. package/mcp-server/src/services/codex-config-heal.ts +80 -29
  104. package/mcp-server/src/services/memory-judge-backfill.ts +7 -1
  105. package/mcp-server/src/services/neural-interface.ts +79 -20
  106. package/mcp-server/src/services/server-instructions.ts +27 -63
  107. package/mcp-server/src/services/tool-catalog.ts +403 -0
  108. package/mcp-server/src/services/tool-list-refresh-barrier.ts +33 -0
  109. package/mcp-server/src/services/tool-list.ts +410 -0
  110. package/mcp-server/src/services/tool-runtime.ts +457 -0
  111. package/mcp-server/src/services/whiteboard-geometry.ts +94 -9
  112. package/mcp-server/src/tools/agents.ts +22 -14
  113. package/mcp-server/src/tools/image-tools.ts +1 -1
  114. package/mcp-server/src/tools/skill-tools.ts +589 -0
  115. package/mcp-server/src/tools/skill.ts +13 -0
  116. package/mcp-server/src/tools/tool-groups.ts +164 -0
  117. package/mcp-server/src/tools/whiteboard-format.ts +9 -3
  118. package/mcp-server/src/tools/whiteboard-tools.ts +39 -5
  119. package/neural-interface/i18n/en.json +3463 -200
  120. package/neural-interface/i18n/pt-BR.json +3411 -151
  121. package/neural-interface/lib/assistant-api.js +127 -28
  122. package/neural-interface/lib/assistant-brains/claude.js +4 -3
  123. package/neural-interface/lib/assistant-brains/codex-browser-policy-hook.mjs +12 -2
  124. package/neural-interface/lib/assistant-brains/codex-route-gate-hook.mjs +32 -9
  125. package/neural-interface/lib/assistant-brains/codex.js +9 -5
  126. package/neural-interface/lib/assistant-brains/opencode.js +120 -54
  127. package/neural-interface/lib/assistant-brains/opencode2-browser-policy/index.js +28 -13
  128. package/neural-interface/lib/assistant-brains/opencode2-route-gate/index.js +59 -19
  129. package/neural-interface/lib/assistant-catalog.js +6 -7
  130. package/neural-interface/lib/assistant-dispatch.js +871 -156
  131. package/neural-interface/lib/assistant-envelope.js +3 -1
  132. package/neural-interface/lib/assistant-persona.js +80 -11
  133. package/neural-interface/lib/assistant-plan-permissions.js +10 -9
  134. package/neural-interface/lib/assistant-route-gate-codex.js +3 -0
  135. package/neural-interface/lib/assistant-route-gate.js +6 -4
  136. package/neural-interface/lib/assistant-router.js +13 -8
  137. package/neural-interface/lib/assistant-runtime.js +56 -18
  138. package/neural-interface/lib/assistant-task-prompt.js +78 -14
  139. package/neural-interface/lib/assistant-tools.js +51 -0
  140. package/neural-interface/lib/backup-service.js +620 -3
  141. package/neural-interface/lib/backup-zip-reader.js +10 -5
  142. package/neural-interface/lib/backup-zip-writer.js +257 -0
  143. package/neural-interface/lib/browser-execution.js +10 -2
  144. package/neural-interface/lib/browser-guard-cdp.js +83 -0
  145. package/neural-interface/lib/browser-network-guard.js +284 -0
  146. package/neural-interface/lib/browser-policy-roots.js +64 -0
  147. package/neural-interface/lib/browser-tool-policy.js +186 -31
  148. package/neural-interface/lib/claude-agent-bridge.js +4 -2
  149. package/neural-interface/lib/claude-hooks-status.js +103 -0
  150. package/neural-interface/lib/claude-temporary.js +5 -11
  151. package/neural-interface/lib/cli-install.js +18 -138
  152. package/neural-interface/lib/cli-resolver.js +4 -1
  153. package/neural-interface/lib/cli-update-planner.js +32 -31
  154. package/neural-interface/lib/cloudflared/tunnel.js +42 -2
  155. package/neural-interface/lib/codex-mcp-approvals.js +11 -0
  156. package/neural-interface/lib/codex-worker-app-server.js +172 -0
  157. package/neural-interface/lib/confined-fs.js +30 -3
  158. package/neural-interface/lib/crash-notice-api.js +98 -0
  159. package/neural-interface/lib/editor-completion-opencode.js +68 -68
  160. package/neural-interface/lib/exec-loop-command.js +4 -8
  161. package/neural-interface/lib/http-guards.js +8 -2
  162. package/neural-interface/lib/install-details.js +4 -1
  163. package/neural-interface/lib/mcp-agent-servers.js +67 -0
  164. package/neural-interface/lib/mcp-client-config.js +0 -29
  165. package/neural-interface/lib/mcp-external-servers.js +323 -0
  166. package/neural-interface/lib/{mcp-profile-refresh-coordinator.js → mcp-tools-refresh-coordinator.js} +4 -4
  167. package/neural-interface/lib/morelogin.js +30 -0
  168. package/neural-interface/lib/native-loop-providers.js +547 -47
  169. package/neural-interface/lib/native-loop-runtime.js +268 -41
  170. package/neural-interface/lib/opencode-config.js +557 -0
  171. package/neural-interface/lib/opencode-db-schema.js +17 -34
  172. package/neural-interface/lib/opencode-history.js +48 -218
  173. package/neural-interface/lib/opencode-mcp-ready.js +108 -0
  174. package/neural-interface/lib/opencode-native-boundary.js +44 -0
  175. package/neural-interface/lib/opencode-protocol.js +249 -112
  176. package/neural-interface/lib/opencode-runtime-config.js +32 -22
  177. package/neural-interface/lib/opencode-serve-records.js +39 -21
  178. package/neural-interface/lib/opencode-v2-client.js +48 -153
  179. package/neural-interface/lib/opencode-v2-ws-requests.js +36 -210
  180. package/neural-interface/lib/opencode-worker-data.js +27 -0
  181. package/neural-interface/lib/opencode2-client.js +73 -37
  182. package/neural-interface/lib/opencode2-proxy.js +23 -63
  183. package/neural-interface/lib/opencode2-translate.js +51 -2
  184. package/neural-interface/lib/owner-authority.js +249 -0
  185. package/neural-interface/lib/page-session.js +275 -0
  186. package/neural-interface/lib/peer-identity.js +763 -0
  187. package/neural-interface/lib/request-gate.js +17 -2
  188. package/neural-interface/lib/rulesets/api.js +1 -1
  189. package/neural-interface/lib/rulesets/fs-safe.js +1 -1
  190. package/neural-interface/lib/rulesets/installer.js +92 -27
  191. package/neural-interface/lib/rulesets/json-edit.js +1 -1
  192. package/neural-interface/lib/session-cache-builder.js +17 -30
  193. package/neural-interface/lib/session-title-generator.js +58 -36
  194. package/neural-interface/lib/skills/api-v2.js +495 -0
  195. package/neural-interface/lib/skills/bundle.js +418 -0
  196. package/neural-interface/lib/skills/catalog.js +294 -0
  197. package/neural-interface/lib/skills/creation-api.js +191 -0
  198. package/neural-interface/lib/skills/creation-brief.js +247 -0
  199. package/neural-interface/lib/skills/creation-sources.js +267 -0
  200. package/neural-interface/lib/skills/creation.js +843 -0
  201. package/neural-interface/lib/skills/deploy.js +564 -0
  202. package/neural-interface/lib/skills/digest.js +119 -0
  203. package/neural-interface/lib/skills/discover.js +111 -0
  204. package/neural-interface/lib/skills/draft-confinement.js +214 -0
  205. package/neural-interface/lib/skills/eval-confinement.js +397 -0
  206. package/neural-interface/lib/skills/eval-sandbox.js +280 -0
  207. package/neural-interface/lib/skills/eval-trace.js +119 -0
  208. package/neural-interface/lib/skills/evals-api.js +212 -0
  209. package/neural-interface/lib/skills/evals.js +1573 -0
  210. package/neural-interface/lib/skills/export.js +200 -0
  211. package/neural-interface/lib/skills/frontmatter.js +64 -0
  212. package/neural-interface/lib/skills/health.js +75 -0
  213. package/neural-interface/lib/skills/json-edit.js +165 -0
  214. package/neural-interface/lib/skills/known-bridge-digests.json +387 -0
  215. package/neural-interface/lib/skills/known-bridges.js +96 -0
  216. package/neural-interface/lib/skills/library.js +823 -0
  217. package/neural-interface/lib/skills/local-store.js +21 -0
  218. package/neural-interface/lib/skills/migration.js +433 -0
  219. package/neural-interface/lib/skills/operations.js +45 -0
  220. package/neural-interface/lib/skills/ownership.js +427 -0
  221. package/neural-interface/lib/skills/packages.js +88 -0
  222. package/neural-interface/lib/skills/reviews.js +212 -0
  223. package/neural-interface/lib/skills/revision.js +80 -0
  224. package/neural-interface/lib/skills/roots.js +262 -0
  225. package/neural-interface/lib/skills/runtime-checks.js +355 -0
  226. package/neural-interface/lib/skills/scan-assets.js +252 -0
  227. package/neural-interface/lib/skills/scan-context.js +26 -0
  228. package/neural-interface/lib/skills/scan-shell.js +324 -0
  229. package/neural-interface/lib/skills/scan.js +364 -0
  230. package/neural-interface/lib/skills/scanners.js +54 -0
  231. package/neural-interface/lib/skills/service.js +522 -0
  232. package/neural-interface/lib/skills/telemetry.js +113 -0
  233. package/neural-interface/lib/sqlite-integrity-worker.js +22 -0
  234. package/neural-interface/lib/tool-lists.js +124 -0
  235. package/neural-interface/lib/whatsapp/bridge.js +6 -3
  236. package/neural-interface/lib/worker-confinement.js +1192 -0
  237. package/neural-interface/lib/worker-guard-setting.js +56 -0
  238. package/neural-interface/lib/worker-mcp-channel.js +175 -0
  239. package/neural-interface/lib/worker-relay-ports.js +227 -0
  240. package/neural-interface/lib/worker-resume.js +229 -0
  241. package/neural-interface/lib/worker-sandbox.js +299 -0
  242. package/neural-interface/package-lock.json +18 -12
  243. package/neural-interface/package.json +2 -2
  244. package/neural-interface/public/index.html +3 -1
  245. package/neural-interface/public/index2d.html +19 -11
  246. package/neural-interface/public/onboarding.html +2 -2
  247. package/neural-interface/public/shared/account-menu.js +8 -5
  248. package/neural-interface/public/shared/agent-runtime-options.js +35 -19
  249. package/neural-interface/public/shared/api.js +1527 -1336
  250. package/neural-interface/public/shared/app-frame.js +192 -0
  251. package/neural-interface/public/shared/assistant/asst-agents-dock.js +33 -2
  252. package/neural-interface/public/shared/assistant/asst-ask-styles.js +270 -0
  253. package/neural-interface/public/shared/assistant/asst-ask-tail.js +118 -0
  254. package/neural-interface/public/shared/assistant/asst-ask.js +397 -0
  255. package/neural-interface/public/shared/assistant/asst-brain-picker.js +49 -35
  256. package/neural-interface/public/shared/assistant/asst-control.js +157 -26
  257. package/neural-interface/public/shared/assistant/asst-followups-card.js +383 -0
  258. package/neural-interface/public/shared/assistant/asst-followups.js +417 -0
  259. package/neural-interface/public/shared/assistant/asst-limit-dock.js +40 -0
  260. package/neural-interface/public/shared/assistant/asst-limit-wait.js +294 -0
  261. package/neural-interface/public/shared/assistant/asst-limit.js +168 -0
  262. package/neural-interface/public/shared/assistant/asst-mascot.js +49 -12
  263. package/neural-interface/public/shared/assistant/asst-menu.js +7 -6
  264. package/neural-interface/public/shared/assistant/asst-panel.js +106 -11
  265. package/neural-interface/public/shared/assistant/asst-rack-styles.js +66 -49
  266. package/neural-interface/public/shared/assistant/asst-render.js +401 -77
  267. package/neural-interface/public/shared/assistant/asst-route.js +83 -12
  268. package/neural-interface/public/shared/assistant/asst-scenes.js +2 -0
  269. package/neural-interface/public/shared/assistant/asst-sidepanel.js +67 -4
  270. package/neural-interface/public/shared/assistant/asst-slash.js +9 -7
  271. package/neural-interface/public/shared/assistant/asst-state.js +11 -15
  272. package/neural-interface/public/shared/assistant/asst-stop.js +127 -0
  273. package/neural-interface/public/shared/assistant/asst-styles.js +59 -21
  274. package/neural-interface/public/shared/assistant/asst-tool-kinds.js +156 -16
  275. package/neural-interface/public/shared/automation-context.js +5 -2
  276. package/neural-interface/public/shared/cc-dropdown.js +89 -19
  277. package/neural-interface/public/shared/cdx/cdx-context-menu.js +10 -9
  278. package/neural-interface/public/shared/cdx/cdx-copy.js +16 -0
  279. package/neural-interface/public/shared/cdx/cdx-output-model.js +22 -1
  280. package/neural-interface/public/shared/cdx/cdx-output.js +8 -7
  281. package/neural-interface/public/shared/cdx/cdx-panel.js +45 -149
  282. package/neural-interface/public/shared/cdx/cdx-protocol.js +28 -1
  283. package/neural-interface/public/shared/cdx/cdx-render.js +47 -29
  284. package/neural-interface/public/shared/cdx/cdx-requests.js +3 -3
  285. package/neural-interface/public/shared/cdx/cdx-skill-hints.js +54 -0
  286. package/neural-interface/public/shared/cdx/cdx-styles.js +11 -3
  287. package/neural-interface/public/shared/cdx/cdx-tabs.js +52 -39
  288. package/neural-interface/public/shared/cdx/cdx-ws.js +0 -1
  289. package/neural-interface/public/shared/cli-install-view.js +4 -8
  290. package/neural-interface/public/shared/cli-status.js +2 -2
  291. package/neural-interface/public/shared/constants.js +2 -2
  292. package/neural-interface/public/shared/context-menu-areas.js +34 -0
  293. package/neural-interface/public/shared/context-menu-logic.js +243 -0
  294. package/neural-interface/public/shared/context-menu-model.js +366 -0
  295. package/neural-interface/public/shared/context-menu.js +372 -0
  296. package/neural-interface/public/shared/cp/cp-context-menu.js +10 -9
  297. package/neural-interface/public/shared/crash-notice-view.js +168 -0
  298. package/neural-interface/public/shared/desktop-update-view.js +20 -0
  299. package/neural-interface/public/shared/editor/editor-panel-logic.js +2 -2
  300. package/neural-interface/public/shared/html-shell.js +9 -11
  301. package/neural-interface/public/shared/i18n.js +2 -0
  302. package/neural-interface/public/shared/ocp-v2/ocp-v2-approvals.js +7 -7
  303. package/neural-interface/public/shared/ocp-v2/ocp-v2-binding.js +4 -4
  304. package/neural-interface/public/shared/ocp-v2/ocp-v2-changes-logic.js +3 -101
  305. package/neural-interface/public/shared/ocp-v2/ocp-v2-childpanel.js +2 -0
  306. package/neural-interface/public/shared/ocp-v2/ocp-v2-compact-button.js +1 -3
  307. package/neural-interface/public/shared/ocp-v2/ocp-v2-composer-logic.js +2 -6
  308. package/neural-interface/public/shared/ocp-v2/ocp-v2-context-menu.js +11 -11
  309. package/neural-interface/public/shared/ocp-v2/ocp-v2-context-model.js +0 -3
  310. package/neural-interface/public/shared/ocp-v2/ocp-v2-events.js +8 -4
  311. package/neural-interface/public/shared/ocp-v2/ocp-v2-manager.js +7 -7
  312. package/neural-interface/public/shared/ocp-v2/ocp-v2-outcome-notifications.js +16 -0
  313. package/neural-interface/public/shared/ocp-v2/ocp-v2-panel.js +47 -252
  314. package/neural-interface/public/shared/ocp-v2/ocp-v2-plan.js +1 -2
  315. package/neural-interface/public/shared/ocp-v2/ocp-v2-projectbar.js +95 -202
  316. package/neural-interface/public/shared/ocp-v2/ocp-v2-render.js +6 -21
  317. package/neural-interface/public/shared/ocp-v2/ocp-v2-send.js +4 -4
  318. package/neural-interface/public/shared/ocp-v2/ocp-v2-session-actions.js +8 -61
  319. package/neural-interface/public/shared/ocp-v2/ocp-v2-sessions-logic.js +2 -91
  320. package/neural-interface/public/shared/ocp-v2/ocp-v2-slash-hints.js +16 -15
  321. package/neural-interface/public/shared/ocp-v2/ocp-v2-state.js +8 -21
  322. package/neural-interface/public/shared/ocp-v2/ocp-v2-status-logic.js +1 -99
  323. package/neural-interface/public/shared/ocp-v2/ocp-v2-status.js +5 -35
  324. package/neural-interface/public/shared/ocp-v2/ocp-v2-styles.js +0 -21
  325. package/neural-interface/public/shared/ocp-v2/{ocp-v2-profile-inheritance.js → ocp-v2-tools-inheritance.js} +16 -16
  326. package/neural-interface/public/shared/ocp-v2/ocp-v2-ws.js +14 -47
  327. package/neural-interface/public/shared/page-session.js +96 -0
  328. package/neural-interface/public/shared/registry.js +5 -3
  329. package/neural-interface/public/shared/retired-2d.js +3 -0
  330. package/neural-interface/public/shared/schedules-view.js +195 -61
  331. package/neural-interface/public/shared/settings/settings-claude-hooks.js +135 -0
  332. package/neural-interface/public/shared/settings/settings-data.js +3 -1
  333. package/neural-interface/public/shared/settings/settings-ia.js +6 -6
  334. package/neural-interface/public/shared/settings/settings-opencode.js +89 -0
  335. package/neural-interface/public/shared/settings/settings-skill-folders-pane.js +265 -0
  336. package/neural-interface/public/shared/settings/settings-skill-folders.js +130 -0
  337. package/neural-interface/public/shared/settings/settings-worker-guard.js +72 -0
  338. package/neural-interface/public/shared/skills/ss-args.js +96 -0
  339. package/neural-interface/public/shared/skills/ss-creation.js +219 -0
  340. package/neural-interface/public/shared/skills/ss-dialog.js +130 -0
  341. package/neural-interface/public/shared/skills/ss-doc.js +173 -0
  342. package/neural-interface/public/shared/skills/ss-eval-adapters.js +269 -0
  343. package/neural-interface/public/shared/skills/ss-eval-grade.js +359 -0
  344. package/neural-interface/public/shared/skills/ss-eval-optimise.js +153 -0
  345. package/neural-interface/public/shared/skills/ss-eval-plan.js +315 -0
  346. package/neural-interface/public/shared/skills/ss-evals.js +417 -0
  347. package/neural-interface/public/shared/skills/ss-form.js +159 -0
  348. package/neural-interface/public/shared/skills/ss-frontmatter.js +376 -0
  349. package/neural-interface/public/shared/skills/ss-ids.js +32 -0
  350. package/neural-interface/public/shared/skills/ss-lint.js +141 -0
  351. package/neural-interface/public/shared/skills/ss-presets.js +117 -0
  352. package/neural-interface/public/shared/skills/ss-profiles.js +475 -0
  353. package/neural-interface/public/shared/skills/ss-resources.js +165 -0
  354. package/neural-interface/public/shared/skills/ss-review-view.js +190 -0
  355. package/neural-interface/public/shared/skills/ss-tabs.js +79 -0
  356. package/neural-interface/public/shared/skills/ss-unicode.js +135 -0
  357. package/neural-interface/public/shared/skills/studio/sx-actions.js +222 -0
  358. package/neural-interface/public/shared/skills/studio/sx-cm.js +101 -0
  359. package/neural-interface/public/shared/skills/studio/sx-create-ai-view.js +749 -0
  360. package/neural-interface/public/shared/skills/studio/sx-create-ai.js +236 -0
  361. package/neural-interface/public/shared/skills/studio/sx-create-view.js +254 -0
  362. package/neural-interface/public/shared/skills/studio/sx-create.js +126 -0
  363. package/neural-interface/public/shared/skills/studio/sx-diff-view.js +43 -0
  364. package/neural-interface/public/shared/skills/studio/sx-diff.js +133 -0
  365. package/neural-interface/public/shared/skills/studio/sx-docs.js +480 -0
  366. package/neural-interface/public/shared/skills/studio/sx-dom.js +229 -0
  367. package/neural-interface/public/shared/skills/studio/sx-edit-view.js +848 -0
  368. package/neural-interface/public/shared/skills/studio/sx-editor-model.js +193 -0
  369. package/neural-interface/public/shared/skills/studio/sx-errors.js +22 -0
  370. package/neural-interface/public/shared/skills/studio/sx-geometry.js +82 -0
  371. package/neural-interface/public/shared/skills/studio/sx-import.js +262 -0
  372. package/neural-interface/public/shared/skills/studio/sx-inspector.js +308 -0
  373. package/neural-interface/public/shared/skills/studio/sx-install-flow.js +279 -0
  374. package/neural-interface/public/shared/skills/studio/sx-install.js +296 -0
  375. package/neural-interface/public/shared/skills/studio/sx-library-view.js +639 -0
  376. package/neural-interface/public/shared/skills/studio/sx-library.js +475 -0
  377. package/neural-interface/public/shared/skills/studio/sx-main.js +681 -0
  378. package/neural-interface/public/shared/skills/studio/sx-operations-view.js +98 -0
  379. package/neural-interface/public/shared/skills/studio/sx-operations.js +11 -0
  380. package/neural-interface/public/shared/skills/studio/sx-plan.js +158 -0
  381. package/neural-interface/public/shared/skills/studio/sx-publish-view.js +621 -0
  382. package/neural-interface/public/shared/skills/studio/sx-review-view.js +369 -0
  383. package/neural-interface/public/shared/skills/studio/sx-review.js +148 -0
  384. package/neural-interface/public/shared/skills/studio/sx-scan.js +35 -0
  385. package/neural-interface/public/shared/skills/studio/sx-snippets.js +96 -0
  386. package/neural-interface/public/shared/skills/studio/sx-subject.js +248 -0
  387. package/neural-interface/public/shared/skills/studio/sx-test-view.js +994 -0
  388. package/neural-interface/public/shared/skills/studio/sx-test.js +328 -0
  389. package/neural-interface/public/shared/skills/studio/sx-versions-view.js +241 -0
  390. package/neural-interface/public/shared/skills/studio/sx-workspace-view.js +425 -0
  391. package/neural-interface/public/shared/styleguide/sg-panel.js +4 -2
  392. package/neural-interface/public/shared/styles.css +1525 -1779
  393. package/neural-interface/public/shared/synabun-mascot.js +1115 -9
  394. package/neural-interface/public/shared/tool-list-picker.js +55 -0
  395. package/neural-interface/public/shared/tool-list-storage.js +24 -0
  396. package/neural-interface/public/shared/tool-list-view.js +112 -0
  397. package/neural-interface/public/shared/tour/tour-actor.js +268 -0
  398. package/neural-interface/public/shared/tour/tour-beats.js +336 -0
  399. package/neural-interface/public/shared/tour/tour-engine.js +884 -0
  400. package/neural-interface/public/shared/tour/tour-ink.js +390 -0
  401. package/neural-interface/public/shared/tour/tour-stage.js +440 -0
  402. package/neural-interface/public/shared/tour/tour-state.js +40 -0
  403. package/neural-interface/public/shared/tour/tour-tips.js +99 -0
  404. package/neural-interface/public/shared/tour/tour.css +144 -0
  405. package/neural-interface/public/shared/ui-automation-studio.js +91 -128
  406. package/neural-interface/public/shared/ui-claude-panel.js +77 -5
  407. package/neural-interface/public/shared/ui-command-runner.js +6 -3
  408. package/neural-interface/public/shared/ui-context-menu.js +295 -0
  409. package/neural-interface/public/shared/ui-cost-widget.js +57 -59
  410. package/neural-interface/public/shared/ui-crash-notice.js +187 -0
  411. package/neural-interface/public/shared/ui-detail.js +15 -3
  412. package/neural-interface/public/shared/ui-image-gallery.js +50 -47
  413. package/neural-interface/public/shared/ui-keybinds.js +26 -1
  414. package/neural-interface/public/shared/ui-menubar.js +8 -18
  415. package/neural-interface/public/shared/ui-native-loop-router-state.js +5 -0
  416. package/neural-interface/public/shared/ui-native-loop-router.js +7 -1
  417. package/neural-interface/public/shared/ui-navbar.js +4 -24
  418. package/neural-interface/public/shared/ui-panels.js +96 -65
  419. package/neural-interface/public/shared/ui-schedules-studio.js +507 -423
  420. package/neural-interface/public/shared/ui-sessions.js +5 -3
  421. package/neural-interface/public/shared/ui-settings.js +594 -462
  422. package/neural-interface/public/shared/ui-sidepanel-sessions.js +1 -1
  423. package/neural-interface/public/shared/ui-sidepanel-state.js +23 -12
  424. package/neural-interface/public/shared/ui-sidepanel-windows.js +16 -11
  425. package/neural-interface/public/shared/ui-skills.js +33 -2830
  426. package/neural-interface/public/shared/ui-styleguide.js +5 -2
  427. package/neural-interface/public/shared/ui-sync.js +15 -5
  428. package/neural-interface/public/shared/ui-terminal.js +124 -180
  429. package/neural-interface/public/shared/ui-tool-updates.js +3 -1
  430. package/neural-interface/public/shared/ui-tooltip.js +10 -5
  431. package/neural-interface/public/shared/ui-trash.js +6 -4
  432. package/neural-interface/public/shared/ui-tutorial-layout.js +3 -117
  433. package/neural-interface/public/shared/ui-tutorial-preview.js +103 -0
  434. package/neural-interface/public/shared/ui-tutorial-steps.js +3 -65
  435. package/neural-interface/public/shared/ui-tutorial.css +47 -100
  436. package/neural-interface/public/shared/ui-tutorial.js +285 -509
  437. package/neural-interface/public/shared/ui-update.js +38 -2
  438. package/neural-interface/public/shared/ui-whiteboard.js +311 -58
  439. package/neural-interface/public/shared/ui-worker-end.js +4 -0
  440. package/neural-interface/public/shared/ui-workspaces.js +3 -2
  441. package/neural-interface/public/shared/view-variant.js +66 -0
  442. package/neural-interface/public/shared/whatsapp/wa-view.js +1 -1
  443. package/neural-interface/public/shared/whiteboard-list.js +172 -0
  444. package/neural-interface/public/shared/worker-end.js +10 -3
  445. package/neural-interface/public/shared/worker-restart.js +12 -0
  446. package/neural-interface/public/sidepanel-session.html +1 -1
  447. package/neural-interface/public/variant/2d/background.js +2 -1
  448. package/neural-interface/public/variant/2d/context-menu.js +8 -2
  449. package/neural-interface/public/variant/2d/graph.js +42 -20
  450. package/neural-interface/public/variant/2d/hulls.js +14 -9
  451. package/neural-interface/public/variant/2d/lasso.js +11 -7
  452. package/neural-interface/public/variant/2d/main.js +32 -1
  453. package/neural-interface/public/variant/2d/minimap.js +11 -13
  454. package/neural-interface/public/variant/3d/main.js +69 -6
  455. package/neural-interface/public/variant/3d/map-controls.js +24 -9
  456. package/neural-interface/public/vendor/caveat/OFL.txt +93 -0
  457. package/neural-interface/public/vendor/caveat/caveat-latin-400-normal.woff2 +0 -0
  458. package/neural-interface/public/vendor/caveat/caveat-latin-700-normal.woff2 +0 -0
  459. package/neural-interface/public/vendor/caveat/caveat.css +17 -0
  460. package/neural-interface/public/vendor/caveat/manifest.json +12 -0
  461. package/neural-interface/public/vendor/yaml/LICENSE +13 -0
  462. package/neural-interface/public/vendor/yaml/manifest.json +4 -0
  463. package/neural-interface/public/vendor/yaml/yaml-2.9.1.min.js +137 -0
  464. package/neural-interface/scripts/build-vendor.mjs +32 -0
  465. package/neural-interface/server.js +3934 -2454
  466. package/neural-interface/templates/rulesets/core.md +1 -1
  467. package/neural-interface/templates/rulesets/legacy-hashes.json +18 -0
  468. package/neural-interface/templates/rulesets/manifest.json +8 -8
  469. package/npm-shrinkwrap.json +18 -12
  470. package/package.json +16 -3
  471. package/postinstall.js +9 -4
  472. package/preuninstall.js +1 -1
  473. package/setup.js +97 -322
  474. package/skills/skill-forge/SKILL.md +177 -0
  475. package/skills/skill-forge/evals/evals.json +54 -0
  476. package/skills/skill-forge/references/package.md +105 -0
  477. package/skills/skill-forge/references/review-and-recovery.md +63 -0
  478. package/skills/skill-forge/references/runtime-profiles.md +20 -0
  479. package/skills/skill-forge/references/sources-and-capabilities.md +51 -0
  480. package/skills/synabun/SKILL.md +10 -7
  481. package/skills/synabun/modules/audit.md +1 -5
  482. package/skills/synabun/modules/changelog.md +1 -5
  483. package/skills/synabun/modules/idea.md +1 -1
  484. package/skills/synabun/modules/memorize.md +6 -9
  485. package/skills/synabun/modules/schedule.md +4 -4
  486. package/mcp-server/dist/services/profiles.d.ts +0 -120
  487. package/mcp-server/dist/services/profiles.d.ts.map +0 -1
  488. package/mcp-server/dist/services/profiles.js +0 -387
  489. package/mcp-server/dist/services/profiles.js.map +0 -1
  490. package/mcp-server/dist/tools/leonardo-browser-tools.d.ts +0 -97
  491. package/mcp-server/dist/tools/leonardo-browser-tools.d.ts.map +0 -1
  492. package/mcp-server/dist/tools/leonardo-browser-tools.js +0 -228
  493. package/mcp-server/dist/tools/leonardo-browser-tools.js.map +0 -1
  494. package/mcp-server/dist/tools/leonardo.d.ts +0 -13
  495. package/mcp-server/dist/tools/leonardo.d.ts.map +0 -1
  496. package/mcp-server/dist/tools/leonardo.js +0 -21
  497. package/mcp-server/dist/tools/leonardo.js.map +0 -1
  498. package/mcp-server/dist/tools/profile.d.ts +0 -17
  499. package/mcp-server/dist/tools/profile.d.ts.map +0 -1
  500. package/mcp-server/dist/tools/profile.js +0 -114
  501. package/mcp-server/dist/tools/profile.js.map +0 -1
  502. package/mcp-server/src/services/profiles.ts +0 -428
  503. package/mcp-server/src/tools/leonardo-browser-tools.ts +0 -291
  504. package/mcp-server/src/tools/leonardo.ts +0 -30
  505. package/mcp-server/src/tools/profile.ts +0 -122
  506. package/neural-interface/lib/assistant-brains/opencode-browser-policy.js +0 -47
  507. package/neural-interface/lib/assistant-brains/opencode-route-gate.js +0 -62
  508. package/neural-interface/lib/mcp-profile-servers.js +0 -120
  509. package/neural-interface/public/shared/ui-tutorial-draw.js +0 -311
  510. package/skills/leonardo/SKILL.md +0 -168
  511. package/skills/leonardo/icon.svg +0 -1
  512. package/skills/leonardo/modules/browser-guide.md +0 -378
  513. package/skills/leonardo/modules/image-prompter.md +0 -283
  514. package/skills/leonardo/modules/model-advisor.md +0 -100
  515. package/skills/leonardo/modules/prompt-library.md +0 -110
  516. package/skills/leonardo/modules/style-guide.md +0 -186
  517. package/skills/leonardo/modules/video-prompter.md +0 -317
@@ -9,6 +9,7 @@ import { fetchTrash, restoreFromTrash, purgeTrash, deleteMemoryPermanent } from
9
9
  import { formatTrashAge, formatMemoryContent } from './utils.js';
10
10
  import { storage } from './storage.js';
11
11
  import { isGuest, hasPermission, showGuestToast } from './ui-sync.js';
12
+ import { centeredInFrame, frameRect } from './app-frame.js';
12
13
 
13
14
  const $ = (id) => document.getElementById(id);
14
15
 
@@ -96,7 +97,7 @@ function openTrashPanel() {
96
97
  return;
97
98
  }
98
99
  const existing = $('trash-window');
99
- if (existing) { existing.style.zIndex = '50101'; return; }
100
+ if (existing) { existing.style.zIndex = '49901'; return; }
100
101
 
101
102
  trashPanelOpen = true;
102
103
  trashSelectedId = null;
@@ -110,12 +111,13 @@ function openTrashPanel() {
110
111
  const saved = JSON.parse(storage.getItem('neural-panel-trash-window') || 'null');
111
112
  if (saved) {
112
113
  if (saved.left && saved.left !== 'auto') win.style.left = saved.left;
113
- if (saved.top) win.style.top = Math.max(48, parseInt(saved.top)) + 'px';
114
+ if (saved.top) win.style.top = Math.max(frameRect().top, parseInt(saved.top)) + 'px';
114
115
  if (saved.width) win.style.width = saved.width;
115
116
  if (saved.height) win.style.height = saved.height;
116
117
  } else {
117
- win.style.left = Math.max(20, (window.innerWidth - 640) / 2) + 'px';
118
- win.style.top = Math.max(48, (window.innerHeight - 480) / 2) + 'px';
118
+ const at = centeredInFrame(640, 480); // in the app frame
119
+ win.style.left = at.left + 'px';
120
+ win.style.top = at.top + 'px';
119
121
  }
120
122
 
121
123
  win.innerHTML = `
@@ -1,8 +1,6 @@
1
- // Pure viewport geometry; no storage, DOM or product state.
2
- const MARGIN = 16; // the note keeps this far from the viewport edges
3
- const GAP = 56; // room for the arrow between the note and its target
4
- const CLEAR = 32; // how far the note stays from chrome it steps aside for (the arrow still fits)
1
+ // Pure viewport geometry the Workspace tour asks of a control's rect; no storage, DOM or product state.
5
2
 
3
+ /** The rect is on screen, whole: a control the tour may ring and point at. */
6
4
  export function visibleRect(rect, width, height) {
7
5
  return !!rect && rect.width > 0 && rect.height > 0 && rect.left >= 0 && rect.top >= 0
8
6
  && rect.right <= width && rect.bottom <= height;
@@ -13,23 +11,7 @@ export function overlaps(a, b, gap = 0) {
13
11
  && a.top < b.bottom + gap && a.bottom > b.top - gap;
14
12
  }
15
13
 
16
- export function overlapArea(a, b) {
17
- return Math.max(0, Math.min(a.right, b.right) - Math.max(a.left, b.left))
18
- * Math.max(0, Math.min(a.bottom, b.bottom) - Math.max(a.top, b.top));
19
- }
20
-
21
- // How much of the straight line from a to b runs inside rect (Liang–Barsky clipping).
22
- export function lengthInside(a, b, rect) {
23
- const dx = b.x - a.x, dy = b.y - a.y;
24
- let t0 = 0, t1 = 1;
25
- for (const [p, q] of [[-dx, a.x - rect.left], [dx, rect.right - a.x], [-dy, a.y - rect.top], [dy, rect.bottom - a.y]]) {
26
- if (p === 0) { if (q < 0) return 0; continue; }
27
- const t = q / p;
28
- if (p < 0) t0 = Math.max(t0, t); else t1 = Math.min(t1, t);
29
- }
30
- return t1 > t0 ? (t1 - t0) * Math.hypot(dx, dy) : 0;
31
- }
32
-
14
+ /** One rect around several (a run of controls: the effort and permission pills). */
33
15
  export function unionRect(rects) {
34
16
  const list = rects.filter(Boolean);
35
17
  if (!list.length) return null;
@@ -37,99 +19,3 @@ export function unionRect(rects) {
37
19
  const right = Math.max(...list.map(r => r.right)), bottom = Math.max(...list.map(r => r.bottom));
38
20
  return { left, top, right, bottom, width: right - left, height: bottom - top };
39
21
  }
40
-
41
- // A compact, squarish target gets a ring; anything long or tall gets a box that hugs it.
42
- export function outlineShape(rect) {
43
- const long = Math.max(rect.width, rect.height), short = Math.min(rect.width, rect.height);
44
- return long <= 72 && long / Math.max(short, 1) <= 1.6 ? 'ring' : 'box';
45
- }
46
-
47
- // The rect the outline is drawn on: the target plus its padding, kept inside the viewport.
48
- // A ring has to clear the corners of the rect it circles (√2 of each half side).
49
- export function outlineRect(rect, width, height, shape = outlineShape(rect)) {
50
- const padX = shape === 'ring' ? rect.width * 0.21 + 3 : 5;
51
- const padY = shape === 'ring' ? rect.height * 0.21 + 3 : 5;
52
- const left = Math.max(3, rect.left - padX), top = Math.max(3, rect.top - padY);
53
- const right = Math.min(width - 3, rect.right + padX), bottom = Math.min(height - 3, rect.bottom + padY);
54
- return { left, top, right, bottom, width: right - left, height: bottom - top };
55
- }
56
-
57
- /**
58
- * Where the note goes. `avoid` rects are never covered (the open dropdown that
59
- * holds the target); `keep` rects are chrome the note leaves visible when there
60
- * is free space (title bar, toolbars, session pills). Candidates sit on each
61
- * side of the target, and of an `avoid` rect that contains it, at three alignments.
62
- * `near` is where the note is now: between two close calls, the shorter move wins.
63
- */
64
- export function placeNote(target, width, height, noteWidth, noteHeight, { avoid = [], keep = [], near = null } = {}) {
65
- const w = Math.min(noteWidth, width - MARGIN * 2);
66
- const h = Math.min(noteHeight, height - MARGIN * 2);
67
- const clamp = (v, min, max) => Math.max(min, Math.min(v, max));
68
- const box = (x, y, bw = w, bh = h) => {
69
- const left = clamp(x, MARGIN, Math.max(MARGIN, width - bw - MARGIN));
70
- const top = clamp(y, MARGIN, Math.max(MARGIN, height - bh - MARGIN));
71
- return { left, top, right: left + bw, bottom: top + bh, width: bw, height: bh };
72
- };
73
- if (!target) return box((width - w) / 2, (height - h) / 2);
74
-
75
- const boxes = [];
76
- const anchors = [target, ...avoid.filter(r => overlaps(r, target))];
77
- for (const a of anchors) {
78
- for (const align of [0.5, 0, 1]) {
79
- const y = target.top + (target.height - h) * align, x = target.left + (target.width - w) * align;
80
- boxes.push(box(a.right + GAP, y), box(a.left - w - GAP, y), box(x, a.bottom + GAP), box(x, a.top - h - GAP));
81
- }
82
- }
83
- // A candidate that covers chrome is also tried just clear of it, on each side: with room
84
- // for the arrow, and tight for a narrow gap. Twice, for a spot wedged between two pieces.
85
- const clearOf = (list) => list.flatMap(b => keep.filter(r => overlaps(b, r)).flatMap(r => [CLEAR, 12].flatMap(c => [
86
- box(b.left, r.bottom + c), box(b.left, r.top - h - c), box(r.left - w - c, b.top), box(r.right + c, b.top)])));
87
- const cleared = clearOf(boxes);
88
- const unique = new Map([...boxes, ...cleared, ...clearOf(cleared)].map(b => [`${Math.round(b.left)},${Math.round(b.top)}`, b]));
89
- const tc = { x: target.left + target.width / 2, y: target.top + target.height / 2 };
90
- // The arrow should not run across the menu the target sits in, over its other entries,
91
- // and would rather not cross other chrome on its way.
92
- const arrow = (b) => {
93
- const { from, to } = arrowPoints(b, target);
94
- const across = (rects) => rects.reduce((sum, r) => sum + lengthInside(from, to, r), 0);
95
- const length = Math.hypot(to.x - from.x, to.y - from.y);
96
- // Short is good, but an arrow needs room to read as one.
97
- return length + Math.max(0, 28 - length) * 6 + across(avoid) * 4 + across(keep) * 2;
98
- };
99
- // Lowest wins: covering nothing, then a short arrow that crosses nothing, then nearness.
100
- const score = (b) => (overlaps(b, target, 20) ? 1e9 : 0)
101
- + avoid.filter(r => overlaps(b, r, 12)).length * 1e8
102
- + keep.reduce((sum, r) => sum + overlapArea(b, r), 0) * 10
103
- + arrow(b)
104
- + Math.hypot(b.left + b.width / 2 - tc.x, b.top + b.height / 2 - tc.y) * 0.1
105
- + (near ? Math.hypot(b.left - near.left, b.top - near.top) * 0.1 : 0);
106
- let best = [...unique.values()].map(b => ({ ...b, score: score(b) })).sort((a, b) => a.score - b.score)[0];
107
- // Too narrow to sit beside the target: keep it exposed and let the note
108
- // scroll in whichever space above or below is taller.
109
- if (best.score >= 1e9) {
110
- const below = height - target.bottom - 16 - MARGIN, above = target.top - 16 - MARGIN;
111
- const room = Math.max(below, above);
112
- if (room >= 96) {
113
- const bh = Math.min(h, room);
114
- best = box((width - w) / 2, below >= above ? target.bottom + 16 : target.top - 16 - bh, w, bh);
115
- }
116
- }
117
- return best;
118
- }
119
-
120
- // From the note's facing edge to the target's, stopping outside its outline.
121
- export function arrowPoints(note, target, pad = 10) {
122
- const clamp = (v, min, max) => Math.max(min, Math.min(v, Math.max(min, max)));
123
- const tc = { x: target.left + target.width / 2, y: target.top + target.height / 2 };
124
- const inset = 28;
125
- if (note.left >= target.right || note.right <= target.left) {
126
- const right = note.left >= target.right;
127
- const y = clamp(tc.y, note.top + inset, note.bottom - inset);
128
- return { from: { x: right ? note.left - 6 : note.right + 6, y },
129
- to: { x: right ? target.right + pad : target.left - pad, y: clamp(y, target.top, target.bottom) } };
130
- }
131
- const below = note.top >= target.bottom;
132
- const x = clamp(tc.x, note.left + inset, note.right - inset);
133
- return { from: { x, y: below ? note.top - 6 : note.bottom + 6 },
134
- to: { x: clamp(x, target.left, target.right), y: below ? target.bottom + pad : target.top - pad } };
135
- }
@@ -0,0 +1,103 @@
1
+ // A session-free Assistant for the Workspace tour, when the panel has no session
2
+ // to present on (no tab, or the tab is mid-conversation). These are the production
3
+ // controls and the production empty state (the renderer, its hero rig, the
4
+ // composer, the brain picker, the route chip, the computer switch, the mascot
5
+ // director), with local state and no socket, run, preference or settings call.
6
+ // Only one thing leaves it: a message the user sends from its composer, which the
7
+ // sidepanel hands to the real Assistant (onSend) after the tour has closed.
8
+ import { t } from './i18n.js';
9
+ import { storage } from './storage.js';
10
+ import { readStoredBrain } from './assistant/asst-state.js';
11
+ import { injectAssistantStyles } from './assistant/asst-styles.js';
12
+ import { createRenderer } from './assistant/asst-render.js';
13
+ import { createMascotDirector } from './assistant/asst-mascot.js';
14
+ import { createBrainPicker } from './assistant/asst-brain-picker.js';
15
+ import { createComposer } from './assistant/asst-composer.js';
16
+ import { createComputerToggle } from './assistant/asst-computer.js';
17
+ import { createRouteModeControl } from './assistant/asst-route.js';
18
+
19
+ const macLike = () => /Mac/i.test(navigator.platform || navigator.userAgent || '');
20
+
21
+ export function createTutorialPreview(panel, { onSend = () => {} } = {}) {
22
+ injectAssistantStyles();
23
+ const viewport = document.createElement('div');
24
+ viewport.className = 'asp-viewport active tour-preview';
25
+ viewport.innerHTML = `<div class="asst-root" data-status="idle"><div class="asst-transcript" role="log" aria-live="off" tabindex="0"></div><div class="asst-announce" role="status" aria-live="polite" aria-atomic="true"></div><div class="asst-bottom"><div class="asst-composer-host"></div></div></div>`;
26
+ const bar = document.createElement('div');
27
+ bar.className = 'asp-tab-bar active tour-preview';
28
+ bar.innerHTML = '<div class="asst-bar"><div class="asst-bar-left"><div class="asst-bar-group" data-group="route"></div><div class="asst-bar-group" data-group="context"></div><div class="asst-bar-group" data-group="computer"></div></div><div class="asst-bar-right"></div></div>';
29
+ panel.querySelector('.asp-body').append(viewport);
30
+ panel.querySelector('.asp-bar-slot').append(bar);
31
+ const root = viewport.querySelector('.asst-root');
32
+ const transcript = root.querySelector('.asst-transcript');
33
+ transcript.setAttribute('aria-label', t('assistant.transcript'));
34
+ let brain = readStoredBrain(storage);
35
+ let director = null;
36
+ let picker = null;
37
+ let composer = null;
38
+ const computerShown = macLike();
39
+ const renderer = createRenderer(transcript, {
40
+ t,
41
+ emptySuggestions: () => [
42
+ ...(computerShown ? [{ id: 'computer', label: t('assistant.empty.suggestComputer'), template: t('assistant.empty.templateComputer') }] : []),
43
+ { id: 'web', label: t('assistant.empty.suggestWeb'), template: t('assistant.empty.templateWeb') },
44
+ { id: 'schedule', label: t('assistant.empty.suggestSchedule'), template: t('assistant.empty.templateSchedule') },
45
+ { id: 'remember', label: t('assistant.empty.suggestRemember'), template: t('assistant.empty.templateRemember') },
46
+ ],
47
+ onSuggestion: (template) => composer?.fillTemplate(template),
48
+ mountEmptyProject: (slot) => picker?.mountEmptyProject(slot),
49
+ unmountEmptyControls: () => picker?.mountEmptyProject(null),
50
+ onMascotChange: () => director?.retarget(),
51
+ });
52
+ composer = createComposer(root.querySelector('.asst-composer-host'), {
53
+ t,
54
+ onDraftChange: (text) => renderer.setDrafting?.(!!String(text || '').trim()),
55
+ onFocusChange: (focused) => { if (focused) director?.touch(); },
56
+ onSubmit: (payload) => {
57
+ const text = String(payload?.text || '').trim();
58
+ if (text) onSend(text);
59
+ },
60
+ onToast: () => {},
61
+ });
62
+ picker = createBrainPicker({ brain: composer.el.querySelector('.asst-composer-brain'), context: bar.querySelector('[data-group="context"]') }, {
63
+ t,
64
+ mascot: () => director,
65
+ getBrain: () => brain,
66
+ getRunning: () => false,
67
+ // Only catalog defaults can change this isolated brain; nothing is saved.
68
+ onChange: (next, meta) => { if (meta?.silent) brain = next; },
69
+ menuPlacement: 'auto',
70
+ });
71
+ const route = createRouteModeControl(bar.querySelector('[data-group="route"]'), { t });
72
+ route.setVisible(true);
73
+ const computer = createComputerToggle(bar.querySelector('[data-group="computer"]'), { t });
74
+ computer.set({ visible: computerShown, enabled: false, supported: computerShown, setupState: 'ready' });
75
+ director = createMascotDirector({ getTarget: () => renderer.mascot(), caret: () => composer?.caretPoint?.() || null });
76
+ try { picker.render(); } catch { /* the pills fill in when the catalog arrives */ }
77
+ picker.refresh?.().then(() => picker.render()).catch(() => {});
78
+ renderer.showEmpty();
79
+ return {
80
+ host: {
81
+ root,
82
+ transcript,
83
+ announcer: root.querySelector('.asst-announce'),
84
+ bar,
85
+ renderer,
86
+ director,
87
+ composer,
88
+ live: false,
89
+ computer: computerShown,
90
+ focusComposer: () => composer.focus(),
91
+ },
92
+ destroy() {
93
+ director.destroy();
94
+ picker.destroy();
95
+ composer.destroy();
96
+ route.destroy();
97
+ computer.destroy();
98
+ renderer.destroy?.();
99
+ viewport.remove();
100
+ bar.remove();
101
+ },
102
+ };
103
+ }
@@ -1,5 +1,6 @@
1
- // The storyboard is shared by 2D and 3D. Copy lives in the `tutorial` namespace
2
- // of i18n/<locale>.json; this file only says what each step points at.
1
+ // The project-exploration setup (ui-tutorial.js openSetup) and the exploration
2
+ // prompt Settings → Projects shares. The Workspace tour's storyboard is
3
+ // public/shared/tour/tour-beats.js.
3
4
  export function buildExplorePrompt(projectSlug) {
4
5
  const cat = projectSlug || 'project';
5
6
  const catProject = `${cat}-project`;
@@ -69,66 +70,3 @@ export const ONBOARDING_STEPS = [
69
70
  { id: 'onboarding-project-picker', kind: 'project' },
70
71
  { id: 'onboarding-memory-explain', kind: 'launch' },
71
72
  ];
72
-
73
- // A feature step:
74
- // targets ordered alternatives, [selector, copyKey = 'body', lastSelector?]. The first one on
75
- // screen is annotated and its copy shown; `lastSelector` widens the outline to a run
76
- // of controls. None on screen: the note stays, with the navigation.
77
- // menu a menubar dropdown opened while the step shows (closed again after); an object
78
- // names it per variant ({ '3d': 'apps' }: none in the other).
79
- // submenu a submenu of that dropdown opened too, by its data-submenu name, same forms as `menu`.
80
- // panel 'assistant' shows the Assistant panel for the step when that starts nothing
81
- // (see assistantPanelPeekable); otherwise the last target, its button, is used.
82
- // copy per-variant copy key for the first target ({ '2d': 'body2d' }).
83
- const ASSISTANT_BUTTON = ['#topright-assistant-panel-btn', 'closed'];
84
- const ACTIVE_TAB = '#assistant-panel.open .asp-viewport.active';
85
- const ACTIVE_BAR = '#assistant-panel.open .asp-tab-bar.active';
86
-
87
- // With the workspace tools hidden (the toolbar's toggle) their controls are off screen, and the step outlines the
88
- // toggle that shows them.
89
- const TOOLS_TOGGLE = ['#topright-tools-btn'];
90
-
91
- export const FEATURE_STEPS = [
92
- { id: 'explain-memory-explorer', chapter: 'memory', targets: [['#topright-memory-explorer-btn'], TOOLS_TOGGLE] },
93
- // 3D: the Map submenu of Apps. 2D: the Graph menu.
94
- { id: 'explain-graph', chapter: 'memory', menu: { '3d': 'apps' }, submenu: { '3d': 'map' }, copy: { '2d': 'body2d' },
95
- targets: [['#menu-map-label', 'body', '#menu-map-rebuild'], ['[data-menu="graph"] > .menubar-label', 'body2d']] },
96
- { id: 'explain-focus', chapter: 'workspace', targets: [['#wb-toolbar'], ['#titlebar-viz-toggle', 'graph']] },
97
- { id: 'explain-workspaces', chapter: 'workspace', targets: [['#ws-indicator'], TOOLS_TOGGLE] },
98
- { id: 'explain-terminals', chapter: 'tools', menu: 'apps', targets: [['#menu-terminal-claude', 'body', '#menu-terminal-opencode']] },
99
- { id: 'explain-browser', chapter: 'tools', menu: 'apps', targets: [['#menu-terminal-browser']] },
100
- { id: 'explain-side-panel', chapter: 'tools', targets: [['#topright-claude-panel-btn', 'body', '#topright-opencode-panel-btn']] },
101
- { id: 'explain-automations', chapter: 'automation', menu: 'automations', targets: [['#menu-open-automation-studio']] },
102
- { id: 'explain-schedules', chapter: 'automation', targets: [['#menubar-schedules-btn']] },
103
- { id: 'assistant-start', chapter: 'assistant', panel: 'assistant', targets: [[`${ACTIVE_TAB} .asst-input`], ASSISTANT_BUTTON] },
104
- { id: 'assistant-tools', chapter: 'assistant', panel: 'assistant', targets: [[`${ACTIVE_BAR} .asst-computer-toggle`], ASSISTANT_BUTTON] },
105
- { id: 'assistant-route', chapter: 'assistant', panel: 'assistant', targets: [[`${ACTIVE_BAR} .asst-route-chip`], ASSISTANT_BUTTON] },
106
- { id: 'assistant-track', chapter: 'assistant', panel: 'assistant',
107
- targets: [[`${ACTIVE_TAB} .asst-usage-strip`], [`${ACTIVE_BAR} .asst-act-more`, 'more'], ASSISTANT_BUTTON] },
108
- { id: 'explain-help', chapter: 'help', targets: [['#titlebar-tutorial-btn']] },
109
- ];
110
-
111
- export const SKIP_HINT = { id: 'skip-hint', chapter: 'help', targets: [['#titlebar-tutorial-btn']] };
112
-
113
- export const CHAPTERS = [...new Set(FEATURE_STEPS.map(s => s.chapter))];
114
-
115
- export const TUTORIAL_STEPS = [...ONBOARDING_STEPS, { id: 'welcome', kind: 'welcome' }, ...FEATURE_STEPS];
116
-
117
- const WELCOME = TUTORIAL_STEPS.findIndex(s => s.id === 'welcome');
118
-
119
- // Existing numeric cursors migrate to retained step ids. The old onboarding
120
- // indices never make a returning user repeat CLI/model/project choices.
121
- export function resumeIndex(value, includeOnboarding = false) {
122
- const direct = TUTORIAL_STEPS.findIndex(s => s.id === value);
123
- if (direct >= 0) return includeOnboarding ? direct : Math.max(WELCOME, direct);
124
- const legacy = ['onboarding-explore', 'onboarding-token-warning', 'onboarding-cli-picker', 'onboarding-model-picker',
125
- 'onboarding-project-picker', 'onboarding-memory-explain', 'welcome', 'explain-sessions', 'explain-gallery',
126
- 'explain-cost', 'explain-help', 'explain-focus', 'explain-fullscreen', 'explain-clock', 'explain-trash', 'explain-grid',
127
- 'explain-tile', 'explain-keybinds', 'explain-memory-explorer', 'explain-file-explorer', 'explain-bookmarks',
128
- 'explain-share', 'explain-workspaces', 'explain-side-panel', 'explain-menubar', 'explain-whiteboard-toolbar', 'feedback'];
129
- if (value != null && /^\d+$/.test(value)) {
130
- const mapped = TUTORIAL_STEPS.findIndex(s => s.id === legacy[Number(value)]);
131
- return mapped >= WELCOME ? mapped : WELCOME;
132
- }
133
- return includeOnboarding ? 0 : WELCOME;
134
- }
@@ -1,102 +1,49 @@
1
- /* The workspace tour: handwriting on the board. The strokes (outlines, arrow,
2
- underline) are SVG drawn by ui-tutorial-draw.js; this file styles the note.
3
- Colours are the Style Guide's dark semantic roles. */
4
- #wb-tutorial-dom {
5
- --tour-paper: var(--color-dark-background, #0e141c); /* opaque: the handwriting stays AA over the graph, a menu or a panel */
6
- --tour-text: var(--color-dark-text, #f0f3f7);
7
- --tour-muted: var(--color-dark-text-muted, #8897ac);
8
- --tour-accent: var(--color-dark-primary, #6da4ff);
9
- --tour-on-accent: var(--color-dark-on-primary, #0e141c);
10
- --tour-hand: 'Caveat', 'Segoe Print', 'Bradley Hand', cursive;
11
- --tour-ease: cubic-bezier(0.2, 0, 0, 1);
12
- position: fixed; inset: 0; z-index: 500001; pointer-events: none;
13
- font: 14px/1.5 Inter, system-ui, sans-serif; color: var(--tour-text);
14
- }
15
- #wb-tutorial {
16
- position: fixed; inset: 0; width: 100%; height: 100%; z-index: 500002;
17
- pointer-events: none; overflow: hidden;
18
- }
19
- #wb-tutorial path { filter: drop-shadow(0 1px 2px rgba(14, 20, 28, 0.9)); }
20
- #wb-tutorial g { transition: opacity 120ms linear; }
21
- #wb-tutorial g.tour-leaving { opacity: 0; }
22
-
23
- /* No border: the outline is sketched around the note by the drawing engine. */
24
- .tour-note {
25
- position: absolute; left: 0; top: 0; box-sizing: border-box;
26
- width: 480px; max-width: calc(100vw - 32px); max-height: calc(100dvh - 32px);
27
- overflow: auto; overscroll-behavior: contain; scrollbar-width: none;
28
- padding: 20px 26px 16px; border-radius: 18px 22px 16px 24px / 22px 16px 24px 18px;
29
- background: var(--tour-paper); box-shadow: 0 18px 48px rgba(0, 0, 0, 0.5);
30
- pointer-events: auto; opacity: 0; visibility: hidden;
31
- transition: transform 250ms var(--tour-ease), opacity 200ms linear;
32
- }
33
- .tour-note.tour-placed { opacity: 1; visibility: visible; }
34
- .tour-note.tour-snap { transition: opacity 200ms linear; }
35
- .tour-note:focus { outline: none; }
36
- #wb-tutorial-dom [hidden] { display: none !important; }
37
-
38
- .tour-progress { display: flex; align-items: center; gap: 12px; color: var(--tour-muted); font-size: 12px; letter-spacing: 0.01em; }
39
- .tour-dots { display: flex; gap: 4px; margin-left: auto; }
40
- .tour-dots span { width: 16px; height: 3px; border-radius: 3px 2px 3px 2px; background: currentColor; opacity: 0.45; }
41
- .tour-dots span.current { background: var(--tour-accent); opacity: 1; }
42
- .tour-note h2 {
43
- margin: 8px 0 14px; color: var(--tour-text);
44
- font: 700 34px/1.1 var(--tour-hand); overflow-wrap: anywhere;
45
- }
46
- .tour-copy { margin: 0; font: 400 26px/1.3 var(--tour-hand); overflow-wrap: anywhere; }
47
- .tour-word { display: inline-block; animation: tour-write 180ms var(--tour-ease) both; }
48
- @keyframes tour-write { from { opacity: 0; transform: translateY(3px); } }
49
- .tour-status { margin: 12px 0 0; color: var(--tour-muted); font-size: 14px; }
50
- .tour-status:empty { display: none; }
51
- .tour-extra:empty { display: none; }
52
- .tour-extra { margin-top: 16px; animation: tour-fade 200ms linear 500ms both; }
53
- @keyframes tour-fade { from { opacity: 0; } }
54
-
55
- /* Controls: chalk-drawn buttons, native semantics. */
56
- .tour-nav { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 20px; }
57
- #wb-tutorial-dom button {
58
- min-height: 44px; padding: 4px 18px; cursor: pointer;
59
- font: 700 22px/1.1 var(--tour-hand); color: var(--tour-text);
60
- background: transparent; border: 1.5px solid rgba(240, 243, 247, 0.62);
61
- border-radius: 255px 15px 225px 15px / 15px 225px 15px 255px;
62
- transition: border-color 150ms linear, background-color 150ms linear, color 150ms linear;
63
- }
64
- #wb-tutorial-dom button:hover:not(:disabled) { border-color: var(--tour-accent); color: var(--tour-accent); }
65
- #wb-tutorial-dom button.primary { color: var(--tour-on-accent); background: var(--tour-accent); border-color: var(--tour-accent); }
66
- #wb-tutorial-dom button.primary:hover:not(:disabled) { color: var(--tour-on-accent); background: #9dc3ff; border-color: #9dc3ff; }
67
- #wb-tutorial-dom button:disabled { opacity: 0.5; cursor: default; }
68
- #wb-tutorial-dom button:focus-visible, #wb-tutorial-dom select:focus-visible {
69
- outline: 2px solid var(--tour-accent); outline-offset: 3px;
70
- }
71
- #wb-tutorial-dom button.primary:focus-visible { outline-color: var(--tour-text); }
72
- #wb-tutorial-dom button.tour-link {
73
- min-height: 44px; padding: 4px 6px; border-color: transparent; color: var(--tour-muted);
74
- text-decoration: underline; text-decoration-style: wavy; text-decoration-thickness: 1px; text-underline-offset: 4px;
75
- }
76
- #wb-tutorial-dom button.tour-link:hover { color: var(--tour-text); border-color: transparent; }
77
- .tour-progress button.tour-link { min-height: 24px; padding: 0 4px; font-size: 18px; }
78
- .tour-nav .tour-skip { margin-left: auto; }
79
- .tour-key-hint { margin: 10px 0 0; color: var(--tour-muted); font-size: 12px; }
80
-
81
- /* First-run setup. */
82
- .tour-options { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
83
- #wb-tutorial-dom .tour-choice { text-align: start; overflow-wrap: anywhere; }
84
- #wb-tutorial-dom .tour-choice[aria-pressed="true"] { border-color: var(--tour-accent); color: var(--tour-accent); }
85
- .tour-field { display: grid; gap: 6px; color: var(--tour-muted); font-size: 12px; }
86
- .tour-field + button, .tour-status + button { margin-top: 12px; }
87
- #wb-tutorial-dom select {
88
- width: 100%; min-width: 0; min-height: 44px; padding: 8px 12px; cursor: pointer;
89
- font: 400 14px/1.5 Inter, system-ui, sans-serif; color: var(--tour-text);
90
- background: #1b232e; border: 1px solid #64748b; border-radius: 4px;
91
- }
92
- #wb-tutorial-dom select:disabled { opacity: 0.5; cursor: default; }
93
-
94
- @media (max-width: 600px) {
95
- .tour-note { padding: 16px 18px 12px; }
96
- .tour-note h2 { font-size: 30px; }
97
- .tour-copy { font-size: 24px; }
98
- .tour-options { grid-template-columns: 1fr; }
99
- }
1
+ /* The project-exploration setup (ui-tutorial.js openSetup): a small dialog in the
2
+ Assistant's own tokens. The tour itself is public/shared/tour/tour.css. */
3
+ .tour-setup-overlay {
4
+ position: fixed; inset: 0; z-index: 500001; display: grid; place-items: center; padding: 16px;
5
+ background: color-mix(in srgb, var(--asst-scrim, #000) 45%, transparent);
6
+ font: calc(13px * var(--font-scale, 1))/1.5 var(--ff-body, Inter, system-ui, sans-serif);
7
+ color: var(--asst-text);
8
+ animation: tour-setup-in var(--asst-dur-moderate) var(--asst-ease-enter) both;
9
+ }
10
+ @keyframes tour-setup-in { from { opacity: 0; } }
11
+ .tour-setup {
12
+ box-sizing: border-box; width: 420px; max-width: 100%; max-height: calc(100dvh - 32px); overflow: auto;
13
+ display: grid; gap: 10px; padding: 18px 20px 14px;
14
+ border-radius: var(--asst-r-card); border: 1px solid var(--asst-line-2);
15
+ background: var(--asst-card); box-shadow: var(--asst-popover-shadow, 0 18px 48px rgba(0, 0, 0, .5));
16
+ animation: tour-setup-rise var(--asst-dur-slow) var(--asst-ease-emphasized) both;
17
+ }
18
+ @keyframes tour-setup-rise { from { opacity: 0; transform: translateY(8px) scale(.98); } }
19
+ .tour-setup:focus { outline: none; }
20
+ .tour-setup [hidden] { display: none !important; }
21
+ .tour-setup-progress { color: var(--asst-text-3); font-size: 11px; }
22
+ .tour-setup-title { margin: 0; font: 600 20px/1.25 var(--ff-heading, 'Space Grotesk', sans-serif); color: var(--asst-text); overflow-wrap: anywhere; }
23
+ .tour-setup-copy { margin: 0; color: var(--asst-text-2); line-height: 1.6; overflow-wrap: anywhere; }
24
+ .tour-setup-extra { display: grid; gap: 10px; }
25
+ .tour-setup-extra:empty { display: none; }
26
+ .tour-setup-field { display: grid; gap: 6px; }
27
+ .tour-setup-label { color: var(--asst-text-3); font-size: 12px; }
28
+ .tour-setup-status { margin: 0; color: var(--asst-text-3); font-size: 12px; }
29
+ .tour-setup-status:empty { display: none; }
30
+ .tour-setup-options { display: flex; flex-wrap: wrap; gap: 6px; }
31
+ .tour-setup-nav { display: flex; align-items: center; justify-content: flex-end; gap: 8px; margin-top: 6px; }
32
+ .tour-setup-btn, .tour-setup-choice {
33
+ display: inline-flex; align-items: center; justify-content: center; height: 30px; padding: 0 12px;
34
+ border: 0; border-radius: var(--asst-pill-r-md); background: var(--asst-fill-1); box-shadow: inset 0 0 0 1px var(--asst-line);
35
+ color: var(--asst-text-2); font: 500 12px/1 var(--ff-body, Inter, system-ui, sans-serif); cursor: pointer;
36
+ transition: background-color var(--asst-dur-fast) var(--asst-ease-standard), color var(--asst-dur-fast) var(--asst-ease-standard), transform var(--asst-dur-instant) var(--asst-ease-standard);
37
+ }
38
+ .tour-setup-btn:hover:not(:disabled), .tour-setup-choice:hover { background: var(--asst-fill-2); color: var(--asst-text); }
39
+ .tour-setup-btn:active:not(:disabled), .tour-setup-choice:active { transform: scale(.97); }
40
+ .tour-setup-btn:disabled { opacity: .45; cursor: default; }
41
+ .tour-setup-btn:focus-visible, .tour-setup-choice:focus-visible { outline: 2px solid var(--asst-brand); outline-offset: 2px; }
42
+ .tour-setup-primary { background: var(--asst-pill-on-fill); box-shadow: inset 0 0 0 1px var(--asst-pill-on-ring); color: var(--asst-text); }
43
+ .tour-setup-link { background: transparent; box-shadow: none; color: var(--asst-text-3); }
44
+ .tour-setup-nav .tour-setup-btn:first-child { margin-right: auto; }
45
+ .tour-setup-choice[aria-pressed="true"] { background: var(--asst-pill-on-fill); box-shadow: inset 0 0 0 1px var(--asst-pill-on-ring); color: var(--asst-text); }
100
46
  @media (prefers-reduced-motion: reduce) {
101
- #wb-tutorial *, #wb-tutorial-dom, #wb-tutorial-dom * { animation: none !important; transition: none !important; }
47
+ .tour-setup-overlay, .tour-setup { animation: none; }
48
+ .tour-setup-btn, .tour-setup-choice { transition: none; }
102
49
  }