synabun 2.0.9 → 2.0.10

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 (252) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +1 -1
  3. package/THIRD-PARTY-LICENSES.md +46 -4
  4. package/launcher.mjs +9 -3
  5. package/lib/start-launcher.js +6 -1
  6. package/mcp-server/package-lock.json +2 -2
  7. package/mcp-server/package.json +1 -1
  8. package/neural-interface/i18n/en.json +218 -7
  9. package/neural-interface/i18n/pt-BR.json +220 -9
  10. package/neural-interface/lib/account-usage.js +5 -3
  11. package/neural-interface/lib/app-controls-api.js +161 -0
  12. package/neural-interface/lib/assistant-api.js +21 -7
  13. package/neural-interface/lib/assistant-brains/opencode.js +13 -1
  14. package/neural-interface/lib/assistant-brains/opencode2-browser-policy/index.js +44 -0
  15. package/neural-interface/lib/assistant-brains/opencode2-route-gate/index.js +57 -0
  16. package/neural-interface/lib/assistant-catalog.js +17 -2
  17. package/neural-interface/lib/assistant-dispatch.js +3 -0
  18. package/neural-interface/lib/assistant-envelope.js +19 -1
  19. package/neural-interface/lib/assistant-runtime.js +127 -8
  20. package/neural-interface/lib/claude-model-catalog.js +64 -14
  21. package/neural-interface/lib/codex-settings-schema.js +109 -47
  22. package/neural-interface/lib/editor-completion-opencode.js +132 -35
  23. package/neural-interface/lib/exec-loop-command.js +8 -1
  24. package/neural-interface/lib/launch-cache.js +293 -0
  25. package/neural-interface/lib/login-start.js +524 -0
  26. package/neural-interface/lib/native-loop-providers.js +18 -3
  27. package/neural-interface/lib/native-loop-runtime.js +19 -0
  28. package/neural-interface/lib/opencode-db-schema.js +75 -0
  29. package/neural-interface/lib/opencode-history.js +16 -1
  30. package/neural-interface/lib/opencode-protocol.js +173 -0
  31. package/neural-interface/lib/opencode-provider-view.js +81 -0
  32. package/neural-interface/lib/opencode-runtime-config.js +10 -3
  33. package/neural-interface/lib/opencode-serve-records.js +606 -0
  34. package/neural-interface/lib/opencode-v2-client.js +33 -6
  35. package/neural-interface/lib/opencode-v2-ws-requests.js +19 -5
  36. package/neural-interface/lib/opencode-worker-activity.js +229 -0
  37. package/neural-interface/lib/opencode2-client.js +760 -0
  38. package/neural-interface/lib/opencode2-proxy.js +116 -0
  39. package/neural-interface/lib/opencode2-translate.js +1008 -0
  40. package/neural-interface/lib/process-identity.js +361 -0
  41. package/neural-interface/lib/session-cache-builder.js +26 -5
  42. package/neural-interface/lib/session-title-generator.js +18 -0
  43. package/neural-interface/lib/style-guide/api.js +4 -3
  44. package/neural-interface/lib/untrusted-file-headers.js +27 -0
  45. package/neural-interface/package-lock.json +1343 -45
  46. package/neural-interface/package.json +5 -1
  47. package/neural-interface/public/index.html +2 -2
  48. package/neural-interface/public/shared/agent-runtime-options.js +55 -11
  49. package/neural-interface/public/shared/assistant/asst-agents-dock.js +172 -17
  50. package/neural-interface/public/shared/assistant/asst-api.js +11 -3
  51. package/neural-interface/public/shared/assistant/asst-brain-picker.js +195 -80
  52. package/neural-interface/public/shared/assistant/asst-composer.js +1 -1
  53. package/neural-interface/public/shared/assistant/asst-hosts.js +49 -2
  54. package/neural-interface/public/shared/assistant/asst-menu.js +77 -6
  55. package/neural-interface/public/shared/assistant/asst-panel.js +197 -33
  56. package/neural-interface/public/shared/assistant/asst-rack-styles.js +28 -10
  57. package/neural-interface/public/shared/assistant/asst-redact.js +186 -0
  58. package/neural-interface/public/shared/assistant/asst-render.js +382 -36
  59. package/neural-interface/public/shared/assistant/asst-run-stage.js +231 -0
  60. package/neural-interface/public/shared/assistant/asst-sanitize.js +193 -3
  61. package/neural-interface/public/shared/assistant/asst-scene-styles.js +273 -0
  62. package/neural-interface/public/shared/assistant/asst-scenes.js +528 -0
  63. package/neural-interface/public/shared/assistant/asst-sidepanel-styles.js +3 -15
  64. package/neural-interface/public/shared/assistant/asst-state.js +14 -0
  65. package/neural-interface/public/shared/assistant/asst-styles.js +43 -0
  66. package/neural-interface/public/shared/assistant/asst-tool-kinds.js +13 -1
  67. package/neural-interface/public/shared/cc-dropdown.js +480 -0
  68. package/neural-interface/public/shared/cdx/cdx-panel.js +13 -1
  69. package/neural-interface/public/shared/cdx/cdx-render.js +15 -3
  70. package/neural-interface/public/shared/cdx/cdx-styles.js +4 -0
  71. package/neural-interface/public/shared/cdx/cdx-tabs.js +149 -35
  72. package/neural-interface/public/shared/cp/cp-markdown.js +4 -57
  73. package/neural-interface/public/shared/data-cache.js +223 -0
  74. package/neural-interface/public/shared/desktop-bridge.js +11 -0
  75. package/neural-interface/public/shared/desktop-titlebar-view.js +78 -1
  76. package/neural-interface/public/shared/desktop-titlebar.js +214 -28
  77. package/neural-interface/public/shared/desktop-update-view.js +15 -5
  78. package/neural-interface/public/shared/file-links.js +73 -8
  79. package/neural-interface/public/shared/html-shell.js +74 -80
  80. package/neural-interface/public/shared/launch-prefetch.js +59 -0
  81. package/neural-interface/public/shared/ocp-v2/ocp-v2-caps.js +3 -2
  82. package/neural-interface/public/shared/ocp-v2/ocp-v2-childpanel.js +7 -2
  83. package/neural-interface/public/shared/ocp-v2/ocp-v2-modelpicker.js +54 -17
  84. package/neural-interface/public/shared/ocp-v2/ocp-v2-panel.js +93 -2
  85. package/neural-interface/public/shared/ocp-v2/ocp-v2-projectbar.js +3 -2
  86. package/neural-interface/public/shared/ocp-v2/ocp-v2-providers.js +11 -9
  87. package/neural-interface/public/shared/ocp-v2/ocp-v2-rehydrate.js +15 -4
  88. package/neural-interface/public/shared/ocp-v2/ocp-v2-render.js +1 -1
  89. package/neural-interface/public/shared/ocp-v2/ocp-v2-send-logic.js +401 -0
  90. package/neural-interface/public/shared/ocp-v2/ocp-v2-send.js +16 -9
  91. package/neural-interface/public/shared/ocp-v2/ocp-v2-sessions-logic.js +60 -0
  92. package/neural-interface/public/shared/ocp-v2/ocp-v2-styles.js +48 -19
  93. package/neural-interface/public/shared/ocp-v2/ocp-v2-ws.js +195 -19
  94. package/neural-interface/public/shared/opencode-providers.js +39 -0
  95. package/neural-interface/public/shared/schedules-view.js +318 -0
  96. package/neural-interface/public/shared/settings/settings-app-pane.js +335 -0
  97. package/neural-interface/public/shared/settings/settings-app.js +243 -0
  98. package/neural-interface/public/shared/settings/settings-data.js +88 -0
  99. package/neural-interface/public/shared/settings/settings-ia.js +17 -0
  100. package/neural-interface/public/shared/sidepanel-session-status.js +49 -0
  101. package/neural-interface/public/shared/styles.css +540 -371
  102. package/neural-interface/public/shared/ui-assistant.js +27 -5
  103. package/neural-interface/public/shared/ui-automation-studio.js +67 -27
  104. package/neural-interface/public/shared/ui-bookmarks.js +2 -1
  105. package/neural-interface/public/shared/ui-claude-panel.js +76 -8
  106. package/neural-interface/public/shared/ui-codex-panel.js +1 -0
  107. package/neural-interface/public/shared/ui-detail.js +6 -6
  108. package/neural-interface/public/shared/ui-file-links.js +1 -0
  109. package/neural-interface/public/shared/ui-image-gallery.js +6 -5
  110. package/neural-interface/public/shared/ui-invite.js +18 -2
  111. package/neural-interface/public/shared/ui-link.js +9 -9
  112. package/neural-interface/public/shared/ui-menubar.js +232 -33
  113. package/neural-interface/public/shared/ui-native-loop-router.js +2 -0
  114. package/neural-interface/public/shared/ui-opencode-panel-v2.js +1 -0
  115. package/neural-interface/public/shared/ui-schedules-studio.js +2099 -869
  116. package/neural-interface/public/shared/ui-sessions.js +15 -4
  117. package/neural-interface/public/shared/ui-settings.js +87 -36
  118. package/neural-interface/public/shared/ui-sidebar.js +4 -4
  119. package/neural-interface/public/shared/ui-sidepanel-session-entry.js +13 -0
  120. package/neural-interface/public/shared/ui-sidepanel-sessions.js +55 -4
  121. package/neural-interface/public/shared/ui-sidepanel-tray.js +84 -8
  122. package/neural-interface/public/shared/ui-skills.js +70 -12
  123. package/neural-interface/public/shared/ui-sync.js +7 -0
  124. package/neural-interface/public/shared/ui-terminal.js +36 -20
  125. package/neural-interface/public/shared/ui-trash.js +8 -1
  126. package/neural-interface/public/shared/ui-tutorial-steps.js +7 -3
  127. package/neural-interface/public/shared/ui-tutorial.js +15 -5
  128. package/neural-interface/public/shared/ui-update.js +83 -14
  129. package/neural-interface/public/shared/ui-whiteboard.js +2 -1
  130. package/neural-interface/public/variant/2d/main.js +4 -1
  131. package/neural-interface/public/variant/3d/main.js +3 -0
  132. package/neural-interface/public/vendor/highlight/LICENSE +29 -0
  133. package/neural-interface/public/vendor/highlight/github-dark-dimmed-11.12.0.min.css +9 -0
  134. package/neural-interface/public/vendor/highlight/highlight-11.12.0.min.js +1262 -0
  135. package/neural-interface/public/vendor/highlight/manifest.json +5 -0
  136. package/neural-interface/public/vendor/html2canvas/LICENSE +22 -0
  137. package/neural-interface/public/vendor/html2canvas/html2canvas-1.4.1.min.js +20 -0
  138. package/neural-interface/public/vendor/html2canvas/manifest.json +4 -0
  139. package/neural-interface/public/vendor/marked/LICENSE.md +44 -0
  140. package/neural-interface/public/vendor/marked/manifest.json +4 -0
  141. package/neural-interface/public/vendor/marked/marked-14.1.4.esm.js +2502 -0
  142. package/neural-interface/public/vendor/mermaid/LICENSE +21 -0
  143. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/abnfDiagram-PAR5IXJI.mjs +1 -0
  144. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/architecture-7GRP2DOG-M7G3SWCO.mjs +1 -0
  145. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/architectureDiagram-2PNWDENW.mjs +36 -0
  146. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/blockDiagram-PUWGUBOA.mjs +129 -0
  147. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/c4Diagram-3NLNHZP5.mjs +38 -0
  148. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-2NMSUPJH.mjs +1 -0
  149. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-32MCUW2P.mjs +206 -0
  150. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-3NPNU5GP.mjs +1 -0
  151. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-3SMGFRGC.mjs +1 -0
  152. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-4CAJECRU.mjs +14 -0
  153. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-4OADUZ5Q.mjs +10 -0
  154. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-5IMINLNL.mjs +1 -0
  155. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-5IQCK5RY.mjs +3 -0
  156. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-5MVFYWFU.mjs +1 -0
  157. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-AQ6EADP3.mjs +1 -0
  158. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-AZZRMDJM.mjs +15 -0
  159. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-CLS4B6BI.mjs +168 -0
  160. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-DZP67EKU.mjs +70 -0
  161. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-EICP7K5X.mjs +1 -0
  162. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-GDY2UAB4.mjs +1 -0
  163. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-H7VHZCWX.mjs +1 -0
  164. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-IJBDOHL6.mjs +1 -0
  165. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-JFFVMJIA.mjs +1 -0
  166. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-JQRUD6KW.mjs +1 -0
  167. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-JZGDI5JK.mjs +1 -0
  168. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-KD6SPIPN.mjs +2 -0
  169. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-NF366YI6.mjs +231 -0
  170. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-NUDPKBEF.mjs +32 -0
  171. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-OJINMHTS.mjs +1 -0
  172. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-Q6NGPIAH.mjs +2 -0
  173. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-QJSWEUOL.mjs +132 -0
  174. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-R7JDMUKV.mjs +1 -0
  175. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-RCXAM2GK.mjs +1 -0
  176. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-RT4MAWR3.mjs +1 -0
  177. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-SFMINX4W.mjs +1 -0
  178. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-SLDQ463B.mjs +88 -0
  179. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-STOV2HOB.mjs +1 -0
  180. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-T5OCTHI4.mjs +1 -0
  181. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-TCEHX7R3.mjs +1 -0
  182. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-VQC2EELJ.mjs +1 -0
  183. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-VRZKL3EH.mjs +1 -0
  184. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-VTHDQ7BV.mjs +1 -0
  185. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-VY2OSTJR.mjs +2 -0
  186. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-WUBWJARI.mjs +1 -0
  187. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-YBMQ5JGJ.mjs +2 -0
  188. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-YDMLL4PJ.mjs +1 -0
  189. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-Z6V44ARX.mjs +62 -0
  190. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZJJ7VQJP.mjs +339 -0
  191. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZNLK7HRR.mjs +1 -0
  192. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZQN7UHIL.mjs +1 -0
  193. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZS6VBONO.mjs +174 -0
  194. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZUNWM646.mjs +1 -0
  195. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/classDiagram-FGAMPOII.mjs +1 -0
  196. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/classDiagram-v2-AI5RJEK4.mjs +1 -0
  197. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/cose-bilkent-Q72C2OJ3.mjs +1 -0
  198. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/cynefin-OW5HDTMX-6OCTWOGG.mjs +1 -0
  199. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/cynefinDiagram-2OOWUY4M.mjs +62 -0
  200. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/dagre-MPVFI544.mjs +4 -0
  201. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-AE4NWXFW.mjs +24 -0
  202. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-BUJID5UG.mjs +41 -0
  203. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-C44CZ5NI.mjs +24 -0
  204. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-EYOLEXXS.mjs +30 -0
  205. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-P7B6PWOJ.mjs +3 -0
  206. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/ebnfDiagram-FTPZ3PV6.mjs +1 -0
  207. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/erDiagram-H3ERR26V.mjs +99 -0
  208. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/eventmodeling-NTZA5JFV-WKSWQHFS.mjs +1 -0
  209. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/flowDiagram-YHGXBVSY.mjs +1 -0
  210. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/ganttDiagram-RWFTB7ED.mjs +292 -0
  211. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/gitGraph-4MIJSDKK-JH2HKYUO.mjs +1 -0
  212. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/gitGraphDiagram-MAR6GKOP.mjs +106 -0
  213. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/info-A6RAGUB7-3TX3OFWW.mjs +1 -0
  214. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/infoDiagram-LV547AFH.mjs +2 -0
  215. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/ishikawaDiagram-PUJQGNDS.mjs +70 -0
  216. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/journeyDiagram-EW5QJT4W.mjs +139 -0
  217. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/kanban-definition-JSQERAZB.mjs +89 -0
  218. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/katex-CZ4GXH2S.mjs +257 -0
  219. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/mindmap-definition-VBJCLQLM.mjs +96 -0
  220. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/packet-AYTQ26CC-MKII6P3Y.mjs +1 -0
  221. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/pegDiagram-7WILOQTJ.mjs +1 -0
  222. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/pie-WAS4IAKB-6B4OPMJ5.mjs +1 -0
  223. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/pieDiagram-EFA7CBSB.mjs +39 -0
  224. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/quadrantDiagram-WARVYA7P.mjs +7 -0
  225. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/radar-RG4KPBEZ-UPTR3XUL.mjs +1 -0
  226. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroad-74A4TZTK-MEFUPFMS.mjs +1 -0
  227. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroad-abnf-HS5TGJTU-R5YG2S5D.mjs +1 -0
  228. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroad-ebnf-LZEXJU2U-G5QEX2L6.mjs +1 -0
  229. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroad-peg-WCYAUIDC-H5I2ZRY2.mjs +1 -0
  230. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroadDiagram-5NIQVNLQ.mjs +1 -0
  231. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/requirementDiagram-SXREGOKZ.mjs +84 -0
  232. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/sankeyDiagram-VV74M2VP.mjs +40 -0
  233. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/sequenceDiagram-52ZFIFDL.mjs +162 -0
  234. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/sizeCapture-FGA5AGYP.mjs +1 -0
  235. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/stateDiagram-3QAKPIVI.mjs +1 -0
  236. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/stateDiagram-v2-HN2P4RDZ.mjs +1 -0
  237. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/swimlanes-QLVP42QD.mjs +1 -0
  238. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/swimlanesDiagram-JKPDBFCN.mjs +8 -0
  239. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/timeline-definition-GS45XAXW.mjs +120 -0
  240. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/treeView-Q6P3EWNA-ZRJGANNQ.mjs +1 -0
  241. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/treemap-WGGIJYW6-K64VN5AS.mjs +1 -0
  242. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/vennDiagram-QIQU2ZRJ.mjs +34 -0
  243. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/wardley-WFR3VGLG-D67OWCCH.mjs +1 -0
  244. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/wardleyDiagram-U6YNM66N.mjs +78 -0
  245. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/xychartDiagram-XJAZEDNM.mjs +7 -0
  246. package/neural-interface/public/vendor/mermaid/manifest.json +4 -0
  247. package/neural-interface/public/vendor/mermaid/mermaid-11.17.2.esm.min.mjs +14 -0
  248. package/neural-interface/scripts/build-vendor.mjs +84 -3
  249. package/neural-interface/server.js +1099 -286
  250. package/npm-shrinkwrap.json +2 -2
  251. package/package.json +1 -1
  252. package/skills/synabun/modules/schedule.md +1 -1
