synabun 2.0.0-beta → 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 +65 -0
- package/NOTICE +5 -0
- package/README.md +1 -1
- package/THIRD-PARTY-LICENSES.md +51 -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/launcher.mjs +40 -0
- package/lib/claude-hooks.js +61 -8
- package/lib/client-config-repair.js +4 -3
- package/lib/data-home-migration.js +4 -0
- package/lib/desktop-pwa.js +206 -0
- package/lib/external-tools.js +221 -0
- package/lib/first-launch-protection.js +5 -0
- package/lib/packaged-runtime.js +110 -0
- package/lib/start-launcher.js +1396 -0
- package/mcp-server/package-lock.json +2 -2
- package/mcp-server/package.json +1 -3
- package/neural-interface/i18n/en.json +1540 -154
- package/neural-interface/i18n/pt-BR.json +1538 -153
- 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-envelope.js +9 -6
- 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/augmented-path.js +23 -3
- package/neural-interface/lib/browser-background-tab.js +134 -0
- package/neural-interface/lib/browser-language.js +83 -0
- package/neural-interface/lib/browser-screenshot.js +678 -61
- package/neural-interface/lib/claude-agent-bridge.js +87 -153
- package/neural-interface/lib/claude-executable.js +241 -0
- package/neural-interface/lib/claude-model-catalog.js +82 -93
- 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-binary-runtime.js +69 -337
- package/neural-interface/lib/native-loop-providers.js +40 -49
- package/neural-interface/lib/offline-page.js +54 -0
- 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/session-title-generator.js +5 -0
- package/neural-interface/lib/synabun-update-plan.js +19 -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 -253
- package/neural-interface/package.json +13 -2
- package/neural-interface/public/install-app.html +34 -0
- package/neural-interface/public/manifest.json +2 -0
- package/neural-interface/public/offline.html +402 -66
- package/neural-interface/public/onboarding.html +264 -147
- 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 +26 -64
- 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-rack-styles.js +0 -3
- package/neural-interface/public/shared/assistant/asst-render.js +219 -67
- 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 +162 -6
- 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/command-runner-model.js +30 -0
- 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 +169 -170
- 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 +62 -0
- package/neural-interface/public/shared/pwa-install.css +12 -0
- package/neural-interface/public/shared/pwa-install.js +127 -0
- 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-rules.js +160 -0
- package/neural-interface/public/shared/settings/settings-user-context.js +154 -0
- package/neural-interface/public/shared/start-bridge.js +802 -0
- package/neural-interface/public/shared/styleguide/sg-colors.js +5 -2
- package/neural-interface/public/shared/styleguide/sg-import-export.js +4 -3
- package/neural-interface/public/shared/styleguide/sg-kit.js +4 -1
- package/neural-interface/public/shared/styleguide/sg-panel.js +9 -1
- package/neural-interface/public/shared/styleguide/sg-typography.js +1 -0
- package/neural-interface/public/shared/styles.css +2219 -1117
- package/neural-interface/public/shared/synabun-mascot.js +20 -56
- package/neural-interface/public/shared/term-ready.js +307 -0
- package/neural-interface/public/shared/tunnel-view.js +167 -0
- package/neural-interface/public/shared/ui-claude-panel.js +160 -19
- package/neural-interface/public/shared/ui-command-runner.js +251 -468
- 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-judgments.js +1 -1
- package/neural-interface/public/shared/ui-keybinds.js +4 -0
- package/neural-interface/public/shared/ui-loading.js +367 -12
- package/neural-interface/public/shared/ui-menubar.js +21 -55
- 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 +491 -547
- 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 +153 -149
- 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 +3 -1
- package/neural-interface/public/variant/2d/main.js +2 -1
- package/neural-interface/public/variant/3d/main.js +2 -1
- 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/rebuild-pty.js +15 -12
- package/neural-interface/scripts/vendor-codemirror-entry.js +121 -0
- package/neural-interface/server.js +1092 -1212
- package/neural-interface/templates/rulesets/README.md +1 -1
- package/package.json +13 -7
- package/postinstall.js +11 -81
- package/setup.js +111 -6
- package/benchmarks/browser-live-results.json +0 -79
- package/benchmarks/browser-v2-results.json +0 -258
- package/docs/browser-v2.md +0 -109
- package/docs/hook-integrity.md +0 -89
- package/docs/judgments.md +0 -182
- package/docs/style-guide.md +0 -246
- 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/scripts/audit-claude-hook-usage.mjs +0 -12
- package/scripts/audit-memory-duplicates.mjs +0 -44
- package/scripts/measure-claude-hook-overhead.mjs +0 -77
- package/scripts/recover-user-config.mjs +0 -254
- package/skills/synabun/synabunicon.png +0 -0
|
@@ -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
|
|
|
@@ -539,7 +540,7 @@
|
|
|
539
540
|
.mcp-other-section.open .mcp-other-chevron { transform: rotate(180deg); }
|
|
540
541
|
.mcp-other-body { padding: 0 14px 12px; }
|
|
541
542
|
|
|
542
|
-
/* ── Rules (Step 5 option, Step 6
|
|
543
|
+
/* ── Rules (Step 5 option, Step 6 installer) ── */
|
|
543
544
|
.rules-option {
|
|
544
545
|
display: flex;
|
|
545
546
|
align-items: center;
|
|
@@ -550,12 +551,37 @@
|
|
|
550
551
|
cursor: pointer;
|
|
551
552
|
user-select: none;
|
|
552
553
|
}
|
|
554
|
+
/* A step whose height follows what the installer reports: on a short window it scrolls (its parts keep their
|
|
555
|
+
height instead of being squeezed) rather than being cut off. */
|
|
556
|
+
.step[data-step="6"] { max-height: calc(90vh - 58px); }
|
|
557
|
+
.step[data-step="6"] > * { flex-shrink: 0; }
|
|
558
|
+
.step[data-step="6"] .subtitle { margin-bottom: 16px; }
|
|
559
|
+
/* The step's one primary action: what it does, then the button. */
|
|
560
|
+
.rules-install-all {
|
|
561
|
+
display: flex;
|
|
562
|
+
align-items: center;
|
|
563
|
+
gap: 14px;
|
|
564
|
+
padding: 12px 14px;
|
|
565
|
+
margin-bottom: 12px;
|
|
566
|
+
border: 1px solid var(--accent-border);
|
|
567
|
+
border-radius: var(--r-card);
|
|
568
|
+
background: var(--accent-bg);
|
|
569
|
+
}
|
|
570
|
+
.rules-install-all .ria-text { flex: 1 1 0; min-width: 0; font-size: 12px; color: var(--t-primary); line-height: 1.5; }
|
|
571
|
+
.rules-install-all .action-btn { flex-shrink: 0; padding: 9px 18px; font-size: 12px; white-space: nowrap; }
|
|
572
|
+
/* What the installer answered, and where the rules live. */
|
|
573
|
+
.rules-result { margin-bottom: 12px; font-size: 12px; color: var(--t-primary); line-height: 1.5; overflow-wrap: anywhere; }
|
|
574
|
+
.rules-result.ok .rr-message::before { content: '\2713'; margin-right: 8px; color: var(--green); }
|
|
575
|
+
.rules-result.fail .rr-message { color: var(--red); }
|
|
576
|
+
.rules-result .rr-where { margin-top: 4px; font-size: 11px; color: var(--t-muted); }
|
|
553
577
|
.rules-list {
|
|
554
578
|
display: flex;
|
|
555
579
|
flex-direction: column;
|
|
556
580
|
gap: 8px;
|
|
557
581
|
margin-bottom: 12px;
|
|
558
582
|
}
|
|
583
|
+
.rules-list:empty { display: none; }
|
|
584
|
+
.rules-list .mcp-toggle-row.has-note { align-items: flex-start; }
|
|
559
585
|
.rules-list .mtr-state {
|
|
560
586
|
margin-left: 6px;
|
|
561
587
|
font-size: 10px;
|
|
@@ -563,8 +589,9 @@
|
|
|
563
589
|
color: var(--t-muted);
|
|
564
590
|
}
|
|
565
591
|
.rules-list .mtr-state.ok { color: var(--green); }
|
|
592
|
+
.rules-list .mtr-note { margin-top: 4px; font-size: 11px; color: var(--t-secondary); line-height: 1.45; overflow-wrap: anywhere; }
|
|
566
593
|
.rules-actions { display: flex; gap: 6px; flex-shrink: 0; }
|
|
567
|
-
.rules-actions button {
|
|
594
|
+
.rules-actions button, .rules-note button {
|
|
568
595
|
padding: 5px 10px;
|
|
569
596
|
border-radius: 8px;
|
|
570
597
|
border: 1px solid var(--b-light);
|
|
@@ -576,11 +603,16 @@
|
|
|
576
603
|
white-space: nowrap;
|
|
577
604
|
transition: all var(--ease);
|
|
578
605
|
}
|
|
579
|
-
.rules-actions button:hover { background: var(--s-medium); color: var(--t-bright); border-color: var(--b-hover); }
|
|
580
|
-
.rules-actions button
|
|
606
|
+
.rules-actions button:hover, .rules-note button:hover { background: var(--s-medium); color: var(--t-bright); border-color: var(--b-hover); }
|
|
607
|
+
.rules-actions button.primary { border-color: var(--accent-border); background: var(--s-active); color: var(--t-bright); font-weight: 600; }
|
|
608
|
+
.rules-actions button:disabled, .rules-note button:disabled { opacity: 0.4; cursor: default; }
|
|
581
609
|
.rules-note { font-size: 11px; color: var(--t-muted); margin-bottom: 12px; line-height: 1.5; }
|
|
610
|
+
.rules-note button { margin-left: 8px; }
|
|
611
|
+
/* Under the installer: the text SynaBun cannot install, to paste by hand. */
|
|
612
|
+
.rules-manual-label { margin: 4px 0 8px; font-size: 10px; color: var(--t-muted); text-transform: uppercase; letter-spacing: 0.5px; }
|
|
582
613
|
.rules-extra { margin-top: 8px; }
|
|
583
614
|
#rulesViewCode, #rulesCursorCode, #rulesCoexistCode { max-height: 160px; }
|
|
615
|
+
#rulesViewCode { margin-bottom: 12px; }
|
|
584
616
|
|
|
585
617
|
/* ── Dependency List ── */
|
|
586
618
|
.dep-list {
|
|
@@ -1188,14 +1220,14 @@
|
|
|
1188
1220
|
<span class="mascot-toast" id="mascotToast"></span>
|
|
1189
1221
|
</div>
|
|
1190
1222
|
<h2>AI Tool Integration</h2>
|
|
1191
|
-
<p class="subtitle">Toggle on the AI coding tools you use. SynaBun registers itself with each one automatically.</p>
|
|
1223
|
+
<p class="subtitle">Toggle on the AI coding tools you use. SynaBun registers itself with each one and installs its rules automatically.</p>
|
|
1192
1224
|
<div class="mcp-toggle-list" id="mcpToggleList"></div>
|
|
1193
1225
|
<label class="rules-option" for="rulesInstallOpt">
|
|
1194
1226
|
<span class="key-backup-checkbox-wrap">
|
|
1195
1227
|
<input type="checkbox" id="rulesInstallOpt" checked>
|
|
1196
1228
|
<span class="key-backup-checkmark"><svg viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg></span>
|
|
1197
1229
|
</span>
|
|
1198
|
-
<span>Install SynaBun's rules
|
|
1230
|
+
<span>Install SynaBun's rules with each tool I connect</span>
|
|
1199
1231
|
</label>
|
|
1200
1232
|
<div class="mcp-other-section" id="mcpOtherSection">
|
|
1201
1233
|
<div class="mcp-other-header" id="mcpOtherHeader">
|
|
@@ -1213,27 +1245,31 @@
|
|
|
1213
1245
|
</div>
|
|
1214
1246
|
</div>
|
|
1215
1247
|
|
|
1216
|
-
<!-- Step 6: SynaBun rules -->
|
|
1248
|
+
<!-- Step 6: Install SynaBun rules. The installer leads; the copy boxes at the bottom are only for what it cannot write. -->
|
|
1217
1249
|
<div class="step right" data-step="6">
|
|
1218
|
-
<div
|
|
1219
|
-
|
|
1220
|
-
|
|
1250
|
+
<div class="step-eyes"></div>
|
|
1251
|
+
<h2>Install SynaBun Rules</h2>
|
|
1252
|
+
<p class="subtitle">SynaBun installs its rules where each connected tool loads them for every project, and keeps them up to date. There is nothing to paste.</p>
|
|
1253
|
+
<div class="rules-note" id="rulesNote" role="status" style="display:none;"></div>
|
|
1254
|
+
<div class="rules-install-all" id="rulesInstallAll" style="display:none;">
|
|
1255
|
+
<div class="ria-text" id="rulesInstallAllHelp"></div>
|
|
1256
|
+
<button type="button" class="action-btn" id="rulesInstallAllBtn" aria-describedby="rulesInstallAllHelp"></button>
|
|
1221
1257
|
</div>
|
|
1222
|
-
<
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
<div class="rules-list" id="rulesList"></div>
|
|
1226
|
-
<div class="code-copy-wrap" id="rulesViewWrap" style="display:none;margin-bottom:12px;">
|
|
1227
|
-
<div class="instructions-preview" id="rulesViewCode"></div>
|
|
1228
|
-
<span class="code-copy-label">copy</span>
|
|
1258
|
+
<div class="rules-result" id="rulesResult" role="status" style="display:none;">
|
|
1259
|
+
<div class="rr-message" id="rulesResultMessage"></div>
|
|
1260
|
+
<div class="rr-where" id="rulesResultWhere"></div>
|
|
1229
1261
|
</div>
|
|
1262
|
+
<div class="rules-list" id="rulesList"></div>
|
|
1263
|
+
<div class="instructions-preview" id="rulesViewCode" role="region" tabindex="0" style="display:none;"></div>
|
|
1264
|
+
<div class="rules-note" id="rulesIdle" style="display:none;"></div>
|
|
1265
|
+
<div class="rules-manual-label">Manual setup</div>
|
|
1230
1266
|
<div class="mcp-other-section" id="rulesCursorSection">
|
|
1231
1267
|
<div class="mcp-other-header" id="rulesCursorHeader">
|
|
1232
|
-
<span>Cursor (
|
|
1268
|
+
<span>Cursor (its rules are pasted by hand)</span>
|
|
1233
1269
|
<svg class="mcp-other-chevron" viewBox="0 0 24 24" width="14" height="14"><polyline points="6 9 12 15 18 9" fill="none" stroke="currentColor" stroke-width="2"/></svg>
|
|
1234
1270
|
</div>
|
|
1235
1271
|
<div class="mcp-other-body" id="rulesCursorBody" style="display:none;">
|
|
1236
|
-
<div style="font-size:12px;color:var(--t-secondary);margin-bottom:6px;">Cursor keeps User Rules inside the app.
|
|
1272
|
+
<div id="rulesCursorHelp" style="font-size:12px;color:var(--t-secondary);margin-bottom:6px;">Cursor keeps its User Rules inside the app, so SynaBun cannot install them. Copy the rules and paste them into Cursor Settings → Rules.</div>
|
|
1237
1273
|
<div class="code-copy-wrap" id="rulesCursorWrap">
|
|
1238
1274
|
<div class="instructions-preview" id="rulesCursorCode"></div>
|
|
1239
1275
|
<span class="code-copy-label">copy</span>
|
|
@@ -1246,7 +1282,7 @@
|
|
|
1246
1282
|
<svg class="mcp-other-chevron" viewBox="0 0 24 24" width="14" height="14"><polyline points="6 9 12 15 18 9" fill="none" stroke="currentColor" stroke-width="2"/></svg>
|
|
1247
1283
|
</div>
|
|
1248
1284
|
<div class="mcp-other-body" id="rulesCoexistBody" style="display:none;">
|
|
1249
|
-
<div style="font-size:12px;color:var(--t-secondary);margin-bottom:6px;">Copy this, name the other tool in it, and paste it into your instructions file. SynaBun never installs it.</div>
|
|
1285
|
+
<div id="rulesCoexistHelp" style="font-size:12px;color:var(--t-secondary);margin-bottom:6px;">Copy this, name the other tool in it, and paste it into your instructions file. SynaBun never installs it.</div>
|
|
1250
1286
|
<div class="code-copy-wrap" id="rulesCoexistWrap">
|
|
1251
1287
|
<div class="instructions-preview" id="rulesCoexistCode"></div>
|
|
1252
1288
|
<span class="code-copy-label">copy</span>
|
|
@@ -1261,7 +1297,7 @@
|
|
|
1261
1297
|
<h2 style="text-align:center;margin-bottom:12px;">Setup Complete!</h2>
|
|
1262
1298
|
<ul class="checklist" id="checklist"></ul>
|
|
1263
1299
|
<div id="restartNotice" style="margin:16px 0 0;padding:12px 14px;background:rgba(255,255,255,0.04);border:1px solid rgba(255,255,255,0.10);border-radius:var(--r-card);font-size:12px;color:var(--t-primary);line-height:1.5;">
|
|
1264
|
-
<span style="color:var(--t-bright);font-weight:600;">Restart required</span> — Relaunch <span id="restartToolName" style="color:var(--t-bright);font-weight:500;"></span> for the MCP changes to be picked up.
|
|
1300
|
+
<span style="color:var(--t-bright);font-weight:600;">Restart required</span> — Relaunch <span id="restartToolName" style="color:var(--t-bright);font-weight:500;"></span> for the MCP changes and SynaBun's rules to be picked up.
|
|
1265
1301
|
</div>
|
|
1266
1302
|
<div style="text-align:center;margin-top:16px;">
|
|
1267
1303
|
<button class="action-btn" id="launchBtn" style="font-size:15px;padding:12px 32px;">Launch Neural Interface</button>
|
|
@@ -1371,12 +1407,27 @@
|
|
|
1371
1407
|
|
|
1372
1408
|
<script type="module">
|
|
1373
1409
|
|
|
1410
|
+
// The rules step is the installer of Settings → AI connections: the same client calls and the same reading
|
|
1411
|
+
// of the status (see STEP 6). Both modules are import-free, so the wizard still loads nothing of the app.
|
|
1412
|
+
import { fetchRulesStatus, fetchRulesTextWithFallback, installRules, installAllRules } from './shared/api.js';
|
|
1413
|
+
import {
|
|
1414
|
+
describeRulesHost, describeRulesInstall, describeRulesInstallAll, describeRulesInPlace, rulesInstallPlan, catalogueTranslator,
|
|
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();
|
|
1422
|
+
|
|
1374
1423
|
// ═══════════════════════════════════════════
|
|
1375
1424
|
// STATE
|
|
1376
1425
|
// ═══════════════════════════════════════════
|
|
1377
1426
|
|
|
1378
1427
|
const TOTAL_STEPS = 8;
|
|
1379
1428
|
let currentStep = 0;
|
|
1429
|
+
// Step 6: a connected tool still has no rules. Leaving the step then is a skip, and the Next button says so.
|
|
1430
|
+
let rulesPending = false;
|
|
1380
1431
|
|
|
1381
1432
|
const wizardState = {
|
|
1382
1433
|
collectionName: 'claude_memory',
|
|
@@ -1386,6 +1437,8 @@ const wizardState = {
|
|
|
1386
1437
|
enabledTools: [], // tool ids toggled on via Step 5 install toggles
|
|
1387
1438
|
dataHome: '',
|
|
1388
1439
|
packageRoot: '',
|
|
1440
|
+
mcpCommand: '',
|
|
1441
|
+
mcpArgs: [],
|
|
1389
1442
|
buildReady: false,
|
|
1390
1443
|
mcpWritten: false,
|
|
1391
1444
|
projects: [],
|
|
@@ -1479,7 +1532,8 @@ function updateNav() {
|
|
|
1479
1532
|
$prevBtn.disabled = currentStep === 0;
|
|
1480
1533
|
|
|
1481
1534
|
const labels = ['Begin', 'Next', 'Next', 'Next', 'Next', 'Next', 'Next', 'Finish'];
|
|
1482
|
-
|
|
1535
|
+
const label = currentStep === 6 && rulesPending ? 'Skip' : (labels[currentStep] || 'Next');
|
|
1536
|
+
$nextBtn.textContent = label + ' \u2192';
|
|
1483
1537
|
|
|
1484
1538
|
if (currentStep === TOTAL_STEPS - 1) {
|
|
1485
1539
|
$nextBtn.style.display = 'none';
|
|
@@ -1491,6 +1545,7 @@ function updateNav() {
|
|
|
1491
1545
|
$prevBtn.addEventListener('click', () => goToStep(currentStep - 1));
|
|
1492
1546
|
$nextBtn.addEventListener('click', () => {
|
|
1493
1547
|
if (validateStep(currentStep)) {
|
|
1548
|
+
offerPwaInstallOnce(); // first, while the click still counts as the user's: see pwa-install.js
|
|
1494
1549
|
goToStep(currentStep + 1);
|
|
1495
1550
|
}
|
|
1496
1551
|
});
|
|
@@ -1774,11 +1829,14 @@ function renderHappyBun() {}
|
|
|
1774
1829
|
|
|
1775
1830
|
// Fresh Install → proceed to step 1
|
|
1776
1831
|
document.getElementById('choiceFreshInstall').addEventListener('click', () => {
|
|
1832
|
+
offerPwaInstallOnce();
|
|
1777
1833
|
goToStep(1);
|
|
1778
1834
|
});
|
|
1779
1835
|
|
|
1780
|
-
// 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.
|
|
1781
1838
|
document.getElementById('choiceRestore').addEventListener('click', () => {
|
|
1839
|
+
offerPwaInstallOnce();
|
|
1782
1840
|
$choices.style.display = 'none';
|
|
1783
1841
|
$restorePanel.style.display = 'block';
|
|
1784
1842
|
requestAnimationFrame(() => {
|
|
@@ -2541,7 +2599,11 @@ function getGenericMcpJson() {
|
|
|
2541
2599
|
const mcpPath = pkgRoot + '/mcp-server/run.mjs';
|
|
2542
2600
|
const envPath = dataHome + '/.env';
|
|
2543
2601
|
const env = { DOTENV_PATH: envPath, SYNABUN_DATA_HOME: dataHome, MEMORY_DATA_DIR: dataHome + '/mcp-data' };
|
|
2544
|
-
|
|
2602
|
+
// A packaged application is started through its own executable; the server says which.
|
|
2603
|
+
const packaged = wizardState.mcpCommand && wizardState.mcpCommand !== 'node';
|
|
2604
|
+
const command = packaged ? wizardState.mcpCommand : 'node';
|
|
2605
|
+
const args = packaged ? wizardState.mcpArgs : [mcpPath];
|
|
2606
|
+
return JSON.stringify({ mcpServers: { SynaBun: { command, args, env } } }, null, 2);
|
|
2545
2607
|
}
|
|
2546
2608
|
|
|
2547
2609
|
// "Other providers" collapsible — shows the generic MCP JSON for paste-based setups.
|
|
@@ -2576,156 +2638,207 @@ document.getElementById('mcpCodeWrap').addEventListener('click', () => {
|
|
|
2576
2638
|
});
|
|
2577
2639
|
|
|
2578
2640
|
// ═══════════════════════════════════════════
|
|
2579
|
-
// STEP 6: SynaBun rules
|
|
2641
|
+
// STEP 6: Install SynaBun rules
|
|
2580
2642
|
// ═══════════════════════════════════════════
|
|
2581
|
-
//
|
|
2582
|
-
//
|
|
2583
|
-
//
|
|
2643
|
+
// The installer, as Settings → AI connections → SynaBun rules shows it: one
|
|
2644
|
+
// button that installs the rules for every connected tool, then one row per
|
|
2645
|
+
// tool with where its rules live, what state they are in (GET /api/setup/rules)
|
|
2646
|
+
// and the action that state calls for, and under them what the installer
|
|
2647
|
+
// answered. The calls are the shared client's (shared/api.js). What a state is
|
|
2648
|
+
// called, which action it gets and every sentence about it come from
|
|
2649
|
+
// shared/settings/settings-rules.js and the Settings strings (i18n/en.json), so
|
|
2650
|
+
// the two surfaces cannot drift apart. Nothing is pasted in this step: the two
|
|
2651
|
+
// boxes under "Manual setup" hold what SynaBun cannot install (Cursor's User
|
|
2652
|
+
// Rules, the coexistence snippet). Nothing here has to be clicked to continue.
|
|
2584
2653
|
|
|
2585
2654
|
const RESTART_HINT = 'Restart SynaBun to finish this update.';
|
|
2586
|
-
const
|
|
2587
|
-
installed: 'Installed', newer: 'Installed by a newer SynaBun', outdated: 'Update available', modified: 'Edited', conflict: 'Conflict',
|
|
2588
|
-
error: 'Error', shadowed: 'Shadowed', 'not-installed': 'Not installed',
|
|
2589
|
-
};
|
|
2590
|
-
const RULES_PRIMARY = { 'not-installed': 'Install', outdated: 'Update', modified: 'Replace' };
|
|
2655
|
+
const RULES_SETTINGS_PATH = 'Settings → AI connections → SynaBun rules';
|
|
2591
2656
|
let rulesStatus = null; // null: the route is missing or failed
|
|
2657
|
+
let rulesTx = null; // the Settings strings; null until they are loaded
|
|
2658
|
+
let rulesReport = null; // what the last install answered: { message, note, ok }
|
|
2659
|
+
let rulesBusy = false; // an install is on its way: every button of the step waits
|
|
2660
|
+
let rulesViewHost = ''; // the tool whose rules text is open under the list
|
|
2592
2661
|
const rulesTextCache = {};
|
|
2593
2662
|
|
|
2594
|
-
|
|
2663
|
+
// The wizard's names for the tools (the ones Step 5 shows), for every sentence that names one.
|
|
2664
|
+
const RULES_TOOL_NAMES = Object.fromEntries(TOOLS.map(t => [t.id, t.name]));
|
|
2665
|
+
const ruleToolNames = (hosts) => hosts.map(host => RULES_TOOL_NAMES[host] || host).join(', ');
|
|
2666
|
+
|
|
2667
|
+
// The words of this step are the Settings ones. One request; a failed one is tried again on the next visit.
|
|
2668
|
+
async function loadRulesStrings() {
|
|
2669
|
+
if (rulesTx) return rulesTx;
|
|
2595
2670
|
try {
|
|
2596
|
-
const res = await fetch('/
|
|
2597
|
-
if (
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
} catch { return null; }
|
|
2671
|
+
const res = await fetch('/i18n/en.json');
|
|
2672
|
+
if (res.ok) rulesTx = catalogueTranslator(await res.json());
|
|
2673
|
+
} catch { /* the step says so and offers to try again */ }
|
|
2674
|
+
return rulesTx;
|
|
2601
2675
|
}
|
|
2602
2676
|
|
|
2603
2677
|
// The rendered text for a host, from the rules route or the older read-only endpoint.
|
|
2604
2678
|
async function loadRulesText(host) {
|
|
2605
|
-
if (rulesTextCache[host])
|
|
2606
|
-
|
|
2607
|
-
try {
|
|
2608
|
-
const res = await fetch(`/api/setup/rules/${host}/text`);
|
|
2609
|
-
if (res.ok) text = (await res.json()).text || '';
|
|
2610
|
-
} catch { /* try the older endpoint */ }
|
|
2611
|
-
if (!text) {
|
|
2612
|
-
const format = host === 'opencode' ? 'generic' : host;
|
|
2613
|
-
const res = await fetch(`/api/claude-code/ruleset?format=${format}`);
|
|
2614
|
-
const data = res.ok ? await res.json() : {};
|
|
2615
|
-
text = data.ruleset || '';
|
|
2616
|
-
}
|
|
2617
|
-
if (!text) throw new Error('Rules text not available');
|
|
2618
|
-
rulesTextCache[host] = text;
|
|
2619
|
-
return text;
|
|
2620
|
-
}
|
|
2621
|
-
|
|
2622
|
-
function showRulesToast(msg, duration = 2600) {
|
|
2623
|
-
const toast = document.getElementById('rulesToast');
|
|
2624
|
-
if (!toast) return;
|
|
2625
|
-
toast.textContent = msg;
|
|
2626
|
-
toast.classList.add('show');
|
|
2627
|
-
clearTimeout(toast._timer);
|
|
2628
|
-
toast._timer = setTimeout(() => toast.classList.remove('show'), duration);
|
|
2679
|
+
if (!rulesTextCache[host]) rulesTextCache[host] = await fetchRulesTextWithFallback(host);
|
|
2680
|
+
return rulesTextCache[host];
|
|
2629
2681
|
}
|
|
2630
2682
|
|
|
2631
2683
|
function enabledRuleTools() {
|
|
2632
2684
|
return wizardState.enabledTools.map(id => TOOLS.find(t => t.id === id)).filter(Boolean);
|
|
2633
2685
|
}
|
|
2634
2686
|
|
|
2635
|
-
function
|
|
2636
|
-
const
|
|
2637
|
-
const
|
|
2638
|
-
const
|
|
2687
|
+
function renderRulesStep() {
|
|
2688
|
+
const el = (id) => document.getElementById(id);
|
|
2689
|
+
const tx = rulesTx;
|
|
2690
|
+
const plan = rulesInstallPlan(rulesStatus);
|
|
2691
|
+
const ready = !!tx && !!rulesStatus;
|
|
2692
|
+
|
|
2693
|
+
// What stands in the way, if anything: the step's own text, the installer, or no connected tool.
|
|
2694
|
+
const note = !tx ? 'This step could not load its text. Check that SynaBun is running, then try again.'
|
|
2695
|
+
: !rulesStatus ? `The rules installer did not answer. ${RESTART_HINT} The rules can also be installed later in ${RULES_SETTINGS_PATH}.`
|
|
2696
|
+
: !plan.connected.length ? 'No tool is connected yet. Connect one in the previous step and its rules are installed with it.'
|
|
2697
|
+
: '';
|
|
2698
|
+
const $note = el('rulesNote');
|
|
2699
|
+
$note.textContent = note;
|
|
2700
|
+
if (note && !ready) {
|
|
2701
|
+
const retry = document.createElement('button');
|
|
2702
|
+
retry.type = 'button';
|
|
2703
|
+
retry.textContent = 'Try again';
|
|
2704
|
+
retry.disabled = rulesBusy;
|
|
2705
|
+
retry.addEventListener('click', () => onRulesetStep());
|
|
2706
|
+
$note.appendChild(retry);
|
|
2707
|
+
}
|
|
2708
|
+
$note.style.display = note ? '' : 'none';
|
|
2709
|
+
|
|
2710
|
+
// The primary action, while a connected tool still has rules to install or update.
|
|
2711
|
+
rulesPending = ready && plan.pending.length > 0;
|
|
2712
|
+
el('rulesInstallAll').style.display = rulesPending ? '' : 'none';
|
|
2713
|
+
if (tx) {
|
|
2714
|
+
el('rulesInstallAllHelp').textContent = tx('settings.redesign.control.set002.help');
|
|
2715
|
+
el('rulesInstallAllBtn').textContent = tx('settings.redesign.control.set002.label');
|
|
2716
|
+
el('rulesCursorHelp').textContent = tx('settings.redesign.setup.cursorHelp');
|
|
2717
|
+
el('rulesCoexistHelp').textContent = tx('settings.redesign.setup.coexistHelp');
|
|
2718
|
+
}
|
|
2719
|
+
el('rulesInstallAllBtn').disabled = rulesBusy;
|
|
2720
|
+
|
|
2721
|
+
// The result: what the last install answered, or, with nothing left to install, the rules that are in place
|
|
2722
|
+
// (the toggles of Step 5 installed them) and the file each tool reads.
|
|
2723
|
+
const report = rulesReport || (ready && !rulesPending ? describeRulesInPlace(rulesStatus, { tx, labels: RULES_TOOL_NAMES }) : null);
|
|
2724
|
+
const $result = el('rulesResult');
|
|
2725
|
+
$result.style.display = report ? '' : 'none';
|
|
2726
|
+
if (report) {
|
|
2727
|
+
$result.className = 'rules-result ' + (report.ok === false ? 'fail' : 'ok');
|
|
2728
|
+
el('rulesResultMessage').textContent = report.message;
|
|
2729
|
+
el('rulesResultWhere').textContent = report.note || '';
|
|
2730
|
+
el('rulesResultWhere').style.display = report.note ? '' : 'none';
|
|
2731
|
+
}
|
|
2732
|
+
|
|
2733
|
+
// One row per tool that has rules or is connected. Without a status only the tools connected in Step 5 are known.
|
|
2734
|
+
const $list = el('rulesList');
|
|
2639
2735
|
$list.innerHTML = '';
|
|
2640
|
-
|
|
2641
|
-
const
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
for (const tool of tools) {
|
|
2648
|
-
const info = rulesStatus && rulesStatus.hosts ? rulesStatus.hosts[tool.id] : null;
|
|
2649
|
-
const state = info ? info.state : '';
|
|
2650
|
-
const good = state === 'installed' || state === 'newer';
|
|
2651
|
-
// A file without SynaBun's markers is the user's own: the server refuses to replace it, so no button.
|
|
2652
|
-
const primary = info && info.detected !== false && info.replaceable !== false ? (RULES_PRIMARY[state] || '') : '';
|
|
2653
|
-
const detail = !info ? RESTART_HINT
|
|
2654
|
-
: info.detected === false ? `${tool.name} was not found on this machine`
|
|
2655
|
-
: ((['conflict', 'error', 'shadowed'].includes(state) || info.replaceable === false) && (info.error || info.detail)) || info.path || '';
|
|
2656
|
-
|
|
2736
|
+
const idle = [];
|
|
2737
|
+
for (const tool of (tx ? (rulesStatus ? TOOLS : enabledRuleTools()) : [])) {
|
|
2738
|
+
const info = rulesStatus?.hosts?.[tool.id];
|
|
2739
|
+
const view = describeRulesHost(info, { label: tool.name, version: rulesStatus?.version, tx });
|
|
2740
|
+
// Rules are for a tool that talks to SynaBun. One that is not connected and has none is only named, under
|
|
2741
|
+
// the list: connecting it in Step 5 installs them.
|
|
2742
|
+
if (view.known && view.state === 'not-installed' && !plan.connected.includes(tool.id)) { idle.push(tool.name); continue; }
|
|
2657
2743
|
const row = document.createElement('div');
|
|
2658
|
-
row.className = 'mcp-toggle-row' + (good ? ' connected' : '');
|
|
2744
|
+
row.className = 'mcp-toggle-row' + (view.good ? ' connected' : '') + (view.note ? ' has-note' : '');
|
|
2659
2745
|
row.dataset.host = tool.id;
|
|
2660
2746
|
row.innerHTML = `
|
|
2661
2747
|
<div class="mtr-body">
|
|
2662
|
-
<div class="mtr-name">${tool.name}<span class="mtr-state${good ? ' ok' : ''}" data-role="state"></span></div>
|
|
2748
|
+
<div class="mtr-name">${tool.name}<span class="mtr-state${view.good ? ' ok' : ''}" data-role="state"></span></div>
|
|
2663
2749
|
<div class="mtr-path" data-role="path"></div>
|
|
2750
|
+
<div class="mtr-note" data-role="note" style="display:none"></div>
|
|
2664
2751
|
</div>
|
|
2665
2752
|
<div class="rules-actions">
|
|
2666
|
-
${
|
|
2667
|
-
<button type="button" data-role="view"
|
|
2668
|
-
<button type="button" data-role="copy">Copy</button>
|
|
2753
|
+
${view.action ? '<button type="button" class="primary" data-role="primary"></button>' : ''}
|
|
2754
|
+
${view.known ? '<button type="button" data-role="view"></button>' : ''}
|
|
2669
2755
|
</div>
|
|
2670
2756
|
`;
|
|
2671
|
-
row.querySelector('[data-role="state"]').textContent =
|
|
2757
|
+
row.querySelector('[data-role="state"]').textContent = view.badge;
|
|
2672
2758
|
const $path = row.querySelector('[data-role="path"]');
|
|
2673
|
-
$path.textContent =
|
|
2674
|
-
$path.title =
|
|
2675
|
-
row.querySelector('[data-role="
|
|
2676
|
-
|
|
2677
|
-
|
|
2759
|
+
$path.textContent = view.pathText;
|
|
2760
|
+
$path.title = view.path;
|
|
2761
|
+
const $rowNote = row.querySelector('[data-role="note"]');
|
|
2762
|
+
$rowNote.textContent = view.note;
|
|
2763
|
+
$rowNote.style.display = view.note ? '' : 'none';
|
|
2764
|
+
const $primary = row.querySelector('[data-role="primary"]');
|
|
2765
|
+
if ($primary) {
|
|
2766
|
+
$primary.textContent = view.actionLabel;
|
|
2767
|
+
$primary.disabled = rulesBusy;
|
|
2768
|
+
$primary.addEventListener('click', () => installToolRules(tool));
|
|
2769
|
+
}
|
|
2770
|
+
const $view = row.querySelector('[data-role="view"]');
|
|
2771
|
+
if ($view) {
|
|
2772
|
+
$view.textContent = tx(rulesViewHost === tool.id ? 'settings.redesign.setup.hide' : 'settings.redesign.setup.view');
|
|
2773
|
+
$view.setAttribute('aria-expanded', String(rulesViewHost === tool.id));
|
|
2774
|
+
$view.setAttribute('aria-controls', 'rulesViewCode');
|
|
2775
|
+
$view.addEventListener('click', () => viewRules(tool));
|
|
2776
|
+
}
|
|
2678
2777
|
$list.appendChild(row);
|
|
2679
2778
|
}
|
|
2779
|
+
el('rulesViewCode').style.display = rulesViewHost && $list.querySelector(`[data-host="${rulesViewHost}"] [data-role="view"]`) ? '' : 'none';
|
|
2780
|
+
// The other tools, in one line. With no tool connected at all, the note at the top already says it.
|
|
2781
|
+
const $idle = el('rulesIdle');
|
|
2782
|
+
$idle.textContent = idle.length && plan.connected.length ? `${tx('settings.redesign.setup.notConnected')}: ${idle.join(', ')}. Connecting a tool in the previous step installs its rules.` : '';
|
|
2783
|
+
$idle.style.display = $idle.textContent ? '' : 'none';
|
|
2784
|
+
|
|
2785
|
+
updateNav();
|
|
2680
2786
|
requestAnimationFrame(() => resizeViewport(currentStep));
|
|
2681
2787
|
}
|
|
2682
2788
|
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
if (
|
|
2686
|
-
|
|
2789
|
+
// Run one install, keep what it answered for the result line, then read the status again.
|
|
2790
|
+
async function runRulesInstall(work) {
|
|
2791
|
+
if (rulesBusy) return;
|
|
2792
|
+
rulesBusy = true;
|
|
2793
|
+
renderRulesStep();
|
|
2687
2794
|
try {
|
|
2688
|
-
|
|
2689
|
-
method: 'POST',
|
|
2690
|
-
headers: { 'Content-Type': 'application/json' },
|
|
2691
|
-
body: JSON.stringify({ force }),
|
|
2692
|
-
});
|
|
2693
|
-
const data = await res.json().catch(() => ({}));
|
|
2694
|
-
if (!res.ok || data.ok === false) showRulesToast(data.error || (res.status === 404 ? RESTART_HINT : `${tool.name} rules were not installed`), 5000);
|
|
2695
|
-
else showRulesToast(`${tool.name} rules installed`);
|
|
2795
|
+
rulesReport = await work();
|
|
2696
2796
|
} catch (err) {
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2797
|
+
// The server's own sentence (an edited copy, damaged markers, another SynaBun at work). A route that is not
|
|
2798
|
+
// there is the server that was not restarted.
|
|
2799
|
+
const message = err?.message === 'HTTP 404' ? RESTART_HINT : (err?.message || rulesTx('settings.redesign.setup.rulesActionFailed'));
|
|
2800
|
+
rulesReport = { message, note: '', ok: false };
|
|
2801
|
+
}
|
|
2802
|
+
rulesStatus = await fetchRulesStatus();
|
|
2803
|
+
rulesBusy = false;
|
|
2804
|
+
renderRulesStep();
|
|
2701
2805
|
}
|
|
2702
2806
|
|
|
2703
|
-
|
|
2704
|
-
|
|
2807
|
+
// "Install for all": every connected tool, by the installer's own rule. Same call as the button in Settings.
|
|
2808
|
+
function installAllToolRules() {
|
|
2809
|
+
runRulesInstall(async () => {
|
|
2810
|
+
const report = describeRulesInstallAll(await installAllRules(), { tx: rulesTx, labels: RULES_TOOL_NAMES });
|
|
2811
|
+
return { message: report.message, note: report.note, ok: report.failed.length === 0 };
|
|
2812
|
+
});
|
|
2813
|
+
}
|
|
2814
|
+
|
|
2815
|
+
// One tool's Install, Update or Replace. Replace is behind the confirm that says the edited copy is backed up.
|
|
2816
|
+
function installToolRules(tool) {
|
|
2817
|
+
const view = describeRulesHost(rulesStatus?.hosts?.[tool.id], { label: tool.name, version: rulesStatus?.version, tx: rulesTx });
|
|
2818
|
+
if (!view.action) return;
|
|
2819
|
+
if (view.force && !confirm(rulesTx('settings.redesign.setup.replaceYourEditedRulesWithSynabun', { label: tool.name }))) return;
|
|
2820
|
+
delete rulesTextCache[tool.id];
|
|
2821
|
+
runRulesInstall(async () => {
|
|
2822
|
+
const result = await installRules(tool.id, { force: view.force });
|
|
2823
|
+
return { message: describeRulesInstall(result, view.state, { label: tool.name, tx: rulesTx }), note: '', ok: true };
|
|
2824
|
+
});
|
|
2825
|
+
}
|
|
2826
|
+
|
|
2827
|
+
// View shows the exact text a tool receives, under the list; a second press hides it.
|
|
2828
|
+
async function viewRules(tool) {
|
|
2705
2829
|
const $code = document.getElementById('rulesViewCode');
|
|
2706
|
-
if (
|
|
2707
|
-
|
|
2830
|
+
if (rulesViewHost === tool.id) {
|
|
2831
|
+
rulesViewHost = '';
|
|
2708
2832
|
} else {
|
|
2709
|
-
try { $code.textContent = await loadRulesText(
|
|
2710
|
-
catch { $code.textContent =
|
|
2711
|
-
$
|
|
2712
|
-
|
|
2833
|
+
try { $code.textContent = await loadRulesText(tool.id); }
|
|
2834
|
+
catch { $code.textContent = rulesTx('settings.redesign.setup.couldNotLoadTheRules', { label: tool.name, RESTART_HINT }); }
|
|
2835
|
+
$code.setAttribute('aria-label', rulesTx('settings.redesign.setup.previewRules', { name: tool.name }));
|
|
2836
|
+
rulesViewHost = tool.id;
|
|
2713
2837
|
}
|
|
2714
|
-
|
|
2838
|
+
renderRulesStep();
|
|
2715
2839
|
}
|
|
2716
2840
|
|
|
2717
|
-
|
|
2718
|
-
let text;
|
|
2719
|
-
try { text = await loadRulesText(host); }
|
|
2720
|
-
catch { showRulesToast(`Could not load the ${name} rules. ${RESTART_HINT}`, 5000); return; }
|
|
2721
|
-
try {
|
|
2722
|
-
await navigator.clipboard.writeText(text);
|
|
2723
|
-
showRulesToast(`${name} rules copied`);
|
|
2724
|
-
} catch {
|
|
2725
|
-
// A refused clipboard is the browser's doing; restarting SynaBun would not help.
|
|
2726
|
-
showRulesToast('Could not copy: the browser refused access to the clipboard.', 5000);
|
|
2727
|
-
}
|
|
2728
|
-
}
|
|
2841
|
+
document.getElementById('rulesInstallAllBtn').addEventListener('click', () => installAllToolRules());
|
|
2729
2842
|
|
|
2730
2843
|
// A click-to-copy code box (the pattern of the MCP JSON box in Step 5). The
|
|
2731
2844
|
// label says "copied!" only once the clipboard took the text; a browser that
|
|
@@ -2747,7 +2860,7 @@ function wireRulesCopyBox(wrapId, codeId) {
|
|
|
2747
2860
|
});
|
|
2748
2861
|
}
|
|
2749
2862
|
|
|
2750
|
-
// A collapsible copy-only section: loads
|
|
2863
|
+
// A collapsible copy-only section, for text SynaBun cannot install: loads it the first time it opens.
|
|
2751
2864
|
function wireRulesExtra(sectionId, headerId, bodyId, wrapId, codeId, host, name) {
|
|
2752
2865
|
const $section = document.getElementById(sectionId);
|
|
2753
2866
|
const $body = document.getElementById(bodyId);
|
|
@@ -2768,15 +2881,10 @@ function wireRulesExtra(sectionId, headerId, bodyId, wrapId, codeId, host, name)
|
|
|
2768
2881
|
wireRulesExtra('rulesCursorSection', 'rulesCursorHeader', 'rulesCursorBody', 'rulesCursorWrap', 'rulesCursorCode', 'cursor', 'Cursor rules');
|
|
2769
2882
|
wireRulesExtra('rulesCoexistSection', 'rulesCoexistHeader', 'rulesCoexistBody', 'rulesCoexistWrap', 'rulesCoexistCode', 'coexistence', 'coexistence snippet');
|
|
2770
2883
|
|
|
2771
|
-
document.getElementById('rulesViewWrap').addEventListener('click', () => {
|
|
2772
|
-
const $wrap = document.getElementById('rulesViewWrap');
|
|
2773
|
-
const tool = TOOLS.find(t => t.id === $wrap.dataset.host);
|
|
2774
|
-
if (tool) copyRules(tool.id, tool.name);
|
|
2775
|
-
});
|
|
2776
|
-
|
|
2777
2884
|
async function onRulesetStep() {
|
|
2778
|
-
|
|
2779
|
-
|
|
2885
|
+
rulesReport = null;
|
|
2886
|
+
[rulesStatus] = await Promise.all([fetchRulesStatus(), loadRulesStrings()]);
|
|
2887
|
+
renderRulesStep();
|
|
2780
2888
|
if (currentStep === 6) resizeViewport(6);
|
|
2781
2889
|
}
|
|
2782
2890
|
|
|
@@ -2805,18 +2913,23 @@ async function onCompleteStep() {
|
|
|
2805
2913
|
} catch { /* non-critical — user can enable via Settings later */ }
|
|
2806
2914
|
}
|
|
2807
2915
|
|
|
2808
|
-
// Rules count as installed when every connected tool has its copy in place.
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
const
|
|
2812
|
-
|
|
2916
|
+
// Rules count as installed when every connected tool has its copy in place. When they are not, the item says
|
|
2917
|
+
// for which tools and where the installer is from now on.
|
|
2918
|
+
rulesStatus = await fetchRulesStatus();
|
|
2919
|
+
const rulesPlan = rulesInstallPlan(rulesStatus);
|
|
2920
|
+
const rulesMissing = rulesPlan.connected.filter(host => !rulesPlan.inPlace.includes(host));
|
|
2921
|
+
const rulesInstalled = rulesPlan.connected.length > 0 && rulesMissing.length === 0;
|
|
2922
|
+
const rulesLabel = rulesInstalled ? 'Rules installed'
|
|
2923
|
+
: !rulesStatus ? `Rules not installed: the installer did not answer (${RULES_SETTINGS_PATH})`
|
|
2924
|
+
: !rulesPlan.connected.length ? 'Rules not installed: no tool is connected'
|
|
2925
|
+
: `Rules not installed for ${ruleToolNames(rulesMissing)} (${RULES_SETTINGS_PATH})`;
|
|
2813
2926
|
|
|
2814
2927
|
const items = [
|
|
2815
2928
|
{ label: 'Memory name set', done: !!wizardState.collectionName },
|
|
2816
2929
|
{ label: 'Dependencies installed & MCP built', done: wizardState.buildReady },
|
|
2817
2930
|
{ label: 'Projects registered', done: (wizardState.projects || []).length > 0 },
|
|
2818
2931
|
{ label: 'AI tool integration enabled', done: wizardState.enabledTools.length > 0 || wizardState.mcpWritten },
|
|
2819
|
-
{ label:
|
|
2932
|
+
{ label: rulesLabel, done: rulesInstalled },
|
|
2820
2933
|
];
|
|
2821
2934
|
|
|
2822
2935
|
const $list = document.getElementById('checklist');
|
|
@@ -2853,6 +2966,10 @@ async function init() {
|
|
|
2853
2966
|
if (data.packageRoot) {
|
|
2854
2967
|
wizardState.packageRoot = data.packageRoot;
|
|
2855
2968
|
}
|
|
2969
|
+
if (data.mcpCommand && Array.isArray(data.mcpArgs)) {
|
|
2970
|
+
wizardState.mcpCommand = data.mcpCommand;
|
|
2971
|
+
wizardState.mcpArgs = data.mcpArgs;
|
|
2972
|
+
}
|
|
2856
2973
|
} catch {}
|
|
2857
2974
|
|
|
2858
2975
|
// Enable the entrance animation only after every top-level initializer has
|