synabun 2.0.9 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (679) hide show
  1. package/CHANGELOG.md +115 -0
  2. package/README.md +25 -2
  3. package/THIRD-PARTY-LICENSES.md +68 -4
  4. package/bin/synabun.js +71 -24
  5. package/docs/whatsapp.md +2 -2
  6. package/hooks/claude-code/pre-websearch.mjs +12 -1
  7. package/hooks/claude-code/shared.mjs +5 -0
  8. package/hooks/claude-code/stop.mjs +1 -1
  9. package/launcher.mjs +9 -3
  10. package/lib/claude-hooks.js +172 -18
  11. package/lib/client-config-repair.js +17 -8
  12. package/lib/desktop-app.js +7 -1
  13. package/lib/external-tools.js +1 -1
  14. package/lib/first-launch-protection.js +57 -12
  15. package/lib/mcp-dist.js +176 -0
  16. package/lib/release-npm-ci.mjs +138 -0
  17. package/lib/release-publish.mjs +91 -0
  18. package/lib/release-scan.mjs +50 -0
  19. package/lib/server-crash-record.js +123 -0
  20. package/lib/server-exit.js +318 -0
  21. package/lib/server-supervisor.js +508 -0
  22. package/lib/start-launcher.js +43 -5
  23. package/lib/tools-cli.js +45 -0
  24. package/lib/update-snapshot.js +228 -0
  25. package/lib/virustotal.mjs +192 -0
  26. package/lib/windows-crash-event.js +269 -0
  27. package/mcp-server/dist/http.d.ts +20 -1
  28. package/mcp-server/dist/http.d.ts.map +1 -1
  29. package/mcp-server/dist/http.js +59 -12
  30. package/mcp-server/dist/http.js.map +1 -1
  31. package/mcp-server/dist/index.d.ts +33 -27
  32. package/mcp-server/dist/index.d.ts.map +1 -1
  33. package/mcp-server/dist/index.js +128 -143
  34. package/mcp-server/dist/index.js.map +1 -1
  35. package/mcp-server/dist/preload.js +1 -1
  36. package/mcp-server/dist/preload.js.map +1 -1
  37. package/mcp-server/dist/services/codex-config-heal.d.ts +6 -2
  38. package/mcp-server/dist/services/codex-config-heal.d.ts.map +1 -1
  39. package/mcp-server/dist/services/codex-config-heal.js +81 -28
  40. package/mcp-server/dist/services/codex-config-heal.js.map +1 -1
  41. package/mcp-server/dist/services/memory-judge-backfill.d.ts +6 -0
  42. package/mcp-server/dist/services/memory-judge-backfill.d.ts.map +1 -1
  43. package/mcp-server/dist/services/memory-judge-backfill.js +7 -1
  44. package/mcp-server/dist/services/memory-judge-backfill.js.map +1 -1
  45. package/mcp-server/dist/services/neural-interface.d.ts +16 -10
  46. package/mcp-server/dist/services/neural-interface.d.ts.map +1 -1
  47. package/mcp-server/dist/services/neural-interface.js +67 -11
  48. package/mcp-server/dist/services/neural-interface.js.map +1 -1
  49. package/mcp-server/dist/services/server-instructions.d.ts +7 -2
  50. package/mcp-server/dist/services/server-instructions.d.ts.map +1 -1
  51. package/mcp-server/dist/services/server-instructions.js +20 -62
  52. package/mcp-server/dist/services/server-instructions.js.map +1 -1
  53. package/mcp-server/dist/services/tool-catalog.d.ts +120 -0
  54. package/mcp-server/dist/services/tool-catalog.d.ts.map +1 -0
  55. package/mcp-server/dist/services/tool-catalog.js +339 -0
  56. package/mcp-server/dist/services/tool-catalog.js.map +1 -0
  57. package/mcp-server/dist/services/tool-list-refresh-barrier.d.ts +12 -0
  58. package/mcp-server/dist/services/tool-list-refresh-barrier.d.ts.map +1 -0
  59. package/mcp-server/dist/services/tool-list-refresh-barrier.js +40 -0
  60. package/mcp-server/dist/services/tool-list-refresh-barrier.js.map +1 -0
  61. package/mcp-server/dist/services/tool-list.d.ts +108 -0
  62. package/mcp-server/dist/services/tool-list.d.ts.map +1 -0
  63. package/mcp-server/dist/services/tool-list.js +334 -0
  64. package/mcp-server/dist/services/tool-list.js.map +1 -0
  65. package/mcp-server/dist/services/tool-runtime.d.ts +161 -0
  66. package/mcp-server/dist/services/tool-runtime.d.ts.map +1 -0
  67. package/mcp-server/dist/services/tool-runtime.js +400 -0
  68. package/mcp-server/dist/services/tool-runtime.js.map +1 -0
  69. package/mcp-server/dist/services/whiteboard-geometry.d.ts +26 -2
  70. package/mcp-server/dist/services/whiteboard-geometry.d.ts.map +1 -1
  71. package/mcp-server/dist/services/whiteboard-geometry.js +91 -8
  72. package/mcp-server/dist/services/whiteboard-geometry.js.map +1 -1
  73. package/mcp-server/dist/tools/agents.d.ts +10 -10
  74. package/mcp-server/dist/tools/agents.d.ts.map +1 -1
  75. package/mcp-server/dist/tools/agents.js +22 -13
  76. package/mcp-server/dist/tools/agents.js.map +1 -1
  77. package/mcp-server/dist/tools/browser-batch.d.ts +3 -3
  78. package/mcp-server/dist/tools/image-tools.d.ts +1 -1
  79. package/mcp-server/dist/tools/image-tools.js +1 -1
  80. package/mcp-server/dist/tools/skill-tools.d.ts +505 -0
  81. package/mcp-server/dist/tools/skill-tools.d.ts.map +1 -0
  82. package/mcp-server/dist/tools/skill-tools.js +639 -0
  83. package/mcp-server/dist/tools/skill-tools.js.map +1 -0
  84. package/mcp-server/dist/tools/skill.d.ts +7 -0
  85. package/mcp-server/dist/tools/skill.d.ts.map +1 -0
  86. package/mcp-server/dist/tools/skill.js +11 -0
  87. package/mcp-server/dist/tools/skill.js.map +1 -0
  88. package/mcp-server/dist/tools/tool-groups.d.ts +68 -0
  89. package/mcp-server/dist/tools/tool-groups.d.ts.map +1 -0
  90. package/mcp-server/dist/tools/tool-groups.js +147 -0
  91. package/mcp-server/dist/tools/tool-groups.js.map +1 -0
  92. package/mcp-server/dist/tools/whiteboard-format.d.ts.map +1 -1
  93. package/mcp-server/dist/tools/whiteboard-format.js +7 -4
  94. package/mcp-server/dist/tools/whiteboard-format.js.map +1 -1
  95. package/mcp-server/dist/tools/whiteboard-tools.d.ts +64 -13
  96. package/mcp-server/dist/tools/whiteboard-tools.d.ts.map +1 -1
  97. package/mcp-server/dist/tools/whiteboard-tools.js +30 -5
  98. package/mcp-server/dist/tools/whiteboard-tools.js.map +1 -1
  99. package/mcp-server/package-lock.json +2 -2
  100. package/mcp-server/package.json +1 -1
  101. package/mcp-server/src/http.ts +75 -12
  102. package/mcp-server/src/index.ts +147 -154
  103. package/mcp-server/src/preload.ts +12 -12
  104. package/mcp-server/src/services/codex-config-heal.ts +80 -29
  105. package/mcp-server/src/services/memory-judge-backfill.ts +7 -1
  106. package/mcp-server/src/services/neural-interface.ts +79 -20
  107. package/mcp-server/src/services/server-instructions.ts +27 -63
  108. package/mcp-server/src/services/tool-catalog.ts +403 -0
  109. package/mcp-server/src/services/tool-list-refresh-barrier.ts +33 -0
  110. package/mcp-server/src/services/tool-list.ts +410 -0
  111. package/mcp-server/src/services/tool-runtime.ts +457 -0
  112. package/mcp-server/src/services/whiteboard-geometry.ts +94 -9
  113. package/mcp-server/src/tools/agents.ts +22 -14
  114. package/mcp-server/src/tools/image-tools.ts +1 -1
  115. package/mcp-server/src/tools/skill-tools.ts +589 -0
  116. package/mcp-server/src/tools/skill.ts +13 -0
  117. package/mcp-server/src/tools/tool-groups.ts +164 -0
  118. package/mcp-server/src/tools/whiteboard-format.ts +9 -3
  119. package/mcp-server/src/tools/whiteboard-tools.ts +39 -5
  120. package/neural-interface/i18n/en.json +3680 -206
  121. package/neural-interface/i18n/pt-BR.json +3628 -157
  122. package/neural-interface/lib/account-usage.js +5 -3
  123. package/neural-interface/lib/app-controls-api.js +161 -0
  124. package/neural-interface/lib/assistant-api.js +148 -35
  125. package/neural-interface/lib/assistant-brains/claude.js +4 -3
  126. package/neural-interface/lib/assistant-brains/codex-browser-policy-hook.mjs +12 -2
  127. package/neural-interface/lib/assistant-brains/codex-route-gate-hook.mjs +32 -9
  128. package/neural-interface/lib/assistant-brains/codex.js +9 -5
  129. package/neural-interface/lib/assistant-brains/opencode.js +122 -44
  130. package/neural-interface/lib/assistant-brains/opencode2-browser-policy/index.js +59 -0
  131. package/neural-interface/lib/assistant-brains/opencode2-route-gate/index.js +97 -0
  132. package/neural-interface/lib/assistant-catalog.js +23 -9
  133. package/neural-interface/lib/assistant-dispatch.js +874 -156
  134. package/neural-interface/lib/assistant-envelope.js +22 -2
  135. package/neural-interface/lib/assistant-persona.js +80 -11
  136. package/neural-interface/lib/assistant-plan-permissions.js +10 -9
  137. package/neural-interface/lib/assistant-route-gate-codex.js +3 -0
  138. package/neural-interface/lib/assistant-route-gate.js +6 -4
  139. package/neural-interface/lib/assistant-router.js +13 -8
  140. package/neural-interface/lib/assistant-runtime.js +183 -26
  141. package/neural-interface/lib/assistant-task-prompt.js +78 -14
  142. package/neural-interface/lib/assistant-tools.js +51 -0
  143. package/neural-interface/lib/backup-service.js +620 -3
  144. package/neural-interface/lib/backup-zip-reader.js +10 -5
  145. package/neural-interface/lib/backup-zip-writer.js +257 -0
  146. package/neural-interface/lib/browser-execution.js +10 -2
  147. package/neural-interface/lib/browser-guard-cdp.js +83 -0
  148. package/neural-interface/lib/browser-network-guard.js +284 -0
  149. package/neural-interface/lib/browser-policy-roots.js +64 -0
  150. package/neural-interface/lib/browser-tool-policy.js +186 -31
  151. package/neural-interface/lib/claude-agent-bridge.js +4 -2
  152. package/neural-interface/lib/claude-hooks-status.js +103 -0
  153. package/neural-interface/lib/claude-model-catalog.js +64 -14
  154. package/neural-interface/lib/claude-temporary.js +5 -11
  155. package/neural-interface/lib/cli-install.js +18 -138
  156. package/neural-interface/lib/cli-resolver.js +4 -1
  157. package/neural-interface/lib/cli-update-planner.js +32 -31
  158. package/neural-interface/lib/cloudflared/tunnel.js +42 -2
  159. package/neural-interface/lib/codex-mcp-approvals.js +11 -0
  160. package/neural-interface/lib/codex-settings-schema.js +109 -47
  161. package/neural-interface/lib/codex-worker-app-server.js +172 -0
  162. package/neural-interface/lib/confined-fs.js +30 -3
  163. package/neural-interface/lib/crash-notice-api.js +98 -0
  164. package/neural-interface/lib/editor-completion-opencode.js +164 -67
  165. package/neural-interface/lib/exec-loop-command.js +4 -1
  166. package/neural-interface/lib/http-guards.js +8 -2
  167. package/neural-interface/lib/install-details.js +4 -1
  168. package/neural-interface/lib/launch-cache.js +293 -0
  169. package/neural-interface/lib/login-start.js +524 -0
  170. package/neural-interface/lib/mcp-agent-servers.js +67 -0
  171. package/neural-interface/lib/mcp-client-config.js +0 -29
  172. package/neural-interface/lib/mcp-external-servers.js +323 -0
  173. package/neural-interface/lib/{mcp-profile-refresh-coordinator.js → mcp-tools-refresh-coordinator.js} +4 -4
  174. package/neural-interface/lib/morelogin.js +30 -0
  175. package/neural-interface/lib/native-loop-providers.js +565 -50
  176. package/neural-interface/lib/native-loop-runtime.js +287 -41
  177. package/neural-interface/lib/opencode-config.js +557 -0
  178. package/neural-interface/lib/opencode-db-schema.js +58 -0
  179. package/neural-interface/lib/opencode-history.js +49 -204
  180. package/neural-interface/lib/opencode-mcp-ready.js +108 -0
  181. package/neural-interface/lib/opencode-native-boundary.js +44 -0
  182. package/neural-interface/lib/opencode-protocol.js +310 -0
  183. package/neural-interface/lib/opencode-provider-view.js +81 -0
  184. package/neural-interface/lib/opencode-runtime-config.js +32 -15
  185. package/neural-interface/lib/opencode-serve-records.js +624 -0
  186. package/neural-interface/lib/opencode-v2-client.js +53 -131
  187. package/neural-interface/lib/opencode-v2-ws-requests.js +35 -195
  188. package/neural-interface/lib/opencode-worker-activity.js +229 -0
  189. package/neural-interface/lib/opencode-worker-data.js +27 -0
  190. package/neural-interface/lib/opencode2-client.js +796 -0
  191. package/neural-interface/lib/opencode2-proxy.js +76 -0
  192. package/neural-interface/lib/opencode2-translate.js +1057 -0
  193. package/neural-interface/lib/owner-authority.js +249 -0
  194. package/neural-interface/lib/page-session.js +275 -0
  195. package/neural-interface/lib/peer-identity.js +763 -0
  196. package/neural-interface/lib/process-identity.js +361 -0
  197. package/neural-interface/lib/request-gate.js +17 -2
  198. package/neural-interface/lib/rulesets/api.js +1 -1
  199. package/neural-interface/lib/rulesets/fs-safe.js +1 -1
  200. package/neural-interface/lib/rulesets/installer.js +92 -27
  201. package/neural-interface/lib/rulesets/json-edit.js +1 -1
  202. package/neural-interface/lib/session-cache-builder.js +18 -10
  203. package/neural-interface/lib/session-title-generator.js +58 -18
  204. package/neural-interface/lib/skills/api-v2.js +495 -0
  205. package/neural-interface/lib/skills/bundle.js +418 -0
  206. package/neural-interface/lib/skills/catalog.js +294 -0
  207. package/neural-interface/lib/skills/creation-api.js +191 -0
  208. package/neural-interface/lib/skills/creation-brief.js +247 -0
  209. package/neural-interface/lib/skills/creation-sources.js +267 -0
  210. package/neural-interface/lib/skills/creation.js +843 -0
  211. package/neural-interface/lib/skills/deploy.js +564 -0
  212. package/neural-interface/lib/skills/digest.js +119 -0
  213. package/neural-interface/lib/skills/discover.js +111 -0
  214. package/neural-interface/lib/skills/draft-confinement.js +214 -0
  215. package/neural-interface/lib/skills/eval-confinement.js +397 -0
  216. package/neural-interface/lib/skills/eval-sandbox.js +280 -0
  217. package/neural-interface/lib/skills/eval-trace.js +119 -0
  218. package/neural-interface/lib/skills/evals-api.js +212 -0
  219. package/neural-interface/lib/skills/evals.js +1573 -0
  220. package/neural-interface/lib/skills/export.js +200 -0
  221. package/neural-interface/lib/skills/frontmatter.js +64 -0
  222. package/neural-interface/lib/skills/health.js +75 -0
  223. package/neural-interface/lib/skills/json-edit.js +165 -0
  224. package/neural-interface/lib/skills/known-bridge-digests.json +387 -0
  225. package/neural-interface/lib/skills/known-bridges.js +96 -0
  226. package/neural-interface/lib/skills/library.js +823 -0
  227. package/neural-interface/lib/skills/local-store.js +21 -0
  228. package/neural-interface/lib/skills/migration.js +433 -0
  229. package/neural-interface/lib/skills/operations.js +45 -0
  230. package/neural-interface/lib/skills/ownership.js +427 -0
  231. package/neural-interface/lib/skills/packages.js +88 -0
  232. package/neural-interface/lib/skills/reviews.js +212 -0
  233. package/neural-interface/lib/skills/revision.js +80 -0
  234. package/neural-interface/lib/skills/roots.js +262 -0
  235. package/neural-interface/lib/skills/runtime-checks.js +355 -0
  236. package/neural-interface/lib/skills/scan-assets.js +252 -0
  237. package/neural-interface/lib/skills/scan-context.js +26 -0
  238. package/neural-interface/lib/skills/scan-shell.js +324 -0
  239. package/neural-interface/lib/skills/scan.js +364 -0
  240. package/neural-interface/lib/skills/scanners.js +54 -0
  241. package/neural-interface/lib/skills/service.js +522 -0
  242. package/neural-interface/lib/skills/telemetry.js +113 -0
  243. package/neural-interface/lib/sqlite-integrity-worker.js +22 -0
  244. package/neural-interface/lib/style-guide/api.js +4 -3
  245. package/neural-interface/lib/tool-lists.js +124 -0
  246. package/neural-interface/lib/untrusted-file-headers.js +27 -0
  247. package/neural-interface/lib/whatsapp/bridge.js +6 -3
  248. package/neural-interface/lib/worker-confinement.js +1192 -0
  249. package/neural-interface/lib/worker-guard-setting.js +56 -0
  250. package/neural-interface/lib/worker-mcp-channel.js +175 -0
  251. package/neural-interface/lib/worker-relay-ports.js +227 -0
  252. package/neural-interface/lib/worker-resume.js +229 -0
  253. package/neural-interface/lib/worker-sandbox.js +299 -0
  254. package/neural-interface/package-lock.json +1354 -50
  255. package/neural-interface/package.json +6 -2
  256. package/neural-interface/public/index.html +5 -3
  257. package/neural-interface/public/index2d.html +19 -11
  258. package/neural-interface/public/onboarding.html +2 -2
  259. package/neural-interface/public/shared/account-menu.js +8 -5
  260. package/neural-interface/public/shared/agent-runtime-options.js +76 -16
  261. package/neural-interface/public/shared/api.js +1527 -1336
  262. package/neural-interface/public/shared/app-frame.js +192 -0
  263. package/neural-interface/public/shared/assistant/asst-agents-dock.js +205 -19
  264. package/neural-interface/public/shared/assistant/asst-api.js +11 -3
  265. package/neural-interface/public/shared/assistant/asst-ask-styles.js +270 -0
  266. package/neural-interface/public/shared/assistant/asst-ask-tail.js +118 -0
  267. package/neural-interface/public/shared/assistant/asst-ask.js +397 -0
  268. package/neural-interface/public/shared/assistant/asst-brain-picker.js +241 -112
  269. package/neural-interface/public/shared/assistant/asst-composer.js +1 -1
  270. package/neural-interface/public/shared/assistant/asst-control.js +157 -26
  271. package/neural-interface/public/shared/assistant/asst-followups-card.js +383 -0
  272. package/neural-interface/public/shared/assistant/asst-followups.js +417 -0
  273. package/neural-interface/public/shared/assistant/asst-hosts.js +49 -2
  274. package/neural-interface/public/shared/assistant/asst-limit-dock.js +40 -0
  275. package/neural-interface/public/shared/assistant/asst-limit-wait.js +294 -0
  276. package/neural-interface/public/shared/assistant/asst-limit.js +168 -0
  277. package/neural-interface/public/shared/assistant/asst-mascot.js +49 -12
  278. package/neural-interface/public/shared/assistant/asst-menu.js +84 -12
  279. package/neural-interface/public/shared/assistant/asst-panel.js +303 -44
  280. package/neural-interface/public/shared/assistant/asst-rack-styles.js +93 -58
  281. package/neural-interface/public/shared/assistant/asst-redact.js +186 -0
  282. package/neural-interface/public/shared/assistant/asst-render.js +770 -100
  283. package/neural-interface/public/shared/assistant/asst-route.js +83 -12
  284. package/neural-interface/public/shared/assistant/asst-run-stage.js +231 -0
  285. package/neural-interface/public/shared/assistant/asst-sanitize.js +193 -3
  286. package/neural-interface/public/shared/assistant/asst-scene-styles.js +273 -0
  287. package/neural-interface/public/shared/assistant/asst-scenes.js +530 -0
  288. package/neural-interface/public/shared/assistant/asst-sidepanel-styles.js +3 -15
  289. package/neural-interface/public/shared/assistant/asst-sidepanel.js +67 -4
  290. package/neural-interface/public/shared/assistant/asst-slash.js +9 -7
  291. package/neural-interface/public/shared/assistant/asst-state.js +25 -15
  292. package/neural-interface/public/shared/assistant/asst-stop.js +127 -0
  293. package/neural-interface/public/shared/assistant/asst-styles.js +102 -21
  294. package/neural-interface/public/shared/assistant/asst-tool-kinds.js +165 -13
  295. package/neural-interface/public/shared/automation-context.js +5 -2
  296. package/neural-interface/public/shared/cc-dropdown.js +550 -0
  297. package/neural-interface/public/shared/cdx/cdx-context-menu.js +10 -9
  298. package/neural-interface/public/shared/cdx/cdx-copy.js +16 -0
  299. package/neural-interface/public/shared/cdx/cdx-output-model.js +22 -1
  300. package/neural-interface/public/shared/cdx/cdx-output.js +8 -7
  301. package/neural-interface/public/shared/cdx/cdx-panel.js +58 -150
  302. package/neural-interface/public/shared/cdx/cdx-protocol.js +28 -1
  303. package/neural-interface/public/shared/cdx/cdx-render.js +62 -32
  304. package/neural-interface/public/shared/cdx/cdx-requests.js +3 -3
  305. package/neural-interface/public/shared/cdx/cdx-skill-hints.js +54 -0
  306. package/neural-interface/public/shared/cdx/cdx-styles.js +15 -3
  307. package/neural-interface/public/shared/cdx/cdx-tabs.js +201 -74
  308. package/neural-interface/public/shared/cdx/cdx-ws.js +0 -1
  309. package/neural-interface/public/shared/cli-install-view.js +4 -8
  310. package/neural-interface/public/shared/cli-status.js +2 -2
  311. package/neural-interface/public/shared/constants.js +2 -2
  312. package/neural-interface/public/shared/context-menu-areas.js +34 -0
  313. package/neural-interface/public/shared/context-menu-logic.js +243 -0
  314. package/neural-interface/public/shared/context-menu-model.js +366 -0
  315. package/neural-interface/public/shared/context-menu.js +372 -0
  316. package/neural-interface/public/shared/cp/cp-context-menu.js +10 -9
  317. package/neural-interface/public/shared/cp/cp-markdown.js +4 -57
  318. package/neural-interface/public/shared/crash-notice-view.js +168 -0
  319. package/neural-interface/public/shared/data-cache.js +223 -0
  320. package/neural-interface/public/shared/desktop-bridge.js +11 -0
  321. package/neural-interface/public/shared/desktop-titlebar-view.js +78 -1
  322. package/neural-interface/public/shared/desktop-titlebar.js +214 -28
  323. package/neural-interface/public/shared/desktop-update-view.js +35 -5
  324. package/neural-interface/public/shared/editor/editor-panel-logic.js +2 -2
  325. package/neural-interface/public/shared/file-links.js +73 -8
  326. package/neural-interface/public/shared/html-shell.js +78 -86
  327. package/neural-interface/public/shared/i18n.js +2 -0
  328. package/neural-interface/public/shared/launch-prefetch.js +59 -0
  329. package/neural-interface/public/shared/ocp-v2/ocp-v2-approvals.js +7 -7
  330. package/neural-interface/public/shared/ocp-v2/ocp-v2-binding.js +4 -4
  331. package/neural-interface/public/shared/ocp-v2/ocp-v2-caps.js +3 -2
  332. package/neural-interface/public/shared/ocp-v2/ocp-v2-changes-logic.js +3 -101
  333. package/neural-interface/public/shared/ocp-v2/ocp-v2-childpanel.js +9 -2
  334. package/neural-interface/public/shared/ocp-v2/ocp-v2-compact-button.js +1 -3
  335. package/neural-interface/public/shared/ocp-v2/ocp-v2-composer-logic.js +2 -6
  336. package/neural-interface/public/shared/ocp-v2/ocp-v2-context-menu.js +11 -11
  337. package/neural-interface/public/shared/ocp-v2/ocp-v2-context-model.js +0 -3
  338. package/neural-interface/public/shared/ocp-v2/ocp-v2-events.js +8 -4
  339. package/neural-interface/public/shared/ocp-v2/ocp-v2-manager.js +7 -7
  340. package/neural-interface/public/shared/ocp-v2/ocp-v2-modelpicker.js +54 -17
  341. package/neural-interface/public/shared/ocp-v2/ocp-v2-outcome-notifications.js +16 -0
  342. package/neural-interface/public/shared/ocp-v2/ocp-v2-panel.js +140 -254
  343. package/neural-interface/public/shared/ocp-v2/ocp-v2-plan.js +1 -2
  344. package/neural-interface/public/shared/ocp-v2/ocp-v2-projectbar.js +97 -203
  345. package/neural-interface/public/shared/ocp-v2/ocp-v2-providers.js +11 -9
  346. package/neural-interface/public/shared/ocp-v2/ocp-v2-rehydrate.js +15 -4
  347. package/neural-interface/public/shared/ocp-v2/ocp-v2-render.js +7 -22
  348. package/neural-interface/public/shared/ocp-v2/ocp-v2-send-logic.js +401 -0
  349. package/neural-interface/public/shared/ocp-v2/ocp-v2-send.js +20 -13
  350. package/neural-interface/public/shared/ocp-v2/ocp-v2-session-actions.js +8 -61
  351. package/neural-interface/public/shared/ocp-v2/ocp-v2-sessions-logic.js +53 -82
  352. package/neural-interface/public/shared/ocp-v2/ocp-v2-slash-hints.js +16 -15
  353. package/neural-interface/public/shared/ocp-v2/ocp-v2-state.js +8 -21
  354. package/neural-interface/public/shared/ocp-v2/ocp-v2-status-logic.js +1 -99
  355. package/neural-interface/public/shared/ocp-v2/ocp-v2-status.js +5 -35
  356. package/neural-interface/public/shared/ocp-v2/ocp-v2-styles.js +48 -40
  357. package/neural-interface/public/shared/ocp-v2/{ocp-v2-profile-inheritance.js → ocp-v2-tools-inheritance.js} +16 -16
  358. package/neural-interface/public/shared/ocp-v2/ocp-v2-ws.js +205 -62
  359. package/neural-interface/public/shared/opencode-providers.js +39 -0
  360. package/neural-interface/public/shared/page-session.js +96 -0
  361. package/neural-interface/public/shared/registry.js +5 -3
  362. package/neural-interface/public/shared/retired-2d.js +3 -0
  363. package/neural-interface/public/shared/schedules-view.js +452 -0
  364. package/neural-interface/public/shared/settings/settings-app-pane.js +335 -0
  365. package/neural-interface/public/shared/settings/settings-app.js +243 -0
  366. package/neural-interface/public/shared/settings/settings-claude-hooks.js +135 -0
  367. package/neural-interface/public/shared/settings/settings-data.js +90 -0
  368. package/neural-interface/public/shared/settings/settings-ia.js +23 -6
  369. package/neural-interface/public/shared/settings/settings-opencode.js +89 -0
  370. package/neural-interface/public/shared/settings/settings-skill-folders-pane.js +265 -0
  371. package/neural-interface/public/shared/settings/settings-skill-folders.js +130 -0
  372. package/neural-interface/public/shared/settings/settings-worker-guard.js +72 -0
  373. package/neural-interface/public/shared/sidepanel-session-status.js +49 -0
  374. package/neural-interface/public/shared/skills/ss-args.js +96 -0
  375. package/neural-interface/public/shared/skills/ss-creation.js +219 -0
  376. package/neural-interface/public/shared/skills/ss-dialog.js +130 -0
  377. package/neural-interface/public/shared/skills/ss-doc.js +173 -0
  378. package/neural-interface/public/shared/skills/ss-eval-adapters.js +269 -0
  379. package/neural-interface/public/shared/skills/ss-eval-grade.js +359 -0
  380. package/neural-interface/public/shared/skills/ss-eval-optimise.js +153 -0
  381. package/neural-interface/public/shared/skills/ss-eval-plan.js +315 -0
  382. package/neural-interface/public/shared/skills/ss-evals.js +417 -0
  383. package/neural-interface/public/shared/skills/ss-form.js +159 -0
  384. package/neural-interface/public/shared/skills/ss-frontmatter.js +376 -0
  385. package/neural-interface/public/shared/skills/ss-ids.js +32 -0
  386. package/neural-interface/public/shared/skills/ss-lint.js +141 -0
  387. package/neural-interface/public/shared/skills/ss-presets.js +117 -0
  388. package/neural-interface/public/shared/skills/ss-profiles.js +475 -0
  389. package/neural-interface/public/shared/skills/ss-resources.js +165 -0
  390. package/neural-interface/public/shared/skills/ss-review-view.js +190 -0
  391. package/neural-interface/public/shared/skills/ss-tabs.js +79 -0
  392. package/neural-interface/public/shared/skills/ss-unicode.js +135 -0
  393. package/neural-interface/public/shared/skills/studio/sx-actions.js +222 -0
  394. package/neural-interface/public/shared/skills/studio/sx-cm.js +101 -0
  395. package/neural-interface/public/shared/skills/studio/sx-create-ai-view.js +749 -0
  396. package/neural-interface/public/shared/skills/studio/sx-create-ai.js +236 -0
  397. package/neural-interface/public/shared/skills/studio/sx-create-view.js +254 -0
  398. package/neural-interface/public/shared/skills/studio/sx-create.js +126 -0
  399. package/neural-interface/public/shared/skills/studio/sx-diff-view.js +43 -0
  400. package/neural-interface/public/shared/skills/studio/sx-diff.js +133 -0
  401. package/neural-interface/public/shared/skills/studio/sx-docs.js +480 -0
  402. package/neural-interface/public/shared/skills/studio/sx-dom.js +229 -0
  403. package/neural-interface/public/shared/skills/studio/sx-edit-view.js +848 -0
  404. package/neural-interface/public/shared/skills/studio/sx-editor-model.js +193 -0
  405. package/neural-interface/public/shared/skills/studio/sx-errors.js +22 -0
  406. package/neural-interface/public/shared/skills/studio/sx-geometry.js +82 -0
  407. package/neural-interface/public/shared/skills/studio/sx-import.js +262 -0
  408. package/neural-interface/public/shared/skills/studio/sx-inspector.js +308 -0
  409. package/neural-interface/public/shared/skills/studio/sx-install-flow.js +279 -0
  410. package/neural-interface/public/shared/skills/studio/sx-install.js +296 -0
  411. package/neural-interface/public/shared/skills/studio/sx-library-view.js +639 -0
  412. package/neural-interface/public/shared/skills/studio/sx-library.js +475 -0
  413. package/neural-interface/public/shared/skills/studio/sx-main.js +681 -0
  414. package/neural-interface/public/shared/skills/studio/sx-operations-view.js +98 -0
  415. package/neural-interface/public/shared/skills/studio/sx-operations.js +11 -0
  416. package/neural-interface/public/shared/skills/studio/sx-plan.js +158 -0
  417. package/neural-interface/public/shared/skills/studio/sx-publish-view.js +621 -0
  418. package/neural-interface/public/shared/skills/studio/sx-review-view.js +369 -0
  419. package/neural-interface/public/shared/skills/studio/sx-review.js +148 -0
  420. package/neural-interface/public/shared/skills/studio/sx-scan.js +35 -0
  421. package/neural-interface/public/shared/skills/studio/sx-snippets.js +96 -0
  422. package/neural-interface/public/shared/skills/studio/sx-subject.js +248 -0
  423. package/neural-interface/public/shared/skills/studio/sx-test-view.js +994 -0
  424. package/neural-interface/public/shared/skills/studio/sx-test.js +328 -0
  425. package/neural-interface/public/shared/skills/studio/sx-versions-view.js +241 -0
  426. package/neural-interface/public/shared/skills/studio/sx-workspace-view.js +425 -0
  427. package/neural-interface/public/shared/styleguide/sg-panel.js +4 -2
  428. package/neural-interface/public/shared/styles.css +2065 -2150
  429. package/neural-interface/public/shared/synabun-mascot.js +1115 -9
  430. package/neural-interface/public/shared/tool-list-picker.js +55 -0
  431. package/neural-interface/public/shared/tool-list-storage.js +24 -0
  432. package/neural-interface/public/shared/tool-list-view.js +112 -0
  433. package/neural-interface/public/shared/tour/tour-actor.js +268 -0
  434. package/neural-interface/public/shared/tour/tour-beats.js +336 -0
  435. package/neural-interface/public/shared/tour/tour-engine.js +884 -0
  436. package/neural-interface/public/shared/tour/tour-ink.js +390 -0
  437. package/neural-interface/public/shared/tour/tour-stage.js +440 -0
  438. package/neural-interface/public/shared/tour/tour-state.js +40 -0
  439. package/neural-interface/public/shared/tour/tour-tips.js +99 -0
  440. package/neural-interface/public/shared/tour/tour.css +144 -0
  441. package/neural-interface/public/shared/ui-assistant.js +27 -5
  442. package/neural-interface/public/shared/ui-automation-studio.js +155 -152
  443. package/neural-interface/public/shared/ui-bookmarks.js +2 -1
  444. package/neural-interface/public/shared/ui-claude-panel.js +153 -13
  445. package/neural-interface/public/shared/ui-codex-panel.js +1 -0
  446. package/neural-interface/public/shared/ui-command-runner.js +6 -3
  447. package/neural-interface/public/shared/ui-context-menu.js +295 -0
  448. package/neural-interface/public/shared/ui-cost-widget.js +57 -59
  449. package/neural-interface/public/shared/ui-crash-notice.js +187 -0
  450. package/neural-interface/public/shared/ui-detail.js +21 -9
  451. package/neural-interface/public/shared/ui-file-links.js +1 -0
  452. package/neural-interface/public/shared/ui-image-gallery.js +56 -52
  453. package/neural-interface/public/shared/ui-invite.js +18 -2
  454. package/neural-interface/public/shared/ui-keybinds.js +26 -1
  455. package/neural-interface/public/shared/ui-link.js +9 -9
  456. package/neural-interface/public/shared/ui-menubar.js +229 -40
  457. package/neural-interface/public/shared/ui-native-loop-router-state.js +5 -0
  458. package/neural-interface/public/shared/ui-native-loop-router.js +9 -1
  459. package/neural-interface/public/shared/ui-navbar.js +4 -24
  460. package/neural-interface/public/shared/ui-opencode-panel-v2.js +1 -0
  461. package/neural-interface/public/shared/ui-panels.js +96 -65
  462. package/neural-interface/public/shared/ui-schedules-studio.js +2267 -953
  463. package/neural-interface/public/shared/ui-sessions.js +20 -7
  464. package/neural-interface/public/shared/ui-settings.js +679 -496
  465. package/neural-interface/public/shared/ui-sidebar.js +4 -4
  466. package/neural-interface/public/shared/ui-sidepanel-session-entry.js +13 -0
  467. package/neural-interface/public/shared/ui-sidepanel-sessions.js +56 -5
  468. package/neural-interface/public/shared/ui-sidepanel-state.js +23 -12
  469. package/neural-interface/public/shared/ui-sidepanel-tray.js +84 -8
  470. package/neural-interface/public/shared/ui-sidepanel-windows.js +16 -11
  471. package/neural-interface/public/shared/ui-skills.js +42 -2781
  472. package/neural-interface/public/shared/ui-styleguide.js +5 -2
  473. package/neural-interface/public/shared/ui-sync.js +22 -5
  474. package/neural-interface/public/shared/ui-terminal.js +159 -199
  475. package/neural-interface/public/shared/ui-tool-updates.js +3 -1
  476. package/neural-interface/public/shared/ui-tooltip.js +10 -5
  477. package/neural-interface/public/shared/ui-trash.js +14 -5
  478. package/neural-interface/public/shared/ui-tutorial-layout.js +3 -117
  479. package/neural-interface/public/shared/ui-tutorial-preview.js +103 -0
  480. package/neural-interface/public/shared/ui-tutorial-steps.js +3 -61
  481. package/neural-interface/public/shared/ui-tutorial.css +47 -100
  482. package/neural-interface/public/shared/ui-tutorial.js +285 -499
  483. package/neural-interface/public/shared/ui-update.js +121 -16
  484. package/neural-interface/public/shared/ui-whiteboard.js +313 -59
  485. package/neural-interface/public/shared/ui-worker-end.js +4 -0
  486. package/neural-interface/public/shared/ui-workspaces.js +3 -2
  487. package/neural-interface/public/shared/view-variant.js +66 -0
  488. package/neural-interface/public/shared/whatsapp/wa-view.js +1 -1
  489. package/neural-interface/public/shared/whiteboard-list.js +172 -0
  490. package/neural-interface/public/shared/worker-end.js +10 -3
  491. package/neural-interface/public/shared/worker-restart.js +12 -0
  492. package/neural-interface/public/sidepanel-session.html +1 -1
  493. package/neural-interface/public/variant/2d/background.js +2 -1
  494. package/neural-interface/public/variant/2d/context-menu.js +8 -2
  495. package/neural-interface/public/variant/2d/graph.js +42 -20
  496. package/neural-interface/public/variant/2d/hulls.js +14 -9
  497. package/neural-interface/public/variant/2d/lasso.js +11 -7
  498. package/neural-interface/public/variant/2d/main.js +36 -2
  499. package/neural-interface/public/variant/2d/minimap.js +11 -13
  500. package/neural-interface/public/variant/3d/main.js +72 -6
  501. package/neural-interface/public/variant/3d/map-controls.js +24 -9
  502. package/neural-interface/public/vendor/caveat/OFL.txt +93 -0
  503. package/neural-interface/public/vendor/caveat/caveat-latin-400-normal.woff2 +0 -0
  504. package/neural-interface/public/vendor/caveat/caveat-latin-700-normal.woff2 +0 -0
  505. package/neural-interface/public/vendor/caveat/caveat.css +17 -0
  506. package/neural-interface/public/vendor/caveat/manifest.json +12 -0
  507. package/neural-interface/public/vendor/highlight/LICENSE +29 -0
  508. package/neural-interface/public/vendor/highlight/github-dark-dimmed-11.12.0.min.css +9 -0
  509. package/neural-interface/public/vendor/highlight/highlight-11.12.0.min.js +1262 -0
  510. package/neural-interface/public/vendor/highlight/manifest.json +5 -0
  511. package/neural-interface/public/vendor/html2canvas/LICENSE +22 -0
  512. package/neural-interface/public/vendor/html2canvas/html2canvas-1.4.1.min.js +20 -0
  513. package/neural-interface/public/vendor/html2canvas/manifest.json +4 -0
  514. package/neural-interface/public/vendor/marked/LICENSE.md +44 -0
  515. package/neural-interface/public/vendor/marked/manifest.json +4 -0
  516. package/neural-interface/public/vendor/marked/marked-14.1.4.esm.js +2502 -0
  517. package/neural-interface/public/vendor/mermaid/LICENSE +21 -0
  518. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/abnfDiagram-PAR5IXJI.mjs +1 -0
  519. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/architecture-7GRP2DOG-M7G3SWCO.mjs +1 -0
  520. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/architectureDiagram-2PNWDENW.mjs +36 -0
  521. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/blockDiagram-PUWGUBOA.mjs +129 -0
  522. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/c4Diagram-3NLNHZP5.mjs +38 -0
  523. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-2NMSUPJH.mjs +1 -0
  524. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-32MCUW2P.mjs +206 -0
  525. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-3NPNU5GP.mjs +1 -0
  526. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-3SMGFRGC.mjs +1 -0
  527. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-4CAJECRU.mjs +14 -0
  528. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-4OADUZ5Q.mjs +10 -0
  529. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-5IMINLNL.mjs +1 -0
  530. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-5IQCK5RY.mjs +3 -0
  531. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-5MVFYWFU.mjs +1 -0
  532. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-AQ6EADP3.mjs +1 -0
  533. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-AZZRMDJM.mjs +15 -0
  534. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-CLS4B6BI.mjs +168 -0
  535. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-DZP67EKU.mjs +70 -0
  536. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-EICP7K5X.mjs +1 -0
  537. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-GDY2UAB4.mjs +1 -0
  538. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-H7VHZCWX.mjs +1 -0
  539. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-IJBDOHL6.mjs +1 -0
  540. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-JFFVMJIA.mjs +1 -0
  541. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-JQRUD6KW.mjs +1 -0
  542. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-JZGDI5JK.mjs +1 -0
  543. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-KD6SPIPN.mjs +2 -0
  544. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-NF366YI6.mjs +231 -0
  545. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-NUDPKBEF.mjs +32 -0
  546. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-OJINMHTS.mjs +1 -0
  547. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-Q6NGPIAH.mjs +2 -0
  548. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-QJSWEUOL.mjs +132 -0
  549. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-R7JDMUKV.mjs +1 -0
  550. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-RCXAM2GK.mjs +1 -0
  551. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-RT4MAWR3.mjs +1 -0
  552. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-SFMINX4W.mjs +1 -0
  553. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-SLDQ463B.mjs +88 -0
  554. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-STOV2HOB.mjs +1 -0
  555. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-T5OCTHI4.mjs +1 -0
  556. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-TCEHX7R3.mjs +1 -0
  557. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-VQC2EELJ.mjs +1 -0
  558. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-VRZKL3EH.mjs +1 -0
  559. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-VTHDQ7BV.mjs +1 -0
  560. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-VY2OSTJR.mjs +2 -0
  561. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-WUBWJARI.mjs +1 -0
  562. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-YBMQ5JGJ.mjs +2 -0
  563. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-YDMLL4PJ.mjs +1 -0
  564. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-Z6V44ARX.mjs +62 -0
  565. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZJJ7VQJP.mjs +339 -0
  566. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZNLK7HRR.mjs +1 -0
  567. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZQN7UHIL.mjs +1 -0
  568. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZS6VBONO.mjs +174 -0
  569. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZUNWM646.mjs +1 -0
  570. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/classDiagram-FGAMPOII.mjs +1 -0
  571. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/classDiagram-v2-AI5RJEK4.mjs +1 -0
  572. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/cose-bilkent-Q72C2OJ3.mjs +1 -0
  573. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/cynefin-OW5HDTMX-6OCTWOGG.mjs +1 -0
  574. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/cynefinDiagram-2OOWUY4M.mjs +62 -0
  575. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/dagre-MPVFI544.mjs +4 -0
  576. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-AE4NWXFW.mjs +24 -0
  577. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-BUJID5UG.mjs +41 -0
  578. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-C44CZ5NI.mjs +24 -0
  579. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-EYOLEXXS.mjs +30 -0
  580. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-P7B6PWOJ.mjs +3 -0
  581. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/ebnfDiagram-FTPZ3PV6.mjs +1 -0
  582. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/erDiagram-H3ERR26V.mjs +99 -0
  583. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/eventmodeling-NTZA5JFV-WKSWQHFS.mjs +1 -0
  584. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/flowDiagram-YHGXBVSY.mjs +1 -0
  585. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/ganttDiagram-RWFTB7ED.mjs +292 -0
  586. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/gitGraph-4MIJSDKK-JH2HKYUO.mjs +1 -0
  587. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/gitGraphDiagram-MAR6GKOP.mjs +106 -0
  588. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/info-A6RAGUB7-3TX3OFWW.mjs +1 -0
  589. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/infoDiagram-LV547AFH.mjs +2 -0
  590. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/ishikawaDiagram-PUJQGNDS.mjs +70 -0
  591. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/journeyDiagram-EW5QJT4W.mjs +139 -0
  592. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/kanban-definition-JSQERAZB.mjs +89 -0
  593. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/katex-CZ4GXH2S.mjs +257 -0
  594. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/mindmap-definition-VBJCLQLM.mjs +96 -0
  595. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/packet-AYTQ26CC-MKII6P3Y.mjs +1 -0
  596. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/pegDiagram-7WILOQTJ.mjs +1 -0
  597. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/pie-WAS4IAKB-6B4OPMJ5.mjs +1 -0
  598. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/pieDiagram-EFA7CBSB.mjs +39 -0
  599. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/quadrantDiagram-WARVYA7P.mjs +7 -0
  600. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/radar-RG4KPBEZ-UPTR3XUL.mjs +1 -0
  601. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroad-74A4TZTK-MEFUPFMS.mjs +1 -0
  602. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroad-abnf-HS5TGJTU-R5YG2S5D.mjs +1 -0
  603. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroad-ebnf-LZEXJU2U-G5QEX2L6.mjs +1 -0
  604. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroad-peg-WCYAUIDC-H5I2ZRY2.mjs +1 -0
  605. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroadDiagram-5NIQVNLQ.mjs +1 -0
  606. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/requirementDiagram-SXREGOKZ.mjs +84 -0
  607. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/sankeyDiagram-VV74M2VP.mjs +40 -0
  608. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/sequenceDiagram-52ZFIFDL.mjs +162 -0
  609. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/sizeCapture-FGA5AGYP.mjs +1 -0
  610. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/stateDiagram-3QAKPIVI.mjs +1 -0
  611. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/stateDiagram-v2-HN2P4RDZ.mjs +1 -0
  612. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/swimlanes-QLVP42QD.mjs +1 -0
  613. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/swimlanesDiagram-JKPDBFCN.mjs +8 -0
  614. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/timeline-definition-GS45XAXW.mjs +120 -0
  615. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/treeView-Q6P3EWNA-ZRJGANNQ.mjs +1 -0
  616. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/treemap-WGGIJYW6-K64VN5AS.mjs +1 -0
  617. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/vennDiagram-QIQU2ZRJ.mjs +34 -0
  618. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/wardley-WFR3VGLG-D67OWCCH.mjs +1 -0
  619. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/wardleyDiagram-U6YNM66N.mjs +78 -0
  620. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/xychartDiagram-XJAZEDNM.mjs +7 -0
  621. package/neural-interface/public/vendor/mermaid/manifest.json +4 -0
  622. package/neural-interface/public/vendor/mermaid/mermaid-11.17.2.esm.min.mjs +14 -0
  623. package/neural-interface/public/vendor/yaml/LICENSE +13 -0
  624. package/neural-interface/public/vendor/yaml/manifest.json +4 -0
  625. package/neural-interface/public/vendor/yaml/yaml-2.9.1.min.js +137 -0
  626. package/neural-interface/scripts/build-vendor.mjs +116 -3
  627. package/neural-interface/server.js +4834 -2541
  628. package/neural-interface/templates/rulesets/core.md +1 -1
  629. package/neural-interface/templates/rulesets/legacy-hashes.json +18 -0
  630. package/neural-interface/templates/rulesets/manifest.json +8 -8
  631. package/npm-shrinkwrap.json +18 -12
  632. package/package.json +16 -3
  633. package/postinstall.js +9 -4
  634. package/preuninstall.js +1 -1
  635. package/setup.js +97 -322
  636. package/skills/skill-forge/SKILL.md +177 -0
  637. package/skills/skill-forge/evals/evals.json +54 -0
  638. package/skills/skill-forge/references/package.md +105 -0
  639. package/skills/skill-forge/references/review-and-recovery.md +63 -0
  640. package/skills/skill-forge/references/runtime-profiles.md +20 -0
  641. package/skills/skill-forge/references/sources-and-capabilities.md +51 -0
  642. package/skills/synabun/SKILL.md +10 -7
  643. package/skills/synabun/modules/audit.md +1 -5
  644. package/skills/synabun/modules/changelog.md +1 -5
  645. package/skills/synabun/modules/idea.md +1 -1
  646. package/skills/synabun/modules/memorize.md +6 -9
  647. package/skills/synabun/modules/schedule.md +5 -5
  648. package/mcp-server/dist/services/profiles.d.ts +0 -120
  649. package/mcp-server/dist/services/profiles.d.ts.map +0 -1
  650. package/mcp-server/dist/services/profiles.js +0 -387
  651. package/mcp-server/dist/services/profiles.js.map +0 -1
  652. package/mcp-server/dist/tools/leonardo-browser-tools.d.ts +0 -97
  653. package/mcp-server/dist/tools/leonardo-browser-tools.d.ts.map +0 -1
  654. package/mcp-server/dist/tools/leonardo-browser-tools.js +0 -228
  655. package/mcp-server/dist/tools/leonardo-browser-tools.js.map +0 -1
  656. package/mcp-server/dist/tools/leonardo.d.ts +0 -13
  657. package/mcp-server/dist/tools/leonardo.d.ts.map +0 -1
  658. package/mcp-server/dist/tools/leonardo.js +0 -21
  659. package/mcp-server/dist/tools/leonardo.js.map +0 -1
  660. package/mcp-server/dist/tools/profile.d.ts +0 -17
  661. package/mcp-server/dist/tools/profile.d.ts.map +0 -1
  662. package/mcp-server/dist/tools/profile.js +0 -114
  663. package/mcp-server/dist/tools/profile.js.map +0 -1
  664. package/mcp-server/src/services/profiles.ts +0 -428
  665. package/mcp-server/src/tools/leonardo-browser-tools.ts +0 -291
  666. package/mcp-server/src/tools/leonardo.ts +0 -30
  667. package/mcp-server/src/tools/profile.ts +0 -122
  668. package/neural-interface/lib/assistant-brains/opencode-browser-policy.js +0 -47
  669. package/neural-interface/lib/assistant-brains/opencode-route-gate.js +0 -62
  670. package/neural-interface/lib/mcp-profile-servers.js +0 -120
  671. package/neural-interface/public/shared/ui-tutorial-draw.js +0 -311
  672. package/skills/leonardo/SKILL.md +0 -168
  673. package/skills/leonardo/icon.svg +0 -1
  674. package/skills/leonardo/modules/browser-guide.md +0 -378
  675. package/skills/leonardo/modules/image-prompter.md +0 -283
  676. package/skills/leonardo/modules/model-advisor.md +0 -100
  677. package/skills/leonardo/modules/prompt-library.md +0 -110
  678. package/skills/leonardo/modules/style-guide.md +0 -186
  679. package/skills/leonardo/modules/video-prompter.md +0 -317
