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
|
@@ -51,15 +51,16 @@ import { cachedProjects, createBrainPicker, testDensityLabel } from './asst-brai
|
|
|
51
51
|
import { createRovingToolbar } from './asst-roving.js';
|
|
52
52
|
import { openAccountsManager } from './asst-accounts.js';
|
|
53
53
|
import { createAgentsDock } from './asst-agents-dock.js';
|
|
54
|
+
import { activityOf } from './asst-scenes.js';
|
|
54
55
|
import { createUsageGauge } from './asst-usage.js';
|
|
55
|
-
import { closeMenu, isMenuOpen, openMenu } from './asst-menu.js';
|
|
56
|
+
import { closeMenu, currentMenuAnchor, isMenuOpen, openMenu } from './asst-menu.js';
|
|
56
57
|
import { createRouteModeControl, openModelsManager, openRoutesEditor, refreshModelsManager, renderRouteCard, routeModeLabel } from './asst-route.js';
|
|
57
58
|
import { budgetChipText, budgetSpendText, budgetTone, closeBudgetEditor, createBudgetController, mountBudgetChip, openBudgetEditor } from './asst-budget.js';
|
|
58
59
|
import { computerRemoteView, createComputerPanel, createComputerToggle, normalizeComputerRemote, openFrameLightbox, closeFrameLightbox, requestDesktopStop } from './asst-computer.js';
|
|
59
60
|
import {
|
|
60
61
|
applyLimit, applyLimitPacket, applyUsagePacket, brainLabel, createRenameWriter, createTabState, DEFAULT_ROUTE_MODE, deserializeTabState, fmtCost, fmtRunLine, limitExpiresIn, limitNoticeText, modelShortName,
|
|
61
62
|
brainModePatch, normalizeBrain, normalizeComputerMode, permissionModeLabel, normalizeRouteMode, normalizeTestDensity, projectLabel, providerShortLabel, readStoredBrain, runFromPayload,
|
|
62
|
-
serializeTabState, tabStorageKey, userSessionTitle,
|
|
63
|
+
serializeTabState, sessionStatus, tabStorageKey, userSessionTitle,
|
|
63
64
|
} from './asst-state.js';
|
|
64
65
|
import {
|
|
65
66
|
closeAssistantSession, dispatchAssistantRun, escalateAssistantRun, focusAssistantRun, getAssistantRun,
|
|
@@ -74,6 +75,7 @@ const ICON_COG = '<svg viewBox="0 0 24 24"><path d="M12.22 2h-.44a2 2 0 0 0-2 2v
|
|
|
74
75
|
const ICON_ROUTE = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 7h13l-3-3M20 17H7l3 3"/></svg>';
|
|
75
76
|
const ICON_COMPUTER = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="12" rx="2"/><path d="M8 20h8M12 16v4"/></svg>';
|
|
76
77
|
const ICON_CLOSE = '<svg viewBox="0 0 24 24"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>';
|
|
78
|
+
const ICON_TRASH = '<svg viewBox="0 0 24 24"><path d="M3 6h18M8 6V4.5A1.5 1.5 0 0 1 9.5 3h5A1.5 1.5 0 0 1 16 4.5V6M18.5 6l-.8 13a2 2 0 0 1-2 1.9H8.3a2 2 0 0 1-2-1.9L5.5 6M10 11v6M14 11v6"/></svg>';
|
|
77
79
|
const REPLAY_WAIT_MS = 1500; // a replay that stops short of its count is drawn after this long
|
|
78
80
|
|
|
79
81
|
function el(tag, className, text) {
|
|
@@ -148,7 +150,9 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
148
150
|
usageView: saved?.usageView || null,
|
|
149
151
|
});
|
|
150
152
|
Object.assign(st, {
|
|
151
|
-
status: 'idle',
|
|
153
|
+
status: 'idle', // the brain's own: its turn, its cards (setStatus)
|
|
154
|
+
workers: { working: 0, waiting: 0 }, // its dispatched agents, from the agents tray (sessionStatus)
|
|
155
|
+
shownStatus: 'idle', // what the host shows: both together (pushStatus)
|
|
152
156
|
dispatchUsd: 0,
|
|
153
157
|
serverCost: false,
|
|
154
158
|
engine: '',
|
|
@@ -165,6 +169,9 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
165
169
|
desktopProbe: false,
|
|
166
170
|
routingProbe: false,
|
|
167
171
|
sessionTitle: String(session?.title || ''), // the server's name (the user's rename, else the first prompt): history + notifications
|
|
172
|
+
// Whether this session holds a chat (a prompt was sent): until then the server keeps it as a draft,
|
|
173
|
+
// New reuses it, and leaving it for another session closes it (nothing of it is stored).
|
|
174
|
+
chatStarted: !!session?.chatStartedAt || Number(session?.turns) > 0,
|
|
168
175
|
});
|
|
169
176
|
let recordName = userSessionTitle(session); // the name the session record holds as the user's ('' = never renamed)
|
|
170
177
|
const controls = new Map(); // requestId → { card, origin, kind }
|
|
@@ -315,18 +322,33 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
315
322
|
notify(host.notifySource || 'cli', type, notifyLabel(), { sessionId, provider: 'assistant', panel: 'assistant' });
|
|
316
323
|
}
|
|
317
324
|
|
|
318
|
-
/** root[data-status] and data-computer drive status styling (the live dot, the Computer switch). */
|
|
325
|
+
/** root[data-status] (the session's status, sessionStatus) and data-computer drive status styling (the live dot, the Computer switch). */
|
|
319
326
|
function renderStatus() {
|
|
320
|
-
root.dataset.status = st.
|
|
327
|
+
root.dataset.status = st.shownStatus || 'idle';
|
|
321
328
|
if (st.desktopActive) root.dataset.computer = 'active';
|
|
322
329
|
else delete root.dataset.computer;
|
|
323
330
|
}
|
|
324
331
|
|
|
332
|
+
/** The brain's own status: its turn ('working', 'done', 'idle') and its cards ('action'). */
|
|
325
333
|
function setStatus(status) {
|
|
326
334
|
st.status = status || 'idle';
|
|
327
|
-
|
|
335
|
+
pushStatus(true);
|
|
328
336
|
syncBlocked();
|
|
329
|
-
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* What the host shows (tray pill, header, terminal badge) is the session's status: the brain's own and
|
|
341
|
+
* its dispatched agents' together (asst-state.js sessionStatus), so the gold stays while a worker works
|
|
342
|
+
* after the turn that dispatched it ended, and a worker that waits on you makes the session need you.
|
|
343
|
+
* The brain's own changes always reach the host; a change of the agents' counts only when the status moved.
|
|
344
|
+
*/
|
|
345
|
+
function pushStatus(always = false) {
|
|
346
|
+
if (destroyed) return;
|
|
347
|
+
const next = sessionStatus(st.status, st.workers);
|
|
348
|
+
if (!always && next === st.shownStatus) return;
|
|
349
|
+
st.shownStatus = next;
|
|
350
|
+
renderStatus();
|
|
351
|
+
try { host.setStatus?.(next); } catch { /* ignore */ }
|
|
330
352
|
}
|
|
331
353
|
|
|
332
354
|
/**
|
|
@@ -632,13 +654,24 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
632
654
|
onStopAll: () => stopAll(),
|
|
633
655
|
onRemove: (runId) => removeRun(runId),
|
|
634
656
|
onClearFinished: () => clearFinished(),
|
|
657
|
+
// A mini scene or a lane: that run's card in the transcript (drawn first when this window never got it).
|
|
658
|
+
onReveal: (runId) => {
|
|
659
|
+
if (renderer.revealRun(runId)) return;
|
|
660
|
+
const run = dock.getRun(runId);
|
|
661
|
+
if (run) { renderer.restoreRuns([run]); renderer.revealRun(runId); }
|
|
662
|
+
},
|
|
663
|
+
// Whatever told the tray (the sync bus, its fetch), the transcript's card and route line follow.
|
|
664
|
+
onRunChange: (run) => renderer.syncRun(run),
|
|
635
665
|
onToggle: (open) => { st.dockOpen = open; agentsBtn.setAttribute('aria-pressed', open ? 'true' : 'false'); persist(); },
|
|
636
666
|
onShowAllChange: (showAll) => { st.dockShowAll = showAll; persist(); },
|
|
637
|
-
onCountChange: ({ total, active, attention, visible: shown }) => {
|
|
667
|
+
onCountChange: ({ total, active, attention, working = 0, waiting = 0, visible: shown }) => {
|
|
638
668
|
agentsCount.textContent = String(active || total);
|
|
639
669
|
agentsCount.classList.toggle('attention', attention > 0);
|
|
640
670
|
agentsBtn.hidden = !shown;
|
|
641
671
|
agentsBtn.classList.toggle('attention', attention > 0);
|
|
672
|
+
// Whatever told the tray (this socket, the sync bus, its fetch after a reload): the session's status follows.
|
|
673
|
+
st.workers = { working, waiting };
|
|
674
|
+
pushStatus();
|
|
642
675
|
},
|
|
643
676
|
});
|
|
644
677
|
agentsBtn.setAttribute('aria-pressed', st.dockOpen ? 'true' : 'false');
|
|
@@ -777,6 +810,8 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
777
810
|
lockControl(packet.request_id, resolvedLabel(packet.origin, tt('assistant.control.state.answered', 'Answered')));
|
|
778
811
|
return;
|
|
779
812
|
case 'reattach_result':
|
|
813
|
+
// Whether a turn runs now: a route the journal left open is that turn's, or nobody's.
|
|
814
|
+
renderer.reattached(!!(packet.ok && packet.running));
|
|
780
815
|
if (packet.ok) {
|
|
781
816
|
if (packet.sessionId) st.providerSessionId = packet.sessionId;
|
|
782
817
|
if (packet.resynced) rehydrate({ force: true });
|
|
@@ -805,6 +840,8 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
805
840
|
finishTurn({ aborted: true });
|
|
806
841
|
return;
|
|
807
842
|
case 'error': {
|
|
843
|
+
// The server no longer has this session: no error row and no retry loop; the host closes the tab.
|
|
844
|
+
if (packet.code === 'SESSION_NOT_FOUND') { sessionGone(); return; }
|
|
808
845
|
// A rejected route answer keeps its card open with the message.
|
|
809
846
|
const routeCard = packet.request_id ? routeCardByRequest(packet.request_id) : null;
|
|
810
847
|
if (routeCard) { routeCard.fail(packet.message); return; }
|
|
@@ -930,6 +967,7 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
930
967
|
if (meta.id && meta.id !== sessionId) return;
|
|
931
968
|
// The server's title names the conversation (history, notifications); the tab's name is the host's.
|
|
932
969
|
applyRecordName(meta);
|
|
970
|
+
if (meta.chatStartedAt || Number(meta.turns) > 0) st.chatStarted = true;
|
|
933
971
|
if (meta.brain && typeof meta.brain === 'object') {
|
|
934
972
|
const next = normalizeBrain({ ...st.brain, ...meta.brain, provider: meta.brain.provider || meta.brain.brain || st.brain.provider });
|
|
935
973
|
if (JSON.stringify(next) !== JSON.stringify(st.brain)) { st.brain = next; picker.render(); host.setBrain?.(next); persist(); }
|
|
@@ -1343,6 +1381,7 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
1343
1381
|
st.turnStartedAt = Date.now();
|
|
1344
1382
|
setRunning(true);
|
|
1345
1383
|
sock.send(msg);
|
|
1384
|
+
st.chatStarted = true; // the server stores the session with this prompt
|
|
1346
1385
|
// Name the conversation like the server will (its first prompt) — not the tab.
|
|
1347
1386
|
if (!st.userRenamed && (!st.sessionTitle || /^(?:SynaBun|Assistant(?: \d+)?)$/.test(st.sessionTitle))) {
|
|
1348
1387
|
const guess = String(payload.text || '').split('\n')[0].trim().slice(0, 60);
|
|
@@ -1504,15 +1543,34 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
1504
1543
|
if (!st.running) setRunning(true, { label: tt('assistant.compacting', 'compacting…') });
|
|
1505
1544
|
}
|
|
1506
1545
|
|
|
1546
|
+
/** Nobody chatted in this session yet (and nothing runs in it): New reuses it, leaving it closes it. */
|
|
1547
|
+
function unused() {
|
|
1548
|
+
return !st.chatStarted && !st.running;
|
|
1549
|
+
}
|
|
1550
|
+
|
|
1507
1551
|
function newSession(provider) {
|
|
1508
1552
|
const b = provider ? normalizeBrain({ ...st.brain, provider, model: '', effort: null, agent: null, accountId: null }) : st.brain;
|
|
1553
|
+
// This one is still empty: it is the new session (the server keeps one draft, not a pile of them).
|
|
1554
|
+
// /new <provider> switches its brain as the picker does; what only this page showed (/help) is cleared.
|
|
1555
|
+
if (unused() && !destroyed) {
|
|
1556
|
+
if (provider && provider !== st.brain.provider) applyBrain(b, { requiresSwitch: true, field: 'provider' });
|
|
1557
|
+
if (!renderer.isEmpty()) clearTranscript();
|
|
1558
|
+
composer.focus();
|
|
1559
|
+
return;
|
|
1560
|
+
}
|
|
1509
1561
|
emit('assistant:new', { brain: b, host: hostId });
|
|
1510
1562
|
}
|
|
1511
1563
|
|
|
1564
|
+
/** Open another assistant session; this one goes with it when nobody chatted in it (`replaces`). */
|
|
1565
|
+
function openOther(id) {
|
|
1566
|
+
emit('assistant:resume', { sessionId: id, host: hostId, replaces: unused() ? sessionId : null });
|
|
1567
|
+
}
|
|
1568
|
+
|
|
1512
1569
|
function resume(id) {
|
|
1513
1570
|
if (!id) return;
|
|
1514
|
-
if (String(id).startsWith('assistant-')) {
|
|
1571
|
+
if (String(id).startsWith('assistant-')) { if (id !== sessionId) openOther(id); return; }
|
|
1515
1572
|
sock.send({ type: 'resume', providerSessionId: id });
|
|
1573
|
+
st.chatStarted = true; // a provider conversation: the server stores the session with it
|
|
1516
1574
|
renderer.appendDivider(tt('assistant.status.resuming', 'resuming {id}', { id: String(id).slice(0, 8) }));
|
|
1517
1575
|
}
|
|
1518
1576
|
|
|
@@ -1634,35 +1692,109 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
1634
1692
|
}
|
|
1635
1693
|
|
|
1636
1694
|
// ── Menus ──
|
|
1695
|
+
/**
|
|
1696
|
+
* The Sessions menu: New, then every session that holds a chat (the server lists no other). Each row
|
|
1697
|
+
* opens its session; its Remove (hover / focus, → from the row, Delete) asks in the row itself, then
|
|
1698
|
+
* removes the session for good: its running turn and agents stop (the question says so), every host
|
|
1699
|
+
* drops its tab, and the session showing here is replaced by a fresh one, as New does.
|
|
1700
|
+
*/
|
|
1637
1701
|
function showSessionsMenu(list) {
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1702
|
+
let sessions = (Array.isArray(list) ? list : []).filter(s => s?.id);
|
|
1703
|
+
let asking = null; // the id of the row that asks "Remove …?"
|
|
1704
|
+
const nameOf = (s) => s.title || s.label || s.id;
|
|
1705
|
+
const build = () => {
|
|
1706
|
+
const items = [
|
|
1707
|
+
{ id: 'new', label: tt('assistant.topbar.new', 'New assistant session'), desc: brainLabel(st.brain), icon: ICON_NEW, onSelect: () => newSession(null) },
|
|
1708
|
+
{ kind: 'separator' },
|
|
1709
|
+
];
|
|
1710
|
+
if (!sessions.length) items.push({ kind: 'info', label: tt('assistant.sessions.empty', 'No other sessions') });
|
|
1711
|
+
else items.push({ kind: 'header', label: tt('assistant.sessions.recent', 'Recent') });
|
|
1712
|
+
for (const s of sessions.slice(0, 30)) {
|
|
1713
|
+
const isCurrent = s.id === sessionId;
|
|
1714
|
+
const name = nameOf(s);
|
|
1715
|
+
if (s.id === asking) { items.push(removeQuestion(s, name, isCurrent)); continue; }
|
|
1716
|
+
const b = s.brain && typeof s.brain === 'object' ? s.brain : { provider: s.brain, model: s.model, effort: s.effort };
|
|
1717
|
+
items.push({
|
|
1718
|
+
kind: 'radio',
|
|
1719
|
+
id: s.id,
|
|
1720
|
+
label: name,
|
|
1721
|
+
desc: [brainLabel(b), relativeTime(s.updatedAt || s.createdAt), s.status].filter(Boolean).join(' · '),
|
|
1722
|
+
selected: isCurrent,
|
|
1723
|
+
onSelect: () => { if (!isCurrent) openOther(s.id); },
|
|
1724
|
+
action: {
|
|
1725
|
+
id: `remove:${s.id}`,
|
|
1726
|
+
icon: ICON_TRASH,
|
|
1727
|
+
label: tt('assistant.sessions.removeNamed', 'Remove “{title}”', { title: name }),
|
|
1728
|
+
tooltip: tt('assistant.sessions.remove', 'Remove session'),
|
|
1729
|
+
onSelect: () => ask(s.id),
|
|
1730
|
+
},
|
|
1731
|
+
});
|
|
1732
|
+
}
|
|
1733
|
+
return items;
|
|
1734
|
+
};
|
|
1735
|
+
/** "Remove “name”? …" with Remove and Cancel, in place of the row (it still matches the filter by name). */
|
|
1736
|
+
const removeQuestion = (s, name, isCurrent) => {
|
|
1737
|
+
const runs = Math.max(0, Number(s.activeRuns) || 0);
|
|
1738
|
+
const running = isCurrent ? st.running : s.running === true;
|
|
1739
|
+
const question = [
|
|
1740
|
+
tt('assistant.sessions.removeAsk', 'Remove “{title}” for good?', { title: name }),
|
|
1741
|
+
running ? tt('assistant.sessions.removeStopsTurn', 'Its running turn stops.') : '',
|
|
1742
|
+
runs ? tt('assistant.sessions.removeStopsAgents', 'Its running agents stop ({count}).', { count: runs }) : '',
|
|
1743
|
+
].filter(Boolean).join(' ');
|
|
1744
|
+
return {
|
|
1745
|
+
kind: 'buttons',
|
|
1746
|
+
id: `ask:${s.id}`,
|
|
1747
|
+
className: 'asst-dd-confirm',
|
|
1748
|
+
label: question,
|
|
1749
|
+
buttons: [
|
|
1750
|
+
{ id: `remove-yes:${s.id}`, label: tt('assistant.sessions.removeConfirm', 'Remove'), danger: true, keywords: name, keepOpen: true, onSelect: () => confirmRemove(s, isCurrent) },
|
|
1751
|
+
{ id: `remove-no:${s.id}`, label: tt('common.cancel', 'Cancel'), keywords: name, keepOpen: true, onSelect: () => cancel() },
|
|
1752
|
+
],
|
|
1753
|
+
};
|
|
1754
|
+
};
|
|
1755
|
+
const handle = openMenu(sessionsBtn, {
|
|
1658
1756
|
title: tt('assistant.topbar.sessions', 'Sessions'),
|
|
1659
|
-
items,
|
|
1757
|
+
items: build(),
|
|
1660
1758
|
role: 'menu',
|
|
1661
1759
|
placement: 'below',
|
|
1662
1760
|
width: 300,
|
|
1663
1761
|
filter: sessions.length > 8,
|
|
1664
1762
|
filterPlaceholder: tt('assistant.sessions.filter', 'Filter sessions…'),
|
|
1763
|
+
// Esc while a row asks: back to the row, the menu stays open.
|
|
1764
|
+
onEscape: () => { if (!asking) return false; cancel(); return true; },
|
|
1665
1765
|
});
|
|
1766
|
+
function ask(id) {
|
|
1767
|
+
asking = id;
|
|
1768
|
+
handle?.update({ items: build(), focus: `remove-no:${id}` });
|
|
1769
|
+
}
|
|
1770
|
+
function cancel() {
|
|
1771
|
+
const id = asking;
|
|
1772
|
+
asking = null;
|
|
1773
|
+
handle?.update({ items: build(), focus: id });
|
|
1774
|
+
}
|
|
1775
|
+
function confirmRemove(s, isCurrent) {
|
|
1776
|
+
asking = null;
|
|
1777
|
+
const name = nameOf(s);
|
|
1778
|
+
const done = (result) => {
|
|
1779
|
+
if (result?.ok) return;
|
|
1780
|
+
const text = tt('assistant.sessions.removeFailed', 'Could not remove “{title}”: {error}', { title: name, error: result?.error || tt('assistant.errorGeneric', 'Something went wrong') });
|
|
1781
|
+
if (destroyed) return;
|
|
1782
|
+
renderer.appendError(text);
|
|
1783
|
+
announce(text);
|
|
1784
|
+
};
|
|
1785
|
+
if (isCurrent) {
|
|
1786
|
+
// This panel's own session: a fresh one takes its place (as New), then this one goes.
|
|
1787
|
+
closeMenu();
|
|
1788
|
+
emit('assistant:remove', { sessionId: s.id, fresh: true, brain: st.brain, done });
|
|
1789
|
+
return;
|
|
1790
|
+
}
|
|
1791
|
+
// Another session (open elsewhere or not): its row goes now, and focus stays in the list.
|
|
1792
|
+
const at = sessions.findIndex((row) => row.id === s.id);
|
|
1793
|
+
sessions = sessions.filter((row) => row.id !== s.id);
|
|
1794
|
+
const next = sessions[Math.min(at, sessions.length - 1)];
|
|
1795
|
+
handle?.update({ items: build(), focus: next ? next.id : 'new' });
|
|
1796
|
+
emit('assistant:remove', { sessionId: s.id, fresh: false, done });
|
|
1797
|
+
}
|
|
1666
1798
|
}
|
|
1667
1799
|
|
|
1668
1800
|
function engineText() {
|
|
@@ -1898,6 +2030,18 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
1898
2030
|
const requestId = msg?.request_id || msg?.requestId;
|
|
1899
2031
|
if (requestId) lockControl(requestId, resolvedLabel(msg.resolvedBy));
|
|
1900
2032
|
}));
|
|
2033
|
+
// What this session's workers do right now (Claude and Codex workers stream their events to the page,
|
|
2034
|
+
// OpenCode workers a compact copy of their tool calls: lib/opencode-worker-activity.js):
|
|
2035
|
+
// their stages and the tray's scenes follow the current call.
|
|
2036
|
+
unsubs.push(on('sync:sidepanel:provider-event', (msg) => {
|
|
2037
|
+
const runId = msg?.run?.runId;
|
|
2038
|
+
if (!runId || !dock.getRun(runId)) return;
|
|
2039
|
+
const activity = activityOf(msg.event);
|
|
2040
|
+
if (!activity) return;
|
|
2041
|
+
const stamped = { ...activity, at: Date.now() };
|
|
2042
|
+
renderer.setRunActivity(runId, stamped);
|
|
2043
|
+
dock.setRunActivity(runId, stamped);
|
|
2044
|
+
}));
|
|
1901
2045
|
unsubs.push(on('sync:assistant:desktop', (msg) => computerPanel.applyDesktop(msg)));
|
|
1902
2046
|
unsubs.push(on('sync:assistant:desktop-setup', (msg) => computerPanel.applySetup(msg)));
|
|
1903
2047
|
// Models switched on/off elsewhere: the open Models manager reloads (the menus drop their cache on their own).
|
|
@@ -1924,6 +2068,19 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
1924
2068
|
}
|
|
1925
2069
|
|
|
1926
2070
|
// ── Rehydration ──
|
|
2071
|
+
/**
|
|
2072
|
+
* The server no longer has this session: a draft it dropped (a restart before its first prompt, a
|
|
2073
|
+
* page away too long) or one removed while this page missed the broadcast. The tab closes; one that
|
|
2074
|
+
* was showing with no chat in it is replaced by a fresh session (asst-hosts.js gone), never left dead.
|
|
2075
|
+
*/
|
|
2076
|
+
let gone = false;
|
|
2077
|
+
function sessionGone() {
|
|
2078
|
+
if (gone || destroyed) return;
|
|
2079
|
+
gone = true;
|
|
2080
|
+
sock.close();
|
|
2081
|
+
emit('assistant:gone', { sessionId, fresh: visible() && unused(), brain: st.brain });
|
|
2082
|
+
}
|
|
2083
|
+
|
|
1927
2084
|
async function rehydrate({ force = false } = {}) {
|
|
1928
2085
|
try {
|
|
1929
2086
|
const data = await getAssistantSession(sessionId);
|
|
@@ -1936,7 +2093,11 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
1936
2093
|
// A conversation with nothing in it yet may be greeted; a restored one never is.
|
|
1937
2094
|
if (Array.isArray(transcript) && !transcript.length && !(Number(meta?.turns) > 0)) renderer.offerGreeting();
|
|
1938
2095
|
for (const run of (Array.isArray(data?.runs) ? data.runs : [])) dock.upsertRun(run);
|
|
2096
|
+
// Run cards are not journaled: the runs the tray fetched come back into the transcript, next to the
|
|
2097
|
+
// calls that dispatched them, and a worker that still works is live at once (its stage, its route line).
|
|
2098
|
+
dock.ready.then(() => { if (!destroyed) renderer.restoreRuns(dock.getRuns()); });
|
|
1939
2099
|
} catch (err) {
|
|
2100
|
+
if (err?.status === 404) { sessionGone(); return; }
|
|
1940
2101
|
console.warn('[assistant] could not restore the conversation', err);
|
|
1941
2102
|
renderer.showEmpty();
|
|
1942
2103
|
}
|
|
@@ -1951,7 +2112,7 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
1951
2112
|
if (session && typeof session === 'object') applySessionMeta(session);
|
|
1952
2113
|
else applyFeatures();
|
|
1953
2114
|
rehydrate().finally(() => {
|
|
1954
|
-
if (destroyed) return;
|
|
2115
|
+
if (destroyed || gone) return;
|
|
1955
2116
|
probeFeatures();
|
|
1956
2117
|
applyLastUsedRouteMode();
|
|
1957
2118
|
applyLastUsedTestDensity();
|
|
@@ -1991,7 +2152,8 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
1991
2152
|
attachPath: (path) => { if (path) { composer.insertText(`\`${path}\` `); composer.focus(); } },
|
|
1992
2153
|
/** The server's name for the conversation (the user's rename, else the first prompt): tooltips. */
|
|
1993
2154
|
getConversationTitle: () => st.sessionTitle || '',
|
|
1994
|
-
|
|
2155
|
+
/** The session's status as its host shows it: the brain's own with its dispatched agents' (sessionStatus). */
|
|
2156
|
+
getStatus: () => st.shownStatus || 'idle',
|
|
1995
2157
|
focus: () => composer.focus(),
|
|
1996
2158
|
onShown: () => { syncTabLabel(); renderer.scrollEnd(true); if (visible()) composer.focus(); director.touch(); },
|
|
1997
2159
|
onHidden: () => { closeMenu(); picker.close(); director.stopTyping(); },
|
|
@@ -2012,7 +2174,9 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
2012
2174
|
unsubs.forEach(off => { try { off(); } catch { /* ignore */ } });
|
|
2013
2175
|
document.removeEventListener('keydown', onEscCapture, true);
|
|
2014
2176
|
surfaces.forEach((node) => { node.removeEventListener('keydown', onRootKey); node.removeEventListener('focusin', onFocusIn); });
|
|
2015
|
-
|
|
2177
|
+
// Its own menu closes; another panel's stays open (its Sessions menu may be what removed this session).
|
|
2178
|
+
const menuAnchor = currentMenuAnchor();
|
|
2179
|
+
if (!menuAnchor || !menuAnchor.isConnected || root.contains(menuAnchor) || barEl.contains(menuAnchor)) closeMenu();
|
|
2016
2180
|
closeFrameLightbox();
|
|
2017
2181
|
if (helpModal) { helpModal.remove(); helpModal = null; }
|
|
2018
2182
|
for (const card of routeCards.values()) card.destroy();
|
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
// Injected once by asst-render.js as <style id="asst-rack-styles">, right
|
|
5
5
|
// after the main assistant styles. One rack per burst of agent work: a stage
|
|
6
6
|
// where the mascot acts out the call it is on (live only), a ledger with one
|
|
7
|
-
// row per tool kind, and a receipt once it settles.
|
|
7
|
+
// row per tool kind, and a receipt once it settles. On a direct route the
|
|
8
|
+
// mascot stands over its task class's scene (asst-scenes.js; the motion is
|
|
9
|
+
// asst-scene-styles.js): one column, as wide as the scene.
|
|
8
10
|
//
|
|
9
11
|
// Rules: gold only means live (the awake row's ring and tick, the caret, the
|
|
10
12
|
// sweep); a rack a card holds (data-state="waiting") drops its gold: "Waiting
|
|
@@ -81,10 +83,12 @@ export const RACK_CSS = `
|
|
|
81
83
|
position: relative;
|
|
82
84
|
display: grid;
|
|
83
85
|
grid-template-columns: auto minmax(0, 1fr);
|
|
84
|
-
|
|
86
|
+
/* The mascot sits level with its bubble (the caption over the bubble), so the notch, near the bubble's top,
|
|
87
|
+
points at the mascot however tall the bubble grows. */
|
|
88
|
+
grid-template-areas: ". caption" "face bubble";
|
|
85
89
|
align-items: center;
|
|
86
90
|
column-gap: 8px;
|
|
87
|
-
row-gap:
|
|
91
|
+
row-gap: 0;
|
|
88
92
|
min-height: 0;
|
|
89
93
|
overflow: hidden;
|
|
90
94
|
padding: 0 14px;
|
|
@@ -96,12 +100,24 @@ export const RACK_CSS = `
|
|
|
96
100
|
visibility: visible;
|
|
97
101
|
transition: padding var(--rk-moderate) var(--rk-ease), visibility 0s;
|
|
98
102
|
}
|
|
99
|
-
|
|
103
|
+
/* The set: the mascot, and under it the direct route's scene (none: the set is the mascot alone). Never between the
|
|
104
|
+
mascot and the bubble's notch: under the mascot here (the bubble is beside it), after it ≤400 (the bubble is under it). */
|
|
105
|
+
.asst-rack-set { grid-area: face; align-self: start; display: flex; flex-direction: column; align-items: center; gap: 4px 6px; min-width: 0; line-height: 0; }
|
|
106
|
+
.asst-rack-face { color: var(--rk-text); line-height: 0; }
|
|
100
107
|
.asst-rack-face svg { display: block; width: 72px; height: 36px; }
|
|
108
|
+
.asst-rack-scene { color: var(--rk-text-2); line-height: 0; }
|
|
109
|
+
.asst-rack-scene:empty { display: none; }
|
|
110
|
+
/* 96×32 (the 120×40 scene at .8, strokes held near the run stage's weight). */
|
|
111
|
+
.asst-rack-scene .asst-scene { width: 96px; height: 32px; stroke-width: 1.9; }
|
|
112
|
+
/* Gold only means live: none while a card holds the rack or once it settled (the scene holds its frame, dimmed). */
|
|
113
|
+
.asst-rack:not(.is-live) .asst-rack-scene,
|
|
114
|
+
.asst-rack[data-state="waiting"] .asst-rack-scene { --sc-gold: currentColor; }
|
|
115
|
+
.asst-rack[data-state="waiting"] .asst-rack-scene { opacity: .55; }
|
|
101
116
|
.asst-rack-caption {
|
|
102
117
|
grid-area: caption;
|
|
103
118
|
align-self: end;
|
|
104
119
|
min-width: 0;
|
|
120
|
+
margin-bottom: 6px; /* the gap over the bubble: an empty caption takes no room */
|
|
105
121
|
overflow: hidden;
|
|
106
122
|
display: -webkit-box;
|
|
107
123
|
-webkit-box-orient: vertical;
|
|
@@ -111,7 +127,6 @@ export const RACK_CSS = `
|
|
|
111
127
|
line-height: 1.45;
|
|
112
128
|
}
|
|
113
129
|
.asst-rack-caption:empty { display: none; }
|
|
114
|
-
.asst-rack-caption:empty ~ .asst-bubble { grid-row: 1 / span 2; }
|
|
115
130
|
|
|
116
131
|
.asst-bubble {
|
|
117
132
|
grid-area: bubble;
|
|
@@ -528,15 +543,17 @@ export const RACK_CSS = `
|
|
|
528
543
|
|
|
529
544
|
/* ── Narrow containers ─────────────────────────────────────────────
|
|
530
545
|
≤400: the face (still 72×36) sits over the bubble, whose notch points up
|
|
531
|
-
at it
|
|
546
|
+
at it (a direct route's scene goes after the face, never between the two);
|
|
547
|
+
the rows keep the last 12 ticks and drop the time (the receipt and
|
|
532
548
|
the Timeline carry it). ≤320: only the bubble's meta goes; its subject
|
|
533
549
|
wraps to two lines, cut from the head so the file name survives, and the
|
|
534
|
-
error keeps two lines. Under a 300px container the face is 56×28
|
|
550
|
+
error keeps two lines. Under a 300px container the face is 56×28 and a
|
|
551
|
+
direct route's scene beside it 72×24 (96×32 above). */
|
|
535
552
|
@container asst (max-width: 400px) {
|
|
536
|
-
.asst-rack-stage { grid-template-columns: auto minmax(0, 1fr); grid-template-areas: "face caption" "bubble bubble"; column-gap: 8px; }
|
|
553
|
+
.asst-rack-stage { grid-template-columns: auto minmax(0, 1fr); grid-template-areas: "face caption" "bubble bubble"; column-gap: 8px; row-gap: 6px; }
|
|
554
|
+
.asst-rack-set { align-self: center; flex-direction: row; }
|
|
537
555
|
.asst-rack.is-staged > .asst-rack-stage { padding: 10px 10px 10px; }
|
|
538
|
-
.asst-rack-caption { align-self: center; }
|
|
539
|
-
.asst-rack-caption:empty ~ .asst-bubble { grid-row: auto; }
|
|
556
|
+
.asst-rack-caption { align-self: center; margin-bottom: 0; }
|
|
540
557
|
.asst-bubble { justify-self: stretch; max-width: 100%; margin: 4px 0 0; border-radius: 3px 12px 12px 12px; }
|
|
541
558
|
.asst-bubble::before { left: 30px; top: -5.5px; box-shadow: inset 1px 1px 0 var(--rk-line); clip-path: polygon(0 100%, 0 0, 100% 0); }
|
|
542
559
|
.asst-station-hdr { gap: 8px; padding: 0 6px; }
|
|
@@ -554,6 +571,7 @@ export const RACK_CSS = `
|
|
|
554
571
|
}
|
|
555
572
|
@container asst (max-width: 299px) {
|
|
556
573
|
.asst-rack-face svg { width: 56px; height: 28px; }
|
|
574
|
+
.asst-rack-scene .asst-scene { width: 72px; height: 24px; stroke-width: 2.2; }
|
|
557
575
|
.asst-bubble::before { left: 22px; }
|
|
558
576
|
}
|
|
559
577
|
|