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
|
@@ -15,6 +15,7 @@ import '../account-i18n.js';
|
|
|
15
15
|
import { restoreMcpAppCards, teardownMcpApps, retireMcpAppNode, stripMcpAppRuntime } from './cdx-mcp-app-host.js';
|
|
16
16
|
import { renderTurnDiff, completeTurnOutputs } from './cdx-render.js';
|
|
17
17
|
import { hydrateOutputControls } from './cdx-output.js';
|
|
18
|
+
import { sanitizeStoredHtml } from '../assistant/asst-sanitize.js';
|
|
18
19
|
import {
|
|
19
20
|
beginPlanTurn, capturePlanItem, finishPlanTurn, getPlanMarkdown, syncPlanMirrors, recordPlanTurn,
|
|
20
21
|
migrateLegacyPlan, recoverPlanFromHistory, planBelongsToTab, useMessageAsPlan,
|
|
@@ -378,6 +379,9 @@ function buildWsCallbacks(tab, options = {}) {
|
|
|
378
379
|
if (_boundTab) _boundTab.running = true;
|
|
379
380
|
setStatus('Resuming…', 'working');
|
|
380
381
|
resetStallTimer();
|
|
382
|
+
// The turn it found is still at work: so is the tab's pill (the panel may be hidden, the tab in the background).
|
|
383
|
+
updateTrayPillRunning();
|
|
384
|
+
renderPills();
|
|
381
385
|
} else if (msg.running === false && (!msg.threadId || String(msg.threadId) === String(_threadId || ''))) {
|
|
382
386
|
// A plan can finish while disconnected. The server's idle reply
|
|
383
387
|
// releases the stale running/query state before history recovery.
|
|
@@ -589,20 +593,17 @@ function buildWsCallbacks(tab, options = {}) {
|
|
|
589
593
|
},
|
|
590
594
|
|
|
591
595
|
onInterruptAck(msg) {
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
_boundTab.running = false;
|
|
596
|
-
_boundTab.activeTurnId = null;
|
|
597
|
-
if (_boundTab._abortRetry) {
|
|
598
|
-
clearTimeout(_boundTab._abortRetry);
|
|
599
|
-
_boundTab._abortRetry = null;
|
|
600
|
-
}
|
|
596
|
+
if (_boundTab?._abortRetry) {
|
|
597
|
+
clearTimeout(_boundTab._abortRetry);
|
|
598
|
+
_boundTab._abortRetry = null;
|
|
601
599
|
}
|
|
602
600
|
clearInterruptTimer();
|
|
603
|
-
|
|
601
|
+
// A prompt sent after the Stop has a turn of its own: the ack is not about it.
|
|
602
|
+
if (!interruptAckEndsTurn(_boundTab)) return;
|
|
603
|
+
// The stopped turn is over: the tab, its pill and the saved tabs say so (setRunning), even
|
|
604
|
+
// when something marked it working again before the ack came back.
|
|
605
|
+
setRunning(false);
|
|
604
606
|
setStatus('Interrupted', 'muted');
|
|
605
|
-
syncInputEnabled();
|
|
606
607
|
syncSessionControls();
|
|
607
608
|
releaseInactiveIdleTab(_boundTab);
|
|
608
609
|
},
|
|
@@ -959,6 +960,7 @@ function rememberBlockingServerRequest(requestId, method, params = {}) {
|
|
|
959
960
|
if (_boundTab) _boundTab.blockingServerRequests = _blockingServerRequests;
|
|
960
961
|
syncWorkStatus();
|
|
961
962
|
syncInputEnabled();
|
|
963
|
+
updateTrayPillRunning(); // the pill needs you
|
|
962
964
|
saveTabs();
|
|
963
965
|
}
|
|
964
966
|
|
|
@@ -968,6 +970,7 @@ function clearBlockingServerRequest(requestId, { flushBuffered = true } = {}) {
|
|
|
968
970
|
if (_boundTab) _boundTab.blockingServerRequests = _blockingServerRequests;
|
|
969
971
|
syncWorkStatus();
|
|
970
972
|
syncInputEnabled();
|
|
973
|
+
updateTrayPillRunning();
|
|
971
974
|
saveTabs();
|
|
972
975
|
if (flushBuffered && !hasBlockingServerRequests()) flushBufferedSocketMessages();
|
|
973
976
|
releaseInactiveIdleTab(_boundTab);
|
|
@@ -985,6 +988,7 @@ function clearAllBlockingServerRequests() {
|
|
|
985
988
|
}
|
|
986
989
|
syncWorkStatus();
|
|
987
990
|
syncInputEnabled();
|
|
991
|
+
updateTrayPillRunning();
|
|
988
992
|
}
|
|
989
993
|
|
|
990
994
|
function shouldBufferSocketMessage(kind, payload) {
|
|
@@ -1064,6 +1068,11 @@ function applySocketError(msg) {
|
|
|
1064
1068
|
|
|
1065
1069
|
function applySocketClosed() {
|
|
1066
1070
|
appendSystem('Codex session closed', 'muted');
|
|
1071
|
+
// The app-server ran the turn: it exited, the turn went with it (the server forgot it too).
|
|
1072
|
+
if (_running) {
|
|
1073
|
+
setRunning(false);
|
|
1074
|
+
setStatus('Codex session closed', 'muted');
|
|
1075
|
+
}
|
|
1067
1076
|
}
|
|
1068
1077
|
|
|
1069
1078
|
function applyBufferedSocketMessage(entry) {
|
|
@@ -1459,7 +1468,7 @@ let _hljs = null;
|
|
|
1459
1468
|
|
|
1460
1469
|
(async () => {
|
|
1461
1470
|
try {
|
|
1462
|
-
const mod = await import('
|
|
1471
|
+
const mod = await import('/vendor/marked/marked-14.1.4.esm.js').catch(() => null);
|
|
1463
1472
|
if (mod) {
|
|
1464
1473
|
_marked = mod.marked || mod.default;
|
|
1465
1474
|
if (_marked?.setOptions) _marked.setOptions({ breaks: true, gfm: true });
|
|
@@ -1471,10 +1480,10 @@ let _hljs = null;
|
|
|
1471
1480
|
try {
|
|
1472
1481
|
const link = document.createElement('link');
|
|
1473
1482
|
link.rel = 'stylesheet';
|
|
1474
|
-
link.href = '
|
|
1483
|
+
link.href = '/vendor/highlight/github-dark-dimmed-11.12.0.min.css';
|
|
1475
1484
|
document.head.appendChild(link);
|
|
1476
1485
|
const script = document.createElement('script');
|
|
1477
|
-
script.src = '
|
|
1486
|
+
script.src = '/vendor/highlight/highlight-11.12.0.min.js';
|
|
1478
1487
|
script.onload = () => { _hljs = window.hljs || null; };
|
|
1479
1488
|
document.head.appendChild(script);
|
|
1480
1489
|
} catch {}
|
|
@@ -2417,14 +2426,26 @@ export function restoreActiveBinding(fallbackState) {
|
|
|
2417
2426
|
else restoreBoundState(fallbackState);
|
|
2418
2427
|
}
|
|
2419
2428
|
|
|
2429
|
+
// How many withTab calls are under way. The outermost one hands the binding back to the active tab; a
|
|
2430
|
+
// nested one hands it back to the tab the call around it bound, with what that call had done so far
|
|
2431
|
+
// written to it first. (The history of a tab in the background renders while another tab is shown, and
|
|
2432
|
+
// a nested withTab in it used to leave the rest of that history to the shown tab: its held approvals
|
|
2433
|
+
// were looked up there and never came back.)
|
|
2434
|
+
let _withTabDepth = 0;
|
|
2435
|
+
|
|
2420
2436
|
export function withTab(tab, fn) {
|
|
2421
2437
|
const prev = snapshotBoundState();
|
|
2438
|
+
const outer = _withTabDepth > 0 ? _boundTab : null;
|
|
2439
|
+
if (outer) commitBoundState();
|
|
2440
|
+
_withTabDepth += 1;
|
|
2422
2441
|
bindTabState(tab);
|
|
2423
2442
|
try {
|
|
2424
2443
|
return fn();
|
|
2425
2444
|
} finally {
|
|
2426
2445
|
commitBoundState();
|
|
2427
|
-
|
|
2446
|
+
_withTabDepth -= 1;
|
|
2447
|
+
if (outer) bindTabState(outer);
|
|
2448
|
+
else restoreActiveBinding(prev);
|
|
2428
2449
|
}
|
|
2429
2450
|
}
|
|
2430
2451
|
|
|
@@ -2676,12 +2697,16 @@ function createTrayPill(tab) {
|
|
|
2676
2697
|
export function renderPills() {
|
|
2677
2698
|
const active = activeTab();
|
|
2678
2699
|
for (const tab of _tabs) {
|
|
2679
|
-
if (!tab.pillEl?.isConnected)
|
|
2700
|
+
if (!tab.pillEl?.isConnected) {
|
|
2701
|
+
tab.pillEl = createTrayPill(tab);
|
|
2702
|
+
// The bound tab's own reference too, or its running state would go on reaching the old node.
|
|
2703
|
+
if (tab === _boundTab) _trayPill = tab.pillEl;
|
|
2704
|
+
}
|
|
2680
2705
|
if (!tab.pillEl) continue;
|
|
2681
2706
|
// Read directly from tab to avoid nested withTab clobbering uncommitted state
|
|
2682
2707
|
const label = tab.pillEl.querySelector('.term-minimized-pill-label');
|
|
2683
2708
|
if (label) label.textContent = tab.sessionLabel || 'New session';
|
|
2684
|
-
tab.pillEl
|
|
2709
|
+
paintTrayPill(tab.pillEl, tab);
|
|
2685
2710
|
const shouldShow = hasMeaningfulTrayState(tab) && (!_getVisible() || tab !== active);
|
|
2686
2711
|
tab.pillEl.style.display = shouldShow ? '' : 'none';
|
|
2687
2712
|
}
|
|
@@ -2874,6 +2899,7 @@ export function createTab(saved = {}, { autoSwitch = true } = {}) {
|
|
|
2874
2899
|
ownedThreadIds: new Set(),
|
|
2875
2900
|
automationRunId,
|
|
2876
2901
|
automationActive: !!saved.automationActive,
|
|
2902
|
+
automationAwaits: false, // the run's turn ended asking the user (runAwaitsAnswer, set by its attach): the pill needs you
|
|
2877
2903
|
automationOwnerId: saved.automationOwnerId || null,
|
|
2878
2904
|
releasedRunId: automationRunId ? null : (saved.releasedRunId || null),
|
|
2879
2905
|
};
|
|
@@ -3039,6 +3065,13 @@ export function saveTabs() {
|
|
|
3039
3065
|
automationActive: !!tab.automationActive,
|
|
3040
3066
|
automationOwnerId: tab.automationOwnerId || null,
|
|
3041
3067
|
releasedRunId: tab.releasedRunId || null,
|
|
3068
|
+
// Whether it was working when this was written: after a reload its placeholder pill says so and
|
|
3069
|
+
// the panel boots to ask (ui-sidepanel-tray.js), and the tab reattaches at once (restoreTabs).
|
|
3070
|
+
// Never restored as running: only the reattach's answer says that. `needsYou`: an approval or a
|
|
3071
|
+
// question card waited on the user; the reattach replays the request the bridge still holds.
|
|
3072
|
+
running: !!tab.running,
|
|
3073
|
+
startingThread: !!tab.startingThread,
|
|
3074
|
+
needsYou: tab.blockingServerRequests?.size > 0 || !!tab.automationAwaits,
|
|
3042
3075
|
};
|
|
3043
3076
|
});
|
|
3044
3077
|
const localRunIds = new Set(localTabs.map((tab) => tab.automationRunId).filter(Boolean));
|
|
@@ -3125,9 +3158,11 @@ export function restoreTabs() {
|
|
|
3125
3158
|
if (raw) {
|
|
3126
3159
|
const data = JSON.parse(raw);
|
|
3127
3160
|
if (Array.isArray(data?.tabs) && data.tabs.length) {
|
|
3161
|
+
const wereWorking = [];
|
|
3128
3162
|
for (const saved of data.tabs) {
|
|
3129
3163
|
if (saved.automationActive && saved.automationOwnerId !== nativeLoopWindowId) continue;
|
|
3130
|
-
createTab(saved, { autoSwitch: false });
|
|
3164
|
+
const tab = createTab(saved, { autoSwitch: false });
|
|
3165
|
+
if (tab && !tab.automationRunId && (saved.running || saved.startingThread || saved.needsYou)) wereWorking.push(tab);
|
|
3131
3166
|
}
|
|
3132
3167
|
if (!_tabs.length) throw new Error('No restorable Codex tabs');
|
|
3133
3168
|
_activeTabIdx = Math.min(Math.max(Number(data.activeIdx) || 0, 0), _tabs.length - 1);
|
|
@@ -3135,6 +3170,11 @@ export function restoreTabs() {
|
|
|
3135
3170
|
if (!_tabs.length) throw new Error('No restorable Codex tabs');
|
|
3136
3171
|
updateActiveTabView();
|
|
3137
3172
|
saveTabs();
|
|
3173
|
+
// A tab that was working when the page went away asks after its turn now, hidden or in the
|
|
3174
|
+
// background (a restored tab reattaches first: its turn outlives the page on the server), so
|
|
3175
|
+
// its pill says what the thread does. An idle one is let go again once it is ready
|
|
3176
|
+
// (releaseInactiveIdleTab); idle tabs stay unconnected until they are shown.
|
|
3177
|
+
for (const tab of wereWorking) if (_tabs.includes(tab) && !tab.ws) connectTab(tab);
|
|
3138
3178
|
return;
|
|
3139
3179
|
}
|
|
3140
3180
|
}
|
|
@@ -3158,8 +3198,47 @@ export function updateTrayPillLabel() {
|
|
|
3158
3198
|
if (label) label.textContent = _sessionLabel;
|
|
3159
3199
|
}
|
|
3160
3200
|
|
|
3201
|
+
/**
|
|
3202
|
+
* What a tab's tray pill says: it needs you while an approval or a question card waits on your answer
|
|
3203
|
+
* (its blocking server requests), or, for a dispatched worker, while its turn ended asking you something
|
|
3204
|
+
* (the run's outcome: automationAwaits), else it works while a turn runs or a thread is being made.
|
|
3205
|
+
* sidepanel-session-status.js reads the same classes for a detached window's pill.
|
|
3206
|
+
*/
|
|
3207
|
+
function paintTrayPill(pill, { running, startingThread, blockingServerRequests, automationAwaits }) {
|
|
3208
|
+
if (!pill) return;
|
|
3209
|
+
const needsYou = blockingServerRequests?.size > 0 || !!automationAwaits;
|
|
3210
|
+
pill.classList.toggle('cxp-pill-attention', needsYou);
|
|
3211
|
+
pill.classList.toggle('cxp-pill-running', !needsYou && !!(running || startingThread));
|
|
3212
|
+
}
|
|
3213
|
+
|
|
3161
3214
|
export function updateTrayPillRunning() {
|
|
3162
|
-
_trayPill
|
|
3215
|
+
paintTrayPill(_trayPill, {
|
|
3216
|
+
running: _running, startingThread: _startingThread, blockingServerRequests: _blockingServerRequests, automationAwaits: _boundTab?.automationAwaits,
|
|
3217
|
+
});
|
|
3218
|
+
}
|
|
3219
|
+
|
|
3220
|
+
/**
|
|
3221
|
+
* The bound tab's work ended (or began) outside setRunning: the tab, its pill and the saved tabs say
|
|
3222
|
+
* so now. The tab is written first: renderPills and saveTabs read it, never the bound copy, and a
|
|
3223
|
+
* nested withTab binds the tab again from it (withTab itself writes it back only when it returns).
|
|
3224
|
+
*/
|
|
3225
|
+
function publishWorkState() {
|
|
3226
|
+
if (_boundTab) {
|
|
3227
|
+
_boundTab.running = _running;
|
|
3228
|
+
_boundTab.startingThread = _startingThread;
|
|
3229
|
+
}
|
|
3230
|
+
updateTrayPillRunning();
|
|
3231
|
+
renderPills();
|
|
3232
|
+
saveTabs();
|
|
3233
|
+
}
|
|
3234
|
+
|
|
3235
|
+
/**
|
|
3236
|
+
* Whether a Stop's ack ends the tab's running state: not once a prompt was sent after that Stop
|
|
3237
|
+
* (dispatchPrompt counts them, interruptTab notes the count it stopped at), whose turn is its own.
|
|
3238
|
+
*/
|
|
3239
|
+
function interruptAckEndsTurn(tab) {
|
|
3240
|
+
if (!tab || tab.interruptedAtPrompt == null) return true;
|
|
3241
|
+
return (tab.promptCount || 0) === tab.interruptedAtPrompt;
|
|
3163
3242
|
}
|
|
3164
3243
|
|
|
3165
3244
|
|
|
@@ -3258,6 +3337,7 @@ export function clearTranscript(emptyText = freshThreadText()) {
|
|
|
3258
3337
|
showEmpty(emptyText);
|
|
3259
3338
|
setCompactingUI(false);
|
|
3260
3339
|
renderStatusChrome();
|
|
3340
|
+
updateTrayPillRunning(); // (its request cards went with the transcript)
|
|
3261
3341
|
}
|
|
3262
3342
|
|
|
3263
3343
|
export function renderStoredTranscript(snapshot, emptyText = freshThreadText()) {
|
|
@@ -3267,7 +3347,10 @@ export function renderStoredTranscript(snapshot, emptyText = freshThreadText())
|
|
|
3267
3347
|
|
|
3268
3348
|
clearTranscript(emptyText);
|
|
3269
3349
|
_messagesEl.querySelectorAll(':scope > .cxp-empty').forEach(node => node.remove());
|
|
3270
|
-
|
|
3350
|
+
// A snapshot is the transcript's own markup, saved and read back from storage, and a build before the panel
|
|
3351
|
+
// sanitised its Markdown saved model HTML in it as it was: it is rebuilt from the stored-transcript allowlist
|
|
3352
|
+
// (asst-sanitize.js, the sanitiser live output goes through) before it reaches the page.
|
|
3353
|
+
_messagesEl.append(sanitizeStoredHtml(normalized.html));
|
|
3271
3354
|
const acceptedItemIds = new Set(normalized.acceptedItemIds);
|
|
3272
3355
|
const acceptedTurnIds = new Set(normalized.acceptedTurnIds);
|
|
3273
3356
|
const restoredNodes = [..._messagesEl.children].filter((node) => (
|
|
@@ -3365,6 +3448,11 @@ export function resetThreadState({ tone = 'ready', preserveStatus = false } = {}
|
|
|
3365
3448
|
_running = false;
|
|
3366
3449
|
_startingThread = false;
|
|
3367
3450
|
if (_boundTab) {
|
|
3451
|
+
// On the tab at once: clearPlanHandoffState below binds the tab again (updatePostPlanTranscriptMeta's
|
|
3452
|
+
// withTab), which read its old running state back over these and saved the reset tab as working.
|
|
3453
|
+
_boundTab.running = false;
|
|
3454
|
+
_boundTab.startingThread = false;
|
|
3455
|
+
_boundTab.activeTurnId = null;
|
|
3368
3456
|
_boundTab.ownedThreadIds = new Set();
|
|
3369
3457
|
_boundTab.expectedThreadId = null;
|
|
3370
3458
|
_boundTab.expectedThreadRequestId = null;
|
|
@@ -3385,8 +3473,7 @@ export function resetThreadState({ tone = 'ready', preserveStatus = false } = {}
|
|
|
3385
3473
|
clearTranscript();
|
|
3386
3474
|
syncInputEnabled();
|
|
3387
3475
|
syncSessionControls();
|
|
3388
|
-
|
|
3389
|
-
saveTabs();
|
|
3476
|
+
publishWorkState();
|
|
3390
3477
|
}
|
|
3391
3478
|
|
|
3392
3479
|
export function setActiveProject(projectPath, { reset = true, preserveStatus = false, tone = 'ready' } = {}) {
|
|
@@ -3577,12 +3664,12 @@ async function startNewThread(tab = activeTab()) {
|
|
|
3577
3664
|
} finally {
|
|
3578
3665
|
if (!tab.closed) withTab(tab, () => {
|
|
3579
3666
|
_startingThread = false;
|
|
3667
|
+
// The tab first, then what reads it (the pill, the saved tabs, the toolbar): renderPills
|
|
3668
|
+
// used to find it still starting and put the running class back on the pill.
|
|
3669
|
+
publishWorkState();
|
|
3580
3670
|
syncInputEnabled();
|
|
3581
3671
|
syncToolbarState();
|
|
3582
3672
|
syncSessionControls();
|
|
3583
|
-
updateTrayPillRunning();
|
|
3584
|
-
renderPills();
|
|
3585
|
-
saveTabs();
|
|
3586
3673
|
releaseInactiveIdleTab(tab);
|
|
3587
3674
|
});
|
|
3588
3675
|
}
|
|
@@ -4438,7 +4525,7 @@ export function promptNameNewSession() {
|
|
|
4438
4525
|
<div class="cxp-name-modal-row">
|
|
4439
4526
|
<label class="cxp-name-modal-label">Project</label>
|
|
4440
4527
|
<select class="cxp-name-modal-select" data-role="project">
|
|
4441
|
-
${projectOptions.map(p => `<option value="${
|
|
4528
|
+
${projectOptions.map(p => `<option value="${esc(p.value)}">${esc(p.label)}</option>`).join('')}
|
|
4442
4529
|
</select>
|
|
4443
4530
|
</div>
|
|
4444
4531
|
<div class="cxp-name-modal-row">
|
|
@@ -4476,7 +4563,8 @@ export function promptNameNewSession() {
|
|
|
4476
4563
|
branchSel.innerHTML = '<option value="">(none)</option>';
|
|
4477
4564
|
branchSel.disabled = true;
|
|
4478
4565
|
} else {
|
|
4479
|
-
|
|
4566
|
+
// A branch name is the repository's (an agent can make one): text, never markup.
|
|
4567
|
+
branchSel.innerHTML = branches.map(b => `<option value="${esc(b)}">${esc(b)}</option>`).join('');
|
|
4480
4568
|
if (branchOriginal) branchSel.value = branchOriginal;
|
|
4481
4569
|
branchSel.disabled = false;
|
|
4482
4570
|
}
|
|
@@ -5078,6 +5166,8 @@ export function dispatchPrompt(prompt, { tab = activeTab(), images = null, paths
|
|
|
5078
5166
|
}
|
|
5079
5167
|
if (tab) {
|
|
5080
5168
|
tab.extendedContextVerificationArmed = normalizeCodexContextMode(tab.contextMode) === 'extended';
|
|
5169
|
+
// A Stop's late ack must not end this prompt's turn (interruptAckEndsTurn).
|
|
5170
|
+
tab.promptCount = (tab.promptCount || 0) + 1;
|
|
5081
5171
|
}
|
|
5082
5172
|
requestCodexSessionTitle(tab, inputText, {
|
|
5083
5173
|
paths: [...pathList, ...mentionList.map((mention) => mention.path).filter(Boolean)],
|
|
@@ -5417,7 +5507,8 @@ export function handleNotify(method, params) {
|
|
|
5417
5507
|
flushPostCompactionPrompt(_boundTab);
|
|
5418
5508
|
}
|
|
5419
5509
|
if (_boundTab?.providerTitleDirty) scheduleCodexTitleReassert(_boundTab);
|
|
5420
|
-
|
|
5510
|
+
// The queue of the tab whose turn this was, never the one on screen.
|
|
5511
|
+
if (!shouldHoldForPlanApproval(tab)) advanceQueue(tab);
|
|
5421
5512
|
releaseInactiveIdleTab(tab);
|
|
5422
5513
|
}
|
|
5423
5514
|
break;
|
|
@@ -6130,6 +6221,7 @@ export function interruptTab(tab = activeTab()) {
|
|
|
6130
6221
|
clearTimeout(tab._abortRetry);
|
|
6131
6222
|
tab._abortRetry = null;
|
|
6132
6223
|
}
|
|
6224
|
+
tab.interruptedAtPrompt = tab.promptCount || 0;
|
|
6133
6225
|
sendSocket({ type: 'interrupt', sessionId: tab.id, threadId });
|
|
6134
6226
|
tab._abortRetry = setTimeout(() => {
|
|
6135
6227
|
tab._abortRetry = null;
|
|
@@ -6160,6 +6252,7 @@ export function interruptAllTabs() {
|
|
|
6160
6252
|
const ws = tab.ws;
|
|
6161
6253
|
const threadId = tab.threadId || null;
|
|
6162
6254
|
if (ws && ws.readyState === 1) {
|
|
6255
|
+
tab.interruptedAtPrompt = tab.promptCount || 0;
|
|
6163
6256
|
try {
|
|
6164
6257
|
ws.send(JSON.stringify({
|
|
6165
6258
|
type: 'interrupt',
|
|
@@ -6935,6 +7028,14 @@ export function steerActiveTurn() {
|
|
|
6935
7028
|
return true;
|
|
6936
7029
|
}
|
|
6937
7030
|
|
|
7031
|
+
/**
|
|
7032
|
+
* Whether `tab` has a turn running. The bound tab's is the module's own state (the freshest: withTab
|
|
7033
|
+
* writes it back to the tab only when it returns); any other tab's is its own.
|
|
7034
|
+
*/
|
|
7035
|
+
function tabTurnRunning(tab) {
|
|
7036
|
+
return tab === _boundTab ? _running : !!tab?.running;
|
|
7037
|
+
}
|
|
7038
|
+
|
|
6938
7039
|
export function syncQueueTray() {
|
|
6939
7040
|
const tab = activeTab();
|
|
6940
7041
|
if (!tab) return;
|
|
@@ -6952,7 +7053,8 @@ export function syncQueueTray() {
|
|
|
6952
7053
|
if (hint) {
|
|
6953
7054
|
hint.textContent = count > 0
|
|
6954
7055
|
? `${count} message${count > 1 ? 's' : ''} queued${tab.queuePaused ? ' (paused)' : ''}. Enter steers. Tab queues the next turn.`
|
|
6955
|
-
|
|
7056
|
+
// The tab on screen's turn, not the bound tab's (a tab working in the background is bound while its events run).
|
|
7057
|
+
: tabTurnRunning(tab)
|
|
6956
7058
|
? 'Enter steers the active turn. Tab queues the next turn. Shift+Enter inserts a newline.'
|
|
6957
7059
|
: 'Enter sends. Shift+Enter inserts a newline.';
|
|
6958
7060
|
}
|
|
@@ -7012,7 +7114,7 @@ export function toggleQueuePause() {
|
|
|
7012
7114
|
if (!tab) return;
|
|
7013
7115
|
tab.queuePaused = !tab.queuePaused;
|
|
7014
7116
|
syncQueueTray();
|
|
7015
|
-
if (!tab.queuePaused) advanceQueue();
|
|
7117
|
+
if (!tab.queuePaused) advanceQueue(tab);
|
|
7016
7118
|
saveTabs();
|
|
7017
7119
|
}
|
|
7018
7120
|
|
|
@@ -7024,11 +7126,17 @@ export function clearQueue() {
|
|
|
7024
7126
|
saveTabs();
|
|
7025
7127
|
}
|
|
7026
7128
|
|
|
7027
|
-
|
|
7028
|
-
|
|
7029
|
-
|
|
7129
|
+
/**
|
|
7130
|
+
* Send the next prompt queued in `tab`, the tab it was typed in, on that tab's own connection and
|
|
7131
|
+
* thread: a background tab whose turn ends advances its own queue, never the one on screen (the
|
|
7132
|
+
* module state is the bound tab's, so the tab is bound first).
|
|
7133
|
+
*/
|
|
7134
|
+
export function advanceQueue(tab = activeTab()) {
|
|
7135
|
+
if (!tab || tab.closed) return false;
|
|
7136
|
+
if (_boundTab !== tab) return withTab(tab, () => advanceQueue(tab));
|
|
7137
|
+
if (_running || tab.queuePaused || !tab.queue?.length || hasBlockingServerRequests() || shouldHoldForPlanApproval(tab)) return false;
|
|
7030
7138
|
const next = tab.queue.shift();
|
|
7031
|
-
if (!next) return;
|
|
7139
|
+
if (!next) return false;
|
|
7032
7140
|
if (tab.planMode) {
|
|
7033
7141
|
preparePlanModeTurn(tab);
|
|
7034
7142
|
}
|
|
@@ -7040,13 +7148,19 @@ export function advanceQueue() {
|
|
|
7040
7148
|
mentions: next.mentions || [],
|
|
7041
7149
|
forcePlanModePrefix: tab.planMode,
|
|
7042
7150
|
});
|
|
7043
|
-
if (!sent)
|
|
7151
|
+
if (!sent) {
|
|
7152
|
+
// Not sent: it stays first in its tab's queue.
|
|
7153
|
+
tab.queue.unshift(next);
|
|
7154
|
+
syncQueueTray();
|
|
7155
|
+
return false;
|
|
7156
|
+
}
|
|
7044
7157
|
// Render queued user message immediately with images
|
|
7045
7158
|
if (queueImages?.length) {
|
|
7046
7159
|
appendLocalUserMessage(next.text || '', queueImages);
|
|
7047
7160
|
tab._pendingSendImages = queueImages;
|
|
7048
7161
|
}
|
|
7049
7162
|
syncQueueTray();
|
|
7163
|
+
return true;
|
|
7050
7164
|
}
|
|
7051
7165
|
|
|
7052
7166
|
// ── Phase 2: Image attachments ──
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
// Markdown → HTML for every Markdown sink of the Claude panel, and the
|
|
2
|
-
// stored transcript snapshot goes through before it is put back on the page.
|
|
1
|
+
// Markdown → HTML for every Markdown sink of the Claude panel, and the panel's one escaper.
|
|
3
2
|
//
|
|
4
3
|
// What a model writes, what a command prints and what a transcript replays is
|
|
5
4
|
// not ours: marked passes raw HTML through, so `<img onerror>` or a
|
|
@@ -47,58 +46,6 @@ export function renderMarkdown(text, { parse = null, sanitize = sanitizeHtmlStri
|
|
|
47
46
|
}
|
|
48
47
|
}
|
|
49
48
|
|
|
50
|
-
//
|
|
51
|
-
//
|
|
52
|
-
//
|
|
53
|
-
// so the Markdown allowlist would destroy it; but it may have been written by
|
|
54
|
-
// a build that did not sanitise, and it comes back from storage. It is parsed
|
|
55
|
-
// into an inert <template> and stripped of everything that can run or load
|
|
56
|
-
// code before it reaches the page.
|
|
57
|
-
|
|
58
|
-
const STORED_DROPPED = new Set(['script', 'iframe', 'frame', 'frameset', 'object', 'embed', 'applet', 'base', 'meta', 'link', 'style', 'template', 'noscript', 'foreignobject', 'animate', 'set', 'animatetransform', 'animatemotion']);
|
|
59
|
-
const URL_ATTRS = new Set(['href', 'src', 'xlink:href', 'action', 'formaction', 'poster', 'data', 'background', 'ping']);
|
|
60
|
-
const REMOVED_ATTRS = new Set(['srcdoc', 'srcset']);
|
|
61
|
-
const SAFE_URL_SCHEMES = new Set(['http', 'https', 'mailto']);
|
|
62
|
-
|
|
63
|
-
/** The scheme of a URL attribute as a browser reads it (whitespace and control characters ignored), or ''. */
|
|
64
|
-
function schemeOf(value) {
|
|
65
|
-
const m = /^([a-z][a-z0-9+.-]*):/i.exec(String(value ?? '').replace(/[\u0000- ]/g, ''));
|
|
66
|
-
return m ? m[1].toLowerCase() : '';
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
function storedImageAllowed(src) {
|
|
70
|
-
const compact = String(src ?? '').replace(/[\u0000- ]/g, '');
|
|
71
|
-
if (!compact) return false;
|
|
72
|
-
if (/^data:image\//i.test(compact) || /^blob:/i.test(compact)) return true;
|
|
73
|
-
// A path on this server; a remote image is not loaded again from storage.
|
|
74
|
-
return !schemeOf(compact) && !compact.startsWith('//');
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
function scrubNode(parent) {
|
|
78
|
-
for (const node of [...parent.childNodes]) {
|
|
79
|
-
if (node.nodeType === 3) continue;
|
|
80
|
-
if (node.nodeType !== 1) { parent.removeChild(node); continue; }
|
|
81
|
-
const tag = String(node.localName || '').toLowerCase();
|
|
82
|
-
if (STORED_DROPPED.has(tag) || (tag === 'img' && !storedImageAllowed(node.getAttribute('src')))) { parent.removeChild(node); continue; }
|
|
83
|
-
for (const name of node.getAttributeNames()) {
|
|
84
|
-
const lower = name.toLowerCase();
|
|
85
|
-
if (lower.startsWith('on') || REMOVED_ATTRS.has(lower)) { node.removeAttribute(name); continue; }
|
|
86
|
-
if (!URL_ATTRS.has(lower)) continue;
|
|
87
|
-
const scheme = schemeOf(node.getAttribute(name));
|
|
88
|
-
if (!scheme || SAFE_URL_SCHEMES.has(scheme)) continue;
|
|
89
|
-
if (tag === 'img' && lower === 'src') continue; // data:image / blob, checked above
|
|
90
|
-
node.removeAttribute(name);
|
|
91
|
-
}
|
|
92
|
-
scrubNode(node);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/** A stored snapshot's markup → a DocumentFragment with nothing executable left in it. */
|
|
97
|
-
export function scrubStoredHtml(html, doc = globalThis.document) {
|
|
98
|
-
const tpl = doc.createElement('template');
|
|
99
|
-
tpl.innerHTML = String(html ?? '');
|
|
100
|
-
scrubNode(tpl.content);
|
|
101
|
-
const out = doc.createDocumentFragment();
|
|
102
|
-
for (const node of [...tpl.content.childNodes]) out.appendChild(node);
|
|
103
|
-
return out;
|
|
104
|
-
}
|
|
49
|
+
// A stored transcript snapshot is not scrubbed here: the panel puts it back through
|
|
50
|
+
// sanitizeStoredHtml() of assistant/asst-sanitize.js, the stored-transcript allowlist
|
|
51
|
+
// every panel uses.
|