synabun 2.0.0 → 2.0.7
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 +97 -0
- package/NOTICE +5 -0
- package/README.md +2 -1
- package/THIRD-PARTY-LICENSES.md +59 -0
- package/benchmarks/fixtures/browser/README.md +1 -1
- package/benchmarks/fixtures/desktop/README.md +1 -1
- package/docs/whatsapp.md +153 -18
- 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 +26 -3
- package/hooks/claude-code/stop.mjs +5 -5
- package/lib/child-path.js +303 -0
- package/lib/claude-hooks.js +2 -1
- package/lib/data-home-migration.js +2 -0
- package/lib/desktop-app.js +265 -0
- package/lib/external-tools.js +7 -3
- package/lib/log-redact.js +102 -0
- package/lib/packaged-runtime.js +138 -11
- package/lib/start-launcher.js +88 -1
- package/mcp-server/dist/http.d.ts +3 -1
- package/mcp-server/dist/http.d.ts.map +1 -1
- package/mcp-server/dist/http.js +15 -4
- package/mcp-server/dist/http.js.map +1 -1
- package/mcp-server/dist/index.d.ts.map +1 -1
- package/mcp-server/dist/index.js +9 -6
- package/mcp-server/dist/index.js.map +1 -1
- package/mcp-server/dist/services/budget-judgments.d.ts +108 -0
- package/mcp-server/dist/services/budget-judgments.d.ts.map +1 -0
- package/mcp-server/dist/services/budget-judgments.js +153 -0
- package/mcp-server/dist/services/budget-judgments.js.map +1 -0
- package/mcp-server/dist/services/codex-config-heal.d.ts +5 -1
- package/mcp-server/dist/services/codex-config-heal.d.ts.map +1 -1
- package/mcp-server/dist/services/codex-config-heal.js +41 -4
- package/mcp-server/dist/services/codex-config-heal.js.map +1 -1
- package/mcp-server/dist/services/identity.d.ts +11 -0
- package/mcp-server/dist/services/identity.d.ts.map +1 -1
- package/mcp-server/dist/services/identity.js +24 -0
- package/mcp-server/dist/services/identity.js.map +1 -1
- package/mcp-server/dist/services/neural-interface.d.ts +13 -0
- package/mcp-server/dist/services/neural-interface.d.ts.map +1 -1
- package/mcp-server/dist/services/neural-interface.js +34 -2
- package/mcp-server/dist/services/neural-interface.js.map +1 -1
- package/mcp-server/dist/services/typesafe-config.d.ts +1 -1
- package/mcp-server/dist/services/typesafe-config.d.ts.map +1 -1
- package/mcp-server/dist/services/typesafe-config.js +4 -1
- package/mcp-server/dist/services/typesafe-config.js.map +1 -1
- package/mcp-server/dist/tools/agents.d.ts +10 -7
- package/mcp-server/dist/tools/agents.d.ts.map +1 -1
- package/mcp-server/dist/tools/agents.js +34 -13
- package/mcp-server/dist/tools/agents.js.map +1 -1
- package/mcp-server/dist/tools/whatsapp-send-file.d.ts +17 -0
- package/mcp-server/dist/tools/whatsapp-send-file.d.ts.map +1 -0
- package/mcp-server/dist/tools/whatsapp-send-file.js +44 -0
- package/mcp-server/dist/tools/whatsapp-send-file.js.map +1 -0
- package/mcp-server/dist/tui.js +2 -1
- package/mcp-server/dist/tui.js.map +1 -1
- package/mcp-server/dist/version.d.ts +5 -0
- package/mcp-server/dist/version.d.ts.map +1 -0
- package/mcp-server/dist/version.js +21 -0
- package/mcp-server/dist/version.js.map +1 -0
- package/mcp-server/package-lock.json +2 -2
- package/mcp-server/package.json +1 -3
- package/mcp-server/run.mjs +15 -9
- package/mcp-server/src/http.ts +18 -3
- package/mcp-server/src/index.ts +9 -6
- package/mcp-server/src/services/budget-judgments.ts +183 -0
- package/mcp-server/src/services/codex-config-heal.ts +35 -4
- package/mcp-server/src/services/identity.ts +27 -0
- package/mcp-server/src/services/neural-interface.ts +34 -2
- package/mcp-server/src/services/typesafe-config.ts +4 -1
- package/mcp-server/src/tools/agents.ts +33 -14
- package/mcp-server/src/tools/whatsapp-send-file.ts +51 -0
- package/mcp-server/src/tui.ts +2 -1
- package/mcp-server/src/version.ts +22 -0
- package/neural-interface/i18n/en.json +2126 -209
- package/neural-interface/i18n/pt-BR.json +2123 -207
- package/neural-interface/lib/account-usage.js +163 -0
- package/neural-interface/lib/assistant-api.js +316 -57
- package/neural-interface/lib/assistant-brains/claude.js +19 -2
- package/neural-interface/lib/assistant-brains/codex.js +3 -0
- package/neural-interface/lib/assistant-brains/opencode.js +17 -4
- package/neural-interface/lib/assistant-budget-planner.js +390 -0
- package/neural-interface/lib/assistant-budget-split.js +408 -0
- package/neural-interface/lib/assistant-budget.js +94 -95
- package/neural-interface/lib/assistant-catalog.js +179 -27
- package/neural-interface/lib/assistant-config.js +91 -14
- package/neural-interface/lib/assistant-dispatch.js +494 -138
- package/neural-interface/lib/assistant-hidden-models.js +393 -66
- package/neural-interface/lib/assistant-jev.js +26 -3
- package/neural-interface/lib/assistant-memory.js +24 -10
- package/neural-interface/lib/assistant-persona.js +73 -12
- package/neural-interface/lib/assistant-plan-permissions.js +8 -1
- package/neural-interface/lib/assistant-pricing.js +21 -6
- package/neural-interface/lib/assistant-route-accounts.js +14 -0
- package/neural-interface/lib/assistant-route-gate.js +19 -3
- package/neural-interface/lib/assistant-router.js +373 -42
- package/neural-interface/lib/assistant-runtime.js +488 -59
- 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 +183 -0
- package/neural-interface/lib/augmented-path.js +317 -53
- package/neural-interface/lib/browser-background-tab.js +134 -0
- package/neural-interface/lib/browser-screenshot.js +678 -61
- package/neural-interface/lib/claude-accounts.js +342 -31
- package/neural-interface/lib/claude-agent-bridge.js +123 -9
- package/neural-interface/lib/claude-executable.js +6 -1
- package/neural-interface/lib/claude-model-catalog.js +33 -5
- package/neural-interface/lib/claude-panel-auth.js +221 -0
- package/neural-interface/lib/claude-profile-api-key.js +62 -0
- package/neural-interface/lib/claude-temporary.js +46 -7
- package/neural-interface/lib/cli-install-api.js +137 -0
- package/neural-interface/lib/cli-install.js +797 -0
- package/neural-interface/lib/cli-path.js +130 -0
- package/neural-interface/lib/cli-resolver.js +744 -0
- package/neural-interface/lib/cli-update-planner.js +143 -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/codex-account-auth.js +178 -0
- package/neural-interface/lib/codex-accounts.js +489 -0
- package/neural-interface/lib/codex-capabilities.js +2 -1
- package/neural-interface/lib/codex-compat-rpc.js +8 -2
- package/neural-interface/lib/codex-mcp-approvals.js +5 -1
- package/neural-interface/lib/codex-panel-auth.js +62 -0
- package/neural-interface/lib/codex-session-settings.js +1 -1
- package/neural-interface/lib/codex-settings-schema.js +120 -0
- package/neural-interface/lib/desktop/config.js +3 -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-bash/bzip2.js +339 -0
- package/neural-interface/lib/git-bash/claude-settings.js +73 -0
- package/neural-interface/lib/git-bash/extract-worker.js +34 -0
- package/neural-interface/lib/git-bash/install.js +529 -0
- package/neural-interface/lib/git-bash/licenses/COPYING +360 -0
- package/neural-interface/lib/git-bash/licenses/LGPL-2.1 +511 -0
- package/neural-interface/lib/git-bash/manager.js +268 -0
- package/neural-interface/lib/git-bash/pins.js +206 -0
- package/neural-interface/lib/git-bash/pins.json +34 -0
- package/neural-interface/lib/git-bash/resolver.js +194 -0
- package/neural-interface/lib/git-diff-api.js +103 -0
- package/neural-interface/lib/git-read.js +234 -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/install-details.js +145 -0
- package/neural-interface/lib/machine-names.js +88 -0
- package/neural-interface/lib/mcp-installer.js +14 -2
- package/neural-interface/lib/memory-api.js +31 -7
- package/neural-interface/lib/native-loop-providers.js +26 -8
- package/neural-interface/lib/native-loop-runtime.js +9 -4
- package/neural-interface/lib/os-path.js +319 -0
- package/neural-interface/lib/plugin-installer.js +4 -2
- package/neural-interface/lib/project-storage.js +5 -7
- package/neural-interface/lib/provider-panel-api-key-auth.js +92 -0
- package/neural-interface/lib/provider-panel-terminal-auth.js +95 -0
- package/neural-interface/lib/pty-host/core.js +2 -1
- package/neural-interface/lib/pty-host/manager.js +27 -2
- package/neural-interface/lib/remote-policy.js +20 -11
- package/neural-interface/lib/request-gate.js +589 -0
- package/neural-interface/lib/session-title-generator.js +4 -3
- package/neural-interface/lib/system-about.js +340 -0
- package/neural-interface/lib/system-activity.js +66 -0
- package/neural-interface/lib/terminal-env.js +11 -3
- package/neural-interface/lib/terminal-path.js +55 -0
- package/neural-interface/lib/ui-blob-api.js +108 -0
- package/neural-interface/lib/ui-blob-store.js +68 -0
- package/neural-interface/lib/virtual-socket.js +12 -1
- package/neural-interface/lib/whatsapp/baileys-adapter.js +165 -45
- package/neural-interface/lib/whatsapp/bridge.js +78 -34
- package/neural-interface/lib/whatsapp/commands.js +13 -14
- package/neural-interface/lib/whatsapp/config.js +134 -20
- package/neural-interface/lib/whatsapp/fake-baileys.js +99 -14
- package/neural-interface/lib/whatsapp/host-core.js +168 -35
- package/neural-interface/lib/whatsapp/inbound.js +5 -3
- package/neural-interface/lib/whatsapp/local-file.js +524 -0
- package/neural-interface/lib/whatsapp/manager.js +92 -32
- package/neural-interface/lib/whatsapp/paths.js +11 -1
- package/neural-interface/lib/whatsapp/protocol.js +65 -5
- package/neural-interface/lib/whatsapp/redact.js +63 -0
- package/neural-interface/lib/whatsapp/service.js +343 -91
- package/neural-interface/lib/whatsapp/transcription.js +463 -0
- package/neural-interface/package-lock.json +701 -2
- package/neural-interface/package.json +13 -2
- package/neural-interface/public/index.html +2 -0
- package/neural-interface/public/index2d.html +2 -0
- package/neural-interface/public/install-app.html +9 -6
- package/neural-interface/public/offline.html +19 -3
- package/neural-interface/public/onboarding.html +107 -2
- package/neural-interface/public/shared/account-i18n.js +7 -0
- package/neural-interface/public/shared/account-menu.js +539 -0
- package/neural-interface/public/shared/account-usage.js +19 -0
- package/neural-interface/public/shared/account-view.js +335 -0
- package/neural-interface/public/shared/agent-runtime-options.js +50 -14
- package/neural-interface/public/shared/assistant/asst-accounts.js +182 -184
- package/neural-interface/public/shared/assistant/asst-api.js +32 -2
- package/neural-interface/public/shared/assistant/asst-automation.js +286 -0
- package/neural-interface/public/shared/assistant/asst-brain-picker.js +430 -81
- package/neural-interface/public/shared/assistant/asst-budget.js +259 -303
- package/neural-interface/public/shared/assistant/asst-composer.js +11 -1
- package/neural-interface/public/shared/assistant/asst-mascot.js +140 -61
- package/neural-interface/public/shared/assistant/asst-menu.js +27 -11
- package/neural-interface/public/shared/assistant/asst-panel.js +198 -42
- package/neural-interface/public/shared/assistant/asst-render.js +197 -23
- package/neural-interface/public/shared/assistant/asst-route-models.js +108 -0
- package/neural-interface/public/shared/assistant/asst-route.js +95 -343
- package/neural-interface/public/shared/assistant/asst-routes-editor.js +534 -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-slash.js +1 -1
- package/neural-interface/public/shared/assistant/asst-state.js +186 -2
- package/neural-interface/public/shared/assistant/asst-styles.js +247 -11
- package/neural-interface/public/shared/blob-store.js +111 -22
- package/neural-interface/public/shared/cdx/cdx-commands.js +4 -1
- package/neural-interface/public/shared/cdx/cdx-features.js +22 -14
- package/neural-interface/public/shared/cdx/cdx-icons.js +2 -0
- package/neural-interface/public/shared/cdx/cdx-panel.js +80 -118
- package/neural-interface/public/shared/cdx/cdx-render.js +25 -89
- package/neural-interface/public/shared/cdx/cdx-settings.js +231 -0
- package/neural-interface/public/shared/cdx/cdx-styles.js +164 -107
- package/neural-interface/public/shared/cdx/cdx-tabs.js +348 -668
- package/neural-interface/public/shared/cdx/cdx-ws.js +2 -0
- package/neural-interface/public/shared/claude-account-view.js +3 -0
- package/neural-interface/public/shared/cli-install-view.js +392 -0
- package/neural-interface/public/shared/cli-status.js +282 -22
- package/neural-interface/public/shared/constants.js +6 -1
- package/neural-interface/public/shared/cp/cp-events.js +2 -1
- package/neural-interface/public/shared/cp/cp-rehydrate.js +2 -1
- package/neural-interface/public/shared/cp/cp-styles.js +61 -0
- package/neural-interface/public/shared/desktop-bridge.js +39 -0
- package/neural-interface/public/shared/desktop-titlebar-page.js +59 -0
- package/neural-interface/public/shared/desktop-titlebar-view.js +122 -0
- package/neural-interface/public/shared/desktop-titlebar.js +153 -0
- package/neural-interface/public/shared/desktop-update-view.js +462 -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/git-bash-view.js +145 -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 +161 -165
- package/neural-interface/public/shared/i18n.js +19 -1
- package/neural-interface/public/shared/install-details-view.js +86 -0
- 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 +131 -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 +22 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-styles.js +158 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-ws.js +3 -2
- package/neural-interface/public/shared/pwa-install-page.js +32 -2
- 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-about-pane.js +271 -0
- package/neural-interface/public/shared/settings/settings-about.js +254 -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 +33 -4
- package/neural-interface/public/shared/settings/settings-user-context.js +154 -0
- package/neural-interface/public/shared/showcase-privacy.js +489 -0
- package/neural-interface/public/shared/start-bridge.js +238 -19
- package/neural-interface/public/shared/storage.js +30 -3
- package/neural-interface/public/shared/styles.css +1710 -770
- package/neural-interface/public/shared/synabun-mascot.js +68 -58
- package/neural-interface/public/shared/tunnel-view.js +167 -0
- package/neural-interface/public/shared/ui-claude-panel.js +369 -229
- package/neural-interface/public/shared/ui-cli-banner.js +355 -0
- 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-git-bash.js +124 -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 +10 -1
- package/neural-interface/public/shared/ui-keybinds.js +4 -0
- package/neural-interface/public/shared/ui-loading.js +187 -19
- package/neural-interface/public/shared/ui-menubar.js +25 -33
- 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 +48 -22
- package/neural-interface/public/shared/ui-provider-auth.js +104 -0
- package/neural-interface/public/shared/ui-provider-terminal-auth.js +223 -0
- package/neural-interface/public/shared/ui-sessions.js +9 -3
- package/neural-interface/public/shared/ui-settings.js +509 -490
- package/neural-interface/public/shared/ui-sidepanel-runtime.js +2 -1
- package/neural-interface/public/shared/ui-sidepanel-sessions.js +3 -1
- package/neural-interface/public/shared/ui-sync.js +22 -0
- package/neural-interface/public/shared/ui-terminal.js +40 -5
- package/neural-interface/public/shared/ui-tool-updates.js +5 -0
- 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-update.js +594 -5
- package/neural-interface/public/shared/ui-whatsapp.js +21 -6
- 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/whatsapp/wa-view.js +51 -8
- package/neural-interface/public/shared/worker-end.js +253 -0
- package/neural-interface/public/sw.js +2 -2
- package/neural-interface/public/variant/2d/main.js +10 -1
- package/neural-interface/public/variant/3d/main.js +10 -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/vendor-codemirror-entry.js +121 -0
- package/neural-interface/server.js +2085 -1629
- package/neural-interface/templates/rulesets/README.md +1 -1
- package/package.json +5 -8
- package/setup.js +53 -15
- 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
|
@@ -12,6 +12,11 @@
|
|
|
12
12
|
// the time it happened), and its own probe of the server. Nothing is guessed:
|
|
13
13
|
// no percentages, and no step is named before the launch reported it.
|
|
14
14
|
//
|
|
15
|
+
// A restart the user asked for is shown by the same bridge (`restart()`): the
|
|
16
|
+
// screen is drawn in the click, and what it says comes from the same three
|
|
17
|
+
// things, plus the server's own word that it is shutting down. The supervisor
|
|
18
|
+
// that brings the server back reports on the same beacon (`reason: 'restart'`).
|
|
19
|
+
//
|
|
15
20
|
// offline.html is shown when nothing can be fetched, so the server pastes this
|
|
16
21
|
// file into it (lib/offline-page.js drops the `export` keywords). Keep every
|
|
17
22
|
// export a plain `export function` / `export const` at the start of a line,
|
|
@@ -37,6 +42,7 @@ export const START_LIMITS = {
|
|
|
37
42
|
lostAfterMs: 3000, // a launch that was reporting went silent: stop repeating what it said
|
|
38
43
|
idleBeaconChecks: 2, // on load, look for a start already under way (a reload in the middle of one)
|
|
39
44
|
reloadDelayMs: 150, // the "it is up" frame before the page reloads
|
|
45
|
+
restartGraceMs: 15000, // a restart was asked and the server neither went away nor said it is going: stop waiting
|
|
40
46
|
beaconTimeoutMs: 1200,
|
|
41
47
|
};
|
|
42
48
|
|
|
@@ -152,7 +158,7 @@ export function startBeaconTarget(loc) {
|
|
|
152
158
|
}
|
|
153
159
|
|
|
154
160
|
const START_LAUNCH_STATES = ['starting', 'started', 'failed', 'gave-up'];
|
|
155
|
-
const START_LAUNCH_STEPS = ['received', 'locked', 'terminal', 'spawned'];
|
|
161
|
+
const START_LAUNCH_STEPS = ['received', 'locked', 'terminal', 'spawned', 'exited'];
|
|
156
162
|
const START_SUPERVISOR_PHASES = ['checking', 'dependencies', 'browser', 'build', 'snapshot', 'server', 'listening', 'failed'];
|
|
157
163
|
|
|
158
164
|
function startCleanError(error) {
|
|
@@ -217,6 +223,8 @@ export function readStartBeacon(data, { port, askedAt = null, following = null,
|
|
|
217
223
|
const newest = Math.max(last.at, supervisor ? supervisor.at : 0, startedAt);
|
|
218
224
|
return {
|
|
219
225
|
id,
|
|
226
|
+
// 'restart': a supervisor bringing its server back, not a launcher starting one.
|
|
227
|
+
reason: data.reason === 'restart' ? 'restart' : 'start',
|
|
220
228
|
state: data.state,
|
|
221
229
|
startedAt,
|
|
222
230
|
step: last.id,
|
|
@@ -251,7 +259,10 @@ export function fetchStartBeacon(target, { fetchImpl, timeoutMs = START_LIMITS.b
|
|
|
251
259
|
* idle → launching → starting | waiting → stalled | failed, or online at any
|
|
252
260
|
* point. The page keeps probing in every state, so a server started by hand is
|
|
253
261
|
* noticed just the same.
|
|
254
|
-
* probe() → Promise<boolean> is the server
|
|
262
|
+
* probe() → Promise<boolean | { up, boot, stopping }> is the server
|
|
263
|
+
* answering? `boot` names the server that answered and
|
|
264
|
+
* `stopping` is its own word that it is shutting down for a
|
|
265
|
+
* restart; a server that says neither is just `true`.
|
|
255
266
|
* launch() → hand START_LINK to the OS
|
|
256
267
|
* beacon() → Promise<object|null> the launch's raw report (optional)
|
|
257
268
|
* port → the server's port (what a beacon must be about)
|
|
@@ -267,6 +278,13 @@ export function fetchStartBeacon(target, { fetchImpl, timeoutMs = START_LIMITS.b
|
|
|
267
278
|
* 'stalled' stallAfterMs with no word, or the launcher gave up waiting
|
|
268
279
|
* 'failed' the launcher reports that the start failed, and why
|
|
269
280
|
* 'online' the server answers this page
|
|
281
|
+
*
|
|
282
|
+
* A restart (`restart()`) adds two:
|
|
283
|
+
* 'restarting' the server was asked to restart, or said it is restarting;
|
|
284
|
+
* it has not come back and no supervisor reports on it yet
|
|
285
|
+
* 'refused' the restart did not happen and the server still answers
|
|
286
|
+
* While one is under way `snapshot().restart` says what is known of it, and
|
|
287
|
+
* 'online' means a server other than the one that was asked answers.
|
|
270
288
|
*/
|
|
271
289
|
export function createStartBridge({
|
|
272
290
|
probe,
|
|
@@ -292,9 +310,13 @@ export function createStartBridge({
|
|
|
292
310
|
let launchSeenAt = 0;
|
|
293
311
|
let idleChecks = 0;
|
|
294
312
|
let shown = '';
|
|
313
|
+
// The restart under way, on this page's clock: when it was asked for (or
|
|
314
|
+
// this page was told), when the server said it is restarting, when it first
|
|
315
|
+
// did not answer, and the server that is being replaced.
|
|
316
|
+
let restart = null;
|
|
295
317
|
const past = [];
|
|
296
318
|
|
|
297
|
-
const busy = () => state === 'launching' || state === 'starting' || state === 'waiting';
|
|
319
|
+
const busy = () => state === 'launching' || state === 'starting' || state === 'waiting' || state === 'restarting';
|
|
298
320
|
|
|
299
321
|
function snapshot() {
|
|
300
322
|
return {
|
|
@@ -304,15 +326,24 @@ export function createStartBridge({
|
|
|
304
326
|
since,
|
|
305
327
|
elapsedMs: since === null ? 0 : Math.max(0, now() - since),
|
|
306
328
|
launch: launchInfo,
|
|
329
|
+
restart: restart ? {
|
|
330
|
+
asked: restart.asked,
|
|
331
|
+
askedAt: restart.askedAt,
|
|
332
|
+
acceptedAt: restart.acceptedAt,
|
|
333
|
+
downAt: restart.downAt,
|
|
334
|
+
refused: restart.refused,
|
|
335
|
+
} : null,
|
|
307
336
|
};
|
|
308
337
|
}
|
|
309
338
|
|
|
310
339
|
function update() {
|
|
311
340
|
const snap = snapshot();
|
|
312
341
|
const l = snap.launch;
|
|
342
|
+
const r = snap.restart;
|
|
313
343
|
const key = [
|
|
314
344
|
snap.state, snap.clicks, busy() ? Math.floor(snap.elapsedMs / 1000) : '',
|
|
315
345
|
l ? [l.id, l.state, l.step, l.supervisor?.phase, l.supervisor?.detail?.step, l.supervisor?.detail?.files, l.quietMs >= lim.quietAfterMs, l.error?.message].join('|') : '',
|
|
346
|
+
r ? [r.acceptedAt !== null, r.downAt !== null, r.refused?.code].join('|') : '',
|
|
316
347
|
].join('/');
|
|
317
348
|
if (key === shown) return;
|
|
318
349
|
shown = key;
|
|
@@ -326,14 +357,65 @@ export function createStartBridge({
|
|
|
326
357
|
}
|
|
327
358
|
|
|
328
359
|
function schedule(delay) {
|
|
329
|
-
if (stopped || state === 'online') return;
|
|
360
|
+
if (stopped || state === 'online' || state === 'refused') return;
|
|
330
361
|
if (timer) clearTimer(timer);
|
|
331
362
|
timer = setTimer(tick, delay ?? (busy() ? lim.pollMs : lim.idlePollMs));
|
|
332
363
|
}
|
|
333
364
|
|
|
365
|
+
/** One probe answer as { up, boot, stopping }; a bare `true` is a server that says nothing about itself. */
|
|
366
|
+
function readProbe(value) {
|
|
367
|
+
if (value === true) return { up: true, boot: '', stopping: false };
|
|
368
|
+
if (value && typeof value === 'object' && value.up === true) {
|
|
369
|
+
return { up: true, boot: typeof value.boot === 'string' ? value.boot : '', stopping: value.stopping === true };
|
|
370
|
+
}
|
|
371
|
+
return { up: false, boot: '', stopping: false };
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/** The restart did not happen and the server is still there: say why and stop. */
|
|
375
|
+
function refuse(why) {
|
|
376
|
+
restart.refused = why;
|
|
377
|
+
set('refused');
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* During a restart an answer is not yet the server being back: the one that
|
|
382
|
+
* was asked keeps answering while it shuts down. True only when the server
|
|
383
|
+
* that answers is another one. A server that names itself (`boot`) settles
|
|
384
|
+
* it; one that does not (an older server) is believed once it was seen gone.
|
|
385
|
+
*/
|
|
386
|
+
function judgeRestart(seen) {
|
|
387
|
+
const r = restart;
|
|
388
|
+
if (!seen.up) {
|
|
389
|
+
if (r.downAt === null) r.downAt = now();
|
|
390
|
+
return false;
|
|
391
|
+
}
|
|
392
|
+
if (seen.stopping) {
|
|
393
|
+
// Its own word: it is the one being replaced, and it is on its way out.
|
|
394
|
+
if (r.acceptedAt === null) r.acceptedAt = now();
|
|
395
|
+
if (!r.boot && seen.boot) r.boot = seen.boot;
|
|
396
|
+
r.downAt = null; // an answer it missed was not it stopping
|
|
397
|
+
return false;
|
|
398
|
+
}
|
|
399
|
+
const named = !!r.boot && !!seen.boot;
|
|
400
|
+
if (named && seen.boot !== r.boot) return true;
|
|
401
|
+
if (!named && r.downAt !== null) return true;
|
|
402
|
+
// The same server (or one that cannot be told apart), not shutting down.
|
|
403
|
+
if (named) r.downAt = null;
|
|
404
|
+
if (r.pending) return false; // the request is still on its way
|
|
405
|
+
if (r.rejected) { refuse(r.rejected); return false; }
|
|
406
|
+
if (r.unanswered) { refuse({ code: 'unreachable', status: 0, message: '' }); return false; }
|
|
407
|
+
if (r.acceptedAt !== null && now() - r.acceptedAt >= lim.restartGraceMs) {
|
|
408
|
+
if (named) { refuse({ code: 'still-running', status: 0, message: '' }); return false; }
|
|
409
|
+
return true; // it tells nothing about itself: load it again and see
|
|
410
|
+
}
|
|
411
|
+
return false;
|
|
412
|
+
}
|
|
413
|
+
|
|
334
414
|
/** What the launch says, when there is one to listen to right now. */
|
|
335
415
|
async function listen() {
|
|
336
416
|
if (!beacon) return;
|
|
417
|
+
// A restart: nobody is starting anything while the old server still answers.
|
|
418
|
+
if (restart && restart.downAt === null) return;
|
|
337
419
|
// Idle: only just after load, for a start that was already under way.
|
|
338
420
|
if (state === 'idle' && idleChecks >= lim.idleBeaconChecks) return;
|
|
339
421
|
if (state === 'idle') idleChecks++;
|
|
@@ -357,7 +439,8 @@ export function createStartBridge({
|
|
|
357
439
|
// reading how. What it said last is no longer known to be true.
|
|
358
440
|
if (state === 'starting' && now() - launchSeenAt >= lim.lostAfterMs) {
|
|
359
441
|
launchInfo = null;
|
|
360
|
-
if (
|
|
442
|
+
if (restart) set('restarting'); // back to what this page sees for itself
|
|
443
|
+
else if (askedAt === null) { since = null; set('idle'); } // a start this page never asked for: back to watching
|
|
361
444
|
else set(now() - askedAt >= lim.hintAfterMs ? 'waiting' : 'launching');
|
|
362
445
|
}
|
|
363
446
|
}
|
|
@@ -366,17 +449,22 @@ export function createStartBridge({
|
|
|
366
449
|
timer = null;
|
|
367
450
|
if (stopped || probing) return;
|
|
368
451
|
probing = true;
|
|
369
|
-
let
|
|
370
|
-
try {
|
|
371
|
-
|
|
452
|
+
let seen = readProbe(false);
|
|
453
|
+
try { seen = readProbe(await probe()); } catch {}
|
|
454
|
+
let up = seen.up && !seen.stopping; // a server on its way out is not one to connect to
|
|
455
|
+
if (restart && !stopped && state !== 'refused') up = judgeRestart(seen);
|
|
456
|
+
if (!up && !stopped && state !== 'refused') await listen();
|
|
372
457
|
probing = false;
|
|
373
458
|
if (stopped) return;
|
|
374
459
|
if (up) { set('online'); update(); return; }
|
|
460
|
+
if (state === 'refused') { update(); return; }
|
|
375
461
|
if (state === 'launching' || state === 'waiting') {
|
|
376
462
|
const waited = now() - askedAt;
|
|
377
463
|
if (waited >= lim.stallAfterMs) set('stalled');
|
|
378
464
|
else if (waited >= lim.hintAfterMs) set('waiting');
|
|
379
465
|
}
|
|
466
|
+
// Gone, and nobody reports bringing it back: the button and the command return.
|
|
467
|
+
if (state === 'restarting' && restart.downAt !== null && now() - restart.downAt >= lim.stallAfterMs) set('stalled');
|
|
380
468
|
update();
|
|
381
469
|
schedule();
|
|
382
470
|
}
|
|
@@ -388,13 +476,14 @@ export function createStartBridge({
|
|
|
388
476
|
watch() { schedule(0); },
|
|
389
477
|
/** The click. Ignored while a start is already under way. */
|
|
390
478
|
start() {
|
|
391
|
-
if (stopped || state === 'online' || busy()) return false;
|
|
479
|
+
if (stopped || state === 'online' || state === 'refused' || busy()) return false;
|
|
392
480
|
clicks++;
|
|
393
481
|
askedAt = now();
|
|
394
482
|
since = askedAt;
|
|
395
483
|
// What the last try reported is over: a launcher still saying so is not this one.
|
|
396
484
|
if (launchInfo && !past.includes(launchInfo.id)) past.push(launchInfo.id);
|
|
397
485
|
launchInfo = null;
|
|
486
|
+
restart = null; // a restart that did not bring it back is over: this is a start
|
|
398
487
|
state = 'idle'; // a second try after 'stalled' announces 'launching' again
|
|
399
488
|
set('launching');
|
|
400
489
|
update();
|
|
@@ -402,6 +491,67 @@ export function createStartBridge({
|
|
|
402
491
|
schedule();
|
|
403
492
|
return true;
|
|
404
493
|
},
|
|
494
|
+
/**
|
|
495
|
+
* A restart of the server. Call it from the click itself: the first
|
|
496
|
+
* snapshot is handed to onUpdate before anything is asked of the network.
|
|
497
|
+
* request() → Promise<{ ok, boot, status, message }> the asking (this
|
|
498
|
+
* page's own click); leave it out when the page is only told
|
|
499
|
+
* announced → the server itself said it is restarting (`boot`: which one)
|
|
500
|
+
* A request that fails counts as refused only once the server is seen to
|
|
501
|
+
* be still there. Returns false when a restart is already being shown; an
|
|
502
|
+
* announcement then still counts as the server's word.
|
|
503
|
+
*/
|
|
504
|
+
restart({ request = null, announced = false, boot = '' } = {}) {
|
|
505
|
+
if (stopped || state === 'online') return false;
|
|
506
|
+
if (restart) {
|
|
507
|
+
if (announced && !restart.refused) {
|
|
508
|
+
if (restart.acceptedAt === null) restart.acceptedAt = now();
|
|
509
|
+
if (!restart.boot && boot) restart.boot = String(boot);
|
|
510
|
+
update();
|
|
511
|
+
}
|
|
512
|
+
return false;
|
|
513
|
+
}
|
|
514
|
+
if (typeof request !== 'function' && !announced) return false;
|
|
515
|
+
askedAt = now();
|
|
516
|
+
since = askedAt;
|
|
517
|
+
if (launchInfo && !past.includes(launchInfo.id)) past.push(launchInfo.id);
|
|
518
|
+
launchInfo = null;
|
|
519
|
+
const mine = restart = {
|
|
520
|
+
asked: typeof request === 'function',
|
|
521
|
+
askedAt,
|
|
522
|
+
acceptedAt: announced ? askedAt : null,
|
|
523
|
+
downAt: null,
|
|
524
|
+
boot: announced && boot ? String(boot) : '',
|
|
525
|
+
pending: typeof request === 'function',
|
|
526
|
+
rejected: null,
|
|
527
|
+
unanswered: false,
|
|
528
|
+
refused: null,
|
|
529
|
+
};
|
|
530
|
+
state = 'idle';
|
|
531
|
+
set('restarting');
|
|
532
|
+
update();
|
|
533
|
+
if (mine.asked) {
|
|
534
|
+
Promise.resolve().then(() => request()).then((answer) => {
|
|
535
|
+
if (stopped || restart !== mine) return;
|
|
536
|
+
mine.pending = false;
|
|
537
|
+
if (answer && answer.ok === true) {
|
|
538
|
+
if (mine.acceptedAt === null) mine.acceptedAt = now();
|
|
539
|
+
if (answer.boot) mine.boot = String(answer.boot);
|
|
540
|
+
} else {
|
|
541
|
+
mine.rejected = { code: 'refused', status: Number(answer?.status) || 0, message: String(answer?.message || '').slice(0, 200) };
|
|
542
|
+
}
|
|
543
|
+
update();
|
|
544
|
+
schedule(0); // look at once: a refusal is only one when the server still answers
|
|
545
|
+
}, () => {
|
|
546
|
+
if (stopped || restart !== mine) return;
|
|
547
|
+
mine.pending = false;
|
|
548
|
+
mine.unanswered = true;
|
|
549
|
+
schedule(0);
|
|
550
|
+
});
|
|
551
|
+
}
|
|
552
|
+
schedule();
|
|
553
|
+
return true;
|
|
554
|
+
},
|
|
405
555
|
stop() {
|
|
406
556
|
stopped = true;
|
|
407
557
|
if (timer) clearTimer(timer);
|
|
@@ -452,6 +602,22 @@ export const START_COPY = {
|
|
|
452
602
|
headingStarting: 'Starting the server',
|
|
453
603
|
headingReady: 'Server is up',
|
|
454
604
|
headingFailed: 'The server did not start',
|
|
605
|
+
// A restart: each sentence is said only once the page holds what it says.
|
|
606
|
+
restartAsked: 'Asked the server to restart.',
|
|
607
|
+
restartStopping: 'The server accepted the restart and is shutting down.',
|
|
608
|
+
restartSlowStop: 'Still shutting down after {seconds} s.',
|
|
609
|
+
restartDown: 'The server stopped answering. Waiting for it to come back.',
|
|
610
|
+
restartRespawning: 'The supervisor is starting the server again.',
|
|
611
|
+
restartStalled: 'The server has not come back. Start it with the button, or run the command below.',
|
|
612
|
+
restartRefused: 'The server did not accept the restart: {reason}',
|
|
613
|
+
restartUnreachable: 'The server did not answer the restart request.',
|
|
614
|
+
restartStillRunning: 'The server accepted the restart but did not shut down.',
|
|
615
|
+
trailAccepted: 'Restart accepted',
|
|
616
|
+
trailNoAnswer: 'Server stopped answering',
|
|
617
|
+
trailStopped: 'Server process exited',
|
|
618
|
+
restartElapsedLabel: 'Time since the restart began',
|
|
619
|
+
headingRestarting: 'Restarting the server',
|
|
620
|
+
headingRestartFailed: 'The server did not restart',
|
|
455
621
|
};
|
|
456
622
|
|
|
457
623
|
/** `{name}` placeholders, like the app's t(). */
|
|
@@ -474,12 +640,15 @@ function startStepSeconds(ms) {
|
|
|
474
640
|
|
|
475
641
|
/**
|
|
476
642
|
* Everything a surface renders for one snapshot, as data:
|
|
643
|
+
* reason 'start' | 'restart' what is under way: a start, or a restart of a server that was up
|
|
477
644
|
* mascot 'asleep' | 'waking' | 'working' | 'ready' | 'failed' | 'stalled'
|
|
478
645
|
* busy the button is disabled (a start is under way)
|
|
479
|
-
* button 'start' | 'starting' | 'retry'
|
|
646
|
+
* button 'start' | 'starting' | 'retry' | 'none' (a restart: nothing to press) | 'back' (it was refused)
|
|
647
|
+
* heading key | null the title when it is not the surface's own for this mascot
|
|
480
648
|
* headline { key, params } | null the status sentence (the live region)
|
|
481
649
|
* hint { key, params } | null a second, quieter sentence
|
|
482
650
|
* elapsed '12 s' | '' the page's clock since the click
|
|
651
|
+
* elapsedLabel key what that clock counts from
|
|
483
652
|
* trail [{ key, time }] what was reported, with when
|
|
484
653
|
* error { message, log } | null
|
|
485
654
|
* A headline names a step only when the snapshot holds the report of it.
|
|
@@ -488,38 +657,57 @@ export function startStatusView(snap, { platform = 'linux', limits = START_LIMIT
|
|
|
488
657
|
const state = snap?.state || 'idle';
|
|
489
658
|
const launchOf = snap?.launch || null;
|
|
490
659
|
const sup = launchOf?.supervisor || null;
|
|
660
|
+
// A restart this page asked for or was told of; or one it only reads the report of.
|
|
661
|
+
const restart = snap?.restart || null;
|
|
662
|
+
const restartReport = launchOf?.reason === 'restart';
|
|
491
663
|
const view = {
|
|
492
664
|
state,
|
|
665
|
+
reason: restart || restartReport ? 'restart' : 'start',
|
|
493
666
|
mascot: 'asleep',
|
|
494
|
-
busy: state === 'launching' || state === 'starting' || state === 'waiting',
|
|
667
|
+
busy: state === 'launching' || state === 'starting' || state === 'waiting' || state === 'restarting',
|
|
495
668
|
button: 'start',
|
|
669
|
+
heading: null,
|
|
496
670
|
headline: null,
|
|
497
671
|
hint: null,
|
|
498
672
|
elapsed: '',
|
|
673
|
+
elapsedLabel: restart || restartReport ? 'restartElapsedLabel' : 'elapsedLabel',
|
|
499
674
|
trail: [],
|
|
500
675
|
error: null,
|
|
501
676
|
};
|
|
502
677
|
if (view.busy) {
|
|
503
|
-
view.button = 'starting';
|
|
678
|
+
view.button = restart ? 'none' : 'starting';
|
|
504
679
|
view.elapsed = formatStartElapsed(snap.elapsedMs);
|
|
680
|
+
if (view.reason === 'restart') view.heading = 'headingRestarting';
|
|
505
681
|
}
|
|
506
682
|
|
|
507
683
|
// The reported steps, each at the time it was reported for, counted from the
|
|
508
684
|
// click (or from the launch's own start when another page asked for it).
|
|
509
|
-
|
|
685
|
+
const firstPhase = (phase) => (sup ? sup.phases.find(p => p.phase === phase)?.at || (sup.phase === phase ? sup.at : 0) : 0);
|
|
686
|
+
if (restart) {
|
|
687
|
+
// A restart this page follows from its beginning: what the server said to
|
|
688
|
+
// it, what its own probe saw, then what the supervisor reports.
|
|
689
|
+
const add = (key, at) => { if (at !== null && at !== undefined) view.trail.push({ key, time: startStepSeconds(at - restart.askedAt) }); };
|
|
690
|
+
add('trailAccepted', restart.acceptedAt);
|
|
691
|
+
const exited = launchOf ? launchOf.steps.find(step => step.id === 'exited')?.at : undefined;
|
|
692
|
+
if (exited !== undefined) add('trailStopped', exited);
|
|
693
|
+
else add('trailNoAnswer', restart.downAt);
|
|
694
|
+
add('trailServer', firstPhase('server') || null);
|
|
695
|
+
add('trailListening', firstPhase('listening') || null);
|
|
696
|
+
} else if (launchOf) {
|
|
510
697
|
const asked = snap.askedAt !== null && snap.askedAt !== undefined && launchOf.startedAt >= snap.askedAt - 2000;
|
|
511
698
|
const zero = asked ? snap.askedAt : launchOf.startedAt;
|
|
512
699
|
const add = (key, at) => { if (at) view.trail.push({ key, time: startStepSeconds(at - zero) }); };
|
|
513
|
-
add('trailLauncher', launchOf.startedAt);
|
|
700
|
+
if (!restartReport) add('trailLauncher', launchOf.startedAt); // a restart has no launcher
|
|
514
701
|
for (const step of launchOf.steps) {
|
|
515
702
|
if (step.id === 'terminal') add('trailTerminal', step.at);
|
|
516
703
|
if (step.id === 'spawned') add('trailProcess', step.at);
|
|
704
|
+
if (step.id === 'exited') add('trailStopped', step.at);
|
|
517
705
|
}
|
|
518
706
|
if (sup) {
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
add('trailServer',
|
|
522
|
-
add('trailListening',
|
|
707
|
+
// The supervisor of a restart was usually there long before it: listed only when it began with it.
|
|
708
|
+
if (!restartReport || sup.startedAt >= launchOf.startedAt - 2000) add('trailSupervisor', sup.startedAt);
|
|
709
|
+
add('trailServer', firstPhase('server'));
|
|
710
|
+
add('trailListening', firstPhase('listening'));
|
|
523
711
|
}
|
|
524
712
|
}
|
|
525
713
|
|
|
@@ -540,7 +728,34 @@ export function startStatusView(snap, { platform = 'linux', limits = START_LIMIT
|
|
|
540
728
|
}
|
|
541
729
|
if (state === 'stalled') {
|
|
542
730
|
view.mascot = 'stalled';
|
|
543
|
-
view.headline = launchOf?.state === 'gave-up' ? { key: 'gaveUp', params: {} }
|
|
731
|
+
view.headline = launchOf?.state === 'gave-up' ? { key: 'gaveUp', params: {} }
|
|
732
|
+
: restart ? { key: 'restartStalled', params: {} } : { key: 'stalled', params: {} };
|
|
733
|
+
return view;
|
|
734
|
+
}
|
|
735
|
+
if (state === 'refused') {
|
|
736
|
+
// The server is still there: nothing to start, only the way back to the app.
|
|
737
|
+
const why = restart?.refused || {};
|
|
738
|
+
view.mascot = 'failed';
|
|
739
|
+
view.button = 'back';
|
|
740
|
+
view.heading = 'headingRestartFailed';
|
|
741
|
+
view.headline = why.code === 'unreachable' ? { key: 'restartUnreachable', params: {} }
|
|
742
|
+
: why.code === 'still-running' ? { key: 'restartStillRunning', params: {} }
|
|
743
|
+
: { key: 'restartRefused', params: { reason: why.message || `HTTP ${why.status || 0}` } };
|
|
744
|
+
return view;
|
|
745
|
+
}
|
|
746
|
+
if (state === 'restarting' && restart) {
|
|
747
|
+
if (restart.downAt !== null) {
|
|
748
|
+
view.mascot = 'working';
|
|
749
|
+
view.headline = { key: 'restartDown', params: {} };
|
|
750
|
+
} else if (restart.acceptedAt !== null) {
|
|
751
|
+
view.mascot = 'working';
|
|
752
|
+
view.headline = { key: 'restartStopping', params: {} };
|
|
753
|
+
const stoppingMs = snap.elapsedMs - (restart.acceptedAt - restart.askedAt);
|
|
754
|
+
if (stoppingMs >= limits.quietAfterMs) view.hint = { key: 'restartSlowStop', params: { seconds: Math.floor(stoppingMs / 1000) } };
|
|
755
|
+
} else {
|
|
756
|
+
view.mascot = 'waking';
|
|
757
|
+
view.headline = { key: 'restartAsked', params: {} };
|
|
758
|
+
}
|
|
544
759
|
return view;
|
|
545
760
|
}
|
|
546
761
|
if (state === 'failed') {
|
|
@@ -568,6 +783,10 @@ export function startStatusView(snap, { platform = 'linux', limits = START_LIMIT
|
|
|
568
783
|
// Slow on purpose (an install, a download, a backup): silence there is expected.
|
|
569
784
|
const slow = ['dependencies', 'browser', 'build', 'snapshot'].includes(sup.phase);
|
|
570
785
|
if (isQuiet && !slow) view.hint = { key: 'quiet', params: { seconds: quiet } };
|
|
786
|
+
} else if (restartReport) {
|
|
787
|
+
// The supervisor opened this report to bring the server back; it has named no step yet.
|
|
788
|
+
view.headline = { key: 'restartRespawning', params: {} };
|
|
789
|
+
if (isQuiet) view.hint = { key: 'quiet', params: { seconds: quiet } };
|
|
571
790
|
} else if (launchOf.step === 'terminal') {
|
|
572
791
|
view.headline = isQuiet ? { key: 'terminalQuiet', params: { seconds: quiet } } : { key: 'terminalOpened', params: {} };
|
|
573
792
|
} else if (launchOf.step === 'spawned') {
|
|
@@ -33,6 +33,27 @@ const FAT_BLOB_KEYS = new Set([
|
|
|
33
33
|
// as a string and still needs JSON.parse for the server payload.
|
|
34
34
|
const STR_SENTINEL = Symbol('storage:str');
|
|
35
35
|
|
|
36
|
+
// Showcase mode: a page opened with `?showcase` (any value but "0" or "false")
|
|
37
|
+
// hydrates as usual but never writes back, so what a demo walk-through opens,
|
|
38
|
+
// moves or types leaves the user's saved UI state as it was. Reads work from
|
|
39
|
+
// the in-memory cache. (blob-store.js keeps its own writes.)
|
|
40
|
+
function _readShowcaseMode() {
|
|
41
|
+
try {
|
|
42
|
+
const params = new URLSearchParams(globalThis.window?.location?.search || '');
|
|
43
|
+
if (!params.has('showcase')) return false;
|
|
44
|
+
const value = String(params.get('showcase')).trim().toLowerCase();
|
|
45
|
+
return value !== '0' && value !== 'false';
|
|
46
|
+
} catch {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const SHOWCASE_MODE = _readShowcaseMode();
|
|
51
|
+
|
|
52
|
+
/** True when this page load is a showcase (`?showcase`): nothing is written back. */
|
|
53
|
+
export function isShowcaseMode() {
|
|
54
|
+
return SHOWCASE_MODE;
|
|
55
|
+
}
|
|
56
|
+
|
|
36
57
|
// ── Hydrate from server ──────────────────────────────
|
|
37
58
|
|
|
38
59
|
async function _hydrate() {
|
|
@@ -55,8 +76,8 @@ async function _hydrate() {
|
|
|
55
76
|
// First run or server down: import from localStorage
|
|
56
77
|
console.info('[storage] Migrating localStorage to server...');
|
|
57
78
|
_migrateFromLocalStorage();
|
|
58
|
-
// Build dirty set from everything we imported
|
|
59
|
-
for (const [key, val] of Object.entries(_cache)) {
|
|
79
|
+
// Build dirty set from everything we imported (a showcase only reads it)
|
|
80
|
+
if (!SHOWCASE_MODE) for (const [key, val] of Object.entries(_cache)) {
|
|
60
81
|
try { _dirty[key] = JSON.parse(val); } catch { _dirty[key] = val; }
|
|
61
82
|
}
|
|
62
83
|
if (Object.keys(_dirty).length > 0) {
|
|
@@ -74,6 +95,10 @@ else await _hydrate();
|
|
|
74
95
|
// ── Drop-in API (mirrors localStorage) ───────────────
|
|
75
96
|
|
|
76
97
|
export const storage = (hostedSidepanelId && sidepanelHost()?.storageFor(hostedSidepanelId)) || {
|
|
98
|
+
// False in showcase mode: values stay in this page. Code that sends a value to the server
|
|
99
|
+
// by itself (an unload beacon) asks this first.
|
|
100
|
+
persists: !SHOWCASE_MODE,
|
|
101
|
+
|
|
77
102
|
getItem(key) {
|
|
78
103
|
return _cache[key] ?? null;
|
|
79
104
|
},
|
|
@@ -105,11 +130,13 @@ export const storage = (hostedSidepanelId && sidepanelHost()?.storageFor(hostedS
|
|
|
105
130
|
// ── Debounced flush to server ────────────────────────
|
|
106
131
|
|
|
107
132
|
function _scheduleDebouncedFlush() {
|
|
133
|
+
if (SHOWCASE_MODE) { _dirty = {}; return; }
|
|
108
134
|
if (_flushTimer) clearTimeout(_flushTimer);
|
|
109
135
|
_flushTimer = setTimeout(_flushToServer, DEBOUNCE_MS);
|
|
110
136
|
}
|
|
111
137
|
|
|
112
138
|
async function _flushToServer() {
|
|
139
|
+
if (SHOWCASE_MODE) { _dirty = {}; _flushTimer = null; return; }
|
|
113
140
|
const payload = {};
|
|
114
141
|
for (const [k, v] of Object.entries(_dirty)) {
|
|
115
142
|
if (v === STR_SENTINEL) {
|
|
@@ -142,7 +169,7 @@ async function _flushToServer() {
|
|
|
142
169
|
|
|
143
170
|
// ── Flush on page unload (sendBeacon for reliability) ──
|
|
144
171
|
|
|
145
|
-
window.addEventListener('beforeunload', () => {
|
|
172
|
+
if (!SHOWCASE_MODE) window.addEventListener('beforeunload', () => {
|
|
146
173
|
if (_flushTimer) {
|
|
147
174
|
clearTimeout(_flushTimer);
|
|
148
175
|
_flushTimer = null;
|