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.
- package/CHANGELOG.md +29 -0
- package/README.md +1 -1
- package/THIRD-PARTY-LICENSES.md +46 -4
- package/launcher.mjs +9 -3
- package/lib/start-launcher.js +6 -1
- package/mcp-server/package-lock.json +2 -2
- package/mcp-server/package.json +1 -1
- package/neural-interface/i18n/en.json +218 -7
- package/neural-interface/i18n/pt-BR.json +220 -9
- package/neural-interface/lib/account-usage.js +5 -3
- package/neural-interface/lib/app-controls-api.js +161 -0
- package/neural-interface/lib/assistant-api.js +21 -7
- package/neural-interface/lib/assistant-brains/opencode.js +13 -1
- package/neural-interface/lib/assistant-brains/opencode2-browser-policy/index.js +44 -0
- package/neural-interface/lib/assistant-brains/opencode2-route-gate/index.js +57 -0
- package/neural-interface/lib/assistant-catalog.js +17 -2
- package/neural-interface/lib/assistant-dispatch.js +3 -0
- package/neural-interface/lib/assistant-envelope.js +19 -1
- package/neural-interface/lib/assistant-runtime.js +127 -8
- package/neural-interface/lib/claude-model-catalog.js +64 -14
- package/neural-interface/lib/codex-settings-schema.js +109 -47
- package/neural-interface/lib/editor-completion-opencode.js +132 -35
- package/neural-interface/lib/exec-loop-command.js +8 -1
- package/neural-interface/lib/launch-cache.js +293 -0
- package/neural-interface/lib/login-start.js +524 -0
- package/neural-interface/lib/native-loop-providers.js +18 -3
- package/neural-interface/lib/native-loop-runtime.js +19 -0
- package/neural-interface/lib/opencode-db-schema.js +75 -0
- package/neural-interface/lib/opencode-history.js +16 -1
- package/neural-interface/lib/opencode-protocol.js +173 -0
- package/neural-interface/lib/opencode-provider-view.js +81 -0
- package/neural-interface/lib/opencode-runtime-config.js +10 -3
- package/neural-interface/lib/opencode-serve-records.js +606 -0
- package/neural-interface/lib/opencode-v2-client.js +33 -6
- package/neural-interface/lib/opencode-v2-ws-requests.js +19 -5
- package/neural-interface/lib/opencode-worker-activity.js +229 -0
- package/neural-interface/lib/opencode2-client.js +760 -0
- package/neural-interface/lib/opencode2-proxy.js +116 -0
- package/neural-interface/lib/opencode2-translate.js +1008 -0
- package/neural-interface/lib/process-identity.js +361 -0
- package/neural-interface/lib/session-cache-builder.js +26 -5
- package/neural-interface/lib/session-title-generator.js +18 -0
- package/neural-interface/lib/style-guide/api.js +4 -3
- package/neural-interface/lib/untrusted-file-headers.js +27 -0
- package/neural-interface/package-lock.json +1343 -45
- package/neural-interface/package.json +5 -1
- package/neural-interface/public/index.html +2 -2
- package/neural-interface/public/shared/agent-runtime-options.js +55 -11
- package/neural-interface/public/shared/assistant/asst-agents-dock.js +172 -17
- package/neural-interface/public/shared/assistant/asst-api.js +11 -3
- package/neural-interface/public/shared/assistant/asst-brain-picker.js +195 -80
- package/neural-interface/public/shared/assistant/asst-composer.js +1 -1
- package/neural-interface/public/shared/assistant/asst-hosts.js +49 -2
- package/neural-interface/public/shared/assistant/asst-menu.js +77 -6
- package/neural-interface/public/shared/assistant/asst-panel.js +197 -33
- package/neural-interface/public/shared/assistant/asst-rack-styles.js +28 -10
- package/neural-interface/public/shared/assistant/asst-redact.js +186 -0
- package/neural-interface/public/shared/assistant/asst-render.js +382 -36
- package/neural-interface/public/shared/assistant/asst-run-stage.js +231 -0
- package/neural-interface/public/shared/assistant/asst-sanitize.js +193 -3
- package/neural-interface/public/shared/assistant/asst-scene-styles.js +273 -0
- package/neural-interface/public/shared/assistant/asst-scenes.js +528 -0
- package/neural-interface/public/shared/assistant/asst-sidepanel-styles.js +3 -15
- package/neural-interface/public/shared/assistant/asst-state.js +14 -0
- package/neural-interface/public/shared/assistant/asst-styles.js +43 -0
- package/neural-interface/public/shared/assistant/asst-tool-kinds.js +13 -1
- package/neural-interface/public/shared/cc-dropdown.js +480 -0
- package/neural-interface/public/shared/cdx/cdx-panel.js +13 -1
- package/neural-interface/public/shared/cdx/cdx-render.js +15 -3
- package/neural-interface/public/shared/cdx/cdx-styles.js +4 -0
- package/neural-interface/public/shared/cdx/cdx-tabs.js +149 -35
- package/neural-interface/public/shared/cp/cp-markdown.js +4 -57
- package/neural-interface/public/shared/data-cache.js +223 -0
- package/neural-interface/public/shared/desktop-bridge.js +11 -0
- package/neural-interface/public/shared/desktop-titlebar-view.js +78 -1
- package/neural-interface/public/shared/desktop-titlebar.js +214 -28
- package/neural-interface/public/shared/desktop-update-view.js +15 -5
- package/neural-interface/public/shared/file-links.js +73 -8
- package/neural-interface/public/shared/html-shell.js +74 -80
- package/neural-interface/public/shared/launch-prefetch.js +59 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-caps.js +3 -2
- package/neural-interface/public/shared/ocp-v2/ocp-v2-childpanel.js +7 -2
- package/neural-interface/public/shared/ocp-v2/ocp-v2-modelpicker.js +54 -17
- package/neural-interface/public/shared/ocp-v2/ocp-v2-panel.js +93 -2
- package/neural-interface/public/shared/ocp-v2/ocp-v2-projectbar.js +3 -2
- package/neural-interface/public/shared/ocp-v2/ocp-v2-providers.js +11 -9
- package/neural-interface/public/shared/ocp-v2/ocp-v2-rehydrate.js +15 -4
- package/neural-interface/public/shared/ocp-v2/ocp-v2-render.js +1 -1
- package/neural-interface/public/shared/ocp-v2/ocp-v2-send-logic.js +401 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-send.js +16 -9
- package/neural-interface/public/shared/ocp-v2/ocp-v2-sessions-logic.js +60 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-styles.js +48 -19
- package/neural-interface/public/shared/ocp-v2/ocp-v2-ws.js +195 -19
- package/neural-interface/public/shared/opencode-providers.js +39 -0
- package/neural-interface/public/shared/schedules-view.js +318 -0
- package/neural-interface/public/shared/settings/settings-app-pane.js +335 -0
- package/neural-interface/public/shared/settings/settings-app.js +243 -0
- package/neural-interface/public/shared/settings/settings-data.js +88 -0
- package/neural-interface/public/shared/settings/settings-ia.js +17 -0
- package/neural-interface/public/shared/sidepanel-session-status.js +49 -0
- package/neural-interface/public/shared/styles.css +540 -371
- package/neural-interface/public/shared/ui-assistant.js +27 -5
- package/neural-interface/public/shared/ui-automation-studio.js +67 -27
- package/neural-interface/public/shared/ui-bookmarks.js +2 -1
- package/neural-interface/public/shared/ui-claude-panel.js +76 -8
- package/neural-interface/public/shared/ui-codex-panel.js +1 -0
- package/neural-interface/public/shared/ui-detail.js +6 -6
- package/neural-interface/public/shared/ui-file-links.js +1 -0
- package/neural-interface/public/shared/ui-image-gallery.js +6 -5
- package/neural-interface/public/shared/ui-invite.js +18 -2
- package/neural-interface/public/shared/ui-link.js +9 -9
- package/neural-interface/public/shared/ui-menubar.js +232 -33
- package/neural-interface/public/shared/ui-native-loop-router.js +2 -0
- package/neural-interface/public/shared/ui-opencode-panel-v2.js +1 -0
- package/neural-interface/public/shared/ui-schedules-studio.js +2099 -869
- package/neural-interface/public/shared/ui-sessions.js +15 -4
- package/neural-interface/public/shared/ui-settings.js +87 -36
- package/neural-interface/public/shared/ui-sidebar.js +4 -4
- package/neural-interface/public/shared/ui-sidepanel-session-entry.js +13 -0
- package/neural-interface/public/shared/ui-sidepanel-sessions.js +55 -4
- package/neural-interface/public/shared/ui-sidepanel-tray.js +84 -8
- package/neural-interface/public/shared/ui-skills.js +70 -12
- package/neural-interface/public/shared/ui-sync.js +7 -0
- package/neural-interface/public/shared/ui-terminal.js +36 -20
- package/neural-interface/public/shared/ui-trash.js +8 -1
- package/neural-interface/public/shared/ui-tutorial-steps.js +7 -3
- package/neural-interface/public/shared/ui-tutorial.js +15 -5
- package/neural-interface/public/shared/ui-update.js +83 -14
- package/neural-interface/public/shared/ui-whiteboard.js +2 -1
- package/neural-interface/public/variant/2d/main.js +4 -1
- package/neural-interface/public/variant/3d/main.js +3 -0
- package/neural-interface/public/vendor/highlight/LICENSE +29 -0
- package/neural-interface/public/vendor/highlight/github-dark-dimmed-11.12.0.min.css +9 -0
- package/neural-interface/public/vendor/highlight/highlight-11.12.0.min.js +1262 -0
- package/neural-interface/public/vendor/highlight/manifest.json +5 -0
- package/neural-interface/public/vendor/html2canvas/LICENSE +22 -0
- package/neural-interface/public/vendor/html2canvas/html2canvas-1.4.1.min.js +20 -0
- package/neural-interface/public/vendor/html2canvas/manifest.json +4 -0
- package/neural-interface/public/vendor/marked/LICENSE.md +44 -0
- package/neural-interface/public/vendor/marked/manifest.json +4 -0
- package/neural-interface/public/vendor/marked/marked-14.1.4.esm.js +2502 -0
- package/neural-interface/public/vendor/mermaid/LICENSE +21 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/abnfDiagram-PAR5IXJI.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/architecture-7GRP2DOG-M7G3SWCO.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/architectureDiagram-2PNWDENW.mjs +36 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/blockDiagram-PUWGUBOA.mjs +129 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/c4Diagram-3NLNHZP5.mjs +38 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-2NMSUPJH.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-32MCUW2P.mjs +206 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-3NPNU5GP.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-3SMGFRGC.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-4CAJECRU.mjs +14 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-4OADUZ5Q.mjs +10 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-5IMINLNL.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-5IQCK5RY.mjs +3 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-5MVFYWFU.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-AQ6EADP3.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-AZZRMDJM.mjs +15 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-CLS4B6BI.mjs +168 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-DZP67EKU.mjs +70 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-EICP7K5X.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-GDY2UAB4.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-H7VHZCWX.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-IJBDOHL6.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-JFFVMJIA.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-JQRUD6KW.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-JZGDI5JK.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-KD6SPIPN.mjs +2 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-NF366YI6.mjs +231 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-NUDPKBEF.mjs +32 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-OJINMHTS.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-Q6NGPIAH.mjs +2 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-QJSWEUOL.mjs +132 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-R7JDMUKV.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-RCXAM2GK.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-RT4MAWR3.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-SFMINX4W.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-SLDQ463B.mjs +88 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-STOV2HOB.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-T5OCTHI4.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-TCEHX7R3.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-VQC2EELJ.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-VRZKL3EH.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-VTHDQ7BV.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-VY2OSTJR.mjs +2 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-WUBWJARI.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-YBMQ5JGJ.mjs +2 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-YDMLL4PJ.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-Z6V44ARX.mjs +62 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZJJ7VQJP.mjs +339 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZNLK7HRR.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZQN7UHIL.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZS6VBONO.mjs +174 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZUNWM646.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/classDiagram-FGAMPOII.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/classDiagram-v2-AI5RJEK4.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/cose-bilkent-Q72C2OJ3.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/cynefin-OW5HDTMX-6OCTWOGG.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/cynefinDiagram-2OOWUY4M.mjs +62 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/dagre-MPVFI544.mjs +4 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-AE4NWXFW.mjs +24 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-BUJID5UG.mjs +41 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-C44CZ5NI.mjs +24 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-EYOLEXXS.mjs +30 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-P7B6PWOJ.mjs +3 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/ebnfDiagram-FTPZ3PV6.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/erDiagram-H3ERR26V.mjs +99 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/eventmodeling-NTZA5JFV-WKSWQHFS.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/flowDiagram-YHGXBVSY.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/ganttDiagram-RWFTB7ED.mjs +292 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/gitGraph-4MIJSDKK-JH2HKYUO.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/gitGraphDiagram-MAR6GKOP.mjs +106 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/info-A6RAGUB7-3TX3OFWW.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/infoDiagram-LV547AFH.mjs +2 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/ishikawaDiagram-PUJQGNDS.mjs +70 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/journeyDiagram-EW5QJT4W.mjs +139 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/kanban-definition-JSQERAZB.mjs +89 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/katex-CZ4GXH2S.mjs +257 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/mindmap-definition-VBJCLQLM.mjs +96 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/packet-AYTQ26CC-MKII6P3Y.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/pegDiagram-7WILOQTJ.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/pie-WAS4IAKB-6B4OPMJ5.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/pieDiagram-EFA7CBSB.mjs +39 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/quadrantDiagram-WARVYA7P.mjs +7 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/radar-RG4KPBEZ-UPTR3XUL.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroad-74A4TZTK-MEFUPFMS.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroad-abnf-HS5TGJTU-R5YG2S5D.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroad-ebnf-LZEXJU2U-G5QEX2L6.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroad-peg-WCYAUIDC-H5I2ZRY2.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroadDiagram-5NIQVNLQ.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/requirementDiagram-SXREGOKZ.mjs +84 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/sankeyDiagram-VV74M2VP.mjs +40 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/sequenceDiagram-52ZFIFDL.mjs +162 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/sizeCapture-FGA5AGYP.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/stateDiagram-3QAKPIVI.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/stateDiagram-v2-HN2P4RDZ.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/swimlanes-QLVP42QD.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/swimlanesDiagram-JKPDBFCN.mjs +8 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/timeline-definition-GS45XAXW.mjs +120 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/treeView-Q6P3EWNA-ZRJGANNQ.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/treemap-WGGIJYW6-K64VN5AS.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/vennDiagram-QIQU2ZRJ.mjs +34 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/wardley-WFR3VGLG-D67OWCCH.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/wardleyDiagram-U6YNM66N.mjs +78 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/xychartDiagram-XJAZEDNM.mjs +7 -0
- package/neural-interface/public/vendor/mermaid/manifest.json +4 -0
- package/neural-interface/public/vendor/mermaid/mermaid-11.17.2.esm.min.mjs +14 -0
- package/neural-interface/scripts/build-vendor.mjs +84 -3
- package/neural-interface/server.js +1099 -286
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- 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, '"')}">
|
|
263
|
+
<input type="checkbox" value="${_escapeHtml(s.id).replace(/"/g, '"')}" />
|
|
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, '"')}">${_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
|
-
|
|
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
|
-
'
|
|
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;
|