@@ -259,11 +259,11 @@ async function _showSetupView() {
259
259
  <div class="link-setup-sessions">${sessions.map(s => {
260
260
  const meta = PROFILE_META[s.profile] || { label: s.profile, color: '#888' };
261
261
  return `
262
- <label class="link-setup-session" data-id="${s.id}">
263
- <input type="checkbox" value="${s.id}" />
262
+ <label class="link-setup-session" data-id="${_escapeHtml(s.id).replace(/"/g, '&quot;')}">
263
+ <input type="checkbox" value="${_escapeHtml(s.id).replace(/"/g, '&quot;')}" />
264
264
  <span class="link-setup-dot" style="background:${meta.color}"></span>
265
- <span class="link-setup-label">${meta.label}</span>
266
- <span class="link-setup-cwd">${s.cwd ? s.cwd.split(/[/\\]/).pop() : ''}</span>
265
+ <span class="link-setup-label">${_escapeHtml(meta.label)}</span>
266
+ <span class="link-setup-cwd">${s.cwd ? _escapeHtml(s.cwd.split(/[/\\]/).pop()) : ''}</span>
267
267
  </label>
268
268
  `;
269
269
  }).join('')}</div>
@@ -350,12 +350,12 @@ function _renderAgents(link) {
350
350
  return `
351
351
  <div class="link-agent ${active ? 'active' : ''}" data-idx="${i}">
352
352
  <span class="link-agent-dot" style="background:${meta.color}"></span>
353
- <span class="link-agent-name">${meta.label}</span>
353
+ <span class="link-agent-name">${_escapeHtml(meta.label)}</span>
354
354
  ${active ? '<span class="link-agent-typing">typing...</span>' : ''}
355
355
  </div>
356
356
  `;
357
357
  }).join('<span class="link-agent-arrow">⇄</span>')