@@ -14,19 +14,20 @@ import { registerAction } from './ui-keybinds.js';
14
14
  import { isGuest, hasPermission } from './ui-sync.js';
15
15
  import { getWhiteboardElementById } from './ui-whiteboard.js';
16
16
  import { createFrameRenderer } from './utils.js';
17
+ import { frameRect, onFrameChange, clampBox, clampBoxLoose } from './app-frame.js';
17
18
  import { notify, NOTIF_TYPE } from './ui-notifications.js';
18
19
  import { getProviderMeta } from './provider-icons.js';
19
20
  import { readinessKind, typeWhenReady } from './term-ready.js';
20
21
  import { initRendererManager, acquireRenderer, disposeRenderer, hasWebgl, noteFocus, adoptRenderer, rendererState, rendererStats } from './term-renderer.js';
21
22
  import { mountAssistant } from './assistant/asst-panel.js';
22
23
  import { getAssistantSession } from './assistant/asst-api.js';
24
+ import { mascotCameoSvg } from './synabun-mascot.js';
23
25
  import { brainLabel, normalizeBrain, readStoredBrain, restoredSessionName, sessionNameGivenUp } from './assistant/asst-state.js';
24
26
  import { initAssistant, registerAssistantHost, openAssistant, assistantOwnerOf, fetchLiveAssistantSessions, isAssistantSessionLive } from './ui-assistant.js';
