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
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
const API_KEY_ERRORS = {
|
|
2
|
+
invalid_key: { status: 400, message: "That doesn't look like an API key for this provider." },
|
|
3
|
+
oauth_token: { status: 400, message: "That's a Claude sign-in token. Use Sign in with Claude." },
|
|
4
|
+
key_rejected: { status: 401, message: 'The provider rejected that key.' },
|
|
5
|
+
account_unavailable: { status: 404, message: 'This account is no longer available. Select an account again.' },
|
|
6
|
+
account_busy: { status: 409, message: 'Finish sign-in or reconnect this account and try again.' },
|
|
7
|
+
verification_unreachable: { status: 503, message: "Couldn't reach {vendor} to check the key. Try again." },
|
|
8
|
+
verification_unavailable: { status: 503, message: "{vendor} couldn't check the key. Try again shortly." },
|
|
9
|
+
storage_failed: { status: 500, message: "Couldn't save the key for this account." },
|
|
10
|
+
};
|
|
11
|
+
// `provider` names the vendor in the two verification messages (Anthropic for Claude, OpenAI for Codex).
|
|
12
|
+
export function providerApiKeyError(code, provider = 'claude') {
|
|
13
|
+
const { status, message } = Object.hasOwn(API_KEY_ERRORS, code) ? API_KEY_ERRORS[code] : API_KEY_ERRORS.storage_failed;
|
|
14
|
+
return Object.assign(new Error(message.replace('{vendor}', provider === 'codex' ? 'OpenAI' : 'Anthropic')), { status, code });
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Return the normalized value: clipboard padding is not part of a credential.
|
|
18
|
+
export function validateProviderApiKey(provider, key) {
|
|
19
|
+
if (!['claude', 'codex'].includes(provider)) throw Object.assign(new Error('Unknown provider'), { status: 404 });
|
|
20
|
+
if (typeof key !== 'string' || key.length > 4096) throw providerApiKeyError('invalid_key');
|
|
21
|
+
key = key.trim();
|
|
22
|
+
// setup-token produces an OAuth token, not an Anthropic API key. Never send
|
|
23
|
+
// it to x-api-key or persist it under the API-key authentication method.
|
|
24
|
+
if (provider === 'claude' && key.startsWith('sk-ant-oat01-')) throw providerApiKeyError('oauth_token');
|
|
25
|
+
const pattern = provider === 'claude' ? /^sk-ant-[A-Za-z0-9_-]{16,}$/ : /^sk-(?!ant-)[A-Za-z0-9_-]{16,}$/;
|
|
26
|
+
if (!pattern.test(key)) throw providerApiKeyError('invalid_key');
|
|
27
|
+
return key;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Defense in depth for native diagnostics/events. Never forward credential fields.
|
|
31
|
+
export function redactProviderSecrets(value) {
|
|
32
|
+
if (typeof value === 'string') return value.replace(/sk-[A-Za-z0-9_-]{16,}/g, '[redacted]');
|
|
33
|
+
if (Array.isArray(value)) return value.map(redactProviderSecrets);
|
|
34
|
+
if (value && typeof value === 'object') return Object.fromEntries(Object.entries(value)
|
|
35
|
+
.filter(([key]) => !/^(api_?key|access_?token|refresh_?token|id_?token|authorization)$/i.test(key))
|
|
36
|
+
.map(([key, item]) => [key, redactProviderSecrets(item)]));
|
|
37
|
+
return value;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function registerProviderPanelApiKeyAuthRoutes(app, { guard, claude, codex }) {
|
|
41
|
+
app.post('/api/provider-panel-auth/:provider/:accountId/api-key', guard, async (req, res) => {
|
|
42
|
+
res.setHeader('Cache-Control', 'no-store');
|
|
43
|
+
const { provider, accountId } = req.params;
|
|
44
|
+
let key = req.body?.key;
|
|
45
|
+
// Express's parsed request body must not outlive this handler with a secret.
|
|
46
|
+
if (req.body) delete req.body.key;
|
|
47
|
+
try {
|
|
48
|
+
key = validateProviderApiKey(provider, key);
|
|
49
|
+
if (!/^[a-z0-9-]{1,64}$/.test(accountId)) throw providerApiKeyError('account_unavailable');
|
|
50
|
+
// Codex keys are kept by SynaBun per account too (lib/codex-accounts.js): an older
|
|
51
|
+
// page may still send the `target` of its live connection, which is not needed now.
|
|
52
|
+
if (provider === 'claude') await claude(accountId, key);
|
|
53
|
+
else await codex(accountId, key);
|
|
54
|
+
res.json({ ok: true });
|
|
55
|
+
} catch (error) {
|
|
56
|
+
// Never serialize provider exceptions; a native error may echo its input.
|
|
57
|
+
const fallback = { 400: 'invalid_key', 401: 'key_rejected', 404: 'account_unavailable', 409: 'account_busy', 503: 'verification_unavailable' }[error.status] || 'storage_failed';
|
|
58
|
+
const code = Object.hasOwn(API_KEY_ERRORS, error.code) ? error.code : fallback;
|
|
59
|
+
const safe = providerApiKeyError(code, provider);
|
|
60
|
+
res.status(safe.status).json({ code, error: safe.message });
|
|
61
|
+
} finally { key = null; }
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Install immediately after the global JSON parser: its SyntaxError may contain
|
|
66
|
+
// a fragment of the secret-bearing body. Never pass that error to Express logs.
|
|
67
|
+
export function providerApiKeyBodyError(error, req, res, next) {
|
|
68
|
+
if (req.method !== 'POST' || !/^\/api\/provider-panel-auth\/[^/]+\/[^/]+\/api-key(?:\?|$)/.test(req.originalUrl || req.url || '')) return next(error);
|
|
69
|
+
delete error.body;
|
|
70
|
+
req.body = undefined;
|
|
71
|
+
res.setHeader('Cache-Control', 'no-store');
|
|
72
|
+
return res.status(error.status === 413 ? 413 : 400).json({ code: 'invalid_key', error: API_KEY_ERRORS.invalid_key.message });
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Native stderr arrives in arbitrary chunks. Redact complete lines so a split
|
|
76
|
+
// credential cannot leave an unmasked suffix; omit unterminated/oversized lines.
|
|
77
|
+
export function providerDiagnosticSink(write, maxChars = 65536) {
|
|
78
|
+
let buffer = '', dropping = false;
|
|
79
|
+
return chunk => {
|
|
80
|
+
const parts = String(chunk).split(/\r?\n/);
|
|
81
|
+
for (let i = 0; i < parts.length; i++) {
|
|
82
|
+
if (!dropping) {
|
|
83
|
+
buffer += parts[i];
|
|
84
|
+
if (buffer.length > maxChars) { buffer = ''; dropping = true; }
|
|
85
|
+
}
|
|
86
|
+
if (i < parts.length - 1) {
|
|
87
|
+
if (!dropping && buffer.trim()) write(redactProviderSecrets(buffer.trim()));
|
|
88
|
+
buffer = ''; dropping = false;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { randomBytes } from 'node:crypto';
|
|
2
|
+
import { isAbsolute } from 'node:path';
|
|
3
|
+
import { claudeAuthEnv } from './claude-panel-auth.js';
|
|
4
|
+
import { applyCodexLaunchEnv } from './codex-accounts.js';
|
|
5
|
+
|
|
6
|
+
// Only server-owned account records and resolved executables enter the PTY.
|
|
7
|
+
export function providerLoginSpec({ provider, accountId, claudeAccounts, codexAccount, claudeExecutable, codexExecutable, env }) {
|
|
8
|
+
if (!['claude', 'codex'].includes(provider) || typeof accountId !== 'string' || !/^[a-z0-9-]{1,64}$/.test(accountId)) {
|
|
9
|
+
throw Object.assign(new Error('Unknown provider account'), { status: 404 });
|
|
10
|
+
}
|
|
11
|
+
const account = provider === 'claude' ? claudeAccounts.profileFor(accountId) : codexAccount(accountId);
|
|
12
|
+
if (!account || account.id !== accountId) throw Object.assign(new Error('Unknown provider account'), { status: 404 });
|
|
13
|
+
const file = provider === 'claude' ? claudeExecutable()?.path : codexExecutable();
|
|
14
|
+
if (!file || !isAbsolute(file) || /\.(cmd|bat)$/i.test(file)) {
|
|
15
|
+
throw new Error(`Could not resolve the ${provider === 'claude' ? 'Claude' : 'Codex'} executable. Check its installation.`);
|
|
16
|
+
}
|
|
17
|
+
let baseEnv = { ...env };
|
|
18
|
+
if (provider === 'codex') {
|
|
19
|
+
// Every Codex account, Default too: `codex login` writes to that account's CODEX_HOME, with no
|
|
20
|
+
// inherited OpenAI/Codex credential around it (lib/codex-accounts.js CODEX_CREDENTIAL_ENV).
|
|
21
|
+
if (!account.home) throw new Error('This Codex account has no home folder.');
|
|
22
|
+
baseEnv = applyCodexLaunchEnv(baseEnv, { env: { CODEX_HOME: account.home } });
|
|
23
|
+
} else if (accountId !== 'default') {
|
|
24
|
+
if (!account.home) throw new Error('This Claude account has no isolated home.');
|
|
25
|
+
baseEnv = claudeAuthEnv(baseEnv, { CLAUDE_CONFIG_DIR: account.home });
|
|
26
|
+
}
|
|
27
|
+
const args = provider === 'claude' ? ['auth', 'login', '--claudeai'] : ['login'];
|
|
28
|
+
return { launch: /\.[cm]?js$/i.test(file) ? { shell: process.execPath, args: [file, ...args] } : { shell: file, args }, baseEnv };
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// `onSettled(provider, id, status)` (optional): told once when a sign-in terminal ends ('exited' when the
|
|
32
|
+
// CLI exited 0, else 'error'), so the host can ask the provider what it now says about the account.
|
|
33
|
+
export function createProviderPanelTerminalAuth({ resolveSpec, createSession, whenSpawned, killSession, timeoutMs = 10 * 60_000, onSettled = null }) {
|
|
34
|
+
const operations = new Map();
|
|
35
|
+
const key = (provider, id) => `${provider}:${id}`;
|
|
36
|
+
const snapshot = op => ({ sessionId: op.sessionId, status: op.status, error: op.error || '' });
|
|
37
|
+
function read(provider, id) {
|
|
38
|
+
resolveSpec(provider, id); // Validate deleted accounts and unsupported providers on reads too.
|
|
39
|
+
const op = operations.get(key(provider, id));
|
|
40
|
+
return op ? snapshot(op) : { status: 'idle' };
|
|
41
|
+
}
|
|
42
|
+
async function start(provider, id) {
|
|
43
|
+
const spec = resolveSpec(provider, id);
|
|
44
|
+
const existing = operations.get(key(provider, id));
|
|
45
|
+
if (existing && ['starting', 'pending'].includes(existing.status)) { await existing.ready; return snapshot(existing); }
|
|
46
|
+
const op = { sessionId: randomBytes(16).toString('hex'), status: 'starting' };
|
|
47
|
+
operations.set(key(provider, id), op);
|
|
48
|
+
let timer;
|
|
49
|
+
const finish = (status, error = '') => {
|
|
50
|
+
if (!['starting', 'pending'].includes(op.status)) return;
|
|
51
|
+
clearTimeout(timer); op.status = status; op.error = error;
|
|
52
|
+
if (typeof onSettled === 'function') Promise.resolve().then(() => onSettled(provider, id, status)).catch(() => {});
|
|
53
|
+
};
|
|
54
|
+
op.ready = (async () => {
|
|
55
|
+
try {
|
|
56
|
+
createSession('shell', 120, 30, undefined, { ...spec, sessionId: op.sessionId,
|
|
57
|
+
onExit: ({ exitCode }) => finish(exitCode === 0 ? 'exited' : 'error', exitCode === 0 ? '' : 'Sign-in failed. Try again.'),
|
|
58
|
+
onClosed: () => finish('error', 'Sign-in terminal closed. Try again.'),
|
|
59
|
+
});
|
|
60
|
+
let spawnTimer;
|
|
61
|
+
try {
|
|
62
|
+
await Promise.race([whenSpawned(op.sessionId), new Promise((_, reject) => {
|
|
63
|
+
spawnTimer = setTimeout(() => reject(new Error('Terminal host did not respond')), 15000);
|
|
64
|
+
})]);
|
|
65
|
+
} finally { clearTimeout(spawnTimer); }
|
|
66
|
+
if (op.status === 'starting') {
|
|
67
|
+
op.status = 'pending';
|
|
68
|
+
timer = setTimeout(() => { finish('error', 'Sign-in timed out. Try again.'); killSession(op.sessionId); }, timeoutMs);
|
|
69
|
+
timer.unref?.();
|
|
70
|
+
}
|
|
71
|
+
} catch {
|
|
72
|
+
finish('error', 'Could not open the sign-in terminal. Try again.');
|
|
73
|
+
killSession(op.sessionId);
|
|
74
|
+
}
|
|
75
|
+
})();
|
|
76
|
+
await op.ready;
|
|
77
|
+
return snapshot(op);
|
|
78
|
+
}
|
|
79
|
+
return { start, read };
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export function registerProviderPanelTerminalAuthRoutes(app, { guard, auth }) {
|
|
83
|
+
const route = '/api/provider-panel-auth/:provider/:id/terminal';
|
|
84
|
+
app.get(route, guard, (req, res) => {
|
|
85
|
+
res.setHeader('Cache-Control', 'no-store');
|
|
86
|
+
try { res.json({ terminal: auth.read(req.params.provider, req.params.id) }); }
|
|
87
|
+
catch (error) { res.status(error.status || 500).json({ error: error.message }); }
|
|
88
|
+
});
|
|
89
|
+
app.post(route, guard, async (req, res) => {
|
|
90
|
+
res.setHeader('Cache-Control', 'no-store');
|
|
91
|
+
if (Object.keys(req.body || {}).length) return res.status(400).json({ error: 'Only provider and account selection are accepted.' });
|
|
92
|
+
try { res.json({ terminal: await auth.start(req.params.provider, req.params.id) }); }
|
|
93
|
+
catch (error) { res.status(error.status || 500).json({ error: error.message }); }
|
|
94
|
+
});
|
|
95
|
+
}
|
|
@@ -18,6 +18,7 @@ import { createTerminalModel } from './snapshot.js';
|
|
|
18
18
|
import { evaluateFlow } from './flow.js';
|
|
19
19
|
import { EV, OP, HOST_DEFAULTS } from './protocol.js';
|
|
20
20
|
import { createEventLoopMonitor } from '../event-loop-monitor.js';
|
|
21
|
+
import { withPathEnv } from '../augmented-path.js';
|
|
21
22
|
|
|
22
23
|
const IS_WIN = process.platform === 'win32';
|
|
23
24
|
const IS_LINUX = process.platform === 'linux';
|
|
@@ -74,7 +75,7 @@ export function createPtyHostCore({ send, config = {}, pty: injectedPty = null }
|
|
|
74
75
|
}
|
|
75
76
|
const cols = clampInt(spec.cols, 2, 1000) || 120;
|
|
76
77
|
const rows = clampInt(spec.rows, 1, 500) || 30;
|
|
77
|
-
const env =
|
|
78
|
+
const env = withPathEnv(spec.env || {});
|
|
78
79
|
for (const k of Object.keys(env)) if (k.startsWith('NODE_CHANNEL_') || k === 'NODE_UNIQUE_ID') delete env[k];
|
|
79
80
|
|
|
80
81
|
let file = spec.file;
|
|
@@ -38,6 +38,7 @@ export function createPtyHostManager({
|
|
|
38
38
|
} = {}) {
|
|
39
39
|
const handlers = new Map(); // id → { onSpawned, onTap, onResized, onClients, onExit }
|
|
40
40
|
const spawnWaiters = new Map(); // id → waiter
|
|
41
|
+
const preparing = new Map(); // id → operations queued while PATH is read
|
|
41
42
|
const requests = new Map(); // reqId → { resolve, reject, timer }
|
|
42
43
|
let reqSeq = 0;
|
|
43
44
|
let child = null;
|
|
@@ -158,6 +159,7 @@ export function createPtyHostManager({
|
|
|
158
159
|
heldSockets = [];
|
|
159
160
|
queue = [];
|
|
160
161
|
const lost = [...handlers.entries()];
|
|
162
|
+
preparing.clear();
|
|
161
163
|
handlers.clear();
|
|
162
164
|
for (const [id] of lost) settleSpawn(id, new Error('pty-host exited'));
|
|
163
165
|
spawnWaiters.clear();
|
|
@@ -175,6 +177,13 @@ export function createPtyHostManager({
|
|
|
175
177
|
|
|
176
178
|
// ── Main → host ──
|
|
177
179
|
function sendOp(msg) {
|
|
180
|
+
if (preparing.has(msg.id) && msg.op !== OP.SPAWN) {
|
|
181
|
+
if (msg.op === OP.KILL) {
|
|
182
|
+
preparing.delete(msg.id);
|
|
183
|
+
dispatch({ t: EV.SPAWN_ERROR, id: msg.id, message: 'Terminal closed before it started' });
|
|
184
|
+
} else preparing.get(msg.id).push(msg);
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
178
187
|
if (mode === 'inproc') {
|
|
179
188
|
if (!core || !ready) { queue.push(msg); return; }
|
|
180
189
|
core.handleMessage(msg);
|
|
@@ -190,11 +199,23 @@ export function createPtyHostManager({
|
|
|
190
199
|
for (const msg of q) sendOp(msg);
|
|
191
200
|
}
|
|
192
201
|
|
|
193
|
-
function spawn(spec, h = {}) {
|
|
202
|
+
function spawn(spec, h = {}, prepare = null) {
|
|
194
203
|
handlers.set(spec.id, h);
|
|
195
204
|
const w = makeWaiter();
|
|
196
205
|
spawnWaiters.set(spec.id, w);
|
|
197
|
-
|
|
206
|
+
if (prepare) {
|
|
207
|
+
const pending = [];
|
|
208
|
+
preparing.set(spec.id, pending);
|
|
209
|
+
Promise.resolve().then(prepare).then(prepared => {
|
|
210
|
+
if (shuttingDown || !handlers.has(spec.id) || preparing.get(spec.id) !== pending) return;
|
|
211
|
+
preparing.delete(spec.id);
|
|
212
|
+
sendOp({ op: OP.SPAWN, ...spec, ...prepared });
|
|
213
|
+
for (const message of pending) sendOp(message);
|
|
214
|
+
}).catch(error => {
|
|
215
|
+
preparing.delete(spec.id);
|
|
216
|
+
dispatch({ t: EV.SPAWN_ERROR, id: spec.id, message: error.message });
|
|
217
|
+
});
|
|
218
|
+
} else sendOp({ op: OP.SPAWN, ...spec });
|
|
198
219
|
return w.promise;
|
|
199
220
|
}
|
|
200
221
|
|
|
@@ -315,6 +336,8 @@ export function createPtyHostManager({
|
|
|
315
336
|
|
|
316
337
|
async function shutdown({ timeoutMs = 1500 } = {}) {
|
|
317
338
|
shuttingDown = true;
|
|
339
|
+
for (const id of preparing.keys()) settleSpawn(id, new Error('Terminal host is shutting down'));
|
|
340
|
+
preparing.clear();
|
|
318
341
|
if (restartTimer) { clearTimeout(restartTimer); restartTimer = null; }
|
|
319
342
|
if (mode === 'inproc') {
|
|
320
343
|
try { core?.shutdownAll(); } catch {}
|
|
@@ -332,6 +355,8 @@ export function createPtyHostManager({
|
|
|
332
355
|
|
|
333
356
|
function killNow() {
|
|
334
357
|
shuttingDown = true;
|
|
358
|
+
for (const id of preparing.keys()) settleSpawn(id, new Error('Terminal host is shutting down'));
|
|
359
|
+
preparing.clear();
|
|
335
360
|
if (restartTimer) { clearTimeout(restartTimer); restartTimer = null; }
|
|
336
361
|
try { child?.kill('SIGTERM'); } catch {}
|
|
337
362
|
try { core?.shutdownAll(); } catch {}
|
|
@@ -10,7 +10,9 @@
|
|
|
10
10
|
// refuse, user allow rules included; routing always asks (one
|
|
11
11
|
// route card per task is the task's approval); workers get no
|
|
12
12
|
// computer, no "user-authorized-full" and a registered cwd.
|
|
13
|
-
// autonomous — the modes as configured
|
|
13
|
+
// autonomous — the modes as configured. On WhatsApp it stays until the owner
|
|
14
|
+
// lowers it in Settings; any other channel only until its
|
|
15
|
+
// autonomousUntil, then ask.
|
|
14
16
|
// Ask and Autonomous hold only on a Claude brain: its in-process PreToolUse
|
|
15
17
|
// hook sees every call with its arguments. A Codex or OpenCode brain runs
|
|
16
18
|
// ordinary commands inside its own sandbox / permissions without asking, so a
|
|
@@ -25,7 +27,7 @@
|
|
|
25
27
|
//
|
|
26
28
|
// Computer use (the Assistant's own computer tools) is off unless the owner
|
|
27
29
|
// turned on its switch at this computer (the policy's `computerUse`), and then
|
|
28
|
-
// only as remoteComputerUse says: unasked while Autonomous is
|
|
30
|
+
// only as remoteComputerUse says: unasked while Autonomous is on, after
|
|
29
31
|
// one yes per turn at Ask, never at Read-only, while paused or on a Codex /
|
|
30
32
|
// OpenCode brain. That function is the one place that decides; the runtime,
|
|
31
33
|
// the brain's hook, the desktop gate, the persona and the panel all ask it.
|
|
@@ -81,16 +83,17 @@ export class RemotePolicyError extends Error {
|
|
|
81
83
|
|
|
82
84
|
/**
|
|
83
85
|
* The level that applies now: null without a policy. Paused reads as
|
|
84
|
-
* read-only,
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
86
|
+
* read-only, a turn whose prompt carried untrusted content is capped at ask,
|
|
87
|
+
* and a session whose brain cannot hold Ask/Autonomous (`provider`, else the
|
|
88
|
+
* policy's brainProvider: Codex, OpenCode) is read-only. Autonomous on
|
|
89
|
+
* WhatsApp has no time limit (it stays until the owner lowers it); on any
|
|
90
|
+
* other channel an expired (or never armed) autonomousUntil reads as ask.
|
|
88
91
|
*/
|
|
89
92
|
export function effectiveLevel(policy, { untrusted = false, now = Date.now(), provider = null } = {}) {
|
|
90
93
|
if (!policy) return null;
|
|
91
94
|
let level = normalizeLevel(policy.level);
|
|
92
95
|
if (policy.paused === true) level = 'read-only';
|
|
93
|
-
if (level === 'autonomous') {
|
|
96
|
+
if (level === 'autonomous' && policy.channel !== 'whatsapp') {
|
|
94
97
|
const until = toMs(policy.autonomousUntil);
|
|
95
98
|
if (!(until > now)) level = 'ask';
|
|
96
99
|
}
|
|
@@ -139,7 +142,8 @@ export const COMPUTER_REASONS = Object.freeze({
|
|
|
139
142
|
* read_only the Read-only level (or a session nobody registered since a restart)
|
|
140
143
|
* unsupported, setup computer use is not available, or not set up, on this machine (`desktop`)
|
|
141
144
|
* ask ask the Ask level: one yes per turn turns it on for that turn
|
|
142
|
-
* autonomous_expired Autonomous is configured but its
|
|
145
|
+
* autonomous_expired Autonomous is configured but its autonomousUntil passed (or was never set): never
|
|
146
|
+
* on WhatsApp, where Autonomous has no time limit
|
|
143
147
|
* untrusted Autonomous is active, but this turn carries content the owner did not write
|
|
144
148
|
* allowed autonomous Autonomous is active: the computer tools run unasked
|
|
145
149
|
* `desktop`: { supported, ready } of the desktop service (omitted: not checked).
|
|
@@ -288,17 +292,20 @@ function defaultDataHome(env = process.env) {
|
|
|
288
292
|
if (osPlatform() === 'win32' && env.APPDATA) return resolve(env.APPDATA, 'synabun');
|
|
289
293
|
return resolve(homedir(), '.synabun');
|
|
290
294
|
}
|
|
291
|
-
/**
|
|
295
|
+
/**
|
|
296
|
+
* Every place the WhatsApp Link may keep its session and connector (lib/whatsapp/paths.js), the refused
|
|
297
|
+
* override too, and the voice-note folder whose programs the WhatsApp host runs (transcriptionDir).
|
|
298
|
+
*/
|
|
292
299
|
function whatsappLocations(dataHome, env, platform) {
|
|
293
300
|
const out = [];
|
|
294
301
|
try {
|
|
295
302
|
const wa = resolveWhatsAppPaths({ dataHome, env, platform });
|
|
296
|
-
out.push(wa.waHome, wa.defaultWaHome, wa.runtimeDir, wa.stagingDir);
|
|
303
|
+
out.push(wa.waHome, wa.defaultWaHome, wa.runtimeDir, wa.stagingDir, wa.transcriptionDir);
|
|
297
304
|
} catch {}
|
|
298
305
|
const override = typeof env.SYNABUN_WHATSAPP_HOME === 'string' ? env.SYNABUN_WHATSAPP_HOME.trim() : '';
|
|
299
306
|
if (override) out.push(resolve(override));
|
|
300
307
|
if (env.LOCALAPPDATA) out.push(resolve(env.LOCALAPPDATA, 'synabun', 'whatsapp'));
|
|
301
|
-
out.push(resolve(dataHome, 'whatsapp'), resolve(dataHome, 'runtime', 'whatsapp'));
|
|
308
|
+
out.push(resolve(dataHome, 'whatsapp'), resolve(dataHome, 'runtime', 'whatsapp'), resolve(dataHome, 'runtime', 'whatsapp-transcription'));
|
|
302
309
|
return [...new Set(out.filter(Boolean))];
|
|
303
310
|
}
|
|
304
311
|
const slash = (value) => String(value || '').replace(/\\/g, '/').replace(/\/{2,}/g, '/').toLowerCase();
|
|
@@ -359,6 +366,8 @@ const DENIED_PATTERNS = [
|
|
|
359
366
|
{ re: /\/etc\/cron|\/var\/at\/tabs|\/usr\/lib\/cron|\/var\/spool\/cron/, why: 'crontab' },
|
|
360
367
|
{ re: /\/api\/whatsapp\b/, why: 'the WhatsApp link' },
|
|
361
368
|
{ re: /(?:^|[^a-z0-9_-])runtime\/whatsapp\b/, why: 'the WhatsApp link' },
|
|
369
|
+
// The voice-note folder by name, wherever it sits (a relative path, a moved home): the WhatsApp host runs the programs in it.
|
|
370
|
+
{ re: /(?:^|[^a-z0-9_.-])whatsapp-transcription(?=$|[^a-z0-9_-])/, why: 'the WhatsApp link (voice-note programs)' },
|
|
362
371
|
{ re: /(?:^|[^a-z0-9_-])\.?synabun\/whatsapp\b/, why: 'the WhatsApp link' },
|
|
363
372
|
// The session store by name, wherever it sits (a relative path, a moved home): state.db and its -wal/-shm/-journal.
|
|
364
373
|
{ re: /(?:^|[^a-z0-9_.-])state\.db(?:-(?:wal|shm|journal))?(?=$|[^a-z0-9_.-])/, why: 'the WhatsApp login (state.db)' },
|