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
|
@@ -10,13 +10,24 @@
|
|
|
10
10
|
// resources are symlinked back to ~/.claude so skills/commands/settings stay in
|
|
11
11
|
// sync; identity-bearing files stay isolated.
|
|
12
12
|
//
|
|
13
|
-
//
|
|
13
|
+
// Default follows CLAUDE_CONFIG_DIR when set, otherwise ~/.claude.
|
|
14
|
+
//
|
|
15
|
+
// One account, two credentials, one mode (docs/claude-sidepanel.md → Claude
|
|
16
|
+
// accounts). Each account can hold a Claude subscription login (Claude Code's
|
|
17
|
+
// own OAuth, inside that account's config directory) and an API key (SynaBun's
|
|
18
|
+
// `.synabun-api-key` file in the same directory). Its mode, "subscription" or
|
|
19
|
+
// "apiKey", decides what its sessions use; when only one credential exists,
|
|
20
|
+
// that one is the mode. describe() is the one reading of an account's state:
|
|
21
|
+
// the account list, the panel's sign-in screens, its composer picker, the
|
|
22
|
+
// Assistant's brain picker, the catalog and worker dispatch all show it.
|
|
23
|
+
// launchFor() is the one place a Claude Code process gets its credential.
|
|
14
24
|
|
|
15
25
|
import {
|
|
16
|
-
|
|
26
|
+
existsSync, lstatSync, mkdirSync, readFileSync, renameSync, rmSync, statSync, symlinkSync, writeFileSync,
|
|
17
27
|
} from 'node:fs';
|
|
18
28
|
import { dirname, resolve } from 'node:path';
|
|
19
29
|
import { homedir } from 'node:os';
|
|
30
|
+
import { readClaudeProfileApiKey, saveClaudeProfileApiKey, clearClaudeProfileApiKey } from './claude-profile-api-key.js';
|
|
20
31
|
|
|
21
32
|
export const DEFAULT_ACCOUNT_ID = 'default';
|
|
22
33
|
// `rules` carries SynaBun's rules file (rules/synabun.md) to accounts created
|
|
@@ -26,6 +37,18 @@ export const SHARED_LINKS = ['settings.json', 'CLAUDE.md', 'rules', 'commands',
|
|
|
26
37
|
export const ISOLATED_ITEMS = ['.credentials.json', '.claude.json', 'projects', 'todos', 'history.jsonl', 'statsig', 'shell-snapshots', 'plans'];
|
|
27
38
|
const CLAUDE_JSON_WHITELIST = ['mcpServers', 'theme', 'editorMode', 'preferredNotifChannel', 'autoUpdates', 'verbose'];
|
|
28
39
|
|
|
40
|
+
export const CLAUDE_AUTH_MODES = Object.freeze(['subscription', 'apiKey']);
|
|
41
|
+
// Everything inherited from the server's own environment that would decide a
|
|
42
|
+
// Claude Code process's credential or backend. Removed from every account
|
|
43
|
+
// launch: the account and its mode decide, never what SynaBun was started with.
|
|
44
|
+
export const CLAUDE_CREDENTIAL_ENV = Object.freeze([
|
|
45
|
+
'ANTHROPIC_API_KEY', 'ANTHROPIC_API_KEY_FILE_DESCRIPTOR', 'ANTHROPIC_AUTH_TOKEN',
|
|
46
|
+
'CLAUDE_CODE_OAUTH_TOKEN', 'CLAUDE_CODE_OAUTH_TOKEN_FILE_DESCRIPTOR',
|
|
47
|
+
'CLAUDE_CODE_USE_BEDROCK', 'CLAUDE_CODE_USE_VERTEX', 'CLAUDE_CODE_USE_FOUNDRY',
|
|
48
|
+
]);
|
|
49
|
+
// A subscription check older than this is asked again when the list is read.
|
|
50
|
+
const STATUS_MAX_AGE_MS = 5 * 60_000;
|
|
51
|
+
|
|
29
52
|
export class ClaudeAccountError extends Error {
|
|
30
53
|
constructor(code, message, status = 400) {
|
|
31
54
|
super(message);
|
|
@@ -49,11 +72,22 @@ function sanitizeLabel(value, fallback = 'Claude account') {
|
|
|
49
72
|
const label = String(value || '').replace(/[\r\n\t]/g, ' ').trim().slice(0, 80);
|
|
50
73
|
return label || fallback;
|
|
51
74
|
}
|
|
75
|
+
const text = (value, max = 200) => (typeof value === 'string' && value.trim() ? value.trim().slice(0, max) : null);
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Claude Code's global config file (`.claude.json`, where `oauthAccount` lives)
|
|
79
|
+
* for a config directory. An explicit CLAUDE_CONFIG_DIR keeps it inside that
|
|
80
|
+
* directory; the ambient default keeps it in the home directory, next to
|
|
81
|
+
* ~/.claude rather than inside it (the CLI's own layout).
|
|
82
|
+
*/
|
|
83
|
+
export function claudeGlobalConfigFile(configDir, { ambient = false, homeDir = homedir() } = {}) {
|
|
84
|
+
return ambient ? resolve(homeDir, '.claude.json') : resolve(configDir, '.claude.json');
|
|
85
|
+
}
|
|
52
86
|
|
|
53
87
|
/** Read the OAuth identity Claude Code records after login. */
|
|
54
|
-
export function readClaudeIdentity(configDir) {
|
|
55
|
-
if (!configDir) return null;
|
|
56
|
-
const data = readJson(resolve(configDir, '.claude.json'), null);
|
|
88
|
+
export function readClaudeIdentity(configDir, file = null) {
|
|
89
|
+
if (!configDir && !file) return null;
|
|
90
|
+
const data = readJson(file || resolve(configDir, '.claude.json'), null);
|
|
57
91
|
const account = data?.oauthAccount;
|
|
58
92
|
if (!account || typeof account !== 'object') return null;
|
|
59
93
|
return {
|
|
@@ -63,58 +97,312 @@ export function readClaudeIdentity(configDir) {
|
|
|
63
97
|
};
|
|
64
98
|
}
|
|
65
99
|
|
|
100
|
+
/** What an API key is shown as: never the key, never its prefix. */
|
|
101
|
+
export function apiKeyHint(key) {
|
|
102
|
+
return typeof key === 'string' && key.length >= 8 ? `…${key.slice(-4)}` : null;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* The mode an account's sessions use, from its stored choice and the
|
|
107
|
+
* credentials it holds. `subscription` is true (signed in), false (confirmed
|
|
108
|
+
* signed out) or null (not known yet). A stored key with an unconfirmed
|
|
109
|
+
* subscription keeps the key unless the user chose the subscription; both
|
|
110
|
+
* present with no choice keeps the key, which is what SynaBun did before modes.
|
|
111
|
+
*/
|
|
112
|
+
export function resolveClaudeAuth({ preferredMode = null, hasKey = false, subscription = null } = {}) {
|
|
113
|
+
const preferred = CLAUDE_AUTH_MODES.includes(preferredMode) ? preferredMode : null;
|
|
114
|
+
let mode = null;
|
|
115
|
+
if (hasKey && subscription === true) mode = preferred || 'apiKey';
|
|
116
|
+
else if (hasKey) mode = preferred === 'subscription' && subscription !== false ? 'subscription' : 'apiKey';
|
|
117
|
+
else if (subscription !== false) mode = 'subscription';
|
|
118
|
+
const signedIn = mode === 'apiKey' ? true : mode === 'subscription' ? subscription : false;
|
|
119
|
+
return { mode, signedIn, switchable: hasKey && subscription === true };
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/** A launch environment applied to a base: inherited credentials out, the account's in. */
|
|
123
|
+
export function applyClaudeLaunchEnv(base, launch) {
|
|
124
|
+
const env = { ...(base || {}) };
|
|
125
|
+
for (const key of launch?.unset || CLAUDE_CREDENTIAL_ENV) delete env[key];
|
|
126
|
+
return Object.assign(env, launch?.env || {});
|
|
127
|
+
}
|
|
128
|
+
|
|
66
129
|
export function createClaudeAccounts({
|
|
67
130
|
dataHome,
|
|
68
131
|
homeDir = homedir(),
|
|
132
|
+
env = process.env,
|
|
69
133
|
accountsRoot = null,
|
|
70
134
|
log = () => {},
|
|
71
135
|
now = Date.now,
|
|
72
136
|
pollIntervalMs = 2000,
|
|
137
|
+
// async (id) => Claude Code's own `auth status --json` for that account
|
|
138
|
+
// ({ loggedIn, email, orgName, subscriptionType, authMethod }), or null.
|
|
139
|
+
readNativeStatus = null,
|
|
140
|
+
statusTimeoutMs = 20_000,
|
|
73
141
|
} = {}) {
|
|
74
142
|
if (!dataHome) throw new Error('createClaudeAccounts requires dataHome');
|
|
75
143
|
const registryPath = resolve(dataHome, 'data', 'claude-accounts.json');
|
|
76
|
-
const
|
|
144
|
+
const configDir = env.CLAUDE_CONFIG_DIR;
|
|
145
|
+
const defaultHome = resolve(configDir || resolve(homeDir, '.claude'));
|
|
146
|
+
const defaultConfigFile = claudeGlobalConfigFile(defaultHome, { ambient: !configDir, homeDir });
|
|
77
147
|
const root = accountsRoot || resolve(homeDir, '.claude-accounts');
|
|
148
|
+
// id → the last answer of Claude Code's own status check (never a credential).
|
|
149
|
+
const nativeStatus = new Map();
|
|
150
|
+
const refreshing = new Map();
|
|
151
|
+
const listeners = new Set();
|
|
152
|
+
let nativeReader = typeof readNativeStatus === 'function' ? readNativeStatus : null;
|
|
78
153
|
|
|
154
|
+
function configFileOf(id, home) { return id === DEFAULT_ACCOUNT_ID ? defaultConfigFile : resolve(home, '.claude.json'); }
|
|
79
155
|
function defaultAccount() {
|
|
80
|
-
const identity = readClaudeIdentity(defaultHome);
|
|
156
|
+
const identity = readClaudeIdentity(defaultHome, defaultConfigFile);
|
|
81
157
|
return { id: DEFAULT_ACCOUNT_ID, label: 'Default', email: identity?.email || null, organization: identity?.organization || null, home: defaultHome, builtin: true, createdAt: null };
|
|
82
158
|
}
|
|
83
159
|
function load() {
|
|
84
160
|
const data = readJson(registryPath, null);
|
|
85
161
|
const accounts = Array.isArray(data?.accounts) ? data.accounts.filter((row) => row?.id && row.id !== DEFAULT_ACCOUNT_ID) : [];
|
|
86
|
-
|
|
162
|
+
const defaults = data?.default && typeof data.default === 'object' ? data.default : {};
|
|
163
|
+
return { accounts, defaultId: DEFAULT_ACCOUNT_ID, default: defaults };
|
|
164
|
+
}
|
|
165
|
+
function save(data) {
|
|
166
|
+
writeJsonAtomic(registryPath, { accounts: data.accounts, defaultId: DEFAULT_ACCOUNT_ID, default: data.default || {}, updatedAt: new Date(now()).toISOString() });
|
|
167
|
+
}
|
|
168
|
+
function storedMode(data, id) {
|
|
169
|
+
const mode = id === DEFAULT_ACCOUNT_ID ? data.default?.authMode : data.accounts.find((row) => row.id === id)?.authMode;
|
|
170
|
+
return CLAUDE_AUTH_MODES.includes(mode) ? mode : null;
|
|
87
171
|
}
|
|
88
|
-
function save(data) { writeJsonAtomic(registryPath, { accounts: data.accounts, defaultId: DEFAULT_ACCOUNT_ID, updatedAt: new Date(now()).toISOString() }); }
|
|
89
172
|
|
|
90
|
-
|
|
173
|
+
// Terminal login needs only registry metadata, without reading CLI identity files.
|
|
174
|
+
function profileFor(id) {
|
|
175
|
+
if (id === DEFAULT_ACCOUNT_ID) return { id, home: defaultHome };
|
|
176
|
+
return load().accounts.find(row => row.id === id) || null;
|
|
177
|
+
}
|
|
178
|
+
function keyHome(id) {
|
|
179
|
+
const row = profileFor(id);
|
|
180
|
+
if (!row || row.id !== id) throw new ClaudeAccountError('ACCOUNT_NOT_FOUND', 'Unknown Claude account', 404);
|
|
181
|
+
return row.home;
|
|
182
|
+
}
|
|
183
|
+
function readApiKey(id) { return readClaudeProfileApiKey(keyHome(id)); }
|
|
184
|
+
function saveApiKey(id, key) {
|
|
185
|
+
saveClaudeProfileApiKey(keyHome(id), key);
|
|
186
|
+
// A key just pasted is what the user wants this account to use.
|
|
187
|
+
writeMode(id, 'apiKey');
|
|
188
|
+
emit(id);
|
|
189
|
+
}
|
|
190
|
+
function clearApiKey(id) {
|
|
191
|
+
clearClaudeProfileApiKey(keyHome(id));
|
|
91
192
|
const data = load();
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
return { ...row, email: identity?.email || row.email || null, organization: identity?.organization || row.organization || null, builtin: false, loggedIn: !!identity?.email };
|
|
95
|
-
});
|
|
96
|
-
const base = defaultAccount();
|
|
97
|
-
return [{ ...base, loggedIn: !!base.email }, ...rows];
|
|
193
|
+
if (storedMode(data, id) === 'apiKey') writeMode(id, null, data);
|
|
194
|
+
emit(id);
|
|
98
195
|
}
|
|
99
|
-
|
|
100
|
-
|
|
196
|
+
// The key itself only for a launch; everything else sees whether one is there.
|
|
197
|
+
function keyState(id) {
|
|
198
|
+
try {
|
|
199
|
+
const key = readApiKey(id);
|
|
200
|
+
return key ? { present: true, hint: apiKeyHint(key), error: null, key } : { present: false, hint: null, error: null, key: null };
|
|
201
|
+
} catch (error) {
|
|
202
|
+
if (error?.code === 'ACCOUNT_NOT_FOUND') throw error;
|
|
203
|
+
return { present: false, hint: null, error: 'unreadable', key: null };
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
function fileChangedSince(file, at) {
|
|
207
|
+
try { return statSync(file).mtimeMs > at; } catch { return false; }
|
|
208
|
+
}
|
|
209
|
+
function subscriptionOf(id, home) {
|
|
210
|
+
const file = configFileOf(id, home);
|
|
211
|
+
const status = nativeStatus.get(id);
|
|
212
|
+
// Claude Code rewrites its global config when it signs in or out, so a file
|
|
213
|
+
// newer than the last check outranks that check until it is asked again.
|
|
214
|
+
if (status && !fileChangedSince(file, status.wall)) {
|
|
215
|
+
return {
|
|
216
|
+
signedIn: status.loggedIn, email: status.email, organization: status.organization,
|
|
217
|
+
plan: status.plan, method: status.method, checkedAt: status.checkedAt, checked: true,
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
// Its own record of an OAuth login, if any: a login is likely, its absence proves nothing.
|
|
221
|
+
const identity = readClaudeIdentity(home, file);
|
|
222
|
+
const signedIn = identity?.email ? true : status?.loggedIn === false ? false : null;
|
|
223
|
+
return {
|
|
224
|
+
signedIn, email: identity?.email || null, organization: identity?.organization || null,
|
|
225
|
+
plan: identity?.email && status?.loggedIn ? status.plan : null, method: identity?.email ? 'claude.ai' : null,
|
|
226
|
+
checkedAt: status?.checkedAt || null, checked: false,
|
|
227
|
+
};
|
|
101
228
|
}
|
|
102
|
-
function
|
|
229
|
+
function describeProfile(profile, data = load()) {
|
|
230
|
+
const id = profile.id;
|
|
231
|
+
const isDefault = id === DEFAULT_ACCOUNT_ID;
|
|
232
|
+
const base = isDefault ? defaultAccount() : profile;
|
|
233
|
+
const key = keyState(id);
|
|
234
|
+
const subscription = subscriptionOf(id, base.home);
|
|
235
|
+
const preferredMode = storedMode(data, id);
|
|
236
|
+
const auth = resolveClaudeAuth({ preferredMode, hasKey: key.present, subscription: subscription.signedIn });
|
|
237
|
+
const identity = auth.mode === 'apiKey' ? key.hint : auth.mode === 'subscription' ? (subscription.email || subscription.organization) : null;
|
|
238
|
+
const row = {
|
|
239
|
+
id, provider: 'claude', label: isDefault ? 'Default' : sanitizeLabel(base.label, 'Claude account'), home: base.home,
|
|
240
|
+
isDefault, builtin: isDefault, createdAt: base.createdAt || null,
|
|
241
|
+
mode: auth.mode, preferredMode, signedIn: auth.signedIn, switchable: auth.switchable, identity: identity || null,
|
|
242
|
+
subscription: { signedIn: subscription.signedIn, email: subscription.email, organization: subscription.organization, plan: subscription.plan, method: subscription.method, checked: subscription.checked, checkedAt: subscription.checkedAt },
|
|
243
|
+
apiKey: { present: key.present, hint: key.hint, error: key.error },
|
|
244
|
+
// The fields older panels read, from the same state.
|
|
245
|
+
loggedIn: auth.signedIn,
|
|
246
|
+
email: auth.mode === 'subscription' ? subscription.email : null,
|
|
247
|
+
organization: auth.mode === 'subscription' ? subscription.organization : null,
|
|
248
|
+
authMethod: auth.mode === 'apiKey' ? 'apiKey' : auth.mode === 'subscription' && subscription.signedIn ? (subscription.method || 'claude.ai') : null,
|
|
249
|
+
// Kept in the registry for older readers; the live record wins.
|
|
250
|
+
registryEmail: isDefault ? null : profile.email || null,
|
|
251
|
+
};
|
|
252
|
+
return { row, key: key.key };
|
|
253
|
+
}
|
|
254
|
+
function describe(id) {
|
|
103
255
|
const wanted = sanitizeId(id) || DEFAULT_ACCOUNT_ID;
|
|
104
|
-
|
|
105
|
-
|
|
256
|
+
const data = load();
|
|
257
|
+
const profile = wanted === DEFAULT_ACCOUNT_ID ? { id: DEFAULT_ACCOUNT_ID, home: defaultHome } : data.accounts.find((row) => row.id === wanted);
|
|
258
|
+
if (!profile) return null;
|
|
259
|
+
return describeProfile(profile, data).row;
|
|
260
|
+
}
|
|
261
|
+
function list() {
|
|
262
|
+
const data = load();
|
|
263
|
+
return [{ id: DEFAULT_ACCOUNT_ID, home: defaultHome }, ...data.accounts].map((profile) => describeProfile(profile, data).row);
|
|
264
|
+
}
|
|
265
|
+
function clientRow(row) {
|
|
266
|
+
const { home, registryEmail, ...rest } = row;
|
|
267
|
+
return rest;
|
|
106
268
|
}
|
|
269
|
+
function listForClient() { return list().map(clientRow); }
|
|
270
|
+
function describeForClient(id) { const row = describe(id); return row ? clientRow(row) : null; }
|
|
271
|
+
function get(id) { return describe(id); }
|
|
107
272
|
const find = get;
|
|
108
273
|
function homeFor(id) {
|
|
109
|
-
const
|
|
110
|
-
if (!
|
|
111
|
-
return
|
|
274
|
+
const wanted = sanitizeId(id);
|
|
275
|
+
if (!wanted || wanted === DEFAULT_ACCOUNT_ID) return null;
|
|
276
|
+
return profileFor(wanted)?.home || null;
|
|
112
277
|
}
|
|
113
278
|
function envFor(id) {
|
|
279
|
+
// Native auth strips ambient config/auth variables before applying this
|
|
280
|
+
// account's environment. Restore Default's explicit config location too.
|
|
281
|
+
if (id === DEFAULT_ACCOUNT_ID && configDir) return { CLAUDE_CONFIG_DIR: defaultHome };
|
|
114
282
|
const home = homeFor(id);
|
|
115
283
|
return home ? { CLAUDE_CONFIG_DIR: home } : {};
|
|
116
284
|
}
|
|
117
285
|
|
|
286
|
+
/**
|
|
287
|
+
* How a Claude Code process runs under an account: `unset` the inherited
|
|
288
|
+
* credential variables, then add `env` (its config directory and, in API-key
|
|
289
|
+
* mode, its key). `env` can carry a secret: pass it to the spawn only, never
|
|
290
|
+
* to a log, a response, an event or a file.
|
|
291
|
+
*/
|
|
292
|
+
function launchFor(id) {
|
|
293
|
+
const wanted = typeof id === 'string' && id ? id : DEFAULT_ACCOUNT_ID;
|
|
294
|
+
const data = load();
|
|
295
|
+
const profile = wanted === DEFAULT_ACCOUNT_ID ? { id: DEFAULT_ACCOUNT_ID, home: defaultHome } : data.accounts.find((row) => row.id === wanted);
|
|
296
|
+
if (!profile || !profile.home) {
|
|
297
|
+
return { ok: false, accountId: wanted, code: 'account_unavailable', message: 'That Claude account is no longer set up in SynaBun.' };
|
|
298
|
+
}
|
|
299
|
+
const { row, key } = describeProfile(profile, data);
|
|
300
|
+
const launchEnv = {};
|
|
301
|
+
if (wanted !== DEFAULT_ACCOUNT_ID) launchEnv.CLAUDE_CONFIG_DIR = profile.home;
|
|
302
|
+
else if (configDir) launchEnv.CLAUDE_CONFIG_DIR = defaultHome;
|
|
303
|
+
if (row.mode === 'apiKey' && key) launchEnv.ANTHROPIC_API_KEY = key;
|
|
304
|
+
return {
|
|
305
|
+
ok: true, accountId: wanted, label: row.label, mode: row.mode, signedIn: row.signedIn, identity: row.identity,
|
|
306
|
+
env: launchEnv, unset: [...CLAUDE_CREDENTIAL_ENV],
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/** Why an account cannot run a session now ('' when it can, or when that is not known yet). */
|
|
311
|
+
function unusableReason(id) {
|
|
312
|
+
const row = describe(id);
|
|
313
|
+
if (!row) return 'That Claude account is no longer set up in SynaBun.';
|
|
314
|
+
if (row.apiKey.error && row.mode !== 'subscription') return `The API key saved for ${row.label} cannot be read. Save it again.`;
|
|
315
|
+
if (row.signedIn === false) return `${row.label} is signed out. Sign in with Claude or add an API key to it first.`;
|
|
316
|
+
return '';
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
function writeMode(id, mode, data = load()) {
|
|
320
|
+
if (id === DEFAULT_ACCOUNT_ID) {
|
|
321
|
+
data.default = { ...(data.default || {}) };
|
|
322
|
+
if (mode) data.default.authMode = mode; else delete data.default.authMode;
|
|
323
|
+
} else {
|
|
324
|
+
const account = data.accounts.find((row) => row.id === id);
|
|
325
|
+
if (!account) throw new ClaudeAccountError('ACCOUNT_NOT_FOUND', `Claude account not found: ${id}`, 404);
|
|
326
|
+
if (mode) account.authMode = mode; else delete account.authMode;
|
|
327
|
+
}
|
|
328
|
+
save(data);
|
|
329
|
+
}
|
|
330
|
+
/** Choose what an account's sessions use. The chosen credential must be there. */
|
|
331
|
+
function setMode(id, mode) {
|
|
332
|
+
const wanted = sanitizeId(id) || DEFAULT_ACCOUNT_ID;
|
|
333
|
+
if (!CLAUDE_AUTH_MODES.includes(mode)) throw new ClaudeAccountError('MODE_INVALID', 'Choose "subscription" or "apiKey".', 400);
|
|
334
|
+
const row = describe(wanted);
|
|
335
|
+
if (!row) throw new ClaudeAccountError('ACCOUNT_NOT_FOUND', `Claude account not found: ${id}`, 404);
|
|
336
|
+
if (mode === 'apiKey' && !row.apiKey.present) throw new ClaudeAccountError('MODE_NEEDS_CREDENTIAL', `Add an API key to ${row.label} first.`, 409);
|
|
337
|
+
if (mode === 'subscription' && row.subscription.signedIn === false) throw new ClaudeAccountError('MODE_NEEDS_CREDENTIAL', `Sign in to ${row.label} with Claude first.`, 409);
|
|
338
|
+
writeMode(wanted, mode);
|
|
339
|
+
emit(wanted);
|
|
340
|
+
return describe(wanted);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/** Remember what Claude Code said about an account's own login. */
|
|
344
|
+
function noteNativeStatus(id, status) {
|
|
345
|
+
if (!status || typeof status.loggedIn !== 'boolean') return;
|
|
346
|
+
nativeStatus.set(id, {
|
|
347
|
+
loggedIn: status.loggedIn,
|
|
348
|
+
email: status.loggedIn ? text(status.email) : null,
|
|
349
|
+
organization: status.loggedIn ? text(status.orgName ?? status.organization) : null,
|
|
350
|
+
plan: status.loggedIn ? text(status.subscriptionType ?? status.plan, 40) : null,
|
|
351
|
+
method: status.loggedIn ? text(status.authMethod ?? status.method, 40) : null,
|
|
352
|
+
checkedAt: now(),
|
|
353
|
+
// Compared with the config file's modification time: the clock files use.
|
|
354
|
+
wall: Date.now(),
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
function forgetNativeStatus(id) { nativeStatus.delete(id); }
|
|
358
|
+
function setNativeStatusReader(reader) { nativeReader = typeof reader === 'function' ? reader : null; }
|
|
359
|
+
function signature(row) { return row ? JSON.stringify([row.label, row.mode, row.signedIn, row.identity, row.subscription.signedIn, row.subscription.email, row.subscription.plan, row.apiKey.present, row.apiKey.hint, row.preferredMode]) : ''; }
|
|
360
|
+
function checkOne(id) {
|
|
361
|
+
if (refreshing.has(id)) return refreshing.get(id);
|
|
362
|
+
const job = (async () => {
|
|
363
|
+
let timer;
|
|
364
|
+
try {
|
|
365
|
+
const status = await Promise.race([
|
|
366
|
+
Promise.resolve().then(() => nativeReader(id)),
|
|
367
|
+
new Promise((_, reject) => { timer = setTimeout(() => reject(new Error('timeout')), statusTimeoutMs); timer.unref?.(); }),
|
|
368
|
+
]);
|
|
369
|
+
if (status && typeof status.loggedIn === 'boolean' && profileFor(id)) noteNativeStatus(id, status);
|
|
370
|
+
} catch (error) {
|
|
371
|
+
log('claude-accounts', `status check failed for ${id}: ${String(error?.message || error).slice(0, 120)}`);
|
|
372
|
+
} finally { clearTimeout(timer); refreshing.delete(id); }
|
|
373
|
+
})();
|
|
374
|
+
refreshing.set(id, job);
|
|
375
|
+
return job;
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* Ask Claude Code for the subscription state of these accounts (all by
|
|
379
|
+
* default): `force` asks again, otherwise only an answer older than
|
|
380
|
+
* `maxAgeMs` or none at all. Listeners hear about every account that changed.
|
|
381
|
+
*/
|
|
382
|
+
async function refreshStatus(ids = null, { force = false, maxAgeMs = STATUS_MAX_AGE_MS } = {}) {
|
|
383
|
+
if (!nativeReader) return list();
|
|
384
|
+
const wanted = (Array.isArray(ids) ? ids : [DEFAULT_ACCOUNT_ID, ...load().accounts.map((row) => row.id)]).filter((id) => profileFor(id));
|
|
385
|
+
const before = new Map(wanted.map((id) => [id, signature(describe(id))]));
|
|
386
|
+
await Promise.all(wanted.map((id) => {
|
|
387
|
+
const known = nativeStatus.get(id);
|
|
388
|
+
if (!force && known && now() - known.checkedAt < maxAgeMs && !stale(id, maxAgeMs)) return null;
|
|
389
|
+
return checkOne(id);
|
|
390
|
+
}));
|
|
391
|
+
for (const id of wanted) if (before.get(id) !== signature(describe(id))) emit(id);
|
|
392
|
+
return list();
|
|
393
|
+
}
|
|
394
|
+
function stale(id, maxAgeMs = STATUS_MAX_AGE_MS) {
|
|
395
|
+
const known = nativeStatus.get(id);
|
|
396
|
+
if (!known || now() - known.checkedAt >= maxAgeMs) return true;
|
|
397
|
+
const profile = profileFor(id);
|
|
398
|
+
return !!profile && fileChangedSince(configFileOf(id, profile.home), known.wall);
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
function subscribe(listener) { listeners.add(listener); return () => listeners.delete(listener); }
|
|
402
|
+
function emit(accountId, extra = {}) {
|
|
403
|
+
for (const listener of [...listeners]) { try { listener({ accountId, ...extra }); } catch {} }
|
|
404
|
+
}
|
|
405
|
+
|
|
118
406
|
function linkShared(home) {
|
|
119
407
|
const linked = [];
|
|
120
408
|
for (const name of SHARED_LINKS) {
|
|
@@ -136,15 +424,17 @@ export function createClaudeAccounts({
|
|
|
136
424
|
function seedClaudeJson(home) {
|
|
137
425
|
const target = resolve(home, '.claude.json');
|
|
138
426
|
if (existsSync(target)) return false;
|
|
139
|
-
|
|
427
|
+
// Only shared preferences from Default's global config; never its login.
|
|
428
|
+
const source = readJson(defaultConfigFile, {}) || {};
|
|
140
429
|
const seeded = { hasCompletedOnboarding: true };
|
|
141
430
|
for (const key of CLAUDE_JSON_WHITELIST) if (source[key] !== undefined) seeded[key] = source[key];
|
|
142
431
|
writeJsonAtomic(target, seeded);
|
|
143
432
|
return true;
|
|
144
433
|
}
|
|
145
434
|
function seedHome(id) {
|
|
146
|
-
const
|
|
147
|
-
|
|
435
|
+
const wanted = sanitizeId(id);
|
|
436
|
+
const account = wanted && wanted !== DEFAULT_ACCOUNT_ID ? profileFor(wanted) : null;
|
|
437
|
+
if (!account) throw new ClaudeAccountError('ACCOUNT_NOT_FOUND', `Claude account not found: ${id}`, 404);
|
|
148
438
|
mkdirSync(resolve(account.home, 'projects'), { recursive: true });
|
|
149
439
|
mkdirSync(resolve(account.home, 'todos'), { recursive: true });
|
|
150
440
|
const linked = linkShared(account.home);
|
|
@@ -156,10 +446,14 @@ export function createClaudeAccounts({
|
|
|
156
446
|
const data = load();
|
|
157
447
|
const id = `cacct-${now().toString(36)}${Math.floor(Math.random() * 1296).toString(36).padStart(2, '0')}`;
|
|
158
448
|
const account = { id, label: sanitizeLabel(label, `Claude ${data.accounts.length + 2}`), email: null, organization: null, home: resolve(root, id), createdAt: new Date(now()).toISOString() };
|
|
449
|
+
if (label && String(label).trim()) account.labelCustom = true;
|
|
159
450
|
data.accounts.push(account);
|
|
160
451
|
save(data);
|
|
161
452
|
const seeded = seedHome(id);
|
|
162
|
-
|
|
453
|
+
// A directory made a moment ago holds no login: nothing to ask Claude Code.
|
|
454
|
+
noteNativeStatus(id, { loggedIn: false });
|
|
455
|
+
emit(id, { created: true });
|
|
456
|
+
return { ...describe(id), seeded };
|
|
163
457
|
}
|
|
164
458
|
function rename(id, label) {
|
|
165
459
|
const wanted = sanitizeId(id);
|
|
@@ -168,7 +462,9 @@ export function createClaudeAccounts({
|
|
|
168
462
|
const account = data.accounts.find((row) => row.id === wanted);
|
|
169
463
|
if (!account) throw new ClaudeAccountError('ACCOUNT_NOT_FOUND', `Claude account not found: ${id}`, 404);
|
|
170
464
|
account.label = sanitizeLabel(label, account.label);
|
|
465
|
+
account.labelCustom = true;
|
|
171
466
|
save(data);
|
|
467
|
+
emit(wanted);
|
|
172
468
|
return get(wanted);
|
|
173
469
|
}
|
|
174
470
|
function remove(id, { inUse = () => null } = {}) {
|
|
@@ -181,9 +477,11 @@ export function createClaudeAccounts({
|
|
|
181
477
|
if (reason) throw new ClaudeAccountError('ACCOUNT_IN_USE', typeof reason === 'string' ? reason : `Claude account ${wanted} is in use`, 409);
|
|
182
478
|
const [account] = data.accounts.splice(index, 1);
|
|
183
479
|
save(data);
|
|
480
|
+
nativeStatus.delete(wanted);
|
|
184
481
|
if (account.home && resolve(account.home).startsWith(resolve(root))) {
|
|
185
482
|
try { rmSync(account.home, { recursive: true, force: true }); } catch (error) { log('claude-accounts', `remove home failed: ${error?.message || error}`); }
|
|
186
483
|
}
|
|
484
|
+
emit(wanted, { removed: true });
|
|
187
485
|
return { ok: true, removed: account.id };
|
|
188
486
|
}
|
|
189
487
|
function recordIdentity(id) {
|
|
@@ -201,6 +499,16 @@ export function createClaudeAccounts({
|
|
|
201
499
|
}
|
|
202
500
|
return { ...account, ...identity };
|
|
203
501
|
}
|
|
502
|
+
/** A subscription sign-in just finished: it is what the account uses from now on. */
|
|
503
|
+
function noteSubscriptionSignIn(id, status = null) {
|
|
504
|
+
const wanted = sanitizeId(id) || DEFAULT_ACCOUNT_ID;
|
|
505
|
+
if (!profileFor(wanted)) return null;
|
|
506
|
+
if (status) noteNativeStatus(wanted, status);
|
|
507
|
+
if (wanted !== DEFAULT_ACCOUNT_ID) recordIdentity(wanted);
|
|
508
|
+
writeMode(wanted, 'subscription');
|
|
509
|
+
emit(wanted);
|
|
510
|
+
return describe(wanted);
|
|
511
|
+
}
|
|
204
512
|
/** Poll for the OAuth identity to appear after a login terminal was opened. */
|
|
205
513
|
function watchLogin(id, { onLogin = () => {}, onTimeout = () => {}, timeoutMs = 10 * 60_000 } = {}) {
|
|
206
514
|
const started = now();
|
|
@@ -223,8 +531,11 @@ export function createClaudeAccounts({
|
|
|
223
531
|
}
|
|
224
532
|
|
|
225
533
|
return {
|
|
226
|
-
registryPath, defaultHome, root,
|
|
227
|
-
list, listForClient,
|
|
228
|
-
|
|
534
|
+
registryPath, defaultHome, defaultConfigFile, root,
|
|
535
|
+
list, listForClient, describe, describeForClient, profileFor, readApiKey, saveApiKey, clearApiKey, get, find, homeFor, envFor,
|
|
536
|
+
launchFor, unusableReason, setMode, noteNativeStatus, forgetNativeStatus, noteSubscriptionSignIn, setNativeStatusReader,
|
|
537
|
+
refreshStatus, stale, subscribe,
|
|
538
|
+
create, rename, remove, seedHome, recordIdentity, watchLogin, loginCommand,
|
|
539
|
+
readIdentity: (id) => (id === DEFAULT_ACCOUNT_ID ? readClaudeIdentity(defaultHome, defaultConfigFile) : readClaudeIdentity(homeFor(id))),
|
|
229
540
|
};
|
|
230
541
|
}
|