synabun 2.0.0 → 2.0.5
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 +57 -0
- package/NOTICE +5 -0
- package/README.md +1 -1
- package/THIRD-PARTY-LICENSES.md +46 -0
- package/benchmarks/fixtures/browser/README.md +1 -1
- package/benchmarks/fixtures/desktop/README.md +1 -1
- package/docs/whatsapp.md +2 -2
- package/hooks/claude-code/pre-compact.mjs +11 -0
- package/hooks/claude-code/prompt-submit.mjs +60 -184
- package/hooks/claude-code/session-start.mjs +73 -16
- package/hooks/claude-code/shared.mjs +20 -0
- package/hooks/claude-code/stop.mjs +5 -5
- package/lib/start-launcher.js +88 -1
- package/mcp-server/package-lock.json +2 -2
- package/mcp-server/package.json +1 -3
- package/neural-interface/i18n/en.json +1500 -153
- package/neural-interface/i18n/pt-BR.json +1498 -152
- package/neural-interface/lib/assistant-api.js +62 -6
- package/neural-interface/lib/assistant-brains/claude.js +4 -0
- package/neural-interface/lib/assistant-catalog.js +179 -27
- package/neural-interface/lib/assistant-config.js +31 -2
- package/neural-interface/lib/assistant-dispatch.js +62 -13
- package/neural-interface/lib/assistant-hidden-models.js +393 -66
- package/neural-interface/lib/assistant-memory.js +24 -10
- package/neural-interface/lib/assistant-persona.js +6 -2
- package/neural-interface/lib/assistant-pricing.js +21 -6
- package/neural-interface/lib/assistant-runtime.js +181 -12
- package/neural-interface/lib/assistant-task-prompt.js +13 -3
- package/neural-interface/lib/assistant-test-density.js +142 -0
- package/neural-interface/lib/assistant-user-context-budgets.js +123 -0
- package/neural-interface/lib/assistant-user-context.js +908 -0
- package/neural-interface/lib/assistant-user-knowledge.js +328 -0
- package/neural-interface/lib/assistant-user-learn.js +404 -0
- package/neural-interface/lib/assistant-user-threads.js +226 -0
- package/neural-interface/lib/assistant-user-writer.js +181 -0
- package/neural-interface/lib/browser-background-tab.js +134 -0
- package/neural-interface/lib/browser-screenshot.js +678 -61
- package/neural-interface/lib/claude-agent-bridge.js +33 -6
- package/neural-interface/lib/claude-model-catalog.js +30 -2
- package/neural-interface/lib/claude-temporary.js +46 -7
- package/neural-interface/lib/cloudflared/install.js +533 -0
- package/neural-interface/lib/cloudflared/manager.js +545 -0
- package/neural-interface/lib/cloudflared/pins.js +115 -0
- package/neural-interface/lib/cloudflared/pins.json +63 -0
- package/neural-interface/lib/cloudflared/tunnel.js +265 -0
- package/neural-interface/lib/editor-completion-endpoint.js +264 -0
- package/neural-interface/lib/editor-completion-opencode.js +436 -0
- package/neural-interface/lib/editor-completion.js +714 -0
- package/neural-interface/lib/editor-config.js +149 -0
- package/neural-interface/lib/editor-files-api.js +268 -0
- package/neural-interface/lib/editor-git-api.js +134 -0
- package/neural-interface/lib/file-explorer-api.js +1039 -0
- package/neural-interface/lib/file-explorer-system.js +355 -0
- package/neural-interface/lib/file-explorer-trash.ps1 +85 -0
- package/neural-interface/lib/file-explorer-watch.js +239 -0
- package/neural-interface/lib/git-diff-api.js +103 -0
- package/neural-interface/lib/git-read.js +202 -0
- package/neural-interface/lib/greeting/api.js +89 -0
- package/neural-interface/lib/greeting/budgets.js +90 -0
- package/neural-interface/lib/greeting/engine.js +461 -0
- package/neural-interface/lib/greeting/facts.js +320 -0
- package/neural-interface/lib/greeting/sources.js +252 -0
- package/neural-interface/lib/greeting/writer.js +139 -0
- package/neural-interface/lib/http-guards.js +189 -13
- package/neural-interface/lib/machine-names.js +88 -0
- package/neural-interface/lib/memory-api.js +31 -7
- package/neural-interface/lib/native-loop-providers.js +10 -5
- package/neural-interface/lib/plugin-installer.js +4 -2
- package/neural-interface/lib/project-storage.js +5 -7
- package/neural-interface/lib/request-gate.js +589 -0
- package/neural-interface/lib/ui-blob-api.js +108 -0
- package/neural-interface/lib/ui-blob-store.js +68 -0
- package/neural-interface/package-lock.json +701 -2
- package/neural-interface/package.json +13 -2
- package/neural-interface/public/install-app.html +9 -6
- package/neural-interface/public/offline.html +3 -2
- package/neural-interface/public/onboarding.html +12 -1
- package/neural-interface/public/shared/agent-runtime-options.js +22 -6
- package/neural-interface/public/shared/assistant/asst-automation.js +286 -0
- package/neural-interface/public/shared/assistant/asst-brain-picker.js +312 -62
- package/neural-interface/public/shared/assistant/asst-composer.js +11 -1
- package/neural-interface/public/shared/assistant/asst-mascot.js +18 -58
- package/neural-interface/public/shared/assistant/asst-menu.js +12 -8
- package/neural-interface/public/shared/assistant/asst-panel.js +150 -28
- package/neural-interface/public/shared/assistant/asst-render.js +162 -19
- package/neural-interface/public/shared/assistant/asst-route-models.js +108 -0
- package/neural-interface/public/shared/assistant/asst-route.js +23 -329
- package/neural-interface/public/shared/assistant/asst-routes-editor.js +495 -0
- package/neural-interface/public/shared/assistant/asst-sanitize.js +8 -1
- package/neural-interface/public/shared/assistant/asst-sidepanel.js +31 -9
- package/neural-interface/public/shared/assistant/asst-state.js +185 -1
- package/neural-interface/public/shared/assistant/asst-styles.js +158 -4
- package/neural-interface/public/shared/blob-store.js +111 -22
- package/neural-interface/public/shared/cdx/cdx-panel.js +32 -11
- package/neural-interface/public/shared/cdx/cdx-render.js +25 -89
- package/neural-interface/public/shared/cdx/cdx-styles.js +36 -0
- package/neural-interface/public/shared/cdx/cdx-tabs.js +87 -4
- package/neural-interface/public/shared/constants.js +6 -1
- package/neural-interface/public/shared/cp/cp-rehydrate.js +2 -1
- package/neural-interface/public/shared/cp/cp-styles.js +15 -0
- package/neural-interface/public/shared/editor/editor-ai-logic.js +409 -0
- package/neural-interface/public/shared/editor/editor-ai.js +619 -0
- package/neural-interface/public/shared/editor/editor-commands.js +212 -0
- package/neural-interface/public/shared/editor/editor-compare.js +103 -0
- package/neural-interface/public/shared/editor/editor-completion-list.js +172 -0
- package/neural-interface/public/shared/editor/editor-doc.js +257 -0
- package/neural-interface/public/shared/editor/editor-git-logic.js +131 -0
- package/neural-interface/public/shared/editor/editor-git.js +95 -0
- package/neural-interface/public/shared/editor/editor-languages.js +156 -0
- package/neural-interface/public/shared/editor/editor-lint.js +229 -0
- package/neural-interface/public/shared/editor/editor-loader.js +51 -0
- package/neural-interface/public/shared/editor/editor-markdown.js +90 -0
- package/neural-interface/public/shared/editor/editor-menu.js +233 -0
- package/neural-interface/public/shared/editor/editor-minimap.js +371 -0
- package/neural-interface/public/shared/editor/editor-palette-logic.js +192 -0
- package/neural-interface/public/shared/editor/editor-palette.js +125 -0
- package/neural-interface/public/shared/editor/editor-panel-logic.js +288 -0
- package/neural-interface/public/shared/editor/editor-panel.js +2099 -0
- package/neural-interface/public/shared/editor/editor-prefs.js +224 -0
- package/neural-interface/public/shared/editor/editor-safety.js +500 -0
- package/neural-interface/public/shared/editor/editor-search.js +352 -0
- package/neural-interface/public/shared/editor/editor-statusbar.js +144 -0
- package/neural-interface/public/shared/editor/editor-tabs-logic.js +331 -0
- package/neural-interface/public/shared/editor/editor-tabs.js +233 -0
- package/neural-interface/public/shared/editor/editor-theme.js +244 -0
- package/neural-interface/public/shared/editor/editor-view.js +332 -0
- package/neural-interface/public/shared/explorer/fx-api.js +216 -0
- package/neural-interface/public/shared/explorer/fx-links.js +204 -0
- package/neural-interface/public/shared/explorer/fx-logic.js +537 -0
- package/neural-interface/public/shared/explorer/fx-main.js +865 -0
- package/neural-interface/public/shared/explorer/fx-names.js +87 -0
- package/neural-interface/public/shared/explorer/fx-ops.js +370 -0
- package/neural-interface/public/shared/explorer/fx-popups.js +490 -0
- package/neural-interface/public/shared/explorer/fx-tree.js +790 -0
- package/neural-interface/public/shared/file-links.js +339 -0
- package/neural-interface/public/shared/greeting/greeting-card.js +178 -0
- package/neural-interface/public/shared/greeting/greeting-view.js +148 -0
- package/neural-interface/public/shared/html-shell.js +160 -165
- package/neural-interface/public/shared/ocp-v2/ocp-v2-childpanel.js +4 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-greeting.js +47 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-panel.js +99 -17
- package/neural-interface/public/shared/ocp-v2/ocp-v2-render.js +7 -1
- package/neural-interface/public/shared/ocp-v2/ocp-v2-send.js +5 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-styles.js +40 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-ws.js +3 -2
- package/neural-interface/public/shared/pwa-install-page.js +29 -1
- package/neural-interface/public/shared/pwa-install.css +3 -3
- package/neural-interface/public/shared/pwa-install.js +100 -1
- package/neural-interface/public/shared/settings/settings-code-editor-pane.js +412 -0
- package/neural-interface/public/shared/settings/settings-code-editor.js +328 -0
- package/neural-interface/public/shared/settings/settings-greeting.js +133 -0
- package/neural-interface/public/shared/settings/settings-ia.js +18 -4
- package/neural-interface/public/shared/settings/settings-user-context.js +154 -0
- package/neural-interface/public/shared/start-bridge.js +238 -19
- package/neural-interface/public/shared/styles.css +1414 -721
- package/neural-interface/public/shared/synabun-mascot.js +20 -56
- package/neural-interface/public/shared/tunnel-view.js +167 -0
- package/neural-interface/public/shared/ui-claude-panel.js +157 -16
- package/neural-interface/public/shared/ui-detail.js +15 -0
- package/neural-interface/public/shared/ui-explorer.js +22 -0
- package/neural-interface/public/shared/ui-file-explorer.js +481 -2496
- package/neural-interface/public/shared/ui-file-links.js +103 -0
- package/neural-interface/public/shared/ui-help.js +26 -0
- package/neural-interface/public/shared/ui-invite.js +126 -116
- package/neural-interface/public/shared/ui-keybinds.js +4 -0
- package/neural-interface/public/shared/ui-loading.js +159 -15
- package/neural-interface/public/shared/ui-menubar.js +12 -30
- package/neural-interface/public/shared/ui-native-loop-router-state.js +11 -0
- package/neural-interface/public/shared/ui-native-loop-router.js +15 -2
- package/neural-interface/public/shared/ui-navbar.js +45 -21
- package/neural-interface/public/shared/ui-settings.js +455 -488
- package/neural-interface/public/shared/ui-sidepanel-runtime.js +2 -1
- package/neural-interface/public/shared/ui-sync.js +16 -0
- package/neural-interface/public/shared/ui-terminal.js +23 -5
- package/neural-interface/public/shared/ui-tunnel.js +130 -0
- package/neural-interface/public/shared/ui-tutorial-steps.js +6 -2
- package/neural-interface/public/shared/ui-whiteboard.js +12 -0
- package/neural-interface/public/shared/ui-worker-end.js +245 -0
- package/neural-interface/public/shared/ui-workspaces.js +41 -27
- package/neural-interface/public/shared/worker-end.js +251 -0
- package/neural-interface/public/sw.js +2 -2
- package/neural-interface/public/vendor/codemirror/chunks/apl-CSDKT72Z.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/asciiarmor-JYYPU5BM.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/asn1-NRWCZDA6.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/asterisk-5OU6D4ZQ.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/brainfuck-ID4N4SYC.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/chunk-4RZWGCS2.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/chunk-ACTJM3JR.js +11 -0
- package/neural-interface/public/vendor/codemirror/chunks/chunk-S6BMAXLK.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/chunk-TO2RDOHQ.js +3 -0
- package/neural-interface/public/vendor/codemirror/chunks/chunk-US2GMZZQ.js +13 -0
- package/neural-interface/public/vendor/codemirror/chunks/chunk-WYYO5ZAJ.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/chunk-XALZTDJC.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/chunk-YRNUTRDV.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/chunk-Z3QOKH62.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/clike-OWQBSOGL.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/clojure-KV75UQWC.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/cmake-GTEP5Y3C.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/cobol-WCZ7QEGJ.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/coffeescript-TGLBOT6B.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/commonlisp-WVVI432V.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/crystal-S6R6HLKQ.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/css-PDA2RINP.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/cypher-HL5QPL4C.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/d-HHJH2HAJ.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/diff-MN3A35BY.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-25SQLBVS.js +3 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-27ZGGJJS.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-4E52OJIF.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-6FT73XDC.js +2 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-BE6YGRMW.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-CJSGKW2O.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-CRPH2WLI.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-CTG7JEQN.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-I3FEVELX.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-IM5BBSWZ.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-KERUKTIF.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-LXTMWZAM.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-MABASSET.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-MJVBUZLL.js +3 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-MNB3WZVU.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-QYWXOE3U.js +7 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-TEBOFWLZ.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-UNXFROM3.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-XL2SLQO6.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-XO42Y3AP.js +6 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-Y2WWDWJK.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-YFEZKWMU.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/dist-ZY7SWQO6.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/dockerfile-3Y4R4NCH.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/dtd-5343GJ4P.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/dylan-FI2CXSW2.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/ebnf-GNQ77YWA.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/ecl-MRPUAE2L.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/eiffel-DZROES27.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/elm-4KICRFKQ.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/erlang-3IHYC263.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/factor-C6D3E5UK.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/fcl-VYTWUJMI.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/forth-ZBO2EH5M.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/fortran-5NDCRWIK.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/gas-SKRMOXFP.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/gherkin-L45YXZLW.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/groovy-GLPTLN44.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/haskell-E7NF7P4Y.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/haxe-K2NVDOB6.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/http-Q6DRQIJB.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/idl-MZYNJVLN.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/javascript-6YRYK2HR.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/julia-HXEL2T5G.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/livescript-MV7CI2JZ.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/lua-E36NHOOD.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/mathematica-3XOZZCMC.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/mbox-ODYGFKS7.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/mirc-WB43AWF5.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/mllike-ZT6ET7ZH.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/modelica-LLMZPFGA.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/mscgen-2OPNNYFH.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/mumps-6P3HWJH6.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/nginx-TCGKQTRW.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/nsis-ATIGIXTJ.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/ntriples-5PLBI5OV.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/octave-QF2S3NL6.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/oz-JFIVFFH2.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/pascal-JG6SW76V.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/perl-4B3IWVVO.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/pig-ABEBH4MI.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/powershell-H32XE7TL.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/properties-NN644MMA.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/protobuf-YKWQK2J3.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/pug-RIYXEKFW.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/puppet-JZQ5WPEV.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/python-EBCGGHAC.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/q-5UMH2YQY.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/r-7XMGG453.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/rpm-IEV7TSLR.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/ruby-T4SPFPNM.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/sas-GEDX67ET.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/scheme-FTLOWKPC.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/shell-HUFRKFSJ.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/sieve-P5QUDVYO.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/smalltalk-2SORJNQI.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/solr-M22TGAR5.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/sparql-4M3KL752.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/spreadsheet-3K23LA4N.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/sql-VHRFMUBI.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/stex-QZDAQUY2.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/stylus-7ZDKAKBD.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/swift-WCLCLGMR.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/tcl-JLMU6WOK.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/textile-4CHDKZ4T.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/tiddlywiki-DKMCZZQ4.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/tiki-F4JIG36Q.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/toml-BHMHTIM2.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/troff-YQ2KV5NT.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/ttcn-ZHRCVFJY.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/ttcn-cfg-KJOVTY4X.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/turtle-535P5N6I.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/vb-76UMQHOT.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/vbscript-CGNDTK6Z.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/velocity-VSJDO5T5.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/verilog-4T6ETXIP.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/vhdl-T7FNAXUN.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/webidl-P6MJSJ6J.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/xquery-UOVILRGN.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/yacas-CV2APROL.js +1 -0
- package/neural-interface/public/vendor/codemirror/chunks/z80-3KFNVM4M.js +1 -0
- package/neural-interface/public/vendor/codemirror/codemirror-6.43.14-75f05e67.min.js +2 -0
- package/neural-interface/public/vendor/codemirror/manifest.json +60 -0
- package/neural-interface/scripts/build-vendor.mjs +78 -2
- package/neural-interface/scripts/vendor-codemirror-entry.js +121 -0
- package/neural-interface/server.js +873 -1028
- package/neural-interface/templates/rulesets/README.md +1 -1
- package/package.json +2 -8
- package/setup.js +44 -7
- package/benchmarks/browser-live-results.json +0 -79
- package/benchmarks/browser-v2-results.json +0 -258
- package/neural-interface/lib/codex-capabilities.d.ts +0 -41
- package/neural-interface/public/category-logos/claude.svg +0 -1
- package/neural-interface/public/category-logos/gemini-color.svg +0 -1
- package/neural-interface/public/category-logos/openai.svg +0 -1
- package/neural-interface/public/category-logos/synabun.png +0 -0
- package/neural-interface/public/claude.svg +0 -1
- package/neural-interface/public/gallery.svg +0 -6
- package/neural-interface/public/leonardoai.svg +0 -1
- package/neural-interface/public/mcp.svg +0 -4
- package/neural-interface/public/opencode-logo-dark-square.svg +0 -1
- package/neural-interface/public/pin-svgrepo-com.svg +0 -25
- package/neural-interface/public/sessionicon.svg +0 -8
- package/neural-interface/public/toolbar-album.svg +0 -8
- package/neural-interface/public/toolbar-question.svg +0 -6
- package/neural-interface/public/toolbar-sessions.svg +0 -6
- package/neural-interface/scripts/codex-protocol-fixture.mjs +0 -83
- package/skills/synabun/synabunicon.png +0 -0
|
@@ -10,6 +10,38 @@
|
|
|
10
10
|
const _putTimers = new Map(); // `${ns}/${id}` -> timeout id
|
|
11
11
|
const _pendingPuts = new Map(); // `${ns}/${id}` -> { ns, id, value, opts }
|
|
12
12
|
const DEFAULT_DEBOUNCE_MS = 500;
|
|
13
|
+
// One request per entry at a time, in the order they were asked for: a delete
|
|
14
|
+
// (or a newer write) that overtook a write still on its way would be undone by it.
|
|
15
|
+
const _inFlight = new Map(); // `${ns}/${id}` -> the request under way (a write or a delete); never rejects
|
|
16
|
+
const _waitingDeletes = new Map(); // `${ns}/${id}` -> sends the delete that waits behind that request
|
|
17
|
+
const _asked = new Map(); // `${ns}/${id}` -> counts the puts and deletes asked for
|
|
18
|
+
|
|
19
|
+
// Every put and delete of this page is numbered when it is asked for, and says which page it is of. Of two
|
|
20
|
+
// requests of one page for an entry the server keeps the one with the higher number, whichever arrives first
|
|
21
|
+
// (lib/ui-blob-store.js): what is sent while the page is being left (flushBlobs) cannot be put in an order here.
|
|
22
|
+
// A server from before this ignores the two fields; the order kept above is then all there is, as it was.
|
|
23
|
+
const _writer = (() => {
|
|
24
|
+
try { return Array.from(crypto.getRandomValues(new Uint8Array(12)), (byte) => byte.toString(16).padStart(2, '0')).join(''); }
|
|
25
|
+
catch { return `${Date.now().toString(36)}${Math.random().toString(36).slice(2, 12)}`; }
|
|
26
|
+
})();
|
|
27
|
+
let _revision = 0;
|
|
28
|
+
|
|
29
|
+
/** The address of one entry, for the request numbered `rev` (and what a write asks to be evicted). */
|
|
30
|
+
const _url = (ns, id, rev, opts = {}) => {
|
|
31
|
+
const params = new URLSearchParams();
|
|
32
|
+
if (opts.maxEntries) params.set('maxEntries', String(opts.maxEntries));
|
|
33
|
+
if (opts.maxChars) params.set('maxChars', String(opts.maxChars));
|
|
34
|
+
params.set('rev', String(rev));
|
|
35
|
+
params.set('writer', _writer);
|
|
36
|
+
return `/api/ui-blobs/${encodeURIComponent(ns)}/${encodeURIComponent(id)}?${params.toString()}`;
|
|
37
|
+
};
|
|
38
|
+
const _ask = (key) => { const n = (_asked.get(key) || 0) + 1; _asked.set(key, n); return n; };
|
|
39
|
+
|
|
40
|
+
function _track(key, request) {
|
|
41
|
+
const tracked = Promise.resolve(request).then(() => {}, () => {}).then(() => { if (_inFlight.get(key) === tracked) _inFlight.delete(key); });
|
|
42
|
+
_inFlight.set(key, tracked);
|
|
43
|
+
return tracked;
|
|
44
|
+
}
|
|
13
45
|
|
|
14
46
|
export async function fetchBlobNamespace(ns) {
|
|
15
47
|
try {
|
|
@@ -22,68 +54,125 @@ export async function fetchBlobNamespace(ns) {
|
|
|
22
54
|
}
|
|
23
55
|
}
|
|
24
56
|
|
|
57
|
+
// One entry, or null: there is none, or the server has no such namespace.
|
|
58
|
+
export async function fetchBlob(ns, id) {
|
|
59
|
+
try {
|
|
60
|
+
const res = await fetch(`/api/ui-blobs/${encodeURIComponent(ns)}/${encodeURIComponent(id)}`);
|
|
61
|
+
if (!res.ok) return null;
|
|
62
|
+
return await res.json();
|
|
63
|
+
} catch {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
25
68
|
async function _sendPut(key) {
|
|
26
69
|
const pending = _pendingPuts.get(key);
|
|
27
70
|
if (!pending) return;
|
|
28
|
-
_pendingPuts.delete(key);
|
|
29
71
|
_putTimers.delete(key);
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
-
if (
|
|
33
|
-
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
72
|
+
// Something of this entry is on its way: this write goes when that is settled (still pending until then).
|
|
73
|
+
const busy = _inFlight.get(key);
|
|
74
|
+
if (busy) { busy.then(() => _sendPut(key)); return; }
|
|
75
|
+
_pendingPuts.delete(key);
|
|
76
|
+
const { ns, id, value, opts, rev } = pending;
|
|
77
|
+
const asked = _asked.get(key);
|
|
78
|
+
const request = (async () => {
|
|
79
|
+
const res = await fetch(_url(ns, id, rev, opts), {
|
|
37
80
|
method: 'PUT',
|
|
38
81
|
headers: { 'Content-Type': 'application/json' },
|
|
39
82
|
body: JSON.stringify(value),
|
|
40
83
|
});
|
|
41
84
|
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
85
|
+
})();
|
|
86
|
+
_track(key, request);
|
|
87
|
+
try {
|
|
88
|
+
await request;
|
|
89
|
+
_answer(pending.waiters, true);
|
|
42
90
|
} catch (err) {
|
|
43
|
-
|
|
44
|
-
//
|
|
45
|
-
|
|
91
|
+
// Re-queue only if nothing was asked for this entry meanwhile: a newer value superseded this one, or the
|
|
92
|
+
// entry was deleted (a retry would bring back what was removed).
|
|
93
|
+
const retry = _asked.get(key) === asked && !_pendingPuts.has(key);
|
|
94
|
+
console.warn(`[blob-store] PUT ${ns}/${id} failed:`, err.message, retry ? '— will retry' : '— superseded');
|
|
95
|
+
if (retry) {
|
|
46
96
|
_pendingPuts.set(key, pending);
|
|
47
97
|
_putTimers.set(key, setTimeout(() => _sendPut(key), 2000));
|
|
98
|
+
} else {
|
|
99
|
+
// Whoever waits for this write waits for the newer one that took its place; without one (the entry was
|
|
100
|
+
// deleted) it was given up.
|
|
101
|
+
const newer = _pendingPuts.get(key);
|
|
102
|
+
if (newer) newer.waiters.push(...pending.waiters.splice(0));
|
|
103
|
+
else _answer(pending.waiters, false);
|
|
48
104
|
}
|
|
49
105
|
}
|
|
50
106
|
}
|
|
51
107
|
|
|
52
|
-
//
|
|
108
|
+
// What the callers of putBlob that wait for it are told: `true`, the server has the value (or a newer one of the
|
|
109
|
+
// entry); `false`, the write was given up.
|
|
110
|
+
const _answer = (waiters, stored) => { for (const done of waiters.splice(0)) done(stored); };
|
|
111
|
+
|
|
112
|
+
// Debounced per-(ns,id), latest value wins. Answers a promise, for a caller that must not go on before the value
|
|
113
|
+
// is in the store: `true` once the server has stored it (or a newer value of the entry, when one was asked for
|
|
114
|
+
// meanwhile), `false` when the write was given up (the entry was deleted, or the page is going and the write was
|
|
115
|
+
// handed to a beacon, which says nothing back). It never rejects; a write that fails is tried again as before, and
|
|
116
|
+
// the promise waits with it.
|
|
53
117
|
export function putBlob(ns, id, value, opts = {}) {
|
|
54
118
|
const key = `${ns}/${id}`;
|
|
55
119
|
const debounceMs = opts.debounceMs ?? DEFAULT_DEBOUNCE_MS;
|
|
56
|
-
|
|
120
|
+
_ask(key);
|
|
121
|
+
const waiters = _pendingPuts.get(key)?.waiters || [];
|
|
122
|
+
const stored = new Promise((done) => { waiters.push(done); });
|
|
123
|
+
_pendingPuts.set(key, { ns, id, value, opts, rev: ++_revision, waiters });
|
|
57
124
|
if (_putTimers.has(key)) clearTimeout(_putTimers.get(key));
|
|
58
125
|
_putTimers.set(key, setTimeout(() => _sendPut(key), debounceMs));
|
|
126
|
+
return stored;
|
|
59
127
|
}
|
|
60
128
|
|
|
129
|
+
// A delete is tried once: one that failed (the server could not make it, refused it, or was not reached) is not
|
|
130
|
+
// sent again. This page cannot know what another page has written to the entry since, and a delete that arrived
|
|
131
|
+
// late would remove that.
|
|
61
132
|
export function deleteBlob(ns, id) {
|
|
62
133
|
const key = `${ns}/${id}`;
|
|
63
134
|
if (_putTimers.has(key)) { clearTimeout(_putTimers.get(key)); _putTimers.delete(key); }
|
|
135
|
+
const dropped = _pendingPuts.get(key);
|
|
64
136
|
_pendingPuts.delete(key);
|
|
65
|
-
|
|
66
|
-
|
|
137
|
+
if (dropped) _answer(dropped.waiters, false);
|
|
138
|
+
_ask(key);
|
|
139
|
+
const rev = ++_revision;
|
|
140
|
+
const send = (init = {}) => fetch(_url(ns, id, rev), { method: 'DELETE', ...init }).catch(() => {});
|
|
141
|
+
const busy = _inFlight.get(key);
|
|
142
|
+
if (!busy) { _track(key, send()); return; }
|
|
143
|
+
// After the request of this entry that is on its way (sent once, also when the page goes first: flushBlobs).
|
|
144
|
+
// Its turn sends it only while it is still the one that waits: a later delete has taken its place, or the
|
|
145
|
+
// page that was about to be left has sent it already.
|
|
146
|
+
_waitingDeletes.set(key, send);
|
|
147
|
+
_track(key, busy.then(() => {
|
|
148
|
+
if (_waitingDeletes.get(key) !== send) return undefined;
|
|
149
|
+
_waitingDeletes.delete(key);
|
|
150
|
+
return send();
|
|
151
|
+
}));
|
|
67
152
|
}
|
|
68
153
|
|
|
69
154
|
// Flush all pending puts immediately. With useBeacon (pagehide path), bodies
|
|
70
155
|
// under ~60KB go via sendBeacon (survives unload); larger ones use a best-
|
|
71
156
|
// effort fetch — the last debounced PUT was at most a debounce window ago, so
|
|
72
|
-
// little is lost if it doesn't complete.
|
|
157
|
+
// little is lost if it doesn't complete. What goes out here goes out at once,
|
|
158
|
+
// beside a request that may still be on its way: each carries its number, and
|
|
159
|
+
// the server keeps what was asked for last.
|
|
73
160
|
export function flushBlobs({ useBeacon = false } = {}) {
|
|
161
|
+
// The page is going: a delete that waits behind a request cannot wait any longer.
|
|
162
|
+
if (useBeacon) {
|
|
163
|
+
for (const [key, send] of [..._waitingDeletes.entries()]) { _waitingDeletes.delete(key); send({ keepalive: true }); }
|
|
164
|
+
}
|
|
74
165
|
for (const [key, pending] of [..._pendingPuts.entries()]) {
|
|
75
166
|
if (_putTimers.has(key)) { clearTimeout(_putTimers.get(key)); _putTimers.delete(key); }
|
|
76
167
|
if (useBeacon) {
|
|
77
|
-
const { ns, id, value } = pending;
|
|
168
|
+
const { ns, id, value, rev } = pending;
|
|
78
169
|
const body = JSON.stringify(value);
|
|
79
170
|
_pendingPuts.delete(key);
|
|
171
|
+
_answer(pending.waiters, false); // a beacon says nothing back: nobody is told it arrived
|
|
80
172
|
if (body.length < 60_000) {
|
|
81
|
-
navigator.sendBeacon(
|
|
82
|
-
`/api/ui-blobs/${encodeURIComponent(ns)}/${encodeURIComponent(id)}`,
|
|
83
|
-
new Blob([body], { type: 'application/json' })
|
|
84
|
-
);
|
|
173
|
+
navigator.sendBeacon(_url(ns, id, rev), new Blob([body], { type: 'application/json' }));
|
|
85
174
|
} else {
|
|
86
|
-
fetch(
|
|
175
|
+
fetch(_url(ns, id, rev), {
|
|
87
176
|
method: 'PUT',
|
|
88
177
|
headers: { 'Content-Type': 'application/json' },
|
|
89
178
|
body,
|
|
@@ -7,6 +7,9 @@ import { registerSidepanel, setSidepanelVisible, sidepanelAcceptsKeyboard, openA
|
|
|
7
7
|
import { subscribeCliStatus, recheckCliStatus, getCliDocUrl, getCliInstallCommand, getCliLabel } from '../cli-status.js';
|
|
8
8
|
import { nativeLoopWindowId } from '../ui-native-window-id.js';
|
|
9
9
|
import { createStickyScrollController, getStickyScrollController } from '../ui-scroll-follow.js';
|
|
10
|
+
import { wireFileLinks } from '../ui-file-links.js';
|
|
11
|
+
import { trackWorkerEnd } from '../ui-worker-end.js';
|
|
12
|
+
import { isDispatchedRun } from '../worker-end.js';
|
|
10
13
|
import { injectStyles } from './cdx-styles.js';
|
|
11
14
|
import { mountContextMenu } from './cdx-context-menu.js';
|
|
12
15
|
import { teardownMcpApps } from './cdx-mcp-app-host.js';
|
|
@@ -39,6 +42,7 @@ import {
|
|
|
39
42
|
handleNotify,
|
|
40
43
|
appendLocalUserMessage, hydrateCodexAutomationHistory,
|
|
41
44
|
clearPlanHandoffState,
|
|
45
|
+
placeWorkerEnd,
|
|
42
46
|
withTab,
|
|
43
47
|
ensureProjectsLoaded,
|
|
44
48
|
setActiveProject,
|
|
@@ -107,7 +111,6 @@ let _contextMenu = null;
|
|
|
107
111
|
* monolith and are referenced by wireEvents / ensurePanel.
|
|
108
112
|
*
|
|
109
113
|
* Expected shape:
|
|
110
|
-
* maybeOpenProjectFileLink(href, event) -> bool
|
|
111
114
|
* flushCardBody(itemState)
|
|
112
115
|
* resetThreadState(opts)
|
|
113
116
|
* appendSystem(text, tone)
|
|
@@ -785,14 +788,18 @@ async function saveRecallProfile(profile) {
|
|
|
785
788
|
// ═══════════════════════════════════════════
|
|
786
789
|
|
|
787
790
|
function wireEvents() {
|
|
788
|
-
//
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
791
|
+
// File links open in the code editor (../ui-file-links.js, shared with the other panels): one listener for
|
|
792
|
+
// every tab's transcript, so stored and streaming messages behave alike. Card heads bind in cdx-render.
|
|
793
|
+
wireFileLinks(panelEl('#cxp-messages-container'), {
|
|
794
|
+
// A relative path is a path in the project of the tab on screen (a worker run's tab has the run's folder).
|
|
795
|
+
cwd: (link) => (allTabs().find((tab) => tab.messagesEl?.contains(link)) || activeTab())?.project || '',
|
|
796
|
+
textLinks: 'a.cxp-file-link',
|
|
797
|
+
// A path the editor does not open keeps what a click on it did: it is copied.
|
|
798
|
+
copyPath: (link, path) => navigator.clipboard.writeText(path).then(() => {
|
|
799
|
+
link.classList.add('cxp-file-link-copied');
|
|
800
|
+
setTimeout(() => link.classList.remove('cxp-file-link-copied'), 1500);
|
|
801
|
+
}),
|
|
802
|
+
});
|
|
796
803
|
|
|
797
804
|
const input = panelEl('#cxp-input');
|
|
798
805
|
const send = panelEl('#cxp-send');
|
|
@@ -1274,6 +1281,19 @@ export async function attachCodexAutomation(run, {
|
|
|
1274
1281
|
ensurePanel();
|
|
1275
1282
|
await ensureProjectsLoaded();
|
|
1276
1283
|
if (isCancelled()) return { ok: false, reason: 'dismissed' };
|
|
1284
|
+
const running = run.status === 'starting' || run.status === 'running';
|
|
1285
|
+
// The user continued this run's thread by hand after the run ended: the tab stays theirs. The
|
|
1286
|
+
// dock's Focus raises it; the run is let go again, and nothing in the tab changes.
|
|
1287
|
+
const own = allTabs().find((entry) => !entry.automationRunId && entry.releasedRunId === run.runId && entry.threadId === threadId);
|
|
1288
|
+
if (own && !running) {
|
|
1289
|
+
window.dispatchEvent(new CustomEvent('native-loop:dismissed', { detail: { runId: run.runId } }));
|
|
1290
|
+
if (focus) {
|
|
1291
|
+
if (!_visible) await toggleCodexPanel();
|
|
1292
|
+
const ownIdx = allTabs().indexOf(own);
|
|
1293
|
+
if (ownIdx >= 0) switchTab(ownIdx);
|
|
1294
|
+
}
|
|
1295
|
+
return { ok: true, tabId: own.id, released: true };
|
|
1296
|
+
}
|
|
1277
1297
|
let tab = allTabs().find((entry) => entry.automationRunId === run.runId);
|
|
1278
1298
|
if (!tab) {
|
|
1279
1299
|
tab = createTab({
|
|
@@ -1291,7 +1311,6 @@ export async function attachCodexAutomation(run, {
|
|
|
1291
1311
|
}, { autoSwitch: false });
|
|
1292
1312
|
}
|
|
1293
1313
|
if (!tab) return { ok: false, reason: 'tab_limit' };
|
|
1294
|
-
const running = run.status === 'starting' || run.status === 'running';
|
|
1295
1314
|
// A task-mode worker between turns (waiting for a follow-up) is alive, not working.
|
|
1296
1315
|
const working = running && run.turnState !== 'idle' && run.turnState !== 'terminal';
|
|
1297
1316
|
tab.automationRunId = run.runId;
|
|
@@ -1315,10 +1334,12 @@ export async function attachCodexAutomation(run, {
|
|
|
1315
1334
|
return { ok: false, reason: 'dismissed' };
|
|
1316
1335
|
}
|
|
1317
1336
|
}
|
|
1318
|
-
|
|
1337
|
+
// (A dispatched worker's failure, with its reason, is on its end card.)
|
|
1338
|
+
if (run.status === 'failed' && run.error && !isDispatchedRun(run) && tab._automationLifecycleError !== run.error) {
|
|
1319
1339
|
tab._automationLifecycleError = run.error;
|
|
1320
1340
|
withTab(tab, () => appendSystem(run.error, 'error'));
|
|
1321
1341
|
}
|
|
1342
|
+
trackWorkerEnd(run, { apply: (view) => { tab._workerEnd = view; placeWorkerEnd(tab); } });
|
|
1322
1343
|
saveTabs();
|
|
1323
1344
|
renderPills();
|
|
1324
1345
|
if (focus) {
|
|
@@ -16,6 +16,7 @@ import { bindExpandableCard, setCardExpanded } from './cdx-cards.js';
|
|
|
16
16
|
import { mountMcpAppCard } from './cdx-mcp-app-host.js';
|
|
17
17
|
import { OUTPUT_LIMITS, boundedText, jsonAnswer, prettyJsonFences, readableStructuredValue, fileChangeDiffs, parseUnifiedDiff, deduplicateTurnDiff } from './cdx-output-model.js';
|
|
18
18
|
import { renderReadableOutput, renderReadableBlock, cleanOutputBlocks, hydrateOutputControls, observeOutputBlocks, renderDiffView, restoreDiffViews } from './cdx-output.js';
|
|
19
|
+
import { fileLinkTitle, fillFileLinkCopy, isInsideRoots, parseFileLinkTarget } from '../file-links.js';
|
|
19
20
|
export { setCardExpanded } from './cdx-cards.js';
|
|
20
21
|
|
|
21
22
|
// ── Shared context (set by cdx-tabs via setRenderContext) ──
|
|
@@ -375,101 +376,45 @@ export function postProcessRenderedHtml(container) {
|
|
|
375
376
|
// ═══════════════════════════════════════════
|
|
376
377
|
// File Path Linking
|
|
377
378
|
// ═══════════════════════════════════════════
|
|
379
|
+
// What a target means is decided in ../file-links.js, shared with the other panels; a click is taken by the
|
|
380
|
+
// one listener cdx-panel.js puts on the transcript (../ui-file-links.js), so links in a stored transcript
|
|
381
|
+
// work like fresh ones.
|
|
378
382
|
|
|
379
383
|
export function normalizePathForCompare(path) {
|
|
380
384
|
return String(path || '').replace(/\\/g, '/').replace(/\/+$/, '');
|
|
381
385
|
}
|
|
382
386
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
]);
|
|
390
|
-
for (const root of roots) {
|
|
391
|
-
if (!root) continue;
|
|
392
|
-
if (normalized === root || normalized.startsWith(`${root}/`)) return true;
|
|
393
|
-
}
|
|
394
|
-
return false;
|
|
387
|
+
// The folder a relative link is read from: the project of the tab the transcript belongs to.
|
|
388
|
+
function fileLinkWhere() {
|
|
389
|
+
return {
|
|
390
|
+
cwd: _ctx.boundTab?.project || _ctx.project || '',
|
|
391
|
+
origin: globalThis.location?.origin || '',
|
|
392
|
+
};
|
|
395
393
|
}
|
|
396
394
|
|
|
397
|
-
export function
|
|
398
|
-
|
|
399
|
-
let raw = String(rawTarget).trim();
|
|
400
|
-
if (!raw || raw === '#') return null;
|
|
401
|
-
if (raw.startsWith('file://')) {
|
|
402
|
-
try { raw = decodeURIComponent(new URL(raw).pathname || ''); }
|
|
403
|
-
catch { raw = raw.replace(/^file:\/\//, ''); }
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
let pathPart = raw;
|
|
407
|
-
let hash = '';
|
|
408
|
-
if (/^[a-z]+:\/\//i.test(raw)) {
|
|
409
|
-
try {
|
|
410
|
-
const parsed = new URL(raw, window.location.origin);
|
|
411
|
-
if (parsed.origin !== window.location.origin) return null;
|
|
412
|
-
pathPart = parsed.pathname || '';
|
|
413
|
-
hash = parsed.hash || '';
|
|
414
|
-
} catch {
|
|
415
|
-
return null;
|
|
416
|
-
}
|
|
417
|
-
} else {
|
|
418
|
-
const hashIndex = raw.indexOf('#');
|
|
419
|
-
if (hashIndex >= 0) {
|
|
420
|
-
pathPart = raw.slice(0, hashIndex);
|
|
421
|
-
hash = raw.slice(hashIndex);
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
try { pathPart = decodeURIComponent(pathPart); } catch {}
|
|
426
|
-
pathPart = normalizePathForCompare(pathPart);
|
|
427
|
-
|
|
428
|
-
let line = null;
|
|
429
|
-
let column = null;
|
|
430
|
-
const suffixMatch = pathPart.match(/:(\d+)(?::(\d+))?$/);
|
|
431
|
-
if (suffixMatch) {
|
|
432
|
-
line = Number(suffixMatch[1]) || null;
|
|
433
|
-
column = Number(suffixMatch[2]) || null;
|
|
434
|
-
pathPart = normalizePathForCompare(pathPart.slice(0, suffixMatch.index));
|
|
435
|
-
}
|
|
436
|
-
if (!isProjectFilePath(pathPart)) return null;
|
|
437
|
-
const hashMatch = hash.match(/^#L(\d+)(?:C(\d+))?$/i);
|
|
438
|
-
if (hashMatch) {
|
|
439
|
-
line = Number(hashMatch[1]) || line;
|
|
440
|
-
column = Number(hashMatch[2]) || column;
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
return { filePath: pathPart, line, column };
|
|
395
|
+
export function isProjectFilePath(path) {
|
|
396
|
+
return isInsideRoots(path, [_ctx.boundTab?.project, _ctx.project, ...(_ctx.projects || []).map((entry) => entry?.path)]);
|
|
444
397
|
}
|
|
445
398
|
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
line: target.line || undefined,
|
|
451
|
-
column: target.column || undefined,
|
|
452
|
-
});
|
|
453
|
-
return true;
|
|
399
|
+
// A link target that is a file of this tab's project or of a registered one, or null.
|
|
400
|
+
function projectFileTarget(rawTarget) {
|
|
401
|
+
const target = parseFileLinkTarget(rawTarget, fileLinkWhere());
|
|
402
|
+
return target?.path && isProjectFilePath(target.path) ? target : null;
|
|
454
403
|
}
|
|
455
404
|
|
|
456
|
-
|
|
457
|
-
const
|
|
458
|
-
|
|
459
|
-
event?.preventDefault?.();
|
|
460
|
-
return openProjectFileTarget(target);
|
|
405
|
+
function openInEditorTitle(target) {
|
|
406
|
+
const { key, params } = fileLinkTitle(target);
|
|
407
|
+
return _ctx.fileLinkText?.(key, params) || fillFileLinkCopy(key, params);
|
|
461
408
|
}
|
|
462
409
|
|
|
463
410
|
export function markProjectFileAnchors(container) {
|
|
464
411
|
if (!container) return;
|
|
465
412
|
container.querySelectorAll('a[href]').forEach((link) => {
|
|
466
|
-
const target =
|
|
413
|
+
const target = projectFileTarget(link.getAttribute('href'));
|
|
467
414
|
if (!target) return;
|
|
468
415
|
link.classList.add('cxp-file-link');
|
|
469
|
-
link.dataset.projectFilePath = target.
|
|
470
|
-
link.title = target
|
|
471
|
-
? `Open in editor${target.column ? ` at line ${target.line}, column ${target.column}` : ` at line ${target.line}`}`
|
|
472
|
-
: 'Open in editor';
|
|
416
|
+
link.dataset.projectFilePath = target.path;
|
|
417
|
+
link.title = openInEditorTitle(target);
|
|
473
418
|
});
|
|
474
419
|
}
|
|
475
420
|
|
|
@@ -497,19 +442,10 @@ export function linkifyFilePaths(container) {
|
|
|
497
442
|
const link = document.createElement('a');
|
|
498
443
|
link.className = 'cxp-file-link';
|
|
499
444
|
link.textContent = pathStr;
|
|
500
|
-
const target =
|
|
501
|
-
link.title = target
|
|
502
|
-
? `Open in editor${target.column ? ` at line ${target.line}, column ${target.column}` : ` at line ${target.line}`}`
|
|
503
|
-
: target ? 'Open in editor' : 'Click to copy path';
|
|
445
|
+
const target = projectFileTarget(pathStr);
|
|
446
|
+
link.title = target ? openInEditorTitle(target) : 'Click to copy path';
|
|
504
447
|
link.href = '#';
|
|
505
|
-
|
|
506
|
-
if (maybeOpenProjectFileLink(pathStr, e)) return;
|
|
507
|
-
e.preventDefault();
|
|
508
|
-
const cleanPath = pathStr.replace(/:\d+(:\d+)?$/, '');
|
|
509
|
-
navigator.clipboard.writeText(cleanPath).catch(() => {});
|
|
510
|
-
link.classList.add('cxp-file-link-copied');
|
|
511
|
-
setTimeout(() => link.classList.remove('cxp-file-link-copied'), 1500);
|
|
512
|
-
});
|
|
448
|
+
// The click is taken on the transcript (cdx-panel.js): the editor when it can open the path, else a copy.
|
|
513
449
|
frag.appendChild(link);
|
|
514
450
|
lastIndex = match.index + match[0].length;
|
|
515
451
|
}
|
|
@@ -2442,6 +2442,42 @@ export function injectStyles() {
|
|
|
2442
2442
|
.cxp-post-plan-utilities .cxp-request-btn { flex: 1; justify-content: center; }
|
|
2443
2443
|
}
|
|
2444
2444
|
|
|
2445
|
+
/* ── A dispatched worker's end (ui-worker-end.js): the post-plan header and note in the
|
|
2446
|
+
compaction card's hairline frame, in the transcript column. The title says the state in words. ── */
|
|
2447
|
+
.cxp-worker-end {
|
|
2448
|
+
display: grid;
|
|
2449
|
+
gap: var(--cxp-space-2);
|
|
2450
|
+
min-width: 0;
|
|
2451
|
+
margin: var(--cxp-space-2) var(--cxp-space-2) var(--cxp-space-3) calc(var(--cxp-space-2) + 24px + var(--cxp-space-2));
|
|
2452
|
+
padding: var(--cxp-space-3) var(--cxp-space-4);
|
|
2453
|
+
border: 1px solid var(--cxp-border-strong);
|
|
2454
|
+
border-radius: var(--cxp-radius-md);
|
|
2455
|
+
font-family: var(--cxp-font);
|
|
2456
|
+
}
|
|
2457
|
+
.cxp-worker-end[data-tone="ok"] .cxp-post-plan-header { color: var(--cxp-success); }
|
|
2458
|
+
.cxp-worker-end[data-tone="warn"] .cxp-post-plan-header { color: var(--cxp-warning); }
|
|
2459
|
+
.cxp-worker-end[data-tone="err"] .cxp-post-plan-header { color: var(--cxp-danger); }
|
|
2460
|
+
.cxp-worker-end .cxp-post-plan-note { overflow-wrap: anywhere; }
|
|
2461
|
+
.cxp-worker-end .worker-end-meta {
|
|
2462
|
+
font-family: var(--cxp-mono);
|
|
2463
|
+
font-size: var(--cxp-fs-xs);
|
|
2464
|
+
color: var(--cxp-text-3);
|
|
2465
|
+
}
|
|
2466
|
+
.cxp-worker-end .worker-end-note {
|
|
2467
|
+
font-size: var(--cxp-fs-sm);
|
|
2468
|
+
line-height: var(--cxp-lh-tight);
|
|
2469
|
+
color: var(--cxp-text-3);
|
|
2470
|
+
}
|
|
2471
|
+
.cxp-worker-end .worker-end-actions { display: flex; margin-top: var(--cxp-space-1); }
|
|
2472
|
+
.cxp-worker-end .cxp-request-btn:focus-visible {
|
|
2473
|
+
outline: 2px solid var(--cxp-focus);
|
|
2474
|
+
outline-offset: 2px;
|
|
2475
|
+
}
|
|
2476
|
+
@media (max-width: 390px) {
|
|
2477
|
+
.cxp-worker-end { margin-left: var(--cxp-space-2); padding: var(--cxp-space-3); }
|
|
2478
|
+
.cxp-worker-end .cxp-request-btn { flex: 1; justify-content: center; }
|
|
2479
|
+
}
|
|
2480
|
+
|
|
2445
2481
|
/* ── Composer ── */
|
|
2446
2482
|
.cxp-bottom {
|
|
2447
2483
|
flex-shrink: 0;
|