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
|
@@ -25,12 +25,21 @@
|
|
|
25
25
|
// • describeSdkError() — the message for an SDK error body. 1.18 errors come
|
|
26
26
|
// as `{ name, data: { message } }` or `{ _tag, message }`; a body with
|
|
27
27
|
// neither used to surface as the literal "opencode SDK error".
|
|
28
|
+
//
|
|
29
|
+
// OpenCode 2 (a different API: /api/*, a password per launch) gets the same
|
|
30
|
+
// wrapper: `connect` and `createClientInstance` take `{ protocol: 2, password }`
|
|
31
|
+
// and build lib/opencode2-client.js instead of the SDK client. It has the
|
|
32
|
+
// SDK client's methods and answers in OpenCode 1's shapes, so nothing below
|
|
33
|
+
// (and nothing that uses this module) changes with the major.
|
|
28
34
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
29
35
|
|
|
30
36
|
import { createOpencodeClient } from '@opencode-ai/sdk/v2';
|
|
37
|
+
import { createOpencode2Client } from './opencode2-client.js';
|
|
31
38
|
|
|
32
39
|
let _client = null;
|
|
33
40
|
let _port = null;
|
|
41
|
+
let _protocol = 1;
|
|
42
|
+
let _password = null;
|
|
34
43
|
let _abort = null;
|
|
35
44
|
let _running = false;
|
|
36
45
|
let _stopRequested = false;
|
|
@@ -58,16 +67,26 @@ export const event = {
|
|
|
58
67
|
},
|
|
59
68
|
};
|
|
60
69
|
|
|
61
|
-
|
|
70
|
+
/** The SDK client for an OpenCode 1 serve, the OpenCode 2 client for an OpenCode 2 serve. */
|
|
71
|
+
function clientFor({ port, protocol, password, version, clientFactory = createOpencodeClient, fetchImpl }) {
|
|
72
|
+
const baseUrl = `http://127.0.0.1:${port}`;
|
|
73
|
+
if (protocol === 2) return createOpencode2Client({ baseUrl, password, version, ...(fetchImpl ? { fetchImpl } : {}) });
|
|
74
|
+
return clientFactory({ baseUrl });
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export async function connect({ port, protocol = 1, password = null, version = '' }) {
|
|
62
78
|
if (!port) throw new Error('opencode-v2-client.connect: port required');
|
|
63
|
-
|
|
79
|
+
const wanted = protocol === 2 ? 2 : 1;
|
|
80
|
+
if (_client && _port === port && _running && _protocol === wanted && _password === (wanted === 2 ? password : null)) {
|
|
64
81
|
logv('connect: already connected to', port);
|
|
65
82
|
return;
|
|
66
83
|
}
|
|
67
84
|
await disconnect();
|
|
68
85
|
_stopRequested = false;
|
|
69
86
|
_port = port;
|
|
70
|
-
|
|
87
|
+
_protocol = wanted;
|
|
88
|
+
_password = wanted === 2 ? password : null;
|
|
89
|
+
_client = clientFor({ port, protocol: wanted, password, version });
|
|
71
90
|
_attempt = 0;
|
|
72
91
|
startSubscribeLoop().catch((err) => {
|
|
73
92
|
console.error('[ocp-v2-client] subscribe loop crashed:', err);
|
|
@@ -82,6 +101,8 @@ export async function disconnect() {
|
|
|
82
101
|
_abort = null;
|
|
83
102
|
_client = null;
|
|
84
103
|
_port = null;
|
|
104
|
+
_protocol = 1;
|
|
105
|
+
_password = null;
|
|
85
106
|
_connected = false;
|
|
86
107
|
_running = false;
|
|
87
108
|
}
|
|
@@ -89,6 +110,8 @@ export async function disconnect() {
|
|
|
89
110
|
export function getClient() { return _client; }
|
|
90
111
|
export function isConnected() { return _connected; }
|
|
91
112
|
export function getPort() { return _port; }
|
|
113
|
+
/** 1 or 2: the OpenCode major the shared client speaks. */
|
|
114
|
+
export function getProtocol() { return _protocol; }
|
|
92
115
|
|
|
93
116
|
async function startSubscribeLoop() {
|
|
94
117
|
_running = true;
|
|
@@ -386,9 +409,10 @@ export const extra = extraGroups(requireClient);
|
|
|
386
409
|
// completely untouched — it remains the shared-serve default, so the common path
|
|
387
410
|
// carries zero risk from this addition. Reuses the module-level unwrap()/clean().
|
|
388
411
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
389
|
-
export function createClientInstance({ port, clientFactory = createOpencodeClient }) {
|
|
412
|
+
export function createClientInstance({ port, clientFactory = createOpencodeClient, protocol = 1, password = null, version = '', fetchImpl = null }) {
|
|
390
413
|
if (!port) throw new Error('createClientInstance: port required');
|
|
391
|
-
|
|
414
|
+
const wanted = protocol === 2 ? 2 : 1;
|
|
415
|
+
let client = clientFor({ port, protocol: wanted, password, version, clientFactory, fetchImpl });
|
|
392
416
|
let abort = null;
|
|
393
417
|
let stopRequested = false;
|
|
394
418
|
let connected = false;
|
|
@@ -429,6 +453,9 @@ export function createClientInstance({ port, clientFactory = createOpencodeClien
|
|
|
429
453
|
|
|
430
454
|
const instance = {
|
|
431
455
|
port,
|
|
456
|
+
protocol: wanted,
|
|
457
|
+
/** The client underneath (the SDK's, or the OpenCode 2 one): raw requests the wrapper has no method for. */
|
|
458
|
+
getClient: () => client,
|
|
432
459
|
onEvent(fn) { listeners.add(fn); return () => listeners.delete(fn); },
|
|
433
460
|
start() { subscribeLoop().catch((e) => console.error('[ocp-v2-iso] subscribe crashed:', e)); },
|
|
434
461
|
async waitUntilConnected(timeoutMs = 10000) {
|
|
@@ -479,7 +506,7 @@ export function createClientInstance({ port, clientFactory = createOpencodeClien
|
|
|
479
506
|
}
|
|
480
507
|
|
|
481
508
|
export default {
|
|
482
|
-
connect, disconnect, getClient, isConnected, getPort,
|
|
509
|
+
connect, disconnect, getClient, isConnected, getPort, getProtocol,
|
|
483
510
|
event, session, permission, question, mcp, createClientInstance,
|
|
484
511
|
extra, describeSdkError, isCompactUnavailable, EXTRA_SDK_METHODS,
|
|
485
512
|
compactOrSummarize, lastModelOf,
|
|
@@ -35,6 +35,7 @@ import { readFileSync } from 'node:fs';
|
|
|
35
35
|
import { dirname, join } from 'node:path';
|
|
36
36
|
import { fileURLToPath } from 'node:url';
|
|
37
37
|
import { compactOrSummarize, lastModelOf } from './opencode-v2-client.js';
|
|
38
|
+
import { sessionTablesFor } from './opencode-db-schema.js';
|
|
38
39
|
|
|
39
40
|
export { lastModelOf };
|
|
40
41
|
|
|
@@ -277,7 +278,10 @@ export const SESSION_LIST_MAX = 500;
|
|
|
277
278
|
* search case-insensitive match on title, slug or directory
|
|
278
279
|
* Un-archiving writes time_archived = 0, so "live" is NULL or 0.
|
|
279
280
|
*/
|
|
280
|
-
|
|
281
|
+
// `flavor` 'v2' reads OpenCode 2's tables (session_v2, session_message; the
|
|
282
|
+
// columns this query names are the same), anything else OpenCode 1's.
|
|
283
|
+
export function buildSessionListQuery(options = {}, { flavor = 'v1' } = {}) {
|
|
284
|
+
const tables = sessionTablesFor(flavor);
|
|
281
285
|
const where = [];
|
|
282
286
|
const params = [];
|
|
283
287
|
where.push(options.archived === true
|
|
@@ -295,8 +299,8 @@ export function buildSessionListQuery(options = {}) {
|
|
|
295
299
|
const sql = `
|
|
296
300
|
SELECT s.id, s.title, s.directory, s.slug, s.project_id, s.parent_id, s.share_url,
|
|
297
301
|
s.time_created, s.time_updated, s.time_archived,
|
|
298
|
-
|
|
299
|
-
FROM session s
|
|
302
|
+
${tables.messageCount} AS message_count
|
|
303
|
+
FROM ${tables.session} s
|
|
300
304
|
WHERE ${where.join(' AND ')}
|
|
301
305
|
ORDER BY s.time_updated DESC${limit ? '\n LIMIT ?' : ''}
|
|
302
306
|
`;
|
|
@@ -922,8 +926,18 @@ export function opencodeSdkVersion() {
|
|
|
922
926
|
}
|
|
923
927
|
|
|
924
928
|
// Everything this server answers, for the panel's feature gating.
|
|
925
|
-
|
|
926
|
-
|
|
929
|
+
// What an OpenCode 2 serve has no counterpart for (lib/opencode2-client.js
|
|
930
|
+
// answers them with "not available"): the panel hides them, as it hides a
|
|
931
|
+
// feature an older SynaBun server lacks.
|
|
932
|
+
export const OPENCODE2_UNSUPPORTED_TYPES = Object.freeze([
|
|
933
|
+
'session:share', 'session:unshare', 'session:share:policy', 'message:delete',
|
|
934
|
+
'worktree:create', 'worktree:remove', 'mcp:authenticate',
|
|
935
|
+
]);
|
|
936
|
+
|
|
937
|
+
/** `protocol`: the OpenCode major the shared serve speaks (2 leaves out OPENCODE2_UNSUPPORTED_TYPES). */
|
|
938
|
+
export function opencodeV2WsCapabilities({ protocol = null } = {}) {
|
|
939
|
+
const all = [...OPENCODE_V2_WS_INLINE_TYPES, ...OPENCODE_V2_WS_MODULE_TYPES, ...OPENCODE_V2_WS_FEATURES];
|
|
940
|
+
return protocol === 2 ? all.filter((type) => !OPENCODE2_UNSUPPORTED_TYPES.includes(type)) : all;
|
|
927
941
|
}
|
|
928
942
|
|
|
929
943
|
export function ownsOpencodeV2Request(type) {
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the Assistant page sees of a dispatched OpenCode worker: its tool calls.
|
|
3
|
+
*
|
|
4
|
+
* Claude and Codex workers reach the page through the sync socket
|
|
5
|
+
* (sidepanel:provider-event); an OpenCode worker's events stay on its own
|
|
6
|
+
* isolated `opencode serve`, which only its V2 panel reads, so server.js keeps
|
|
7
|
+
* them off the socket. The Assistant's run stage and agents tray
|
|
8
|
+
* (public/shared/assistant/asst-scenes.js activityOf) only need to know which
|
|
9
|
+
* call the worker is on, so this relay forwards a copy of each tool call's
|
|
10
|
+
* start (its part turns `running`) and finish (`completed` or `error`), once
|
|
11
|
+
* each, in the real event shape: { provider: 'opencode', runId, eventType:
|
|
12
|
+
* 'message.part.updated', event: { sessionID, part: { type: 'tool', tool,
|
|
13
|
+
* callID, state: { status, input } } } }. Nothing else goes: no text,
|
|
14
|
+
* reasoning or file parts, no output, title, metadata or error text, and of
|
|
15
|
+
* the call's input only the short fields a step line names ("Editing
|
|
16
|
+
* router.js", "Running npm test", "Opening localhost:3344"), made safe
|
|
17
|
+
* (public/shared/assistant/asst-redact.js: credentials masked, a command's
|
|
18
|
+
* heredoc and inline file bodies omitted, an address without its query) and
|
|
19
|
+
* then clipped; a file tool's path only; never an edit's text, a written file
|
|
20
|
+
* or a typed value.
|
|
21
|
+
*
|
|
22
|
+
* Bounded: at most one event per run every `minIntervalMs`; a call seen inside
|
|
23
|
+
* the window waits for its end, the newest replacing the one before (so the
|
|
24
|
+
* page always learns the latest call), and a run's state goes with its end.
|
|
25
|
+
* Calls overlap (OpenCode runs tools in parallel): the end of a call older than
|
|
26
|
+
* one still running is no news to the page and is never sent, so it can never
|
|
27
|
+
* replace or follow the newer call's start, in the window or after it.
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
import { redactSecrets, safeCommand, safeUrl } from '../public/shared/assistant/asst-redact.js';
|
|
31
|
+
|
|
32
|
+
export const OPENCODE_ACTIVITY_MIN_MS = 250;
|
|
33
|
+
const MAX_CALLS_PER_RUN = 256; // callIDs remembered per run (start / finish seen)
|
|
34
|
+
const MAX_RUNS = 64; // runs tracked at once (each forgotten at its end)
|
|
35
|
+
const FIELD_MAX = 300; // characters of an input field
|
|
36
|
+
const PLAN_ITEMS = 20; // todowrite items forwarded
|
|
37
|
+
const PLAN_ITEM_MAX = 120;
|
|
38
|
+
|
|
39
|
+
const str = (v) => (v == null ? '' : String(v));
|
|
40
|
+
const clip = (v, max = FIELD_MAX) => {
|
|
41
|
+
const s = str(v).replace(/\s+/g, ' ').trim();
|
|
42
|
+
return s.length > max ? `${s.slice(0, max - 1).trimEnd()}…` : s;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/** Input fields a step line reads (asst-tool-kinds.js sayCall), whatever the tool. */
|
|
46
|
+
const STEP_FIELDS = Object.freeze([
|
|
47
|
+
'command', 'cmd', // a shell command
|
|
48
|
+
'filePath', 'file_path', 'path', 'notebook_path', // a file, a folder
|
|
49
|
+
'pattern', 'query', 'q', 'include', 'glob', // a search
|
|
50
|
+
'url', 'href', // a page
|
|
51
|
+
'element', 'label', 'name', 'target', 'selector', 'ref', 'key', 'keys', // a browser control, a key, never what is typed into it
|
|
52
|
+
'subagent_type', 'agent', 'action', // a sub-agent, a desktop or memory action
|
|
53
|
+
]);
|
|
54
|
+
const STEP_NUMBERS = Object.freeze(['offset', 'limit']);
|
|
55
|
+
/** Fields that are a step only for some tools: a click's visible text, a sub-agent's one-line description. */
|
|
56
|
+
const TOOL_FIELDS = Object.freeze([
|
|
57
|
+
[/(^|_)browser_(click|hover)$/i, ['text']],
|
|
58
|
+
[/^task$/i, ['description']],
|
|
59
|
+
]);
|
|
60
|
+
/** File tools: their step is the file, so the path is all that goes (a read keeps its line range). */
|
|
61
|
+
const FILE_TOOLS = /^(?:read|edit|write|patch|multiedit|notebook_?(?:read|edit))$/i;
|
|
62
|
+
const PATH_FIELDS = Object.freeze(['filePath', 'file_path', 'path', 'notebook_path']);
|
|
63
|
+
const COMMAND_FIELDS = new Set(['command', 'cmd']);
|
|
64
|
+
const URL_FIELDS = new Set(['url', 'href']);
|
|
65
|
+
|
|
66
|
+
/** A field as its step line may say it: a command and an address made safe, anything else masked, then clipped. */
|
|
67
|
+
function safeField(key, value) {
|
|
68
|
+
const text = COMMAND_FIELDS.has(key) ? safeCommand(value) : URL_FIELDS.has(key) ? safeUrl(value) : redactSecrets(value);
|
|
69
|
+
return clip(text);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* The part of a tool call's input its step line needs: a command with its credentials masked and its heredoc or
|
|
74
|
+
* inline file bodies left out, an address as scheme://host/path, a file tool's path only; every field masked
|
|
75
|
+
* (asst-redact.js) before it is clipped. Never an edit's text, a file's content or a typed value.
|
|
76
|
+
*/
|
|
77
|
+
export function stepInput(tool, input) {
|
|
78
|
+
const i = input && typeof input === 'object' && !Array.isArray(input) ? input : {};
|
|
79
|
+
const out = {};
|
|
80
|
+
const file = FILE_TOOLS.test(str(tool));
|
|
81
|
+
const fields = file ? [...PATH_FIELDS] : [...STEP_FIELDS];
|
|
82
|
+
if (!file) for (const [re, extra] of TOOL_FIELDS) if (re.test(str(tool))) fields.push(...extra);
|
|
83
|
+
for (const key of fields) {
|
|
84
|
+
const value = i[key];
|
|
85
|
+
if (typeof value === 'string' && value.trim()) out[key] = safeField(key, value);
|
|
86
|
+
else if (Array.isArray(value) && value.every((v) => typeof v === 'string')) {
|
|
87
|
+
const joined = safeField(key, value.join(' '));
|
|
88
|
+
if (joined) out[key] = joined;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
if (file && !/^read$/i.test(str(tool))) return out;
|
|
92
|
+
for (const key of STEP_NUMBERS) if (Number.isFinite(i[key])) out[key] = i[key];
|
|
93
|
+
if (file) return out;
|
|
94
|
+
// A plan: its items' words and states (planState's current step), never more than a short list.
|
|
95
|
+
if (Array.isArray(i.todos)) {
|
|
96
|
+
out.todos = i.todos.filter((x) => x && typeof x === 'object').slice(0, PLAN_ITEMS)
|
|
97
|
+
.map((x) => ({ content: clip(redactSecrets(x.content ?? x.text), PLAN_ITEM_MAX), status: clip(x.status, 24) }));
|
|
98
|
+
}
|
|
99
|
+
return out;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* One OpenCode provider event ({ provider, runId, eventType, event }, the
|
|
104
|
+
* adapter's onEvent payload) as a tool call's start or finish, or null for
|
|
105
|
+
* anything else (text, reasoning, files, a sub-agent's session, other events).
|
|
106
|
+
* → { callID, phase: 'start' | 'finish', payload } with `payload` the compact
|
|
107
|
+
* copy the page gets.
|
|
108
|
+
*/
|
|
109
|
+
export function openCodeToolCall(payload) {
|
|
110
|
+
if (!payload || payload.provider !== 'opencode' || payload.childSession) return null;
|
|
111
|
+
if (!/^message[.:]part[.:]updated$/i.test(str(payload.eventType))) return null;
|
|
112
|
+
const event = payload.event && typeof payload.event === 'object' ? payload.event : {};
|
|
113
|
+
const part = event.part && typeof event.part === 'object' ? event.part : null;
|
|
114
|
+
if (!part || part.type !== 'tool' || !str(part.tool).trim()) return null;
|
|
115
|
+
const status = str(part.state?.status);
|
|
116
|
+
const phase = status === 'running' ? 'start' : status === 'completed' || status === 'error' ? 'finish' : null;
|
|
117
|
+
if (!phase) return null; // pending: its input is still streaming
|
|
118
|
+
const tool = clip(part.tool, 160);
|
|
119
|
+
const callID = str(part.callID || part.id);
|
|
120
|
+
const sessionID = str(event.sessionID || part.sessionID) || undefined;
|
|
121
|
+
return {
|
|
122
|
+
callID,
|
|
123
|
+
phase,
|
|
124
|
+
payload: {
|
|
125
|
+
provider: 'opencode',
|
|
126
|
+
runId: payload.runId,
|
|
127
|
+
eventType: 'message.part.updated',
|
|
128
|
+
event: {
|
|
129
|
+
sessionID,
|
|
130
|
+
part: { id: str(part.id) || undefined, sessionID, messageID: str(part.messageID) || undefined, type: 'tool', callID, tool, state: { status, input: stepInput(tool, part.state?.input) } },
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const TERMINAL = new Set(['sidepanel:run-completed', 'sidepanel:run-failed', 'sidepanel:run-stopped']);
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* createOpenCodeActivityRelay({ send, minIntervalMs, now, setTimer, clearTimer })
|
|
140
|
+
* observe(message) takes every NativeLoopRuntime message (onEvent): it returns
|
|
141
|
+
* true for an OpenCode provider event, which it never passes on as it is
|
|
142
|
+
* (its tool calls go to send() as compact copies, at the bounded rate), and
|
|
143
|
+
* false for everything else, which the caller sends as before.
|
|
144
|
+
*/
|
|
145
|
+
export function createOpenCodeActivityRelay({
|
|
146
|
+
send,
|
|
147
|
+
minIntervalMs = OPENCODE_ACTIVITY_MIN_MS,
|
|
148
|
+
now = () => Date.now(),
|
|
149
|
+
setTimer = (fn, ms) => { const timer = setTimeout(fn, ms); timer.unref?.(); return timer; },
|
|
150
|
+
clearTimer = (timer) => clearTimeout(timer),
|
|
151
|
+
} = {}) {
|
|
152
|
+
const runs = new Map(); // runId → { calls: Map(callID → { phase, seq }), seq, last, pending, timer }
|
|
153
|
+
|
|
154
|
+
function forget(runId) {
|
|
155
|
+
const state = runs.get(runId);
|
|
156
|
+
if (!state) return;
|
|
157
|
+
if (state.timer) clearTimer(state.timer);
|
|
158
|
+
runs.delete(runId);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function stateOf(runId) {
|
|
162
|
+
let state = runs.get(runId);
|
|
163
|
+
if (!state) {
|
|
164
|
+
while (runs.size >= MAX_RUNS) forget(runs.keys().next().value);
|
|
165
|
+
state = { calls: new Map(), seq: 0, last: -Infinity, pending: null, timer: null };
|
|
166
|
+
runs.set(runId, state);
|
|
167
|
+
}
|
|
168
|
+
return state;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/** A call that started after the one `seq` names is still running. */
|
|
172
|
+
function newerRunning(state, callID, seq) {
|
|
173
|
+
for (const [id, c] of state.calls) if (id !== callID && c.phase === 'start' && c.seq > seq) return true;
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function emit(state, message) {
|
|
178
|
+
state.last = now();
|
|
179
|
+
try { send(message); } catch { /* the socket is gone */ }
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function flush(runId) {
|
|
183
|
+
const state = runs.get(runId);
|
|
184
|
+
if (!state) return;
|
|
185
|
+
state.timer = null;
|
|
186
|
+
const message = state.pending;
|
|
187
|
+
state.pending = null;
|
|
188
|
+
if (message) emit(state, message);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
function observe(message) {
|
|
192
|
+
const type = str(message?.type);
|
|
193
|
+
if (TERMINAL.has(type)) {
|
|
194
|
+
const runId = message.run?.runId || message.runId;
|
|
195
|
+
if (runId) forget(runId);
|
|
196
|
+
return false;
|
|
197
|
+
}
|
|
198
|
+
if (type !== 'sidepanel:provider-event' || message.event?.provider !== 'opencode') return false;
|
|
199
|
+
const call = openCodeToolCall(message.event);
|
|
200
|
+
const runId = str(message.run?.runId || message.event?.runId);
|
|
201
|
+
if (!call || !runId) return true;
|
|
202
|
+
const state = stateOf(runId);
|
|
203
|
+
// Once per call and phase (OpenCode updates a running part many times); a start after its finish is old news.
|
|
204
|
+
const seen = state.calls.get(call.callID);
|
|
205
|
+
if (call.callID && (seen?.phase === call.phase || seen?.phase === 'finish')) return true;
|
|
206
|
+
const seq = seen?.seq ?? ++state.seq; // the order calls started in (a call first seen at its end starts now)
|
|
207
|
+
if (call.callID) {
|
|
208
|
+
state.calls.delete(call.callID);
|
|
209
|
+
state.calls.set(call.callID, { phase: call.phase, seq });
|
|
210
|
+
while (state.calls.size > MAX_CALLS_PER_RUN) state.calls.delete(state.calls.keys().next().value);
|
|
211
|
+
}
|
|
212
|
+
// An older call's end, while a newer call runs: the page shows the newer one, and keeps it.
|
|
213
|
+
if (call.phase === 'finish' && newerRunning(state, call.callID, seq)) return true;
|
|
214
|
+
const out = { type: 'sidepanel:provider-event', run: message.run, event: call.payload };
|
|
215
|
+
const wait = state.last + minIntervalMs - now();
|
|
216
|
+
if (wait <= 0 && !state.timer) { emit(state, out); return true; }
|
|
217
|
+
state.pending = out; // the newest call the window held back
|
|
218
|
+
if (!state.timer) state.timer = setTimer(() => flush(runId), Math.max(0, wait));
|
|
219
|
+
return true;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
return {
|
|
223
|
+
observe,
|
|
224
|
+
/** Runs with state (tests and devtools). */
|
|
225
|
+
size: () => runs.size,
|
|
226
|
+
/** Drop every run's state and timer (shutdown). */
|
|
227
|
+
clear() { for (const runId of [...runs.keys()]) forget(runId); },
|
|
228
|
+
};
|
|
229
|
+
}
|