358
- + `<span class="link-mode-badge ${link.mode || 'sidecar'}">${(link.mode || 'sidecar').toUpperCase()}</span>`;
358
+ + `<span class="link-mode-badge ${_escapeHtml(link.mode || 'sidecar').replace(/"/g, '&quot;')}">${_escapeHtml((link.mode || 'sidecar').toUpperCase())}</span>`;
359
359
  }
360
360
 
361
361
  function _renderControls(link) {
@@ -421,7 +421,7 @@ function _renderTargetSelector(link) {
421
421
  el.innerHTML = `<span class="link-target-label">Send to:</span>` +
422
422
  link.sessions.map((s, i) => {
423
423
  const meta = PROFILE_META[s.profile] || { label: s.profile, color: '#888' };
424
- return `<button class="link-target-btn ${i === 0 ? 'selected' : ''}" data-idx="${i}" style="--agent-color:${meta.color}">${meta.label}</button>`;
424
+ return `<button class="link-target-btn ${i === 0 ? 'selected' : ''}" data-idx="${i}" style="--agent-color:${meta.color}">${_escapeHtml(meta.label)}</button>`;
425
425
  }).join('');
426
426
 
427
427
  el.querySelectorAll('.link-target-btn').forEach(btn => {
@@ -452,7 +452,7 @@ function _renderMessages() {
452
452
  <div class="link-msg ${isUser ? 'link-msg-user' : 'link-msg-agent'}">
453
453
  <div class="link-msg-header">
454
454
  <span class="link-msg-dot" style="background:${meta.color}"></span>
455
- <span class="link-msg-name">${meta.label}</span>
455
+ <span class="link-msg-name">${_escapeHtml(meta.label)}</span>
456
456
  <span class="link-msg-time">${time}</span>
457
457
  </div>
458
458
  <div class="link-msg-content">${_escapeHtml(msg.content)}</div>
@@ -505,7 +505,7 @@ function _onSyncChunk(msg) {
505
505
  streamEl.innerHTML = `
506
506
  <div class="link-msg-header">
507
507
  <span class="link-msg-dot" style="background:${meta.color}"></span>
508
- <span class="link-msg-name">${meta.label}</span>
508
+ <span class="link-msg-name">${_escapeHtml(meta.label)}</span>
509
509
  <span class="link-msg-time">streaming...</span>
510
510
  </div>
511
511
  <div class="link-msg-content"></div>
@@ -23,6 +23,10 @@ const $ = (id) => document.getElementById(id);
23
23
 
24
24
  let openMenu = null; // currently open data-menu value, or null
25
25
  let hoverMode = false; // after first click, hovering over labels opens them
26
+ const SUBMENUS = new Map(); // submenu row (.menu-submenu-parent) → its panel (.menubar-submenu)
27
+ let openSub = null; // { parent, panel } of the submenu showing, or null
28
+ let subTimer = 0; // a pending hover open, switch or close of a submenu
29
+ let subPending = null; // the row that pending change is for
26
30
 
27
31
  // ── Public API ──
28
32
 
@@ -73,10 +77,11 @@ export function initMenubar() {
73
77
  }
74
78
  });
75
79
 
76
- // Escape closes menu
80
+ // Escape closes an open submenu (back to its row), then the menu
77
81
  document.addEventListener('keydown', (e) => {
78
82
  if (e.key === 'Escape' && openMenu) {
79
- closeAll();
83
+ if (openSub) closeSubmenu({ focusParent: true });
84
+ else closeAll();
80
85
  e.stopPropagation();
81
86
  }
82
87
  });
@@ -86,6 +91,8 @@ export function initMenubar() {
86
91
  if (!openMenu) return;
87
92
  const dropdown = document.querySelector('.menubar-item.open .menubar-dropdown');
88
93
  if (!dropdown) return;
94
+ // The keyboard is in an open submenu: its keys stay there.
95
+ if (submenuKey(e)) return;
89
96
 
90
97
  const allItems = [...dropdown.querySelectorAll('.menu-item:not(.disabled):not([hidden])')];
91
98
  if (allItems.length === 0) return;
@@ -98,11 +105,22 @@ export function initMenubar() {
98
105
  if (focused) focused.classList.remove('focused');
99
106
  idx = (idx + 1) % allItems.length;
100
107
  allItems[idx].classList.add('focused');
108
+ allItems[idx].scrollIntoView({ block: 'nearest' });
109
+ if (openSub && openSub.parent !== allItems[idx]) closeSubmenu();
101
110
  } else if (e.key === 'ArrowUp') {
102
111
  e.preventDefault();
103
112
  if (focused) focused.classList.remove('focused');
104
113
  idx = (idx - 1 + allItems.length) % allItems.length;
105
114
  allItems[idx].classList.add('focused');
115
+ allItems[idx].scrollIntoView({ block: 'nearest' });
116
+ if (openSub && openSub.parent !== allItems[idx]) closeSubmenu();
117
+ } else if (SUBMENUS.has(focused) && (e.key === 'Enter' || e.key === ' ' || e.key === 'ArrowRight')) {
118
+ e.preventDefault();
119
+ openSubmenu(focused, { focusFirst: true });
120
+ } else if (e.key === 'ArrowRight' && !focused && openSub) {
121
+ // Opened by hover: ArrowRight goes into it
122
+ e.preventDefault();
123
+ openSubmenu(openSub.parent, { focusFirst: true });
106
124
  } else if (e.key === 'Enter' && focused) {
107
125
  e.preventDefault();
108
126
  focused.click();
@@ -123,9 +141,11 @@ export function initMenubar() {
123
141
  wireGraphMenu();
124
142
  wireSkillsMenu();
125
143
  wireAutomationsMenu();
144
+ wireSchedulesButton();
126
145
  wireTerminalMenu();
127
146
  injectVariantMenuItems();
128
147
  populateLinkTypes();
148
+ wireSubmenus();
129
149
 
130
150
  // ── Guest permission visual feedback on menu items ──
131
151
  const MENU_PERM_MAP = {
@@ -134,9 +154,7 @@ export function initMenubar() {
134
154
  'menu-skills-import': 'skills',
135
155
  'menu-open-styleguide': 'styleGuide',
136
156
  'menu-open-automation-studio': 'automations',
137
- 'menu-automations-schedule-new': 'automations',
138
- 'menu-automations-quick-timer': 'automations',
139
- 'menu-automations-schedule-groups': 'automations',
157
+ 'menubar-schedules-btn': 'automations',
140
158
  'menu-automations-new': 'automations',
141
159
  'menu-automations-import': 'automations',
142
160
  'menu-terminal-assistant': 'terminal',
@@ -172,6 +190,7 @@ export function closeMenubar() {
172
190
  function openMenuById(menuId) {
173
191
  const menubar = document.querySelector('.menubar');
174
192
  if (!menubar) return;
193
+ closeSubmenu();
175
194
 
176
195
  // Close all first
177
196
  menubar.querySelectorAll('.menubar-item').forEach(item => {
@@ -190,12 +209,29 @@ function openMenuById(menuId) {
190
209
  if (menuId === 'bookmarks') emit('bookmarks:render');
191
210
  if (menuId === 'layouts') emit('layouts:render');
192
211
  if (menuId === 'resume') emit('resume:render');
212
+ fitDropdown(target);
213
+ }
214
+ }
215
+
216
+ // A menu taller than the room under the bar scrolls inside itself (Apps holds the Map and
217
+ // Games sections). Measured from the label, not the dropdown, which is still sliding in.
218
+ function fitDropdown(item) {
219
+ const dropdown = item.querySelector(':scope > .menubar-dropdown');
220
+ if (!dropdown || dropdown.classList.contains('menubar-dropdown--resume')) return;
221
+ dropdown.style.maxHeight = '';
222
+ dropdown.classList.remove('menubar-dropdown--scroll');
223
+ const top = item.getBoundingClientRect().bottom + 14;
224
+ const room = Math.floor(window.innerHeight - top - 12);
225
+ if (room > 120 && dropdown.scrollHeight > room) {
226
+ dropdown.style.maxHeight = room + 'px';
227
+ dropdown.classList.add('menubar-dropdown--scroll');
193
228
  }
194
229
  }
195
230
 
196
231
  function closeAll() {
197
232
  const menubar = document.querySelector('.menubar');
198
233
  if (!menubar) return;
234
+ closeSubmenu();
199
235
  menubar.querySelectorAll('.menubar-item').forEach(item => {
200
236
  item.classList.remove('open');
201
237
  const focused = item.querySelector('.menu-item.focused');
@@ -205,6 +241,181 @@ function closeAll() {
205
241
  hoverMode = false;
206
242
  }
207
243
 
244
+ // ── Submenus ──
245
+ // A dropdown row with data-submenu (Apps › Browser apps, Map, Games) opens the .menubar-submenu of
246
+ // that name beside the dropdown: on hover after a short intent delay, on click, and on Enter, Space
247
+ // or ArrowRight with its first entry focused. Hovering another row of the dropdown closes it after
248
+ // a grace delay, so the pointer can cross rows on its way in. One is open at a time.
249
+
250
+ const SUBMENU_OPEN_DELAY = 120;
251
+ const SUBMENU_GRACE = 300;
252
+ const SUBMENU_GAP = 2; // between the dropdown and the panel
253
+ const VIEWPORT_MARGIN = 8;
254
+
255
+ function wireSubmenus() {
256
+ document.querySelectorAll('.menubar-item').forEach(host => {
257
+ const dropdown = host.querySelector(':scope > .menubar-dropdown');
258
+ const rows = dropdown ? [...dropdown.querySelectorAll(':scope > .menu-submenu-parent')] : [];
259
+ if (!rows.length) return;
260
+ for (const row of rows) {
261
+ const panel = dropdown.querySelector(`:scope > .menubar-submenu[data-submenu-for="${row.dataset.submenu}"]`);
262
+ if (!panel) { row.hidden = true; continue; }
263
+ // Out of the dropdown, whose scroll box (fitDropdown) would clip it.
264
+ host.appendChild(panel);
265
+ SUBMENUS.set(row, panel);
266
+ row.addEventListener('click', () => openSubmenu(row));
267
+ panel.addEventListener('mouseenter', cancelSubmenuTimer);
268
+ }
269
+ dropdown.addEventListener('mouseover', (e) => {
270
+ const row = e.target.closest('.menu-item');
271
+ if (row && row.parentElement === dropdown) hoverRow(row);
272
+ });
273
+ dropdown.addEventListener('mouseleave', cancelSubmenuTimer);
274
+ dropdown.addEventListener('scroll', () => { if (openSub) placeSubmenu(openSub.parent, openSub.panel); }, { passive: true });
275
+ // The rows follow their entries ([hidden], display:none, a guest's blocked items), and the separators the rows.
276
+ const sync = () => syncSubmenuRows(dropdown);
277
+ new MutationObserver(sync).observe(host, { subtree: true, attributes: true, attributeFilter: ['hidden', 'style'] });
278
+ sync();
279
+ });
280
+ window.addEventListener('resize', () => { if (openSub) placeSubmenu(openSub.parent, openSub.panel); });
281
+ // The tour shows a submenu by name (ui-tutorial.js showStage); null closes it.
282
+ on('menubar:submenu', (name) => {
283
+ const row = name ? [...SUBMENUS.keys()].find(r => r.dataset.submenu === name) : null;
284
+ if (row && !row.hidden) openSubmenu(row);
285
+ else closeSubmenu();
286
+ });
287
+ }
288
+
289
+ function openSubmenu(row, { focusFirst = false } = {}) {
290
+ cancelSubmenuTimer();
291
+ const panel = SUBMENUS.get(row);
292
+ if (!panel || row.hidden) return;
293
+ if (openSub?.parent !== row) {
294
+ closeSubmenu();
295
+ openSub = { parent: row, panel };
296
+ row.classList.add('submenu-open');
297
+ row.setAttribute('aria-expanded', 'true');
298
+ panel.classList.add('open');
299
+ placeSubmenu(row, panel);
300
+ }
301
+ if (focusFirst) {
302
+ panel.querySelectorAll('.menu-item.focused').forEach(el => el.classList.remove('focused'));
303
+ submenuEntries(panel)[0]?.classList.add('focused');
304
+ }
305
+ }
306
+
307
+ function closeSubmenu({ focusParent = false } = {}) {
308
+ cancelSubmenuTimer();
309
+ if (!openSub) return;
310
+ const { parent, panel } = openSub;
311
+ openSub = null;
312
+ parent.classList.remove('submenu-open');
313
+ parent.setAttribute('aria-expanded', 'false');
314
+ panel.classList.remove('open');
315
+ panel.querySelectorAll('.menu-item.focused').forEach(el => el.classList.remove('focused'));
316
+ if (focusParent) {
317
+ parent.parentElement.querySelectorAll(':scope > .menu-item.focused').forEach(el => el.classList.remove('focused'));
318
+ parent.classList.add('focused');
319
+ }
320
+ }
321
+
322
+ function hoverRow(row) {
323
+ if (row === subPending) return; // still on the row the pending change is for: let it run
324
+ const opens = SUBMENUS.has(row) && !row.hidden;
325
+ if (openSub) {
326
+ if (row === openSub.parent) { cancelSubmenuTimer(); return; }
327
+ // The pointer may only be crossing this row on its way into the open submenu.
328
+ scheduleSubmenu(row, () => (opens ? openSubmenu(row) : closeSubmenu()), SUBMENU_GRACE);
329
+ } else if (opens) {
330
+ scheduleSubmenu(row, () => openSubmenu(row), SUBMENU_OPEN_DELAY);
331
+ } else {
332
+ cancelSubmenuTimer();
333
+ }
334
+ }
335
+
336
+ function scheduleSubmenu(row, fn, ms) {
337
+ clearTimeout(subTimer);
338
+ subPending = row;
339
+ subTimer = setTimeout(() => { subTimer = 0; subPending = null; fn(); }, ms);
340
+ }
341
+
342
+ function cancelSubmenuTimer() {
343
+ clearTimeout(subTimer);
344
+ subTimer = 0;
345
+ subPending = null;
346
+ }
347
+
348
+ // Keys for an open submenu the keyboard is in (one of its entries is focused). True when the key was its.
349
+ function submenuKey(e) {
350
+ const focused = openSub?.panel.querySelector('.menu-item.focused');
351
+ if (!focused) return false;
352
+ if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {
353
+ e.preventDefault();
354
+ const entries = submenuEntries(openSub.panel);
355
+ focused.classList.remove('focused');
356
+ if (!entries.length) return true;
357
+ const idx = entries.indexOf(focused), dir = e.key === 'ArrowDown' ? 1 : -1;
358
+ const next = idx < 0 ? (dir > 0 ? 0 : entries.length - 1) : (idx + dir + entries.length) % entries.length;
359
+ entries[next].classList.add('focused');
360
+ } else if (e.key === 'Enter' || e.key === ' ') {
361
+ e.preventDefault();
362
+ focused.click();
363
+ } else if (e.key === 'ArrowLeft') {
364
+ e.preventDefault();
365
+ closeSubmenu({ focusParent: true });
366
+ } else if (e.key === 'ArrowRight') {
367
+ e.preventDefault(); // no level below this one, and the menubar stays on this menu
368
+ } else {
369
+ return false;
370
+ }
371
+ return true;
372
+ }
373
+
374
+ // The entries the keyboard reaches: not [hidden], disabled or display:none (a guest's Rebuild map).
375
+ function submenuEntries(panel) {
376
+ return [...panel.querySelectorAll('.menu-item')]
377
+ .filter(el => !el.hidden && !el.classList.contains('disabled') && getComputedStyle(el).display !== 'none');
378
+ }
379
+
380
+ // Right of the dropdown with its first entry level with the row; on the left when the window has no room
381
+ // on the right, and kept inside the window. The dropdown's laid-out place (offsetTop/Left) is what its
382
+ // drop-in animation does not move, so a submenu opened together with the menu (the tour) lines up too.
383
+ function placeSubmenu(row, panel) {
384
+ const dropdown = row.parentElement, host = panel.parentElement;
385
+ const hostBox = host.getBoundingClientRect(), panelBox = panel.getBoundingClientRect();
386
+ const first = submenuEntries(panel)[0];
387
+ const lead = first ? first.getBoundingClientRect().top - panelBox.top : 0;
388
+ const top = dropdown.offsetTop + row.getBoundingClientRect().top - dropdown.getBoundingClientRect().top - lead;
389
+ let left = dropdown.offsetLeft + dropdown.offsetWidth + SUBMENU_GAP;
390
+ if (hostBox.left + left + panelBox.width > innerWidth - VIEWPORT_MARGIN) left = dropdown.offsetLeft - SUBMENU_GAP - panelBox.width;
391
+ const maxTop = innerHeight - VIEWPORT_MARGIN - panelBox.height - hostBox.top;
392
+ panel.style.left = `${Math.max(VIEWPORT_MARGIN - hostBox.left, left)}px`;
393
+ panel.style.top = `${Math.max(VIEWPORT_MARGIN - hostBox.top, Math.min(top, maxTop))}px`;
394
+ }
395
+
396
+ // A row whose entries are all hidden or blocked for a guest is hidden. Then each separator shows only
397
+ // between two groups with something on screen, so none is doubled or left at an end.
398
+ function syncSubmenuRows(dropdown) {
399
+ for (const row of dropdown.querySelectorAll(':scope > .menu-submenu-parent')) {
400
+ const panel = SUBMENUS.get(row);
401
+ const empty = !panel || !submenuEntries(panel).some(el => el.style.pointerEvents !== 'none');
402
+ if (row.hidden !== empty) row.hidden = empty;
403
+ if (empty && openSub?.parent === row) closeSubmenu();
404
+ }
405
+ const seps = new Map();
406
+ let shown = false, waiting = null;
407
+ for (const el of dropdown.children) {
408
+ if (el.classList.contains('menu-sep')) {
409
+ seps.set(el, false);
410
+ if (shown) { waiting = el; shown = false; }
411
+ } else if (el.matches('.menu-item, .menu-group-label') && getComputedStyle(el).display !== 'none') {
412
+ if (waiting) { seps.set(waiting, true); waiting = null; }
413
+ shown = true;
414
+ }
415
+ }
416
+ for (const [sep, show] of seps) if (sep.hidden === show) sep.hidden = !show;
417
+ }
418
+
208
419
  // ── View Menu ──
209
420
 
210
421
  function wireViewMenu() {
@@ -323,34 +534,6 @@ function wireAutomationsMenu() {
323
534
  emit('automations:open');
324
535
  });
325
536
  }
326
- const schedulesItem = $('menu-automations-schedules');
327
- if (schedulesItem) {
328
- schedulesItem.addEventListener('click', () => {
329
- closeAll();
330
- emit('automations:open-schedules');
331
- });
332
- }
333
- const newScheduleItem = $('menu-automations-schedule-new');
334
- if (newScheduleItem) {
335
- newScheduleItem.addEventListener('click', () => {
336
- closeAll();
337
- emit('automations:open-schedules', { action: 'new-schedule' });
338
- });
339
- }
340
- const quickTimerItem = $('menu-automations-quick-timer');
341
- if (quickTimerItem) {
342
- quickTimerItem.addEventListener('click', () => {
343
- closeAll();
344
- emit('automations:open-schedules', { action: 'quick-timer' });
345
- });
346
- }
347
- const scheduleGroupsItem = $('menu-automations-schedule-groups');
348
- if (scheduleGroupsItem) {
349
- scheduleGroupsItem.addEventListener('click', () => {
350
- closeAll();
351
- emit('automations:open-schedules', { tab: 'groups' });
352
- });
353
- }
354
537
  const newItem = $('menu-automations-new');
355
538
  if (newItem) {
356
539
  newItem.addEventListener('click', () => {
@@ -369,6 +552,22 @@ function wireAutomationsMenu() {
369
552
  registerAction('open-automations', () => emit('automations:open'));
370
553
  }
371
554
 
555
+ // ── Schedules (a menubar button: one click opens the window, the next closes it) ──
556
+
557
+ function wireSchedulesButton() {
558
+ const btn = $('menubar-schedules-btn');
559
+ if (!btn) return;
560
+ btn.addEventListener('click', () => {
561
+ closeAll();
562
+ emit('schedules:toggle');
563
+ });
564
+ // ui-schedules-studio.js reports the window opening and closing, whoever opened it.
565
+ on('schedules:window', ({ open } = {}) => {
566
+ btn.classList.toggle('active', !!open);
567
+ btn.setAttribute('aria-expanded', String(!!open));
568
+ });
569
+ }
570
+
372
571
  // ── Apps Menu (formerly Terminal) ──
373
572
 
374
573
  function wireTerminalMenu() {
@@ -404,6 +404,8 @@ export function initNativeLoopRouter() {
404
404
  on('sync:sidepanel:run-failed', route);
405
405
  on('sync:sidepanel:run-stopped', route);
406
406
  on('sync:sidepanel:provider-event', (message) => {
407
+ // An OpenCode worker's panel streams from its own serve: the sync copy of its tool calls is the Assistant's.
408
+ if (message?.event?.provider === 'opencode') return;
407
409
  const run = descriptorFrom(message);
408
410
  if (_suspended || !run?.runId || _dismissed.has(run.runId)) return;
409
411
  const claimAge = run.claimedAt ? Date.now() - new Date(run.claimedAt).getTime() : Infinity;
@@ -10,6 +10,7 @@
10
10
  export {
11
11
  toggleOpencodePanel,
12
12
  isOpencodePanelOpen,
13
+ bootOpencodePanel,
13
14
  openOpencodeWithPrompt,
14
15
  attachPathToOpencode,
15
16
  attachOpenCodeAutomation,