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
|
@@ -73,6 +73,74 @@ export function blobDelete(ns, id) {
|
|
|
73
73
|
d.prepare('DELETE FROM ui_blobs WHERE ns = ? AND id = ?').run(ns, id);
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
+
// ── Which of a page's requests for one entry is the newer ──
|
|
77
|
+
// A page numbers what it asks for (public/shared/blob-store.js: `rev`, counted up, and `writer`, the page's own
|
|
78
|
+
// id). The requests it sends while it is being left (a keepalive fetch, a beacon) reach the server in any order:
|
|
79
|
+
// a delete may arrive before the write it was meant to follow, an older write after a newer one. So what the
|
|
80
|
+
// store last did for a page is remembered here, entry by entry, a deletion too, and a request of that page with
|
|
81
|
+
// a number that is not higher is not applied.
|
|
82
|
+
//
|
|
83
|
+
// Remembered per namespace, entry and page. A request of another page, and one without a number, is applied as
|
|
84
|
+
// it arrives, as it always was, and takes nothing away from what is remembered: a page that deleted an entry
|
|
85
|
+
// with its request 2 does not get its request 1 applied because somebody else wrote in between. And remembered
|
|
86
|
+
// only once the store has done what was asked (`stale()` asks, `applied()` records): a write that failed has used
|
|
87
|
+
// up no number, and is applied when the page sends it again.
|
|
88
|
+
//
|
|
89
|
+
// Kept in memory for a quarter of an hour, far longer than a request of a page that is gone can still be on its
|
|
90
|
+
// way, and for at most BLOB_ORDER_MAX marks (those applied longest ago go first); a restart forgets all of it.
|
|
91
|
+
export const BLOB_ORDER_TTL_MS = 15 * 60_000;
|
|
92
|
+
const BLOB_ORDER_MAX = 5000;
|
|
93
|
+
const WRITER_RE = /^[A-Za-z0-9_-]{1,64}$/;
|
|
94
|
+
|
|
95
|
+
/** The revision a request carries in its query (`?rev=<n>&writer=<id>`), or null when it carries none that counts. */
|
|
96
|
+
export function blobRevision(query) {
|
|
97
|
+
const rev = Number(typeof query?.rev === 'string' ? query.rev : NaN);
|
|
98
|
+
const writer = query?.writer;
|
|
99
|
+
if (!Number.isSafeInteger(rev) || rev < 1 || typeof writer !== 'string' || !WRITER_RE.test(writer)) return null;
|
|
100
|
+
return { writer, rev };
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* The memory of what the store last did for each page, entry by entry.
|
|
105
|
+
* @param {{ now?: () => number, ttlMs?: number, max?: number }} [o]
|
|
106
|
+
* @returns {{
|
|
107
|
+
* stale: (ns: string, id: string, revision: { writer: string, rev: number } | null) => boolean,
|
|
108
|
+
* applied: (ns: string, id: string, revision: { writer: string, rev: number } | null) => void,
|
|
109
|
+
* size: () => number,
|
|
110
|
+
* }}
|
|
111
|
+
* `stale`: is this request older than (or the same as) what was last applied for its page and entry? It only
|
|
112
|
+
* asks: nothing is remembered of a request until `applied` is told that the store has done it. Both take a
|
|
113
|
+
* request without a revision (null): never stale, never remembered.
|
|
114
|
+
*/
|
|
115
|
+
export function createBlobOrder({ now = Date.now, ttlMs = BLOB_ORDER_TTL_MS, max = BLOB_ORDER_MAX } = {}) {
|
|
116
|
+
const marks = new Map(); // namespace, entry and page → { rev, at }, the one applied longest ago first
|
|
117
|
+
// Three parts that cannot run into one another: the first two are written with their lengths.
|
|
118
|
+
const keyOf = (ns, id, writer) => `${String(ns).length}:${ns}${String(id).length}:${id}${writer}`;
|
|
119
|
+
return {
|
|
120
|
+
stale(ns, id, revision) {
|
|
121
|
+
if (!revision) return false;
|
|
122
|
+
const mark = marks.get(keyOf(ns, id, revision.writer));
|
|
123
|
+
return !!mark && now() - mark.at < ttlMs && revision.rev <= mark.rev;
|
|
124
|
+
},
|
|
125
|
+
applied(ns, id, revision) {
|
|
126
|
+
if (!revision) return;
|
|
127
|
+
const at = now();
|
|
128
|
+
const key = keyOf(ns, id, revision.writer);
|
|
129
|
+
const mark = marks.get(key);
|
|
130
|
+
const rev = mark && at - mark.at < ttlMs ? Math.max(mark.rev, revision.rev) : revision.rev;
|
|
131
|
+
marks.delete(key);
|
|
132
|
+
marks.set(key, { rev, at });
|
|
133
|
+
// What has expired goes (it lies at the old end), then whatever is over the bound.
|
|
134
|
+
for (const [oldest, value] of marks) {
|
|
135
|
+
if (at - value.at < ttlMs) break;
|
|
136
|
+
marks.delete(oldest);
|
|
137
|
+
}
|
|
138
|
+
while (marks.size > max) marks.delete(marks.keys().next().value);
|
|
139
|
+
},
|
|
140
|
+
size: () => marks.size,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
|
|
76
144
|
export function blobClearNamespace(ns) {
|
|
77
145
|
const d = getBlobDb();
|
|
78
146
|
const result = d.prepare('DELETE FROM ui_blobs WHERE ns = ?').run(ns);
|
|
@@ -15,7 +15,17 @@ export const OPEN = 1;
|
|
|
15
15
|
export const CLOSING = 2;
|
|
16
16
|
export const CLOSED = 3;
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
// A brain's credential (assistant-runtime.js mintBrainCredential), kept beside the socket object
|
|
19
|
+
// that server code built: a client's WebSocket never has one, and nothing a client sends can set
|
|
20
|
+
// it. The Codex skin handler reads it here (brainCredentialOf), never from a message.
|
|
21
|
+
const credentials = new WeakMap();
|
|
22
|
+
|
|
23
|
+
/** The credential the server attached to this in-process socket, or null (always null for a client's socket). */
|
|
24
|
+
export function brainCredentialOf(socket) {
|
|
25
|
+
return (socket && credentials.get(socket)) || null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function createVirtualSocket({ onSend = () => {}, name = 'virtual', credential = null } = {}) {
|
|
19
29
|
const emitter = new EventEmitter();
|
|
20
30
|
emitter.setMaxListeners(50);
|
|
21
31
|
const socket = {
|
|
@@ -56,5 +66,6 @@ export function createVirtualSocket({ onSend = () => {}, name = 'virtual' } = {}
|
|
|
56
66
|
emit: (...args) => emitter.emit(...args),
|
|
57
67
|
listenerCount: (type) => emitter.listenerCount(type),
|
|
58
68
|
};
|
|
69
|
+
if (typeof credential === 'string' && credential) credentials.set(socket, credential);
|
|
59
70
|
return socket;
|
|
60
71
|
}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import { existsSync, readFileSync } from 'node:fs';
|
|
8
8
|
import { join } from 'node:path';
|
|
9
9
|
import { pathToFileURL } from 'node:url';
|
|
10
|
-
import { CONN, ERR, LIMITS } from './protocol.js';
|
|
10
|
+
import { CONN, CONN_WARNINGS, ERR, LIMITS, VOICE_MARKER } from './protocol.js';
|
|
11
11
|
import { parseJid, sameAccount } from './identity.js';
|
|
12
12
|
import { redactWa } from './redact.js';
|
|
13
13
|
|
|
@@ -18,7 +18,7 @@ export const RUNTIME_EXPORTS = Object.freeze([
|
|
|
18
18
|
]);
|
|
19
19
|
|
|
20
20
|
const QUOTED_MAX = 1000;
|
|
21
|
-
const DOWNLOAD_TIMEOUT_MS = 30_000;
|
|
21
|
+
export const DOWNLOAD_TIMEOUT_MS = 30_000;
|
|
22
22
|
const VERSION_RECHECK_MS = 6 * 3600_000;
|
|
23
23
|
|
|
24
24
|
function adapterError(code, message, cause) {
|
|
@@ -235,68 +235,103 @@ export function disconnectCode(err) {
|
|
|
235
235
|
return null;
|
|
236
236
|
}
|
|
237
237
|
|
|
238
|
+
// Baileys 7.0.0-rc14 (the pinned connector) closes with 500 for more than a
|
|
239
|
+
// bad session: 500 is DisconnectReason.badSession, but it is also the code
|
|
240
|
+
// getErrorCodeFromStreamError (Utils/generics.js) gives any <stream:error>
|
|
241
|
+
// without a code of its own ("Stream Errored (<first child tag>)", the child
|
|
242
|
+
// node in `data`), the code getCodeFromWSError gives a WebSocket error it
|
|
243
|
+
// cannot place ("WebSocket Error (…)"), and the default of a <failure> without
|
|
244
|
+
// a reason ("Connection Failure"). Baileys itself never names a bad session:
|
|
245
|
+
// only WhatsApp's own stream-error child tag can, and only that wipes the
|
|
246
|
+
// saved credentials. Every other 500 is transport noise and is retried.
|
|
247
|
+
const STREAM_ERROR = /^Stream Errored \(/;
|
|
248
|
+
const INVALID_SESSION_TAG = /\b(?:bad[-_ ]?session|not[-_ ]?authori[sz]ed|invalid[-_ ]?session)\b/i;
|
|
249
|
+
|
|
250
|
+
/** WhatsApp said the saved session is invalid: a stream error whose reason tag names it (`<not-authorized/>`). */
|
|
251
|
+
export function invalidSessionSignal(err) {
|
|
252
|
+
const message = typeof err?.message === 'string' ? err.message : '';
|
|
253
|
+
if (!STREAM_ERROR.test(message)) return false;
|
|
254
|
+
const tag = typeof err?.data?.tag === 'string' ? err.data.tag : '';
|
|
255
|
+
return INVALID_SESSION_TAG.test(`${message} ${tag}`);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/** Which kind of generic 500 this is (the reason a log line and lastDisconnect carry). */
|
|
259
|
+
function transportReason(err) {
|
|
260
|
+
const message = typeof err?.message === 'string' ? err.message : '';
|
|
261
|
+
if (STREAM_ERROR.test(message)) return 'stream_error';
|
|
262
|
+
if (/^WebSocket Error \(/.test(message)) return 'websocket_error';
|
|
263
|
+
if (/^Connection Failure\b/.test(message)) return 'connection_failure';
|
|
264
|
+
return 'status_500';
|
|
265
|
+
}
|
|
266
|
+
|
|
238
267
|
/**
|
|
239
268
|
* Map a lastDisconnect error to what the host does next, by DisconnectReason
|
|
240
269
|
* NAME (408 is both connectionLost and timedOut; the enum's reverse map says
|
|
241
|
-
* timedOut).
|
|
242
|
-
*
|
|
270
|
+
* timedOut). A saved session never gives up on its own: only 401 (logged out)
|
|
271
|
+
* and an explicitly invalid session stop it, and both wipe the credentials.
|
|
272
|
+
* 440 and 403 retry from the longest delay (`delay: 'long'`) and carry a
|
|
273
|
+
* `warning` the service shows (CONN_WARNINGS). While linking (no saved
|
|
274
|
+
* session) anything but 515, 405, 401 and 403 means the QR or code ran out.
|
|
275
|
+
* @returns {{action:'reconnect_now'|'refresh_version'|'backoff'|'stop', state:string, wipe:boolean, reason:string, code:number|null,
|
|
276
|
+
* delay?:'long', warning?:'replaced'|'forbidden'}}
|
|
243
277
|
*/
|
|
244
278
|
export function classifyDisconnect(err, { linking = false, DisconnectReason = {} } = {}) {
|
|
245
279
|
const code = disconnectCode(err);
|
|
246
280
|
const name = code !== null && typeof DisconnectReason[code] === 'string' ? DisconnectReason[code] : null;
|
|
247
|
-
const out = (action, state, wipe, reason) => ({ action, state, wipe, reason, code });
|
|
281
|
+
const out = (action, state, wipe, reason, extra = null) => ({ action, state, wipe, reason, code, ...(extra || {}) });
|
|
282
|
+
// 500: an explicit bad session, or noise (a generic stream / WebSocket / failure error).
|
|
283
|
+
const reason = name === 'badSession' ? (invalidSessionSignal(err) ? 'badSession' : transportReason(err)) : name;
|
|
248
284
|
if (code === 405) return out('refresh_version', linking ? CONN.CONNECTING : CONN.RECONNECTING, false, 'outdated_version');
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
default:
|
|
262
|
-
// timedOut / connectionLost / connectionClosed / unavailableService /
|
|
263
|
-
// anything unknown. While linking that means the QR or code ran out:
|
|
264
|
-
// stop instead of looping through fresh QR codes.
|
|
265
|
-
if (linking) return out('stop', CONN.LINK_EXPIRED, true, name || 'link_failed');
|
|
266
|
-
return out('backoff', CONN.RECONNECTING, false, name || (code === null ? 'closed' : `status_${code}`));
|
|
285
|
+
if (name === 'restartRequired') return out('reconnect_now', CONN.CONNECTING, false, name);
|
|
286
|
+
if (name === 'loggedOut') return out('stop', CONN.LOGGED_OUT, true, name);
|
|
287
|
+
if (linking) {
|
|
288
|
+
if (name === 'forbidden') return out('stop', CONN.FORBIDDEN, false, name);
|
|
289
|
+
// A timeout or a closed stream means the QR / code ran out: stop instead of looping through fresh QR codes.
|
|
290
|
+
return out('stop', CONN.LINK_EXPIRED, true, reason || 'link_failed');
|
|
291
|
+
}
|
|
292
|
+
if (reason === 'badSession') return out('stop', CONN.LOGGED_OUT, true, reason);
|
|
293
|
+
const warning = CONN_WARNINGS[code];
|
|
294
|
+
if (warning) {
|
|
295
|
+
// Two copies of one session would kick each other every few seconds, and a refused account is not hammered.
|
|
296
|
+
return out('backoff', CONN.RECONNECTING, false, name || `status_${code}`, { delay: 'long', warning });
|
|
267
297
|
}
|
|
298
|
+
// timedOut / connectionLost / connectionClosed / unavailableService / multideviceMismatch /
|
|
299
|
+
// a generic 500 / anything unknown: keep the credentials and try again.
|
|
300
|
+
return out('backoff', CONN.RECONNECTING, false, reason || (code === null ? 'closed' : `status_${code}`));
|
|
268
301
|
}
|
|
269
302
|
|
|
270
303
|
/**
|
|
271
|
-
* Reconnect delays 2/
|
|
272
|
-
*
|
|
304
|
+
* Reconnect delays 2/4/8/16/32/64/128/256/300 s, each ±20% and never above
|
|
305
|
+
* 300 s; the ladder starts over after 10 minutes connected (noteStable). It
|
|
306
|
+
* never gives up. `next({ long: true })` (440, 403) goes to the top at once and
|
|
307
|
+
* stays there until that stable connection: after a session another copy took
|
|
308
|
+
* or an account WhatsApp refused, any drop waits the long delay (a refused
|
|
309
|
+
* account may fail in other ways too, and two copies must not trade quick
|
|
310
|
+
* retries), the same 10 minutes that end the warning Settings shows.
|
|
273
311
|
*/
|
|
274
312
|
export function createReconnectPolicy({
|
|
275
|
-
now = () => Date.now(),
|
|
276
313
|
rng = Math.random,
|
|
277
|
-
scheduleSec = [2,
|
|
314
|
+
scheduleSec = [2, 4, 8, 16, 32, 64, 128, 256, 300],
|
|
278
315
|
jitter = 0.2,
|
|
279
|
-
|
|
280
|
-
windowMs = 10 * 60_000,
|
|
316
|
+
maxMs = 300_000,
|
|
281
317
|
} = {}) {
|
|
282
318
|
let idx = 0;
|
|
283
|
-
let attempts =
|
|
319
|
+
let attempts = 0;
|
|
284
320
|
return {
|
|
285
|
-
/** @returns {{delayMs:number}
|
|
286
|
-
next() {
|
|
287
|
-
|
|
288
|
-
attempts = attempts.filter((a) => t - a < windowMs);
|
|
289
|
-
if (attempts.length >= limit) return { giveUp: true };
|
|
290
|
-
attempts.push(t);
|
|
321
|
+
/** @returns {{delayMs:number}} */
|
|
322
|
+
next({ long = false } = {}) {
|
|
323
|
+
if (long) idx = Math.max(idx, scheduleSec.length - 1);
|
|
291
324
|
const base = scheduleSec[Math.min(idx, scheduleSec.length - 1)] * 1000;
|
|
292
325
|
idx += 1;
|
|
326
|
+
attempts += 1;
|
|
293
327
|
const factor = 1 + (rng() * 2 - 1) * jitter;
|
|
294
|
-
return { delayMs: Math.max(0, Math.round(base * factor)) };
|
|
328
|
+
return { delayMs: Math.min(maxMs, Math.max(0, Math.round(base * factor))) };
|
|
295
329
|
},
|
|
296
330
|
/** Connected long enough: start the ladder over. */
|
|
297
331
|
noteStable() { idx = 0; },
|
|
298
|
-
reset() { idx = 0; attempts =
|
|
299
|
-
|
|
332
|
+
reset() { idx = 0; attempts = 0; },
|
|
333
|
+
/** Retries scheduled since the last reset (an explicit connect). */
|
|
334
|
+
get attempts() { return attempts; },
|
|
300
335
|
};
|
|
301
336
|
}
|
|
302
337
|
|
|
@@ -323,8 +358,8 @@ const DROP_TYPES = Object.freeze({
|
|
|
323
358
|
stickerPackMessage: 'sticker',
|
|
324
359
|
});
|
|
325
360
|
|
|
361
|
+
// audioMessage (voice notes and audio files) is kind 'audio': transcribed on this computer (transcription.js).
|
|
326
362
|
const UNSUPPORTED = Object.freeze({
|
|
327
|
-
audioMessage: 'audio',
|
|
328
363
|
videoMessage: 'video',
|
|
329
364
|
ptvMessage: 'video',
|
|
330
365
|
documentMessage: 'document',
|
|
@@ -347,7 +382,7 @@ function captionOf(inner) {
|
|
|
347
382
|
|
|
348
383
|
/**
|
|
349
384
|
* Classify the content of one message without downloading anything.
|
|
350
|
-
* @returns {{drop:string} | {type:string, kind:'text'|'image'|'unsupported', inner:object|null,
|
|
385
|
+
* @returns {{drop:string} | {type:string, kind:'text'|'image'|'audio'|'unsupported', inner:object|null,
|
|
351
386
|
* contextInfo:object|null, text:string, unsupportedType:string|null}}
|
|
352
387
|
*/
|
|
353
388
|
export function describeContent(msg, mod) {
|
|
@@ -370,6 +405,9 @@ export function describeContent(msg, mod) {
|
|
|
370
405
|
if (type === 'imageMessage') {
|
|
371
406
|
return { type, kind: 'image', inner, contextInfo, text: captionOf(inner), unsupportedType: null };
|
|
372
407
|
}
|
|
408
|
+
if (type === 'audioMessage') {
|
|
409
|
+
return { type, kind: 'audio', inner, contextInfo, text: captionOf(inner), unsupportedType: null };
|
|
410
|
+
}
|
|
373
411
|
return { type, kind: 'unsupported', inner, contextInfo, text: captionOf(inner), unsupportedType: UNSUPPORTED[type] || 'other' };
|
|
374
412
|
}
|
|
375
413
|
|
|
@@ -401,13 +439,65 @@ function withTimeout(promise, ms, label) {
|
|
|
401
439
|
|
|
402
440
|
const MSG_ID_RE = /^[A-Za-z0-9._:+/=-]{1,128}$/;
|
|
403
441
|
|
|
442
|
+
/** A size or duration a message declares about itself (a number, a protobuf Long, a string), or null when it says none. */
|
|
443
|
+
function declared(value) {
|
|
444
|
+
if (value === null || value === undefined || value === '') return null;
|
|
445
|
+
let n = NaN;
|
|
446
|
+
if (typeof value === 'number') n = value;
|
|
447
|
+
else if (typeof value === 'bigint' || typeof value === 'string') n = Number(value);
|
|
448
|
+
else if (typeof value?.toNumber === 'function') { try { n = value.toNumber(); } catch { n = NaN; } }
|
|
449
|
+
return Number.isFinite(n) && n >= 0 ? n : null;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* A voice note or audio file (kind 'audio'), only for a message host-core already accepted:
|
|
454
|
+
* → { transcript, recorded } or { unsupported: { type: 'audio', reason } }. `recorded`: a voice note
|
|
455
|
+
* the sender recorded in WhatsApp (ptt), not an audio file attached to the chat. Nothing is downloaded while
|
|
456
|
+
* transcription is off or cannot run here, or when the message says it is over a limit.
|
|
457
|
+
* transcriber transcription.js createTranscriber() (enabled, available(), transcribe())
|
|
458
|
+
* stale sent so long ago that the bridge will skip it anyway: not worth transcribing
|
|
459
|
+
*/
|
|
460
|
+
async function readAudio(msg, { mod, sock, logger, inner, transcriber, stale }) {
|
|
461
|
+
const refuse = (reason) => ({ unsupported: { type: 'audio', reason } });
|
|
462
|
+
if (!transcriber || !transcriber.enabled) return refuse('transcription_disabled');
|
|
463
|
+
let ready = false;
|
|
464
|
+
try { ready = transcriber.available() === true; } catch { ready = false; }
|
|
465
|
+
if (!ready) return refuse('transcription_unavailable');
|
|
466
|
+
if ((declared(inner?.fileLength) ?? 0) > LIMITS.MAX_AUDIO_BYTES) return refuse('too_large');
|
|
467
|
+
if ((declared(inner?.seconds) ?? 0) > LIMITS.MAX_AUDIO_SECONDS) return refuse('too_long');
|
|
468
|
+
if (stale) return refuse('stale');
|
|
469
|
+
let bytes;
|
|
470
|
+
try {
|
|
471
|
+
const buf = await withTimeout(
|
|
472
|
+
mod.downloadMediaMessage(msg, 'buffer', {}, { logger, reuploadRequest: sock?.updateMediaMessage }),
|
|
473
|
+
DOWNLOAD_TIMEOUT_MS,
|
|
474
|
+
'audio download',
|
|
475
|
+
);
|
|
476
|
+
bytes = Buffer.isBuffer(buf) ? buf : Buffer.from(buf || []);
|
|
477
|
+
} catch {
|
|
478
|
+
return refuse('transcription_failed');
|
|
479
|
+
}
|
|
480
|
+
if (bytes.length > LIMITS.MAX_AUDIO_BYTES) return refuse('too_large');
|
|
481
|
+
if (!bytes.length) return refuse('transcription_failed');
|
|
482
|
+
let result = null;
|
|
483
|
+
try { result = await transcriber.transcribe(bytes); } catch { result = null; }
|
|
484
|
+
if (result?.ok && typeof result.text === 'string' && result.text.trim()) return { transcript: result.text.trim(), recorded: inner?.ptt === true };
|
|
485
|
+
// Turned off while the note waited its turn: said as such, not as a failure.
|
|
486
|
+
return refuse(['too_long', 'too_large', 'transcription_disabled'].includes(result?.reason) ? result.reason : 'transcription_failed');
|
|
487
|
+
}
|
|
488
|
+
|
|
404
489
|
/**
|
|
405
490
|
* Turn an accepted message into the parts of an InboundMessage (never a JID).
|
|
406
|
-
*
|
|
491
|
+
* A transcribed voice note: `text` is VOICE_MARKER + the transcript, then "\n" + the caption when
|
|
492
|
+
* there is one (the transcript first when the text is cut), and `voice: true`; `audioFile: true` when
|
|
493
|
+
* it is an audio file rather than a note recorded in WhatsApp (its words may be anyone's: the bridge
|
|
494
|
+
* treats it like a picture).
|
|
495
|
+
* @returns {Promise<{text:string, images:Array, unsupported:null|{type:string, reason?:string}, forwarded:boolean,
|
|
496
|
+
* quoted:null|{id:string,text:string,fromBot:boolean}, voice:boolean, audioFile:boolean}>}
|
|
407
497
|
*/
|
|
408
|
-
export async function extractInbound(msg, { mod, sock, logger, sentIds, described, text }) {
|
|
498
|
+
export async function extractInbound(msg, { mod, sock, logger, sentIds, described, text, transcriber = null, audioStale = false }) {
|
|
409
499
|
const d = described;
|
|
410
|
-
|
|
500
|
+
let body = String(text ?? d.text ?? '').slice(0, LIMITS.MAX_INBOUND_TEXT);
|
|
411
501
|
const ctx = d.contextInfo;
|
|
412
502
|
const forwarded = !!(ctx && (ctx.isForwarded || Number(ctx.forwardingScore) > 0));
|
|
413
503
|
let quoted = null;
|
|
@@ -420,7 +510,21 @@ export async function extractInbound(msg, { mod, sock, logger, sentIds, describe
|
|
|
420
510
|
}
|
|
421
511
|
const images = [];
|
|
422
512
|
let unsupported = null;
|
|
513
|
+
let voice = false;
|
|
514
|
+
let audioFile = false;
|
|
423
515
|
if (d.kind === 'unsupported') unsupported = { type: d.unsupportedType };
|
|
516
|
+
if (d.kind === 'audio') {
|
|
517
|
+
const audio = await readAudio(msg, { mod, sock, logger, inner: d.inner, transcriber, stale: audioStale });
|
|
518
|
+
if (audio.transcript) {
|
|
519
|
+
const caption = String(text ?? d.text ?? '');
|
|
520
|
+
body = `${VOICE_MARKER} ${audio.transcript}${caption.trim() ? `\n${caption}` : ''}`.slice(0, LIMITS.MAX_INBOUND_TEXT);
|
|
521
|
+
voice = true;
|
|
522
|
+
audioFile = !audio.recorded;
|
|
523
|
+
} else {
|
|
524
|
+
// The same unsupported-audio shape as before, with why; a caption still gets through.
|
|
525
|
+
unsupported = audio.unsupported;
|
|
526
|
+
}
|
|
527
|
+
}
|
|
424
528
|
if (d.kind === 'image') {
|
|
425
529
|
const mime = String(d.inner?.mimetype || '').split(';')[0].trim().toLowerCase();
|
|
426
530
|
const declared = Number(d.inner?.fileLength ?? 0);
|
|
@@ -443,7 +547,23 @@ export async function extractInbound(msg, { mod, sock, logger, sentIds, describe
|
|
|
443
547
|
}
|
|
444
548
|
}
|
|
445
549
|
}
|
|
446
|
-
return { text: body, images, unsupported, forwarded, quoted };
|
|
550
|
+
return { text: body, images, unsupported, forwarded, quoted, voice, audioFile };
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
/**
|
|
554
|
+
* The sendMessage content for a file prepared by local-file.js (prepareLocalFile): a document
|
|
555
|
+
* (mimetype + fileName, the caption when there is one), a photo or a video (the caption), or audio
|
|
556
|
+
* (never a caption, never a voice note). `jpegThumbnail: null` keeps Baileys from building a preview,
|
|
557
|
+
* which for a video means running FFmpeg through a shell: SynaBun never decodes the file it sends.
|
|
558
|
+
*/
|
|
559
|
+
export function fileMessage(file) {
|
|
560
|
+
const caption = typeof file?.caption === 'string' && file.caption ? { caption: file.caption } : {};
|
|
561
|
+
switch (file?.type) {
|
|
562
|
+
case 'image': return { image: file.data, mimetype: file.mimetype, jpegThumbnail: null, ...caption };
|
|
563
|
+
case 'video': return { video: file.data, mimetype: file.mimetype, jpegThumbnail: null, ...caption };
|
|
564
|
+
case 'audio': return { audio: file.data, mimetype: file.mimetype, ptt: false };
|
|
565
|
+
default: return { document: file.data, mimetype: file.mimetype, fileName: file.fileName || 'file', ...caption };
|
|
566
|
+
}
|
|
447
567
|
}
|
|
448
568
|
|
|
449
569
|
/** The minimal message Baileys needs to quote an owner message in a reply. */
|