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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "neural-memory-interface",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.5",
|
|
4
4
|
"private": true,
|
|
5
5
|
"description": "Private local SynaBun interface for memory visualization and multi-agent workflows",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -17,7 +17,6 @@
|
|
|
17
17
|
"scripts": {
|
|
18
18
|
"start": "node server.js",
|
|
19
19
|
"dev": "node --watch server.js",
|
|
20
|
-
"test": "node --test tests/*.test.mjs",
|
|
21
20
|
"build:vendor": "node scripts/build-vendor.mjs",
|
|
22
21
|
"postinstall": "node scripts/rebuild-pty.js && node scripts/build-vendor.mjs"
|
|
23
22
|
},
|
|
@@ -52,6 +51,18 @@
|
|
|
52
51
|
"tar": "^7.5.19"
|
|
53
52
|
},
|
|
54
53
|
"devDependencies": {
|
|
54
|
+
"@codemirror/autocomplete": "6.20.3",
|
|
55
|
+
"@codemirror/commands": "6.11.1",
|
|
56
|
+
"@codemirror/language": "6.13.1",
|
|
57
|
+
"@codemirror/language-data": "6.5.2",
|
|
58
|
+
"@codemirror/legacy-modes": "6.5.5",
|
|
59
|
+
"@codemirror/lint": "6.9.7",
|
|
60
|
+
"@codemirror/merge": "6.12.2",
|
|
61
|
+
"@codemirror/search": "6.7.2",
|
|
62
|
+
"@codemirror/state": "6.7.6",
|
|
63
|
+
"@codemirror/view": "6.43.14",
|
|
64
|
+
"@lezer/highlight": "1.2.5",
|
|
65
|
+
"@replit/codemirror-indentation-markers": "6.5.3",
|
|
55
66
|
"esbuild": "^0.28.1",
|
|
56
67
|
"three": "0.169.0"
|
|
57
68
|
}
|
|
@@ -11,21 +11,24 @@
|
|
|
11
11
|
<link rel="stylesheet" href="/shared/pwa-install.css">
|
|
12
12
|
</head>
|
|
13
13
|
<body id="pwa-install">
|
|
14
|
-
|
|
14
|
+
<!-- Hidden until pwa-install-page.js knows what this browser gets: the wizard or the main UI (Chrome or Edge
|
|
15
|
+
sent here by the launcher), one button (asked for from the Apps menu), or one plain instruction. -->
|
|
16
|
+
<main aria-labelledby="install-title" hidden>
|
|
15
17
|
<img src="/icon-192.png" width="48" height="48" alt="SynaBun">
|
|
16
18
|
<h1 id="install-title">Install SynaBun as an app</h1>
|
|
17
19
|
<p id="install-intro">The server is running in the background. Confirm installation once in your browser to give SynaBun its own app window.</p>
|
|
18
|
-
<
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
</ol>
|
|
20
|
+
<p id="install-chromium" hidden>Chrome or Edge: choose Install as App below, or the browser's Install app menu.</p>
|
|
21
|
+
<p id="install-safari" hidden>Safari on macOS: choose File → Add to Dock. Keep the name SynaBun.</p>
|
|
22
|
+
<p id="install-other" hidden>SynaBun installs as an app from Chrome, Edge, or Safari on macOS. Open it in one of them to install.</p>
|
|
22
23
|
<p id="install-later">After installation, reopen the native SynaBun launcher. It starts or reuses the server and opens your installed PWA. Closing the app window leaves the server running. Use Apps → Stop Server to stop it.</p>
|
|
23
24
|
<div class="actions">
|
|
24
|
-
<button id="install-button" type="button">Install as App</button>
|
|
25
|
+
<button id="install-button" type="button" hidden>Install as App</button>
|
|
25
26
|
<a id="install-continue" href="/">Continue to SynaBun</a>
|
|
26
27
|
</div>
|
|
27
28
|
<p id="install-status" role="status" aria-live="polite"></p>
|
|
28
29
|
</main>
|
|
30
|
+
<!-- Should the script never answer, the page and its way on still show. -->
|
|
31
|
+
<script>setTimeout(() => { document.querySelector('main').hidden = false; }, 4000);</script>
|
|
29
32
|
<script type="module" src="/shared/pwa-install-page.js"></script>
|
|
30
33
|
</body>
|
|
31
34
|
</html>
|
|
@@ -614,7 +614,8 @@
|
|
|
614
614
|
function render(snap) {
|
|
615
615
|
const view = startStatusView(snap, { platform });
|
|
616
616
|
$('mascot').setAttribute('data-state', view.mascot);
|
|
617
|
-
|
|
617
|
+
// A restart read from the supervisor's report names itself (view.heading).
|
|
618
|
+
$('heading').textContent = view.heading ? START_COPY[view.heading] : headings[view.mascot][0];
|
|
618
619
|
$('subtext').textContent = headings[view.mascot][1];
|
|
619
620
|
startBtn.disabled = view.busy || view.state === 'online';
|
|
620
621
|
startLabel.textContent = labels[view.button];
|
|
@@ -622,7 +623,7 @@
|
|
|
622
623
|
const line = say(view.headline);
|
|
623
624
|
if (startStatus.textContent !== line) startStatus.textContent = line;
|
|
624
625
|
$('startElapsed').textContent = view.elapsed;
|
|
625
|
-
$('startElapsed').setAttribute('aria-label', view.elapsed ? START_COPY.elapsedLabel + ': ' + view.elapsed : '');
|
|
626
|
+
$('startElapsed').setAttribute('aria-label', view.elapsed ? START_COPY[view.elapsedLabel] + ': ' + view.elapsed : '');
|
|
626
627
|
$('startHint').textContent = say(view.hint);
|
|
627
628
|
$('startTrail').replaceChildren(...view.trail.map((row) => {
|
|
628
629
|
const item = document.createElement('li');
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
|
|
8
8
|
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
|
|
9
9
|
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
|
|
10
|
+
<link rel="manifest" href="/manifest.json">
|
|
10
11
|
<style>
|
|
11
12
|
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
|
|
12
13
|
|
|
@@ -1412,6 +1413,12 @@ import { fetchRulesStatus, fetchRulesTextWithFallback, installRules, installAllR
|
|
|
1412
1413
|
import {
|
|
1413
1414
|
describeRulesHost, describeRulesInstall, describeRulesInstallAll, describeRulesInPlace, rulesInstallPlan, catalogueTranslator,
|
|
1414
1415
|
} from './shared/settings/settings-rules.js';
|
|
1416
|
+
// Install as an app: the wizard has no step for it. The browser's own dialog opens once, from a click that
|
|
1417
|
+
// moves the wizard on anyway (the welcome choices, Next), and the wizard never reads the answer. Also import-free.
|
|
1418
|
+
import { initPwaInstall, isStandalone, offerPwaInstallOnce } from './shared/pwa-install.js';
|
|
1419
|
+
|
|
1420
|
+
// Chrome and Edge hand the page their install event when it can be installed; Safari and Firefox have none.
|
|
1421
|
+
if (!isStandalone()) initPwaInstall();
|
|
1415
1422
|
|
|
1416
1423
|
// ═══════════════════════════════════════════
|
|
1417
1424
|
// STATE
|
|
@@ -1538,6 +1545,7 @@ function updateNav() {
|
|
|
1538
1545
|
$prevBtn.addEventListener('click', () => goToStep(currentStep - 1));
|
|
1539
1546
|
$nextBtn.addEventListener('click', () => {
|
|
1540
1547
|
if (validateStep(currentStep)) {
|
|
1548
|
+
offerPwaInstallOnce(); // first, while the click still counts as the user's: see pwa-install.js
|
|
1541
1549
|
goToStep(currentStep + 1);
|
|
1542
1550
|
}
|
|
1543
1551
|
});
|
|
@@ -1821,11 +1829,14 @@ function renderHappyBun() {}
|
|
|
1821
1829
|
|
|
1822
1830
|
// Fresh Install → proceed to step 1
|
|
1823
1831
|
document.getElementById('choiceFreshInstall').addEventListener('click', () => {
|
|
1832
|
+
offerPwaInstallOnce();
|
|
1824
1833
|
goToStep(1);
|
|
1825
1834
|
});
|
|
1826
1835
|
|
|
1827
|
-
// Restore → show restore panel
|
|
1836
|
+
// Restore → show restore panel. A restore never passes Next, so this is its click for the browser's
|
|
1837
|
+
// install dialog; the file picker opens on a later click of its own.
|
|
1828
1838
|
document.getElementById('choiceRestore').addEventListener('click', () => {
|
|
1839
|
+
offerPwaInstallOnce();
|
|
1829
1840
|
$choices.style.display = 'none';
|
|
1830
1841
|
$restorePanel.style.display = 'block';
|
|
1831
1842
|
requestAnimationFrame(() => {
|
|
@@ -130,6 +130,14 @@ export function clampEffortId(effort, ids) {
|
|
|
130
130
|
|
|
131
131
|
export const CODEX_EFFORT_VALUE_IDS = EFFORT_LEVELS_BY_PROFILE.codex.map(e => e.id);
|
|
132
132
|
|
|
133
|
+
// The Claude and Codex lists are asked again once a copy is this old (the server
|
|
134
|
+
// answers from its own discovery cache, so it is a local round trip): a page that
|
|
135
|
+
// stays open for days must not keep the list it loaded with. OpenCode's copy is
|
|
136
|
+
// dropped by its change events instead (`ocp-providers-changed`): its list is large.
|
|
137
|
+
const MODEL_LIST_MAX_AGE_MS = 60_000;
|
|
138
|
+
const _modelListAt = new Map();
|
|
139
|
+
function modelListIsFresh(key) { return Date.now() - (_modelListAt.get(key) || 0) < MODEL_LIST_MAX_AGE_MS; }
|
|
140
|
+
|
|
133
141
|
const _codexModelsCache = new Map();
|
|
134
142
|
const _codexModelsLoading = new Map();
|
|
135
143
|
let _opencodeModelsCache = null;
|
|
@@ -268,7 +276,7 @@ export function mergeCodexModelIds(models = []) {
|
|
|
268
276
|
|
|
269
277
|
export async function fetchCodexModels(force = false, accountId = 'default') {
|
|
270
278
|
const account = String(accountId || 'default');
|
|
271
|
-
if (!force && _codexModelsCache.has(account)) return _codexModelsCache.get(account);
|
|
279
|
+
if (!force && _codexModelsCache.has(account) && modelListIsFresh(`codex:${account}`)) return _codexModelsCache.get(account);
|
|
272
280
|
if (_codexModelsLoading.has(account)) return _codexModelsLoading.get(account);
|
|
273
281
|
const loading = (async () => {
|
|
274
282
|
try {
|
|
@@ -278,6 +286,7 @@ export async function fetchCodexModels(force = false, accountId = 'default') {
|
|
|
278
286
|
const models = Array.isArray(data?.models) ? data.models : [];
|
|
279
287
|
const normalized = mergeCodexModelOptions(models, { fallback: false });
|
|
280
288
|
_codexModelsCache.set(account, normalized);
|
|
289
|
+
_modelListAt.set(`codex:${account}`, Date.now());
|
|
281
290
|
return normalized;
|
|
282
291
|
} catch {
|
|
283
292
|
const previous = _codexModelsCache.get(account) || [];
|
|
@@ -455,19 +464,25 @@ export async function fetchOpencodeModels(force = false) {
|
|
|
455
464
|
// Live model list from the installed Claude Code CLI. Falls back to the static
|
|
456
465
|
// list so the picker still renders when the CLI is missing or discovery fails.
|
|
457
466
|
export async function fetchClaudeModels(force = false) {
|
|
458
|
-
if (!force && _claudeModelsCache && _claudeModelsCache.length) return _claudeModelsCache;
|
|
467
|
+
if (!force && _claudeModelsCache && _claudeModelsCache.length && modelListIsFresh('claude-code')) return _claudeModelsCache;
|
|
459
468
|
if (_claudeModelsLoading) return _claudeModelsLoading;
|
|
469
|
+
// A list the CLI verified is never traded for the unverified stand-in: a discovery
|
|
470
|
+
// that fails once (mid-update, mid-restart) must not strip a working picker.
|
|
471
|
+
const verified = () => (_claudeModelsCache?.length && _claudeModelsCache.some(m => m.catalogSource !== 'fallback') ? _claudeModelsCache : null);
|
|
460
472
|
_claudeModelsLoading = (async () => {
|
|
461
473
|
try {
|
|
462
474
|
const resp = await fetch(`/api/claude/models${force ? '?refresh=1' : ''}`);
|
|
463
475
|
const data = await resp.json().catch(() => ({}));
|
|
464
476
|
const models = Array.isArray(data?.models) ? data.models : [];
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
477
|
+
if (models.length && data?.source !== 'fallback') {
|
|
478
|
+
_claudeModelsCache = models.map(model => ({ ...model, catalogSource: data?.source || 'cli' }));
|
|
479
|
+
_modelListAt.set('claude-code', Date.now());
|
|
480
|
+
} else {
|
|
481
|
+
_claudeModelsCache = verified() || (models.length ? models.map(model => ({ ...model, catalogSource: 'fallback' })) : [...CLAUDE_FALLBACK_MODELS]);
|
|
482
|
+
}
|
|
468
483
|
return _claudeModelsCache;
|
|
469
484
|
} catch {
|
|
470
|
-
_claudeModelsCache = [...CLAUDE_FALLBACK_MODELS];
|
|
485
|
+
_claudeModelsCache = verified() || [...CLAUDE_FALLBACK_MODELS];
|
|
471
486
|
return _claudeModelsCache;
|
|
472
487
|
} finally {
|
|
473
488
|
_claudeModelsLoading = null;
|
|
@@ -585,6 +600,7 @@ export function clearRuntimeOptionCaches() {
|
|
|
585
600
|
_codexModelsLoading.clear();
|
|
586
601
|
_opencodeModelsCache = null;
|
|
587
602
|
_claudeModelsCache = null;
|
|
603
|
+
_modelListAt.clear();
|
|
588
604
|
_mcpProfilePresets = null;
|
|
589
605
|
_claudeAccountsCache = null;
|
|
590
606
|
_opencodeAgentsCache = null;
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
// ═══════════════════════════════════════════
|
|
2
|
+
// SynaBun — Assistant: the automation trace, as words (DOM-free)
|
|
3
|
+
// ═══════════════════════════════════════════
|
|
4
|
+
//
|
|
5
|
+
// One `synabun.automation` event per turn phase (lib/assistant-user-context.js)
|
|
6
|
+
// says what the harness did for the turn: what it put into the brain's context
|
|
7
|
+
// (the standing digest, the per-turn notes, the related memories), what it held
|
|
8
|
+
// back and why, and what it learned from the user's own words afterwards.
|
|
9
|
+
// This module turns one snapshot into the lines asst-render.js draws: nothing
|
|
10
|
+
// here touches the DOM, so it is unit-tested in Node.
|
|
11
|
+
//
|
|
12
|
+
// AUTOMATION_COPY is the English; `assistant.automation.*` in i18n/*.json must
|
|
13
|
+
// equal it (tests/assistant-automation-view.test.mjs).
|
|
14
|
+
|
|
15
|
+
export const AUTOMATION_EVENT = 'synabun.automation';
|
|
16
|
+
|
|
17
|
+
export const AUTOMATION_COPY = Object.freeze({
|
|
18
|
+
title: 'Automation',
|
|
19
|
+
'sum.turn': '{n} tok this turn',
|
|
20
|
+
'sum.standing': '{n} standing',
|
|
21
|
+
'sum.none': 'nothing injected',
|
|
22
|
+
'state.waiting': 'learning after the reply',
|
|
23
|
+
'state.running': 'learning…',
|
|
24
|
+
'state.learned': 'learned 1 thing',
|
|
25
|
+
'state.confirmed': 'confirmed 1 thing',
|
|
26
|
+
'state.replaced': 'replaced 1 thing',
|
|
27
|
+
'group.injected': 'Injected',
|
|
28
|
+
'group.withheld': 'Withheld',
|
|
29
|
+
'group.learning': 'Learning',
|
|
30
|
+
'group.session': 'This conversation',
|
|
31
|
+
'tier.greeting': 'Greeting',
|
|
32
|
+
'tier.digest': 'Knowledge digest',
|
|
33
|
+
'tier.last-thread': 'Last conversation',
|
|
34
|
+
'tier.environment': 'Environment',
|
|
35
|
+
'tier.open-item': 'Open item',
|
|
36
|
+
'tier.cue': 'Knowledge cue',
|
|
37
|
+
'tier.delta': 'New knowledge',
|
|
38
|
+
'tier.recall': 'Related memories',
|
|
39
|
+
'tier.knowledge': 'Knowledge of you',
|
|
40
|
+
'tier.nudges': 'Recent-interaction nudges',
|
|
41
|
+
'tier.turn': 'Per-turn notes',
|
|
42
|
+
tok: '{n} tok',
|
|
43
|
+
'meta.standing': 'system slot · frozen {time}',
|
|
44
|
+
'meta.standingRef': 'already in the system slot, not resent',
|
|
45
|
+
'meta.memories': '{n} memories',
|
|
46
|
+
'meta.memory': '1 memory',
|
|
47
|
+
'meta.alreadyPresent': 'already supplied earlier',
|
|
48
|
+
'meta.budget': 'budget {used}/{max} tok',
|
|
49
|
+
'meta.greetingWriter': 'said at session open · written ahead by {model}',
|
|
50
|
+
'meta.greetingFallback': 'said at session open · from the records, no model',
|
|
51
|
+
'reason.layer-off': 'switched off in Settings',
|
|
52
|
+
'reason.nothing-known': 'nothing learned yet',
|
|
53
|
+
'reason.no-recent-thread': 'no recent conversation to mention',
|
|
54
|
+
'reason.in-greeting': 'already said in the greeting',
|
|
55
|
+
'reason.budget': 'over the turn budget, kept for a later turn',
|
|
56
|
+
'reason.not-ranked': 'not ranked relevant by Jev',
|
|
57
|
+
'reason.in-digest': 'already in the digest',
|
|
58
|
+
'reason.already-told': 'already told in this conversation',
|
|
59
|
+
'reason.replaced': 'replaced by a newer statement',
|
|
60
|
+
'reason.one-per-turn': 'one cue per turn',
|
|
61
|
+
'reason.unusable': 'no usable statement',
|
|
62
|
+
'reason.not-delivered': 'the turn ended before the notes could be delivered',
|
|
63
|
+
'reason.trivial': 'trivial prompt',
|
|
64
|
+
'reason.pattern': 'a command or an acknowledgement',
|
|
65
|
+
'reason.judged': 'Jev: memory would not change the reply',
|
|
66
|
+
'reason.nothing-retrieved': 'nothing relevant found',
|
|
67
|
+
'reason.disabled': 'automatic recall is off',
|
|
68
|
+
'reason.error': 'the search failed',
|
|
69
|
+
'reason.system': 'not a prompt of yours',
|
|
70
|
+
'learn.waiting': 'Your words are judged once the reply is done.',
|
|
71
|
+
'learn.running': 'Jev is reading what you typed…',
|
|
72
|
+
'learn.skipped': 'Not judged: {reason}.',
|
|
73
|
+
'learn.cues': 'Cue words: {cues}',
|
|
74
|
+
'learn.judged': 'Jev: lasting signal {p} · {facet} · {scope}',
|
|
75
|
+
'learn.matched': 'Matches: {statement}',
|
|
76
|
+
'learn.contradicts': 'Contradicts: {statement}',
|
|
77
|
+
'learn.created': 'Learned: {statement}',
|
|
78
|
+
'learn.updated': 'Confirmed (seen {n}×): {statement}',
|
|
79
|
+
'learn.superseded': 'Replaced “{old}” with: {statement}',
|
|
80
|
+
'learn.none': 'Nothing stored: {reason}.',
|
|
81
|
+
'learn.evidence': 'Evidence: “{quote}”',
|
|
82
|
+
'learn.writer': 'Written by {engine}',
|
|
83
|
+
'learn.writerOwn': 'Kept as your own sentence ({reason})',
|
|
84
|
+
'learn.writerKept': 'Statement kept as recorded',
|
|
85
|
+
'learn.cost': '{requests} Jev requests · {tokens} tok · {cost}',
|
|
86
|
+
'learn.scope.global': 'all projects',
|
|
87
|
+
'skip.no-cue': 'no always / never / from-now-on wording',
|
|
88
|
+
'skip.trivial': 'trivial prompt',
|
|
89
|
+
'skip.short': 'too short',
|
|
90
|
+
'skip.origin': 'not typed by you',
|
|
91
|
+
'skip.untrusted': 'forwarded content',
|
|
92
|
+
'skip.no-typed-text': 'only attachments or pasted text',
|
|
93
|
+
'skip.seen': 'the same words were already judged',
|
|
94
|
+
'skip.gate-cap': 'this conversation reached its limit of judgments',
|
|
95
|
+
'skip.write-cap': 'this conversation reached its limit of learned facts',
|
|
96
|
+
'skip.layer-off': 'Knowledge of you is off',
|
|
97
|
+
'skip.system': 'not a prompt of yours',
|
|
98
|
+
'none.not-durable': 'not a lasting preference',
|
|
99
|
+
'none.no-answer': 'Jev did not answer',
|
|
100
|
+
'none.jev-unavailable': 'Jev is off or has no key',
|
|
101
|
+
'none.duplicate': 'memory already states this',
|
|
102
|
+
'none.write-cap': 'this conversation reached its limit of learned facts',
|
|
103
|
+
'none.no-evidence': 'no sentence carried it',
|
|
104
|
+
'none.no-statement': 'no usable statement',
|
|
105
|
+
'none.write-error': 'the memory write failed',
|
|
106
|
+
'none.no-store': 'memory is not available',
|
|
107
|
+
'none.error': 'the learning step failed',
|
|
108
|
+
'writer.unverified': 'the rewrite could not be checked',
|
|
109
|
+
'writer.not-faithful': 'the rewrite added something',
|
|
110
|
+
'writer.no-writer': 'no writer model',
|
|
111
|
+
'writer.writer-cap': 'writer limit reached',
|
|
112
|
+
'writer.other': 'the writer failed',
|
|
113
|
+
totals: 'Judged {gate}/{gateCap} · writer {writer}/{writerCap} · learned {writes}/{writeCap} · {tokens} tok injected over {turns} turns · {cost}',
|
|
114
|
+
open: 'Open memory',
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
const fill = (text, params) => (params ? String(text).replace(/\{(\w+)\}/g, (_, key) => (params[key] != null ? params[key] : `{${key}}`)) : String(text));
|
|
118
|
+
|
|
119
|
+
/** The translator: `t(key, params)` when it knows the key, else the English above. */
|
|
120
|
+
export function automationText(t, key, params) {
|
|
121
|
+
const full = `assistant.automation.${key}`;
|
|
122
|
+
let value;
|
|
123
|
+
try { value = typeof t === 'function' ? t(full, params) : undefined; } catch { value = undefined; }
|
|
124
|
+
if (typeof value === 'string' && value && value !== full) return value;
|
|
125
|
+
const fallback = AUTOMATION_COPY[key];
|
|
126
|
+
return fallback == null ? key : fill(fallback, params);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const num = (value) => (Number.isFinite(Number(value)) ? Number(value) : 0);
|
|
130
|
+
|
|
131
|
+
/** A dollar amount small enough to matter: 5 decimals under a cent, 2 above. */
|
|
132
|
+
export function formatUsd(value) {
|
|
133
|
+
const n = num(value);
|
|
134
|
+
if (n <= 0) return '$0';
|
|
135
|
+
return n < 0.01 ? `$${n.toFixed(5).replace(/0+$/, '').replace(/\.$/, '')}` : `$${n.toFixed(2)}`;
|
|
136
|
+
}
|
|
137
|
+
const pct = (value) => `${Math.round(num(value) * 100)}%`;
|
|
138
|
+
const defaultTime = (iso) => {
|
|
139
|
+
const ms = Date.parse(iso ?? '');
|
|
140
|
+
if (!Number.isFinite(ms)) return '';
|
|
141
|
+
try { return new Date(ms).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }); } catch { return ''; }
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
function writerLine(tx, learning) {
|
|
145
|
+
const action = learning.action || {};
|
|
146
|
+
const writer = learning.writer || {};
|
|
147
|
+
if (!action.engine) return null;
|
|
148
|
+
if (action.engine === 'kept') return tx('learn.writerKept');
|
|
149
|
+
if (action.engine === 'user-sentence') {
|
|
150
|
+
const code = writer.reason && AUTOMATION_COPY[`writer.${writer.reason}`] ? writer.reason : 'other';
|
|
151
|
+
return tx('learn.writerOwn', { reason: tx(`writer.${code}`) });
|
|
152
|
+
}
|
|
153
|
+
return tx('learn.writer', { engine: writer.verified != null ? `${action.engine} · ${pct(writer.verified)}` : action.engine });
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* One snapshot → what the trace row shows.
|
|
158
|
+
* → { traceId, phase, summary, state, tone, groups:[{ key, title, rows:[{ label, meta, text, pre, ids, tone }] }] }
|
|
159
|
+
* tone: '' | 'busy' | 'learned'. `pre`: `text` is exact injected text (keep its line breaks).
|
|
160
|
+
*/
|
|
161
|
+
export function automationView(ev = {}, { t = null, formatTime = defaultTime } = {}) {
|
|
162
|
+
const tx = (key, params) => automationText(t, key, params);
|
|
163
|
+
const tokens = ev.tokens || {};
|
|
164
|
+
const injected = Array.isArray(ev.injected) ? ev.injected : [];
|
|
165
|
+
const withheld = Array.isArray(ev.withheld) ? ev.withheld : [];
|
|
166
|
+
const learning = ev.learning || {};
|
|
167
|
+
const totals = ev.totals || {};
|
|
168
|
+
const tok = (n) => tx('tok', { n: num(n) });
|
|
169
|
+
const tier = (code) => tx(`tier.${AUTOMATION_COPY[`tier.${code}`] ? code : 'turn'}`);
|
|
170
|
+
|
|
171
|
+
// ── the one-line summary ──
|
|
172
|
+
const turnTokens = num(tokens.turn) + num(tokens.recall);
|
|
173
|
+
const parts = [];
|
|
174
|
+
if (turnTokens > 0) parts.push(tx('sum.turn', { n: turnTokens }));
|
|
175
|
+
if (num(tokens.digest) > 0) parts.push(tx('sum.standing', { n: num(tokens.digest) }));
|
|
176
|
+
const summary = parts.length ? parts.join(' · ') : tx('sum.none');
|
|
177
|
+
let state = '';
|
|
178
|
+
let tone = '';
|
|
179
|
+
const action = learning.action || null;
|
|
180
|
+
if (learning.state === 'waiting') { state = tx('state.waiting'); tone = 'busy'; }
|
|
181
|
+
else if (learning.state === 'running') { state = tx('state.running'); tone = 'busy'; }
|
|
182
|
+
else if (learning.state === 'done' && action && action.type && action.type !== 'none') {
|
|
183
|
+
state = tx(action.type === 'update' ? 'state.confirmed' : action.type === 'supersede' ? 'state.replaced' : 'state.learned');
|
|
184
|
+
tone = 'learned';
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const groups = [];
|
|
188
|
+
// ── injected ──
|
|
189
|
+
const injectedRows = injected.map((item) => {
|
|
190
|
+
const meta = [tok(item.tokens)];
|
|
191
|
+
if (item.tier === 'digest') meta.push(item.text ? tx('meta.standing', { time: formatTime(item.frozenAt) }) : tx('meta.standingRef'));
|
|
192
|
+
// The greeting: who wrote it and what that cost (the records it was built from are the links below it).
|
|
193
|
+
if (item.tier === 'greeting') {
|
|
194
|
+
meta.push(item.source === 'writer' ? tx('meta.greetingWriter', { model: item.model || 'Claude' }) : tx('meta.greetingFallback'));
|
|
195
|
+
if (item.source === 'writer' && Number(item.costUsd) > 0) meta.push(formatUsd(item.costUsd));
|
|
196
|
+
}
|
|
197
|
+
if (item.tier === 'recall') {
|
|
198
|
+
const n = Array.isArray(item.ids) ? item.ids.length : 0;
|
|
199
|
+
meta.push(n === 1 ? tx('meta.memory') : tx('meta.memories', { n }));
|
|
200
|
+
if (item.alreadyPresent) meta.push(tx('meta.alreadyPresent'));
|
|
201
|
+
}
|
|
202
|
+
return { label: tier(item.tier), meta: meta.filter(Boolean).join(' · '), text: item.text || '', pre: item.tier === 'digest' && !!item.text, ids: item.tier === 'recall' ? [] : (Array.isArray(item.ids) ? item.ids : []), tone: '' };
|
|
203
|
+
});
|
|
204
|
+
if (injectedRows.length) {
|
|
205
|
+
if (num(tokens.budget) > 0) injectedRows.push({ label: tier('turn'), meta: tx('meta.budget', { used: num(tokens.turn), max: num(tokens.budget) }), text: '', pre: false, ids: [], tone: 'muted' });
|
|
206
|
+
groups.push({ key: 'injected', title: tx('group.injected'), rows: injectedRows });
|
|
207
|
+
}
|
|
208
|
+
// ── withheld ──
|
|
209
|
+
if (withheld.length) {
|
|
210
|
+
groups.push({
|
|
211
|
+
key: 'withheld', title: tx('group.withheld'),
|
|
212
|
+
rows: withheld.map((item) => ({
|
|
213
|
+
label: tier(item.tier), meta: tx(`reason.${AUTOMATION_COPY[`reason.${item.reason}`] ? item.reason : 'unusable'}`),
|
|
214
|
+
text: item.text || '', pre: false, ids: Array.isArray(item.ids) ? item.ids : [], tone: 'muted',
|
|
215
|
+
})),
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
// ── learning ──
|
|
219
|
+
const learnRows = [];
|
|
220
|
+
const pre = learning.prefilter || {};
|
|
221
|
+
if (learning.state === 'skipped') {
|
|
222
|
+
learnRows.push({ label: '', meta: '', text: tx('learn.skipped', { reason: tx(`skip.${AUTOMATION_COPY[`skip.${pre.reason}`] ? pre.reason : 'no-cue'}`) }), pre: false, ids: [], tone: 'muted' });
|
|
223
|
+
} else if (learning.state === 'waiting' || learning.state === 'running') {
|
|
224
|
+
if (Array.isArray(pre.cues) && pre.cues.length) learnRows.push({ label: '', meta: '', text: tx('learn.cues', { cues: pre.cues.join(', ') }), pre: false, ids: [], tone: '' });
|
|
225
|
+
learnRows.push({ label: '', meta: '', text: tx(learning.state === 'waiting' ? 'learn.waiting' : 'learn.running'), pre: false, ids: [], tone: 'muted' });
|
|
226
|
+
} else if (learning.state === 'done') {
|
|
227
|
+
const gate = learning.gate || null;
|
|
228
|
+
if (Array.isArray(pre.cues) && pre.cues.length) learnRows.push({ label: '', meta: '', text: tx('learn.cues', { cues: pre.cues.join(', ') }), pre: false, ids: [], tone: '' });
|
|
229
|
+
if (gate?.answered) {
|
|
230
|
+
learnRows.push({ label: '', meta: '', text: tx('learn.judged', { p: pct(gate.durable), facet: gate.facet || '', scope: !gate.scope || gate.scope === 'global' ? tx('learn.scope.global') : gate.scope }), pre: false, ids: [], tone: '' });
|
|
231
|
+
if (gate.contradicts) learnRows.push({ label: '', meta: pct(gate.contradicts.probability), text: tx('learn.contradicts', { statement: gate.contradicts.statement }), pre: false, ids: [gate.contradicts.id].filter(Boolean), tone: '' });
|
|
232
|
+
else if (gate.match) learnRows.push({ label: '', meta: pct(gate.match.confidence), text: tx('learn.matched', { statement: gate.match.statement }), pre: false, ids: [gate.match.id].filter(Boolean), tone: '' });
|
|
233
|
+
}
|
|
234
|
+
const act = action || { type: 'none', reason: 'error' };
|
|
235
|
+
if (act.type === 'none') {
|
|
236
|
+
const code = AUTOMATION_COPY[`none.${act.reason}`] ? act.reason : 'error';
|
|
237
|
+
const extra = act.reason === 'not-durable' && gate?.durable != null ? ` (${pct(gate.durable)})` : '';
|
|
238
|
+
learnRows.push({ label: '', meta: '', text: tx('learn.none', { reason: `${tx(`none.${code}`)}${extra}` }), pre: false, ids: [act.duplicateOf].filter(Boolean), tone: 'muted' });
|
|
239
|
+
} else {
|
|
240
|
+
const text = act.type === 'update' ? tx('learn.updated', { n: num(act.seen) || 2, statement: act.statement })
|
|
241
|
+
: act.type === 'supersede' ? tx('learn.superseded', { old: act.replaced || '', statement: act.statement })
|
|
242
|
+
: tx('learn.created', { statement: act.statement });
|
|
243
|
+
learnRows.push({ label: '', meta: [act.facet, !act.scope || act.scope === 'global' ? tx('learn.scope.global') : act.scope].filter(Boolean).join(' · '), text, pre: false, ids: [act.memoryId, act.supersedes].filter(Boolean), tone: 'learned' });
|
|
244
|
+
if (act.evidence) learnRows.push({ label: '', meta: '', text: tx('learn.evidence', { quote: act.evidence }), pre: false, ids: [], tone: '' });
|
|
245
|
+
const written = writerLine(tx, learning);
|
|
246
|
+
if (written) learnRows.push({ label: '', meta: '', text: written, pre: false, ids: [], tone: 'muted' });
|
|
247
|
+
}
|
|
248
|
+
const cost = learning.cost || {};
|
|
249
|
+
if (num(cost.jevRequests) > 0 || num(cost.writerUsd) > 0) {
|
|
250
|
+
const writerTokens = cost.writerTokens ? num(cost.writerTokens.input) + num(cost.writerTokens.output) + num(cost.writerTokens.cacheRead) + num(cost.writerTokens.cacheWrite) : 0;
|
|
251
|
+
learnRows.push({ label: '', meta: '', text: tx('learn.cost', { requests: num(cost.jevRequests), tokens: num(cost.jevInputTokens) + num(cost.jevOutputTokens) + writerTokens, cost: formatUsd(cost.totalUsd) }), pre: false, ids: [], tone: 'muted' });
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
if (learnRows.length) groups.push({ key: 'learning', title: tx('group.learning'), rows: learnRows });
|
|
255
|
+
// ── session totals ──
|
|
256
|
+
if (num(totals.turns) > 0) {
|
|
257
|
+
groups.push({
|
|
258
|
+
key: 'session', title: tx('group.session'),
|
|
259
|
+
rows: [{ label: '', meta: '', text: tx('totals', { gate: num(totals.gate), gateCap: num(totals.gateCap), writer: num(totals.writer), writerCap: num(totals.writerCap), writes: num(totals.writes), writeCap: num(totals.writeCap), tokens: num(totals.injectedTokens), turns: num(totals.turns), cost: formatUsd(totals.costUsd) }), pre: false, ids: [], tone: 'muted' }],
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
return { traceId: String(ev.traceId || ''), phase: String(ev.phase || 'sent'), title: tx('title'), summary, state, tone, groups };
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// ── typed words (the composer) ──────────────────────────────────────────────
|
|
266
|
+
// A paste this long, or this many lines, is text the user did not type
|
|
267
|
+
// (lib/assistant-user-context-budgets.js LEARN.pasteChars / pasteLines): the
|
|
268
|
+
// prompt still carries it, the `typed` text the server may learn from does not.
|
|
269
|
+
export const PASTE_MIN_CHARS = 200;
|
|
270
|
+
export const PASTE_MIN_LINES = 4;
|
|
271
|
+
|
|
272
|
+
export function isLongPaste(text) {
|
|
273
|
+
const value = String(text ?? '');
|
|
274
|
+
if (!value.trim()) return false;
|
|
275
|
+
return value.length >= PASTE_MIN_CHARS || value.split(/\r\n|\r|\n/).filter((line) => line.trim()).length >= PASTE_MIN_LINES;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/** The composer's text without the long pastes still in it (those edited since count as typed). */
|
|
279
|
+
export function typedText(text, pastes = []) {
|
|
280
|
+
let out = String(text ?? '').replace(/\r\n?/g, '\n');
|
|
281
|
+
for (const paste of Array.isArray(pastes) ? pastes : []) {
|
|
282
|
+
const block = String(paste ?? '').replace(/\r\n?/g, '\n').trim();
|
|
283
|
+
if (block && out.includes(block)) out = out.split(block).join('\n');
|
|
284
|
+
}
|
|
285
|
+
return out.replace(/[ \t]+\n/g, '\n').replace(/\n{3,}/g, '\n\n').trim();
|
|
286
|
+
}
|