25
27
 
26
28
  const $ = (id) => document.getElementById(id);
27
29
  const CLI_PROFILES = new Set(['claude-code', 'codex', 'gemini', 'opencode']);
28
30
  const NOTIF_TRACKED_CLI_PROFILES = new Set(['claude-code', 'codex', 'gemini', 'opencode']);
29
- const CLI_PROFILES_NEED_PROFILER = new Set(['codex', 'gemini']); // Claude Code has tool search — no profiler needed
30
31
  const CLI_PROFILES_NEED_RECALL = new Set(['claude-code', 'codex', 'gemini', 'opencode']);
31
32
 
32
33
  // ── Platform ──
@@ -447,13 +448,25 @@ function _setBadgeStatus(container, status) {
447
448
  if (lbl) lbl.textContent = _CLI_LABELS[status] || '';
448
449
  }
449
450
 
451
+ /**
452
+ * An Assistant tab minimises to the Assistant's own tray pill (assistant/asst-styles.js "Tray pill"), the one
453
+ * its sidepanel shows: the mark, the gold cameo and hairline while the session works (its turn or a worker it
454
+ * dispatched), the warn tint while it needs you. No CLI dot and no check: its status is the panel's.
455
+ */
456
+ function _paintAssistantPill(pill, status) {
457
+ pill.classList.toggle('asp-pill-running', status === CLI_STATUS.WORKING);
458
+ pill.classList.toggle('asp-pill-attention', status === CLI_STATUS.ACTION);
459
+ pill.classList.toggle('asp-pill-done', status === CLI_STATUS.DONE);
460
+ }
461
+
450
462
  function _updateSessionBadges(sessionId, status) {
451
463
  _notifyStatusChange(sessionId, status);
452
464
  const refs = _getBadgeContainers(sessionId);
453
465
  _setBadgeStatus(refs.tab, status);
454
466
  _setBadgeStatus(refs.float, status);
467
+ if (refs.pill?.classList.contains('asp-session-pill')) _paintAssistantPill(refs.pill, status);
455
468
  // Minimized pill badge + icon swap on done
456
- if (refs.pill) {
469
+ else if (refs.pill) {
457
470
  _setBadgeStatus(refs.pill, status);
458
471
  const ico = refs.pill.querySelector('.term-minimized-pill-icon');
459
472
  if (ico) {
@@ -604,79 +617,6 @@ function _cliBadgeHtml(sessionId) {
604
617
  : '';
605
618
  }
606
619
 
607
- // ── Floating terminal MCP profile dropdown ──
608
-
609
- let _floatProfileCache = null;
610
- let _floatProfileCacheTime = 0;
611
-
612
- async function _fetchFloatProfiles() {
613
- const now = Date.now();
614
- if (_floatProfileCache && now - _floatProfileCacheTime < 60000) return _floatProfileCache;
615
- try {
616
- const resp = await fetch('/api/mcp/profile');
617
- const data = await resp.json();
618
- if (data.ok) {
619
- _floatProfileCache = { current: data.profile || 'full', presets: data.presets || {} };
620
- _floatProfileCacheTime = now;
621
- }
622
- } catch {}
623
- return _floatProfileCache || { current: 'full', presets: {} };
624
- }
625
-
626
- function _initFloatProfileDropdown(dd) {
627
- const btn = dd.querySelector('.term-float-profile-btn');
628
- const menu = dd.querySelector('.term-float-profile-menu');
629
- const label = dd.querySelector('.term-float-profile-label');
630
-
631
- // Load current profile label
632
- _fetchFloatProfiles().then(data => {
633
- const p = data.presets[data.current];
634
- label.textContent = p?.label || data.current;
635
- });
636
-
637
- btn.addEventListener('click', async (e) => {
638
- e.stopPropagation();
639
- const wasOpen = menu.classList.contains('open');
640
- // Close all other open profile menus
641
- document.querySelectorAll('.term-float-profile-menu.open').forEach(m => m.classList.remove('open'));
642
- if (wasOpen) return;
643
-
644
- const data = await _fetchFloatProfiles();
645
- menu.innerHTML = '';
646
- for (const [id, preset] of Object.entries(data.presets)) {
647
- const opt = document.createElement('div');
648
- opt.className = 'term-float-profile-option' + (id === data.current ? ' selected' : '');
649
- opt.innerHTML = `<span class="tfp-name">${preset.label || id}</span><span class="tfp-hint">${preset.tools} tools</span>`;
650
- opt.addEventListener('click', async (ev) => {
651
- ev.stopPropagation();
652
- menu.classList.remove('open');
653
- if (id === data.current) return;
654
- label.textContent = preset.label || id;
655
- try {
656
- await fetch('/api/mcp/profile', {
657
- method: 'POST',
658
- headers: { 'Content-Type': 'application/json' },
659
- body: JSON.stringify({ profile: id }),
660
- });
661
- _floatProfileCache = null; // bust cache
662
- // Update all other floating profile dropdowns
663
- document.querySelectorAll('.term-float-profile-label').forEach(lbl => {
664
- lbl.textContent = preset.label || id;
665
- });
666
- } catch {}
667
- });
668
- menu.appendChild(opt);
669
- }
670
- menu.classList.add('open');
671
-
672
- // Close on outside click
673
- const close = (ev) => {
674
- if (!dd.contains(ev.target)) { menu.classList.remove('open'); document.removeEventListener('mousedown', close); }
675
- };
676
- setTimeout(() => document.addEventListener('mousedown', close), 0);
677
- });
678
- }
679
-
680
620
  // ── Floating terminal Recall profile dropdown ──
681
621
 
682
622
  const FLOAT_RECALL_META = [
@@ -726,7 +666,7 @@ function _initFloatRecallDropdown(dd) {
726
666
  for (const p of FLOAT_RECALL_META) {
727
667
  const opt = document.createElement('div');
728
668
  opt.className = 'term-float-recall-option' + (p.value === data.profile ? ' selected' : '');
729
- opt.innerHTML = `<span class="tfr-name">${p.label}</span><span class="tfr-hint">${p.hint}</span>`;
669
+ opt.innerHTML = `<span class="tfr-name">${_escHtml(p.label)}</span><span class="tfr-hint">${_escHtml(p.hint)}</span>`;
730
670
  opt.addEventListener('click', async (ev) => {
731
671
  ev.stopPropagation();
732
672
  menu.classList.remove('open');
@@ -1740,7 +1680,7 @@ function pickProject(profile) {
1740
1680
 
1741
1681
  const title = document.createElement('div');
1742
1682
  title.className = 'term-picker-title';
1743
- title.innerHTML = `<span class="term-picker-icon">${profileDef?.svg || SVG_SHELL}</span>Open ${label} in...`;
1683
+ title.innerHTML = `<span class="term-picker-icon">${profileDef?.svg || SVG_SHELL}</span>Open ${_escHtml(String(label))} in...`;
1744
1684
 
1745
1685
  const list = document.createElement('div');
1746
1686
  list.className = 'term-picker-list';
@@ -1757,7 +1697,7 @@ function pickProject(profile) {
1757
1697
  const item = document.createElement('button');
1758
1698
  item.className = 'term-picker-item';
1759
1699
  const folder = p.path.split(/[\\/]/).pop();
1760
- item.innerHTML = `<span class="term-picker-item-icon"><svg viewBox="0 0 24 24"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/></svg></span><span class="term-picker-item-label">${p.label || folder}</span><span class="term-picker-item-path">${p.path}</span>`;
1700
+ item.innerHTML = `<span class="term-picker-item-icon"><svg viewBox="0 0 24 24"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/></svg></span><span class="term-picker-item-label">${_escHtml(String(p.label || folder))}</span><span class="term-picker-item-path">${_escHtml(String(p.path))}</span>`;
1761
1701
  item.addEventListener('click', () => { overlay.remove(); resolve(p.path); });
1762
1702
  list.appendChild(item);
1763
1703
  });
@@ -2309,24 +2249,22 @@ function detachPanel() {
2309
2249
  // so left margin matches right margin — accounts for left sidebars and right sidepanel)
2310
2250
  let pos;
2311
2251
  try { pos = JSON.parse(storage.getItem(KEYS.TERMINAL_FLOAT_POS)); } catch {}
2252
+ const f = frameRect();
2312
2253
  if (!pos) {
2313
- const cs = getComputedStyle(document.documentElement);
2314
- const leftEdge = (parseFloat(cs.getPropertyValue('--explorer-width')) || 0)
2315
- + (parseFloat(cs.getPropertyValue('--file-explorer-width')) || 0);
2316
- const rightEdge = window.innerWidth - getRightPanelReservedWidth(cs);
2254
+ const { left: leftEdge, right: rightEdge } = _usableArea(f);
2317
2255
  const usableW = Math.max(0, rightEdge - leftEdge);
2318
2256
  const w = Math.min(800, usableW * 0.6);
2319
2257
  const h = Math.min(500, dockedH);
2320
2258
  pos = {
2321
2259
  left: leftEdge + (usableW - w) / 2,
2322
- top: Math.max(48, (window.innerHeight - h) / 2),
2260
+ top: Math.max(f.top, f.top + (f.height - h) / 2),
2323
2261
  width: w, height: h,
2324
2262
  };
2325
2263
  }
2326
2264
 
2327
2265
  _panel.classList.add('detached');
2328
- _panel.style.left = pos.left + 'px';
2329
- _panel.style.top = Math.max(48, pos.top) + 'px';
2266
+ _panel.style.left = Math.max(f.left, Math.min(pos.left, f.right - 80)) + 'px';
2267
+ _panel.style.top = Math.max(f.top, Math.min(pos.top, f.bottom - 80)) + 'px';
2330
2268
  _panel.style.width = pos.width + 'px';
2331
2269
  _panel.style.height = pos.height + 'px';
2332
2270
 
@@ -2423,7 +2361,7 @@ function initFloatDrag() {
2423
2361
  // Header drag for floating mode
2424
2362
  function _startPanelDrag(x, y) {
2425
2363
  const rect = _panel.getBoundingClientRect();
2426
- _floatDrag = { startX: x, startY: y, startL: rect.left, startT: rect.top };
2364
+ _floatDrag = { startX: x, startY: y, startL: rect.left, startT: rect.top, w: rect.width, h: rect.height, frame: frameRect() };
2427
2365
  pendingPanelDrag = null;
2428
2366
  _panel.classList.add('float-dragging');
2429
2367
  document.body.classList.add('ui-interacting');
@@ -2439,7 +2377,10 @@ function initFloatDrag() {
2439
2377
  finalL = Math.round(finalL / gs) * gs;
2440
2378
  finalT = Math.round(finalT / gs) * gs;
2441
2379
  }
2442
- finalT = Math.max(48, finalT);
2380
+ // Inside the app frame: the header stays below the bar, 80px of the window stays in reach
2381
+ const f = _floatDrag.frame || (_floatDrag.frame = frameRect());
2382
+ const w = _floatDrag.w || 0, h = _floatDrag.h || 0;
2383
+ ({ x: finalL, y: finalT } = clampBoxLoose(finalL, finalT, w, h, f, 80));
2443
2384
  // Transform during drag (composited, no layout); committed on dragend
2444
2385
  _floatDrag.lastL = finalL;
2445
2386
  _floatDrag.lastT = finalT;
@@ -2533,7 +2474,11 @@ function initFloatResize() {
2533
2474
  nl = Math.round(nl / gs) * gs; nt = Math.round(nt / gs) * gs;
2534
2475
  nw = Math.round(nw / gs) * gs; nh = Math.round(nh / gs) * gs;
2535
2476
  }
2536
- nt = Math.max(48, nt);
2477
+ const f = frameRect();
2478
+ if (nt < f.top) { if (dir.includes('n')) nh -= f.top - nt; nt = f.top; }
2479
+ if (nl < f.left) { if (dir.includes('w')) nw -= f.left - nl; nl = f.left; }
2480
+ nw = Math.max(MIN_W, Math.min(nw, f.right - nl));
2481
+ nh = Math.max(MIN_H, Math.min(nh, f.bottom - nt));
2537
2482
  _panel.style.left = nl + 'px';
2538
2483
  _panel.style.top = nt + 'px';
2539
2484
  _panel.style.width = nw + 'px';
@@ -2640,10 +2585,12 @@ function initResizeHandle() {
2640
2585
  _draggingResize = true;
2641
2586
  document.body.classList.add('ui-interacting');
2642
2587
  graphLayers = [$('graph-container'), $('static-bg')].filter(Boolean);
2588
+ // Up to 80% of the window, and never past the top of the app frame (its 12px inner padding kept)
2589
+ const dockBottom = _panel.getBoundingClientRect().bottom;
2590
+ const maxH = Math.max(MIN_HEIGHT, Math.min(window.innerHeight * 0.8, dockBottom - frameRect().top - 12));
2643
2591
 
2644
2592
  const onMove = (e) => {
2645
2593
  const dy = startY - e.clientY;
2646
- const maxH = window.innerHeight * 0.8;
2647
2594
  const newH = Math.max(MIN_HEIGHT, Math.min(maxH, startH + dy));
2648
2595
  scheduleHeight(newH);
2649
2596
  };
@@ -3288,7 +3235,7 @@ async function reconnectBrowserSession(sessionId, liveData, saved) {
3288
3235
  <div class="browser-url-bar">
3289
3236
  <input type="text" class="browser-url-input" value="${currentUrl.replace(/"/g, '&quot;')}" spellcheck="false" autocomplete="off">
3290
3237
  </div>
3291
- <span class="browser-title-label">${liveData?.title || ''}</span>
3238
+ <span class="browser-title-label">${_escHtml(String(liveData?.title || ''))}</span>
3292
3239
  `;
3293
3240
  viewport.appendChild(navbar);
3294
3241
 
@@ -4167,12 +4114,13 @@ function initContextMenu(viewport, term, getWs) {
4167
4114
  menu.style.top = '0px';
4168
4115
  menu.classList.add('open');
4169
4116
  const rect = menu.getBoundingClientRect();
4117
+ const f = frameRect();
4170
4118
  let x = e.clientX;
4171
4119
  let y = e.clientY;
4172
- if (x + rect.width > window.innerWidth) x = window.innerWidth - rect.width - 4;
4173
- if (y + rect.height > window.innerHeight) y = e.clientY - rect.height;
4174
- if (x < 0) x = 4;
4175
- if (y < 0) y = 4;
4120
+ if (x + rect.width > f.right) x = f.right - rect.width - 4;
4121
+ if (y + rect.height > f.bottom) y = e.clientY - rect.height;
4122
+ if (x < f.left) x = f.left + 4;
4123
+ if (y < f.top) y = f.top + 4;
4176
4124
  menu.style.left = x + 'px';
4177
4125
  menu.style.top = y + 'px';
4178
4126
 
@@ -4402,7 +4350,8 @@ function sendMemoryDrop(node, ws) {
4402
4350
  ws.send(JSON.stringify({ type: 'memory_drop', content, title }));
4403
4351
  }
4404
4352
 
4405
- function formatMemoryForCLI(node) {
4353
+ // Also what the context menu sends to the AI panel (ui-context-menu.js).
4354
+ export function formatMemoryForCLI(node) {
4406
4355
  const p = node.payload;
4407
4356
  const parts = [];
4408
4357
 
@@ -4538,10 +4487,11 @@ function _placeFloatColorPicker(picker, colorBtn) {
4538
4487
  const inset = first ? first.left + first.width / 2 - box.left : 0;
4539
4488
  const margin = 8, gap = 6;
4540
4489
  const left = btn.left + btn.width / 2 - inset;
4490
+ const f = frameRect();
4541
4491
  let top = btn.top - gap - box.height;
4542
- if (top < margin) top = btn.bottom + gap;
4543
- picker.style.left = Math.max(margin, Math.min(left, window.innerWidth - box.width - margin)) + 'px';
4544
- picker.style.top = Math.max(margin, Math.min(top, window.innerHeight - box.height - margin)) + 'px';
4492
+ if (top < f.top + margin) top = btn.bottom + gap;
4493
+ picker.style.left = Math.max(f.left + margin, Math.min(left, f.right - box.width - margin)) + 'px';
4494
+ picker.style.top = Math.max(f.top + margin, Math.min(top, f.bottom - box.height - margin)) + 'px';
4545
4495
  }
4546
4496
 
4547
4497
  function getRightPanelReservedWidth(cs = getComputedStyle(document.documentElement)) {
@@ -4550,17 +4500,24 @@ function getRightPanelReservedWidth(cs = getComputedStyle(document.documentEleme
4550
4500
  || 0;
4551
4501
  }
4552
4502
 
4503
+ /** The app frame's area left for the floats: right of the explorers, left of a docked right sidepanel (its reserved
4504
+ * width counts from the window's right edge), below the bar. */
4505
+ function _usableArea(f = frameRect(), cs = getComputedStyle(document.documentElement)) {
4506
+ const reserved = getRightPanelReservedWidth(cs);
4507
+ return { left: f.left, top: f.top, right: Math.max(f.left, Math.min(f.right, window.innerWidth - reserved)), bottom: f.bottom };
4508
+ }
4509
+
4553
4510
  /** Update snapped-edge classes on all floating tabs based on adjacency */
4554
- /** Compute viewport/panel snap boundaries (getComputedStyle reads — cache during drag) */
4511
+ /** Compute frame/panel snap boundaries (getComputedStyle reads — cache during drag) */
4555
4512
  function _snapEnv() {
4556
- const cs = getComputedStyle(document.documentElement);
4557
- const explorerW = parseFloat(cs.getPropertyValue('--explorer-width')) || 0;
4558
- const fileExplorerW = parseFloat(cs.getPropertyValue('--file-explorer-width')) || 0;
4513
+ const f = frameRect();
4514
+ const area = _usableArea(f);
4559
4515
  return {
4560
- leftPanelEdge: explorerW + fileExplorerW,
4561
- rightPanelEdge: window.innerWidth - getRightPanelReservedWidth(cs),
4562
- topEdge: parseFloat(cs.getPropertyValue('--navbar-height')) || 48,
4563
- bottomEdge: window.innerHeight,
4516
+ leftPanelEdge: f.left,
4517
+ rightPanelEdge: area.right,
4518
+ frameRight: f.right,
4519
+ topEdge: f.top,
4520
+ bottomEdge: f.bottom,
4564
4521
  };
4565
4522
  }
4566
4523
 
@@ -4578,7 +4535,7 @@ function _updateSnappedEdges(rectsOverride, envOverride) {
4578
4535
  }
4579
4536
  }
4580
4537
 
4581
- const { leftPanelEdge, rightPanelEdge, topEdge, bottomEdge } = envOverride || _snapEnv();
4538
+ const { leftPanelEdge, rightPanelEdge, frameRight, topEdge, bottomEdge } = envOverride || _snapEnv();
4582
4539
 
4583
4540
  for (const [sid, dt] of _detachedTabs) {
4584
4541
  if (!dt.el || dt.minimized) continue;
@@ -4598,8 +4555,8 @@ function _updateSnappedEdges(rectsOverride, envOverride) {
4598
4555
  }
4599
4556
 
4600
4557
  // Check adjacency to viewport / panel edges
4601
- if (Math.abs(me.left - leftPanelEdge) < TOLERANCE || Math.abs(me.left) < TOLERANCE) edges.left = true;
4602
- if (Math.abs(me.right - rightPanelEdge) < TOLERANCE || Math.abs(me.right - window.innerWidth) < TOLERANCE) edges.right = true;
4558
+ if (Math.abs(me.left - leftPanelEdge) < TOLERANCE) edges.left = true;
4559
+ if (Math.abs(me.right - rightPanelEdge) < TOLERANCE || Math.abs(me.right - frameRight) < TOLERANCE) edges.right = true;
4603
4560
  if (Math.abs(me.top - topEdge) < TOLERANCE) edges.top = true;
4604
4561
  if (Math.abs(me.bottom - bottomEdge) < TOLERANCE) edges.bottom = true;
4605
4562
 
@@ -4655,20 +4612,16 @@ export function tileFloatingTerminals() {
4655
4612
  }
4656
4613
  if (entries.length === 0) return;
4657
4614
 
4658
- // Compute available whiteboard area (respect open panels)
4659
- const cs = getComputedStyle(document.documentElement);
4660
- const explorerW = parseFloat(cs.getPropertyValue('--explorer-width')) || 0;
4661
- const fileExplorerW = parseFloat(cs.getPropertyValue('--file-explorer-width')) || 0;
4662
- const sidebarW = explorerW + fileExplorerW;
4663
- const rightPanelW = getRightPanelReservedWidth(cs);
4615
+ // Compute the available area: the app frame, minus a docked right sidepanel and the docked terminal (which sits
4616
+ // 12px inside the frame's bottom: the tiles stop at its top)
4617
+ const area = _usableArea();
4664
4618
  const termPanel = document.getElementById('terminal-panel');
4665
- const termH = (termPanel && !termPanel.classList.contains('hidden') && !termPanel.classList.contains('detached'))
4666
- ? termPanel.getBoundingClientRect().height : 0;
4667
- const TOP_PAD = parseFloat(cs.getPropertyValue('--navbar-height')) || 48;
4668
- const areaL = sidebarW;
4669
- const areaT = TOP_PAD;
4670
- const areaW = window.innerWidth - sidebarW - rightPanelW;
4671
- const areaH = window.innerHeight - TOP_PAD - termH;
4619
+ const termTop = (termPanel && !termPanel.classList.contains('hidden') && !termPanel.classList.contains('detached'))
4620
+ ? termPanel.getBoundingClientRect().top : area.bottom;
4621
+ const areaL = area.left;
4622
+ const areaT = area.top;
4623
+ const areaW = Math.max(0, area.right - area.left);
4624
+ const areaH = Math.max(0, Math.min(area.bottom, termTop) - area.top);
4672
4625
 
4673
4626
  // Calculate grid: find best cols/rows to fill the space
4674
4627
  const n = entries.length;
@@ -4719,17 +4672,16 @@ function _defaultFloatRect(kind = {}) {
4719
4672
  const offset = _detachedTabs.size * 30;
4720
4673
  const isBrowser = kind.profile === 'browser';
4721
4674
  const isAssistant = !!kind._isAssistant || kind.profile === 'assistant';
4722
- const cs = getComputedStyle(document.documentElement);
4723
- const leftEdge = (parseFloat(cs.getPropertyValue('--explorer-width')) || 0)
4724
- + (parseFloat(cs.getPropertyValue('--file-explorer-width')) || 0);
4725
- const rightEdge = window.innerWidth - getRightPanelReservedWidth(cs);
4675
+ const f = frameRect();
4676
+ const { left: leftEdge, right: rightEdge } = _usableArea(f);
4726
4677
  const usableW = Math.max(0, rightEdge - leftEdge);
4727
4678
  // Assistant floats default to 780×560 (chat + agents dock need more room than a TUI)
4728
4679
  const w = Math.round(Math.min(isBrowser ? 960 : (isAssistant ? 780 : 700), usableW * (isBrowser ? 0.65 : (isAssistant ? 0.6 : 0.5))));
4729
- const h = Math.round(Math.min(isBrowser ? 640 : (isAssistant ? 560 : 420), window.innerHeight * (isBrowser ? 0.6 : (isAssistant ? 0.7 : 0.5))));
4680
+ const h = Math.round(Math.min(isBrowser ? 640 : (isAssistant ? 560 : 420), f.height * (isBrowser ? 0.6 : (isAssistant ? 0.7 : 0.5))));
4681
+ const at = clampBox(leftEdge + (usableW - w) / 2 + offset, f.top + (f.height - h) / 2 + offset, w, h, f);
4730
4682
  return {
4731
- left: Math.round(leftEdge + (usableW - w) / 2 + offset),
4732
- top: Math.round(Math.max(48, (window.innerHeight - h) / 2 + offset)),
4683
+ left: Math.round(at.x),
4684
+ top: Math.round(at.y),
4733
4685
  width: w,
4734
4686
  height: h,
4735
4687
  };
@@ -4779,10 +4731,6 @@ function detachTab(idx, opts = {}) {
4779
4731
  <span class="term-float-tab-icon">${prof?.svg || SVG_SHELL}</span>
4780
4732
  <button class="term-float-color-strip" data-tooltip="Change color"></button>
4781
4733
  <span class="term-float-tab-title">${_escHtml(_displayLabel(session))}</span>${session._isAssistant ? '<span class="term-float-brain-chip" data-tooltip="Brain" hidden></span>' : ''}${_cliBadgeHtml(session.id)}
4782
- ${CLI_PROFILES_NEED_PROFILER.has(session.profile) ? `<div class="term-float-profile-dd" data-tooltip="Tool profile">
4783
- <button class="term-float-profile-btn"><span class="term-float-profile-label">...</span><span class="term-float-profile-arrow">&#x25BE;</span></button>
4784
- <div class="term-float-profile-menu"></div>
4785
- </div>` : ''}
4786
4734
  ${CLI_PROFILES_NEED_RECALL.has(session.profile) ? `<div class="term-float-recall-dd" data-tooltip="Recall profile">
4787
4735
  <button class="term-float-recall-btn"><span class="term-float-recall-label">...</span><span class="term-float-recall-arrow">&#x25BE;</span></button>
4788
4736
  <div class="term-float-recall-menu"></div>
@@ -5005,11 +4953,6 @@ function detachTab(idx, opts = {}) {
5005
4953
  });
5006
4954
  }
5007
4955
 
5008
- // Wire MCP profile dropdown (CLI profiles only)
5009
- const profileDd = win.querySelector('.term-float-profile-dd');
5010
- if (profileDd) {
5011
- _initFloatProfileDropdown(profileDd);
5012
- }
5013
4956
 
5014
4957
  // Wire recall profile dropdown
5015
4958
  const recallDd = win.querySelector('.term-float-recall-dd');
@@ -5133,10 +5076,11 @@ function minimizeTab(sessionId) {
5133
5076
  if (!tray) { tabState.el.style.display = 'none'; _syncRenderers(); return; }
5134
5077
  const prof = PROFILES.find(p => p.id === session.profile);
5135
5078
  const pill = document.createElement('div');
5136
- pill.className = 'term-minimized-pill' + (session._bell ? ' has-bell' : '');
5079
+ pill.className = 'term-minimized-pill' + (session._isAssistant ? ' asp-session-pill' : '') + (session._bell ? ' has-bell' : '');
5137
5080
  pill.setAttribute('data-session-id', sessionId);
5081
+ // (An Assistant's carries the running cameo beside its mark: _paintAssistantPill shows one or the other.)
5138
5082
  pill.innerHTML = `
5139
- <span class="term-minimized-pill-icon">${prof?.svg || SVG_SHELL}</span>
5083
+ <span class="term-minimized-pill-icon"${session._isAssistant ? ' aria-hidden="true"' : ''}>${prof?.svg || SVG_SHELL}${session._isAssistant ? mascotCameoSvg() : ''}</span>
5140
5084
  <span class="term-minimized-pill-label">${_escHtml(_displayLabel(session))}</span>
5141
5085
  <button class="term-minimized-pill-close" data-tooltip="Close">&times;</button>
5142
5086
  `;
@@ -5150,9 +5094,11 @@ function minimizeTab(sessionId) {
5150
5094
  tray.appendChild(pill);
5151
5095
  tabState.pill = pill;
5152
5096
 
5153
- // Set initial CLI status badge on pill
5097
+ // Set initial CLI status badge on pill (an Assistant's: the state the panel last pushed)
5154
5098
  const tracked = _cliSessionStatus.get(sessionId);
5155
- if (tracked) {
5099
+ if (tracked && session._isAssistant) {
5100
+ _paintAssistantPill(pill, tracked.status);
5101
+ } else if (tracked) {
5156
5102
  const badge = _ensureBadge(pill);
5157
5103
  badge.dataset.status = tracked.status;
5158
5104
  const lbl = badge.querySelector('.cli-status-label');
@@ -5290,7 +5236,7 @@ function initTabFloatDrag(win, sessionId) {
5290
5236
 
5291
5237
  function _checkHeader(target) {
5292
5238
  const header = target.closest('.term-float-tab-header');
5293
- if (!header || target.closest('button, .term-float-profile-dd')) return false;
5239
+ if (!header || target.closest('button')) return false;
5294
5240
  const session = _sessions.find(s => s.id === sessionId);
5295
5241
  return !session?.pinned;
5296
5242
  }
@@ -5327,8 +5273,9 @@ function initTabFloatDrag(win, sessionId) {
5327
5273
  const KEEP = 80;
5328
5274
  const w = drag.startW || parseFloat(win.style.width) || 700;
5329
5275
  const h = drag.startH || parseFloat(win.style.height) || 420;
5330
- finalL = Math.max(KEEP - w, Math.min(finalL, window.innerWidth - KEEP));
5331
- finalT = Math.max(48, Math.min(finalT, window.innerHeight - KEEP));
5276
+ const env = drag.snapEnv;
5277
+ const frame = { left: env.leftPanelEdge, top: env.topEdge, right: env.frameRight, bottom: env.bottomEdge };
5278
+ ({ x: finalL, y: finalT } = clampBoxLoose(finalL, finalT, w, h, frame, KEEP));
5332
5279
 
5333
5280
  // Snap to other floating windows (rects cached at drag start)
5334
5281
  const SNAP_DIST = 12;
@@ -5359,11 +5306,12 @@ function initTabFloatDrag(win, sessionId) {
5359
5306
  else if (Math.abs(myB - or.bottom) < SNAP_DIST) { finalT = or.bottom - h; snapped = true; }
5360
5307
  }
5361
5308
  }
5362
- // Also snap to viewport edges
5363
- if (Math.abs(finalL) < SNAP_DIST) { finalL = 0; snapped = true; }
5364
- if (Math.abs(finalT - 48) < SNAP_DIST) { finalT = 48; snapped = true; }
5365
- if (Math.abs(myR - window.innerWidth) < SNAP_DIST) { finalL = window.innerWidth - w; snapped = true; }
5366
- if (Math.abs(myB - window.innerHeight) < SNAP_DIST) { finalT = window.innerHeight - h; snapped = true; }
5309
+ // Also snap to the app frame's edges (and a docked right sidepanel's)
5310
+ if (Math.abs(finalL - frame.left) < SNAP_DIST) { finalL = frame.left; snapped = true; }
5311
+ if (Math.abs(finalT - frame.top) < SNAP_DIST) { finalT = frame.top; snapped = true; }
5312
+ if (Math.abs(myR - frame.right) < SNAP_DIST) { finalL = frame.right - w; snapped = true; }
5313
+ else if (Math.abs(myR - env.rightPanelEdge) < SNAP_DIST) { finalL = env.rightPanelEdge - w; snapped = true; }
5314
+ if (Math.abs(myB - frame.bottom) < SNAP_DIST) { finalT = frame.bottom - h; snapped = true; }
5367
5315
 
5368
5316
  win.classList.toggle('float-snapping', snapped);
5369
5317
  // Transform-based positioning: left/top force layout every frame; a
@@ -5482,7 +5430,9 @@ function initTabFloatResize(win, sessionId) {
5482
5430
  nl = Math.round(nl / gs) * gs; nt = Math.round(nt / gs) * gs;
5483
5431
  nw = Math.round(nw / gs) * gs; nh = Math.round(nh / gs) * gs;
5484
5432
  }
5485
- nt = Math.max(48, nt);
5433
+ // The header never goes above the app frame's top (a top edge stops there, the bottom edge stays put)
5434
+ const frameTop = frameRect().top;
5435
+ if (nt < frameTop) { if (dir.includes('n')) nh = Math.max(MIN_H, nh - (frameTop - nt)); nt = frameTop; }
5486
5436
  win.style.left = nl + 'px';
5487
5437
  win.style.top = nt + 'px';
5488
5438
  win.style.width = nw + 'px';
@@ -5825,41 +5775,48 @@ export async function initTerminal() {
5825
5775
  }
5826
5776
  });
5827
5777
 
5828
- // ── Window resize — clamp floating tabs on screen, refit all terminals ──
5778
+ // ── Window resize, an explorer opening or closing — keep the floats in the app frame, refit all terminals ──
5779
+ const clampFloatsToFrame = () => {
5780
+ const f = frameRect();
5781
+ const KEEP = 80; // min px of tab that must remain visible
5782
+ const floats = [..._detachedTabs.values()].filter(tabState => !tabState.minimized).map(tabState => tabState.el);
5783
+ if (_detached && _panel && !_panel.classList.contains('hidden')) floats.push(_panel);
5784
+
5785
+ for (const el of floats) {
5786
+ if (!el) continue;
5787
+ let l = parseFloat(el.style.left) || 0;
5788
+ let t = parseFloat(el.style.top) || 0;
5789
+ let w = parseFloat(el.style.width) || 700;
5790
+ let h = parseFloat(el.style.height) || 420;
5791
+
5792
+ // Clamp dimensions to the frame
5793
+ w = Math.min(w, f.width);
5794
+ h = Math.min(h, f.height);
5795
+
5796
+ // Clamp position so the header stays reachable, below the title bar and right of the explorers
5797
+ ({ x: l, y: t } = clampBoxLoose(l, t, w, h, f, KEEP));
5798
+
5799
+ el.style.left = l + 'px';
5800
+ el.style.top = t + 'px';
5801
+ el.style.width = w + 'px';
5802
+ el.style.height = h + 'px';
5803
+ }
5804
+
5805
+ // Refit all terminals to new dimensions
5806
+ _sessions.forEach(s => _scheduleFit(s));
5807
+ };
5829
5808
  window.addEventListener('resize', () => {
5830
5809
  if (_windowResizeTimer) clearTimeout(_windowResizeTimer);
5831
5810
  _windowResizeTimer = setTimeout(() => {
5832
5811
  _windowResizeTimer = null;
5833
- const vw = window.innerWidth;
5834
- const vh = window.innerHeight;
5835
- const KEEP = 80; // min px of tab that must remain visible
5836
-
5837
- for (const [, tabState] of _detachedTabs) {
5838
- if (tabState.minimized) continue;
5839
- const el = tabState.el;
5840
- let l = parseFloat(el.style.left) || 0;
5841
- let t = parseFloat(el.style.top) || 0;
5842
- let w = parseFloat(el.style.width) || 700;
5843
- let h = parseFloat(el.style.height) || 420;
5844
-
5845
- // Clamp dimensions to viewport
5846
- w = Math.min(w, vw);
5847
- h = Math.min(h, vh);
5848
-
5849
- // Clamp position so header stays reachable and below title bar
5850
- l = Math.max(KEEP - w, Math.min(l, vw - KEEP));
5851
- t = Math.max(48, Math.min(t, vh - KEEP));
5852
-
5853
- el.style.left = l + 'px';
5854
- el.style.top = t + 'px';
5855
- el.style.width = w + 'px';
5856
- el.style.height = h + 'px';
5857
- }
5858
-
5859
- // Refit all terminals to new dimensions
5860
- _sessions.forEach(s => _scheduleFit(s));
5812
+ clampFloatsToFrame();
5861
5813
  }, 150);
5862
5814
  });
5815
+ onFrameChange(() => {
5816
+ if (_windowResizeTimer) return; // the resize pass runs shortly
5817
+ clampFloatsToFrame();
5818
+ _updateSnappedEdges();
5819
+ });
5863
5820
 
5864
5821
  // ── Visibility change — flow control, warm renderers, one focus target ──
5865
5822
  document.addEventListener('visibilitychange', () => {
@@ -6466,11 +6423,13 @@ async function attachDetached(terminalSessionId, profile, initialMessage, autoSu
6466
6423
  if (dt?.el) {
6467
6424
  const panelWidth = getRightPanelReservedWidth();
6468
6425
  if (panelWidth > 0) {
6469
- const availWidth = window.innerWidth - panelWidth - 16;
6470
- const w = Math.min(700, availWidth * 0.6);
6471
- const h = Math.min(500, window.innerHeight - 96);
6472
- dt.el.style.left = (window.innerWidth - panelWidth - w - 24) + 'px';
6473
- dt.el.style.top = '56px';
6426
+ // Beside the panel, 24px from its slot, at the top of the app frame
6427
+ const f = frameRect();
6428
+ const area = _usableArea(f);
6429
+ const w = Math.min(700, Math.max(0, area.right - area.left - 16) * 0.6);
6430
+ const h = Math.min(500, f.height - 40);
6431
+ dt.el.style.left = Math.max(f.left, area.right - w - 24) + 'px';
6432
+ dt.el.style.top = f.top + 'px';
6474
6433
  dt.el.style.width = w + 'px';
6475
6434
  dt.el.style.height = h + 'px';
6476
6435
  }
@@ -6653,10 +6612,11 @@ function applyTerminalLayout(snap) {
6653
6612
  const minW = 280, minH = 160;
6654
6613
  const w = Math.max(minW, dt.width || minW);
6655
6614
  const h = Math.max(minH, dt.height || minH);
6656
- const maxL = window.innerWidth - 80;
6657
- const maxT = window.innerHeight - 40;
6658
- const l = Math.max(0, Math.min(dt.left || 0, maxL));
6659
- const t = Math.max(48, Math.min(dt.top || 0, maxT));
6615
+ const f = frameRect();
6616
+ const maxL = f.right - 80;
6617
+ const maxT = f.bottom - 40;
6618
+ const l = Math.max(f.left, Math.min(dt.left || 0, maxL));
6619
+ const t = Math.max(f.top, Math.min(dt.top || 0, maxT));
6660
6620
 
6661
6621
  tabState.el.style.left = l + 'px';
6662
6622
  tabState.el.style.top = t + 'px';
@@ -6905,9 +6865,9 @@ async function toggleFileTree(sidebar, session) {
6905
6865
 
6906
6866
  // Branch (clickable if git)
6907
6867
  const branchHtml = data.branch
6908
- ? `<button class="ft-branch" data-tooltip="Switch branch"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="6" y1="3" x2="6" y2="15"/><circle cx="18" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><path d="M18 9a9 9 0 0 1-9 9"/></svg><span class="ft-branch-name">${data.branch}</span></button>`
6868
+ ? `<button class="ft-branch" data-tooltip="Switch branch"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="6" y1="3" x2="6" y2="15"/><circle cx="18" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><path d="M18 9a9 9 0 0 1-9 9"/></svg><span class="ft-branch-name">${_escHtml(String(data.branch))}</span></button>`
6909
6869
  : '';
6910
- header.innerHTML = `<span class="ft-header-label" data-tooltip="Click to change path" title="${session.cwd}">${dirName}</span>${branchHtml}`;
6870
+ header.innerHTML = `<span class="ft-header-label" data-tooltip="Click to change path" title="${_escHtml(session.cwd).replace(/"/g, '&quot;')}">${_escHtml(dirName)}</span>${branchHtml}`;
6911
6871
 
6912
6872
  // Wire header label click → inline path editor
6913
6873
  header.querySelector('.ft-header-label').addEventListener('click', (e) => {
@@ -6980,7 +6940,7 @@ async function toggleFileTree(sidebar, session) {
6980
6940
 
6981
6941
  renderFileItems(tree, originalItems, session.cwd, 0, session);
6982
6942
  } catch (err) {
6983
- sidebar.innerHTML = `<div class="ft-empty">Error: ${err.message}</div>`;
6943
+ sidebar.innerHTML = `<div class="ft-empty">Error: ${_escHtml(String(err?.message || err))}</div>`;
6984
6944
  }
6985
6945
  }
6986
6946
 
@@ -7001,7 +6961,7 @@ function renderFileItems(container, items, parentPath, depth, session) {
7001
6961
  const gitBadge = item.git ? `<span class="ft-git-badge" data-tooltip="${item.git}">${GIT_STATUS_LABEL[item.git] || '?'}</span>` : '';
7002
6962
 
7003
6963
  if (item.type === 'dir') {
7004
- row.innerHTML = `<span class="ft-chevron">${SVG_CHEVRON}</span><span class="ft-icon">${SVG_DIR}</span><span class="ft-name">${item.name}</span>${gitBadge}`;
6964
+ row.innerHTML = `<span class="ft-chevron">${SVG_CHEVRON}</span><span class="ft-icon">${SVG_DIR}</span><span class="ft-name">${_escHtml(item.name)}</span>${gitBadge}`;
7005
6965
  row.dataset.path = fullPath;
7006
6966
  row.dataset.expanded = 'false';
7007
6967
 
@@ -7045,7 +7005,7 @@ function renderFileItems(container, items, parentPath, depth, session) {
7045
7005
  }
7046
7006
  });
7047
7007
  } else {
7048
- row.innerHTML = `<span class="ft-chevron-spacer"></span><span class="ft-icon">${SVG_FILE}</span><span class="ft-name">${item.name}</span>${gitBadge}`;
7008
+ row.innerHTML = `<span class="ft-chevron-spacer"></span><span class="ft-icon">${SVG_FILE}</span><span class="ft-name">${_escHtml(item.name)}</span>${gitBadge}`;
7049
7009
  row.dataset.path = fullPath;
7050
7010
 
7051
7011
  // Click file → type path into terminal
@@ -7076,9 +7036,9 @@ function renderSearchResults(container, items, session) {
7076
7036
  // Show relative path — highlight the filename part
7077
7037
  const parts = item.name.split('/');
7078
7038
  const fileName = parts.pop();
7079
- const dirPath = parts.length ? `<span class="ft-search-path">${parts.join('/')}/</span>` : '';
7039
+ const dirPath = parts.length ? `<span class="ft-search-path">${_escHtml(parts.join('/'))}/</span>` : '';
7080
7040
 
7081
- row.innerHTML = `<span class="ft-icon">${icon}</span>${dirPath}<span class="ft-name">${fileName}</span>`;
7041
+ row.innerHTML = `<span class="ft-icon">${icon}</span>${dirPath}<span class="ft-name">${_escHtml(fileName)}</span>`;
7082
7042
 
7083
7043
  const fullPath = session.cwd.replace(/[\\/]$/, '') + '/' + item.name;
7084
7044
  row.dataset.path = fullPath;
@@ -7235,7 +7195,7 @@ async function openBranchPicker(sidebar, session, anchorEl) {
7235
7195
  for (const branch of data.branches) {
7236
7196
  const item = document.createElement('button');
7237
7197
  item.className = `ft-branch-item${branch === data.current ? ' current' : ''}`;
7238
- item.innerHTML = `<span class="ft-branch-item-name">${branch}</span>${branch === data.current ? '<span class="ft-branch-item-check">&#10003;</span>' : ''}`;
7198
+ item.innerHTML = `<span class="ft-branch-item-name">${_escHtml(branch)}</span>${branch === data.current ? '<span class="ft-branch-item-check">&#10003;</span>' : ''}`;
7239
7199
 
7240
7200
  item.addEventListener('click', async (e) => {
7241
7201
  e.stopPropagation();
@@ -7246,7 +7206,7 @@ async function openBranchPicker(sidebar, session, anchorEl) {
7246
7206
 
7247
7207
  // Show loading state
7248
7208
  item.classList.add('switching');
7249
- item.innerHTML = `<span class="ft-branch-item-name">${branch}</span><span class="ft-branch-item-check">...</span>`;
7209
+ item.innerHTML = `<span class="ft-branch-item-name">${_escHtml(branch)}</span><span class="ft-branch-item-check">...</span>`;
7250
7210
 
7251
7211
  try {
7252
7212
  const result = await checkoutTerminalBranch(session.cwd, branch);
@@ -7270,7 +7230,7 @@ async function openBranchPicker(sidebar, session, anchorEl) {
7270
7230
  }
7271
7231
  } catch (err) {
7272
7232
  item.classList.remove('switching');
7273
- item.innerHTML = `<span class="ft-branch-item-name">${branch}</span><span class="ft-branch-item-check" style="color:#ff5252">!</span>`;
7233
+ item.innerHTML = `<span class="ft-branch-item-name">${_escHtml(branch)}</span><span class="ft-branch-item-check" style="color:#ff5252">!</span>`;
7274
7234
  writeGitOutput('error', err.message || 'Checkout failed');
7275
7235
  }
7276
7236
  });