@iislee/opencodex 2.11.0 → 2.35.0
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/AGENTS_INSTALL.md +109 -0
- package/README.md +117 -22
- package/bin/ocx.mjs +245 -88
- package/bin/package-main.mjs +1 -1
- package/gui/dist/assets/index-Be1sDpWw.css +1 -0
- package/gui/dist/assets/index-D4OKgUV4.js +114 -0
- package/gui/dist/index.html +2 -2
- package/gui/dist/provider-icons/alibaba-color.svg +1 -1
- package/gui/dist/provider-icons/antigravity-color.svg +1 -1
- package/gui/dist/provider-icons/claude-color.svg +1 -1
- package/gui/dist/provider-icons/cline-color.svg +16 -0
- package/gui/dist/provider-icons/cloudflare-ai-gateway-color.svg +1 -1
- package/gui/dist/provider-icons/commandcode-color.svg +1 -0
- package/gui/dist/provider-icons/copilot-color.svg +1 -1
- package/gui/dist/provider-icons/cursor-color.svg +1 -1
- package/gui/dist/provider-icons/deepseek-color.svg +1 -1
- package/gui/dist/provider-icons/firepass-color.svg +1 -1
- package/gui/dist/provider-icons/fireworks-color.svg +1 -1
- package/gui/dist/provider-icons/gemini-color.svg +1 -1
- package/gui/dist/provider-icons/github-copilot-color.svg +1 -1
- package/gui/dist/provider-icons/gitlab-duo-color.svg +1 -1
- package/gui/dist/provider-icons/grok.svg +1 -1
- package/gui/dist/provider-icons/groq-color.svg +1 -1
- package/gui/dist/provider-icons/huggingface-color.svg +1 -1
- package/gui/dist/provider-icons/kimi-color.svg +1 -1
- package/gui/dist/provider-icons/kiro-color.svg +2 -2
- package/gui/dist/provider-icons/lm-studio-color.svg +1 -1
- package/gui/dist/provider-icons/mistral-color.svg +1 -1
- package/gui/dist/provider-icons/moonshot-color.svg +1 -1
- package/gui/dist/provider-icons/nvidia-color.svg +1 -1
- package/gui/dist/provider-icons/ollama-color.svg +1 -1
- package/gui/dist/provider-icons/openai.svg +1 -1
- package/gui/dist/provider-icons/opencode.svg +2 -1
- package/gui/dist/provider-icons/openrouter-color.svg +1 -1
- package/gui/dist/provider-icons/pi.svg +2 -2
- package/gui/dist/provider-icons/qianfan-color.svg +1 -1
- package/gui/dist/provider-icons/qwen-portal-color.svg +1 -1
- package/gui/dist/provider-icons/vercel-ai-gateway-color.svg +1 -1
- package/gui/dist/provider-icons/vllm-color.svg +1 -1
- package/gui/dist/provider-icons/xiaomi-color.svg +1 -1
- package/package.json +21 -10
- package/src/adapters/anthropic-output-schema.ts +137 -0
- package/src/adapters/anthropic.ts +475 -62
- package/src/adapters/base.ts +82 -7
- package/src/adapters/client-fingerprint.ts +18 -12
- package/src/adapters/cline-pass-deepseek-v4-tool-replay.ts +69 -0
- package/src/adapters/command-code.ts +637 -0
- package/src/adapters/cursor/call-id.ts +44 -0
- package/src/adapters/cursor/catalog.ts +541 -0
- package/src/adapters/cursor/checkpoint-store.ts +308 -0
- package/src/adapters/cursor/cursor-errors.ts +144 -6
- package/src/adapters/cursor/discovery.ts +122 -14
- package/src/adapters/cursor/effort-map.ts +106 -4
- package/src/adapters/cursor/envelope-echo.ts +290 -0
- package/src/adapters/cursor/framing.ts +39 -0
- package/src/adapters/cursor/h2-pool.ts +123 -0
- package/src/adapters/cursor/http1-bidi.ts +361 -0
- package/src/adapters/cursor/images.ts +704 -0
- package/src/adapters/cursor/live-models.ts +180 -59
- package/src/adapters/cursor/live-transport.ts +623 -170
- package/src/adapters/cursor/message-mapper.ts +4 -1
- package/src/adapters/cursor/native-exec-common.ts +23 -2
- package/src/adapters/cursor/native-exec-desktop.ts +23 -0
- package/src/adapters/cursor/native-exec-fs.ts +10 -7
- package/src/adapters/cursor/native-exec-network.ts +1 -1
- package/src/adapters/cursor/native-exec-shell.ts +5 -3
- package/src/adapters/cursor/native-exec.ts +121 -14
- package/src/adapters/cursor/protobuf-events.ts +829 -11
- package/src/adapters/cursor/protobuf-request.ts +447 -75
- package/src/adapters/cursor/request-builder.ts +271 -35
- package/src/adapters/cursor/tool-definitions.ts +252 -12
- package/src/adapters/cursor/tool-result-normalize.ts +115 -0
- package/src/adapters/cursor/transport.ts +22 -0
- package/src/adapters/cursor/types.ts +48 -1
- package/src/adapters/cursor.ts +336 -39
- package/src/adapters/exec-tool-result-normalize.ts +99 -0
- package/src/adapters/google-antigravity-replay.ts +713 -41
- package/src/adapters/google-antigravity-wire.ts +48 -10
- package/src/adapters/google-errors.ts +44 -12
- package/src/adapters/google-http.ts +38 -10
- package/src/adapters/google-tool-schema.ts +80 -15
- package/src/adapters/google-truncation.ts +11 -0
- package/src/adapters/google.ts +742 -86
- package/src/adapters/identity.ts +39 -6
- package/src/adapters/image.ts +1 -1
- package/src/adapters/kiro-constants.ts +27 -0
- package/src/adapters/kiro-errors.ts +11 -0
- package/src/adapters/kiro-events.ts +19 -1
- package/src/adapters/kiro-thinking.ts +18 -2
- package/src/adapters/kiro-tools.ts +65 -17
- package/src/adapters/kiro.ts +270 -73
- package/src/adapters/mimo-free.ts +17 -0
- package/src/adapters/openai-chat-url.ts +11 -0
- package/src/adapters/openai-chat.ts +1377 -344
- package/src/adapters/openai-responses-url.ts +16 -0
- package/src/adapters/openai-responses.ts +1164 -64
- package/src/adapters/registry.ts +175 -0
- package/src/adapters/responses-tool-schema.ts +67 -0
- package/src/adapters/run-turn-queue.ts +36 -1
- package/src/adapters/tool-call-id.ts +119 -0
- package/src/adapters/tool-catalog-nudge.ts +105 -21
- package/src/adapters/xai-tool-schema.ts +436 -0
- package/src/adapters/xai-web-search.ts +186 -0
- package/src/bridge.ts +512 -92
- package/src/chat/inbound.ts +57 -20
- package/src/chat/outbound.ts +97 -33
- package/src/claude/agents-inject.ts +40 -10
- package/src/claude/context-windows.ts +37 -14
- package/src/claude/desktop-3p.ts +243 -9
- package/src/claude/gateway-cache.ts +41 -4
- package/src/claude/inbound.ts +72 -3
- package/src/claude/model-info.ts +38 -15
- package/src/claude/outbound.ts +88 -21
- package/src/cli/access.ts +46 -3
- package/src/cli/account-api.ts +150 -19
- package/src/cli/account-auth.ts +33 -6
- package/src/cli/account-catalog-refresh.ts +14 -0
- package/src/cli/account-extended.ts +648 -28
- package/src/cli/account-main.ts +317 -0
- package/src/cli/account.ts +97 -19
- package/src/cli/agent.ts +53 -2
- package/src/cli/alias.ts +66 -0
- package/src/cli/capabilities-command.ts +94 -0
- package/src/cli/capabilities.ts +496 -0
- package/src/cli/claude-agent-startup-sync.ts +73 -0
- package/src/cli/claude-desktop.ts +60 -15
- package/src/cli/claude.ts +129 -35
- package/src/cli/codex-log-guard-doctor.ts +103 -0
- package/src/cli/codex-shim-autorestore.ts +2 -0
- package/src/cli/codex-shim-readiness.ts +76 -0
- package/src/cli/combo.ts +8 -0
- package/src/cli/config-command.ts +74 -10
- package/src/cli/dispatch.ts +821 -0
- package/src/cli/doctor.ts +440 -56
- package/src/cli/ensure-desired-integrations.ts +152 -0
- package/src/cli/export-command.ts +46 -20
- package/src/cli/help.ts +34 -274
- package/src/cli/index.ts +417 -528
- package/src/cli/init.ts +5 -17
- package/src/cli/inspect.ts +230 -0
- package/src/cli/integrations.ts +120 -2
- package/src/cli/lab.ts +607 -0
- package/src/cli/launcher-context.ts +77 -0
- package/src/cli/minimax.ts +497 -0
- package/src/cli/models-runtime.ts +130 -2
- package/src/cli/models.ts +118 -16
- package/src/cli/observe.ts +123 -11
- package/src/cli/opencode.ts +4 -2
- package/src/cli/provider-runtime.ts +34 -3
- package/src/cli/provider.ts +25 -3
- package/src/cli/ready.ts +301 -0
- package/src/cli/registry.ts +476 -0
- package/src/cli/root.ts +86 -0
- package/src/cli/route-policy.ts +92 -0
- package/src/cli/runtime-api.ts +57 -10
- package/src/cli/star-prompt.ts +71 -15
- package/src/cli/status.ts +51 -4
- package/src/cli/storage.ts +234 -0
- package/src/cli/system-command.ts +16 -0
- package/src/cli/system-restart-client.ts +146 -0
- package/src/cli/tray-proxy.ts +153 -6
- package/src/cli/usage-report.ts +184 -0
- package/src/cli/v2.ts +137 -18
- package/src/cli/version-skew.ts +46 -0
- package/src/cli.ts +1 -1
- package/src/clients/config-export.ts +1442 -23
- package/src/clients/effective-status.ts +30 -2
- package/src/clients/probes/cline.ts +81 -0
- package/src/codex/account-label.ts +35 -1
- package/src/codex/account-lifecycle.ts +130 -13
- package/src/codex/account-namespaces.ts +49 -3
- package/src/codex/account-pause.ts +2 -1
- package/src/codex/account-priority.ts +84 -0
- package/src/codex/account-store.ts +29 -2
- package/src/codex/account-usability.ts +25 -2
- package/src/codex/admission.ts +256 -0
- package/src/codex/affinity-debug.ts +162 -0
- package/src/codex/app-server-processes.ts +570 -107
- package/src/codex/app-server-restart-service.ts +232 -0
- package/src/codex/auth-api.ts +893 -246
- package/src/codex/auth-collision.ts +5 -3
- package/src/codex/auth-context.ts +348 -32
- package/src/codex/autostart-health.ts +24 -1
- package/src/codex/catalog/account-models.ts +67 -0
- package/src/codex/catalog/aggregation.ts +86 -10
- package/src/codex/catalog/bundled.ts +331 -33
- package/src/codex/catalog/effort.ts +138 -32
- package/src/codex/catalog/filesystem-evidence.ts +302 -0
- package/src/codex/catalog/kinds.ts +2 -0
- package/src/codex/catalog/metadata.ts +555 -45
- package/src/codex/catalog/native-models.ts +75 -0
- package/src/codex/catalog/parsing.ts +269 -30
- package/src/codex/catalog/provider-fetch.ts +1626 -144
- package/src/codex/catalog/sync.ts +1576 -187
- package/src/codex/catalog-admission.ts +199 -0
- package/src/codex/catalog-refresh-status.ts +105 -0
- package/src/codex/catalog-write-serialization.ts +242 -0
- package/src/codex/catalog.ts +6 -3
- package/src/codex/codex-write-lock.ts +386 -0
- package/src/codex/convergence-types.ts +614 -0
- package/src/codex/convergence.ts +676 -0
- package/src/codex/coordinator-doctor.ts +332 -0
- package/src/codex/custom-model-catalog-migration.ts +176 -0
- package/src/codex/desired-state.ts +230 -0
- package/src/codex/desktop-app-restart.ts +355 -0
- package/src/codex/features.ts +636 -39
- package/src/codex/generation.ts +202 -0
- package/src/codex/history-job.ts +436 -0
- package/src/codex/history-lock.ts +242 -0
- package/src/codex/history-manifest.ts +112 -0
- package/src/codex/history-migration-guardian.ts +30 -24
- package/src/codex/history-provider.ts +1016 -235
- package/src/codex/history-transition.ts +105 -0
- package/src/codex/history-worker.ts +223 -0
- package/src/codex/inject-coordination.ts +373 -0
- package/src/codex/inject.ts +1114 -152
- package/src/codex/injected-marker.ts +37 -3
- package/src/codex/integration-record.ts +266 -0
- package/src/codex/internal/catalog-writer.ts +203 -0
- package/src/codex/internal/history-writer.ts +81 -0
- package/src/codex/journal.ts +66 -4
- package/src/codex/log-guard/inspect.ts +524 -0
- package/src/codex/log-guard/lock.ts +150 -0
- package/src/codex/log-guard/maintenance.ts +403 -0
- package/src/codex/log-guard/path-safety.ts +88 -0
- package/src/codex/log-guard/policy.ts +44 -0
- package/src/codex/log-guard/processes.ts +205 -0
- package/src/codex/log-guard/protection.ts +489 -0
- package/src/codex/log-guard/sqlite-errors.ts +9 -0
- package/src/codex/main-account-cache.ts +24 -0
- package/src/codex/main-account.ts +29 -1
- package/src/codex/management-convergence.ts +167 -0
- package/src/codex/model-cache.ts +56 -10
- package/src/codex/model-entitlements.ts +360 -0
- package/src/codex/native-main-admission.ts +47 -0
- package/src/codex/native-main-auth-temp.ts +187 -0
- package/src/codex/native-main-claim.ts +178 -0
- package/src/codex/native-main-lock-file.ts +162 -0
- package/src/codex/native-main-owner.ts +329 -0
- package/src/codex/native-profile-api.ts +247 -0
- package/src/codex/native-profile-manager.ts +1531 -0
- package/src/codex/native-profile-processes.ts +121 -0
- package/src/codex/native-profile-recovery.ts +99 -0
- package/src/codex/native-profile-stage-store.ts +387 -0
- package/src/codex/native-profile-startup.ts +622 -0
- package/src/codex/native-profile-store.ts +855 -0
- package/src/codex/native-profile-types.ts +120 -0
- package/src/codex/native-residue.ts +675 -0
- package/src/codex/paths.ts +80 -1
- package/src/codex/plan-from-token.ts +140 -0
- package/src/codex/plan.ts +40 -0
- package/src/codex/plugins-doctor.ts +1 -1
- package/src/codex/pool-rotation.ts +74 -4
- package/src/codex/project-config-warnings.ts +20 -6
- package/src/codex/prompt-journal.ts +352 -0
- package/src/codex/prompt-layers.ts +1313 -0
- package/src/codex/prompt-lock.ts +143 -0
- package/src/codex/prompt-text-probe.ts +238 -0
- package/src/codex/quota-rejection.ts +298 -0
- package/src/codex/quota.ts +264 -21
- package/src/codex/refresh.ts +11 -2
- package/src/codex/reset-credit-recovery.ts +1044 -0
- package/src/codex/routing.ts +514 -94
- package/src/codex/runtime.ts +159 -38
- package/src/codex/shim.ts +1065 -31
- package/src/codex/subagent-model-fallback.ts +437 -43
- package/src/codex/sync.ts +191 -2
- package/src/codex/transition-state.ts +720 -0
- package/src/codex/upstream-host-health.ts +368 -0
- package/src/codex/user-identity.ts +557 -0
- package/src/codex/warmup.ts +187 -81
- package/src/codex/write-coordination.ts +114 -0
- package/src/combos/failover.ts +47 -0
- package/src/combos/index.ts +4 -0
- package/src/combos/request.ts +32 -0
- package/src/combos/types.ts +91 -9
- package/src/compatibility/index.ts +26 -0
- package/src/compatibility/manifest.ts +253 -0
- package/src/compatibility/openai-responses.ts +121 -0
- package/src/config/atomic-write.ts +219 -0
- package/src/config/paths.ts +40 -0
- package/src/config/process-state.ts +309 -0
- package/src/config/provider-name.ts +24 -0
- package/src/config/provider-validation.ts +177 -0
- package/src/config/rebase-provenance.ts +68 -0
- package/src/config.ts +1713 -709
- package/src/generated/compatibility-version.json +3324 -0
- package/src/generated/{jawcode-model-metadata.ts → model-metadata.ts} +19 -17
- package/src/grok/inject.ts +16 -5
- package/src/grok/inspect.ts +45 -0
- package/src/grok/sync.ts +2 -2
- package/src/images/loop.ts +157 -33
- package/src/images/plan.ts +24 -13
- package/src/integrations/config-io.ts +269 -0
- package/src/integrations/journal.ts +315 -0
- package/src/integrations/merge.ts +135 -0
- package/src/integrations/mutation-flight.ts +71 -0
- package/src/integrations/native/ownership-preflight.ts +202 -0
- package/src/integrations/omp-yaml-source.ts +358 -0
- package/src/integrations/owned-refresh.ts +74 -0
- package/src/integrations/ownership-policy.ts +160 -0
- package/src/integrations/ownership.ts +155 -0
- package/src/integrations/registry.ts +166 -0
- package/src/integrations/serialize.ts +314 -0
- package/src/integrations/state.ts +433 -0
- package/src/integrations/store.ts +103 -0
- package/src/integrations/writer-lock.ts +98 -0
- package/src/integrations/writer.ts +715 -0
- package/src/lab/artifacts/sanitize.ts +586 -0
- package/src/lab/artifacts/secure-fs.ts +475 -0
- package/src/lab/artifacts/store.ts +310 -0
- package/src/lab/automation/budgets.ts +78 -0
- package/src/lab/automation/config-persistence.ts +256 -0
- package/src/lab/automation/constants.ts +39 -0
- package/src/lab/automation/cooldown.ts +103 -0
- package/src/lab/automation/dispatch.ts +211 -0
- package/src/lab/automation/index.ts +13 -0
- package/src/lab/automation/orchestrator.ts +499 -0
- package/src/lab/automation/persistence.ts +512 -0
- package/src/lab/automation/planner.ts +371 -0
- package/src/lab/automation/policy.ts +136 -0
- package/src/lab/automation/queue.ts +191 -0
- package/src/lab/automation/recovery.ts +24 -0
- package/src/lab/automation/route-context.ts +21 -0
- package/src/lab/automation/run-key.ts +44 -0
- package/src/lab/automation/runs-query.ts +34 -0
- package/src/lab/automation/types.ts +160 -0
- package/src/lab/conformance/assertion.ts +325 -0
- package/src/lab/conformance/digest.ts +22 -0
- package/src/lab/conformance/executor.ts +741 -0
- package/src/lab/conformance/fixture-provider.ts +27 -0
- package/src/lab/conformance/fixtures/live-v1-cases.json +175 -0
- package/src/lab/conformance/fixtures/protocol-v1-cases.json +461 -0
- package/src/lab/conformance/harness-budget.ts +47 -0
- package/src/lab/conformance/index.ts +5 -0
- package/src/lab/conformance/jcs.ts +64 -0
- package/src/lab/conformance/json-pointer.ts +39 -0
- package/src/lab/conformance/manifest.ts +180 -0
- package/src/lab/conformance/mcp-stub.ts +179 -0
- package/src/lab/conformance/negative-controls.ts +164 -0
- package/src/lab/conformance/observation.ts +355 -0
- package/src/lab/conformance/runner.ts +68 -0
- package/src/lab/conformance/sse-normalize.ts +59 -0
- package/src/lab/conformance/suite-manifest.ts +78 -0
- package/src/lab/conformance/types.ts +214 -0
- package/src/lab/constants.ts +126 -0
- package/src/lab/digest.ts +64 -0
- package/src/lab/events/errors.ts +9 -0
- package/src/lab/events/limits.ts +117 -0
- package/src/lab/events/types.ts +229 -0
- package/src/lab/events/validate.ts +781 -0
- package/src/lab/fabric/constants.ts +40 -0
- package/src/lab/fabric/executor.ts +492 -0
- package/src/lab/fabric/index.ts +80 -0
- package/src/lab/fabric/manifest.ts +222 -0
- package/src/lab/fabric/observe.ts +489 -0
- package/src/lab/fabric/patch.ts +79 -0
- package/src/lab/fabric/producer-child.ts +139 -0
- package/src/lab/fabric/producer-isolate.ts +276 -0
- package/src/lab/fabric/producer-protocol.ts +61 -0
- package/src/lab/fabric/scratch.ts +439 -0
- package/src/lab/fabric/subject.ts +106 -0
- package/src/lab/fabric/types.ts +134 -0
- package/src/lab/fabric/verifier.ts +98 -0
- package/src/lab/index.ts +54 -0
- package/src/lab/ledger/artifact-refs.ts +127 -0
- package/src/lab/ledger/invalidation.ts +136 -0
- package/src/lab/ledger/purge.ts +310 -0
- package/src/lab/ledger/store.ts +532 -0
- package/src/lab/live/credential-lease.ts +53 -0
- package/src/lab/live/destination.ts +155 -0
- package/src/lab/live/executor.ts +336 -0
- package/src/lab/live/inert-tools.ts +56 -0
- package/src/lab/live/manifest.ts +85 -0
- package/src/lab/live/mcp-loopback.ts +57 -0
- package/src/lab/live/runner.ts +19 -0
- package/src/lab/live/sandbox.ts +61 -0
- package/src/lab/live/suite-manifest.ts +41 -0
- package/src/lab/live/transport.ts +118 -0
- package/src/lab/live/types.ts +197 -0
- package/src/lab/observe/from-conformance.ts +301 -0
- package/src/lab/observe/from-live.ts +117 -0
- package/src/lab/paths.ts +153 -0
- package/src/lab/projection/rebuild.ts +495 -0
- package/src/lab/projection/schema.ts +135 -0
- package/src/lab/projection/verdicts.ts +474 -0
- package/src/lab/projection/verification.ts +412 -0
- package/src/lab/public/bundle.ts +217 -0
- package/src/lab/public/community-authority.ts +175 -0
- package/src/lab/public/community-files.ts +29 -0
- package/src/lab/public/community.ts +479 -0
- package/src/lab/public/file-safety.ts +155 -0
- package/src/lab/public/ids.ts +26 -0
- package/src/lab/public/index.ts +16 -0
- package/src/lab/public/mutation-lock.ts +424 -0
- package/src/lab/public/operator.ts +353 -0
- package/src/lab/public/origin-purge.ts +79 -0
- package/src/lab/public/origin.ts +203 -0
- package/src/lab/public/privacy.ts +143 -0
- package/src/lab/public/private-file.ts +261 -0
- package/src/lab/public/project.ts +124 -0
- package/src/lab/public/purge-test-fault.ts +21 -0
- package/src/lab/public/purge.ts +223 -0
- package/src/lab/public/registry.ts +44 -0
- package/src/lab/public/revocation.ts +252 -0
- package/src/lab/public/signature.ts +243 -0
- package/src/lab/public/storage.ts +105 -0
- package/src/lab/public/strict-json.ts +206 -0
- package/src/lab/public/time.ts +26 -0
- package/src/lab/public/types.ts +172 -0
- package/src/lab/public/validate.ts +391 -0
- package/src/lab/query/catalog.ts +101 -0
- package/src/lab/query/connection.ts +107 -0
- package/src/lab/query/constants.ts +4 -0
- package/src/lab/query/cursor.ts +132 -0
- package/src/lab/query/dto-map.ts +277 -0
- package/src/lab/query/errors.ts +22 -0
- package/src/lab/query/freshness.ts +53 -0
- package/src/lab/query/index.ts +45 -0
- package/src/lab/query/latest-observation.ts +59 -0
- package/src/lab/query/passive-production.ts +159 -0
- package/src/lab/query/queries.ts +444 -0
- package/src/lab/query/types.ts +266 -0
- package/src/lab/subject/behavior-fingerprint.ts +77 -0
- package/src/lab/subject/installation-salt.ts +112 -0
- package/src/lab/subject/protocol-subject.ts +80 -0
- package/src/lab/subject/route-subject.ts +74 -0
- package/src/lib/admin-secrets.ts +24 -0
- package/src/lib/app-owned-memory-stores.ts +22 -0
- package/src/lib/bounded-body.ts +167 -11
- package/src/lib/bun-runtime.ts +125 -12
- package/src/lib/bun-stream-caps.ts +13 -9
- package/src/lib/codex-restart-contract.ts +120 -0
- package/src/lib/config-ownership.ts +26 -2
- package/src/lib/destination-policy.ts +65 -1
- package/src/lib/errors.ts +80 -5
- package/src/lib/fabric-task-execution-authority.ts +7 -0
- package/src/lib/fabric-task-host.ts +29 -0
- package/src/lib/lab-activation.ts +223 -0
- package/src/lib/lab-live-execution-authority.ts +13 -0
- package/src/lib/lab-live-host.ts +30 -0
- package/src/lib/lab-live-pinned-sender.ts +56 -0
- package/src/lib/lab-live-route-production.ts +130 -0
- package/src/lib/lab-passive-linker-registration.ts +26 -0
- package/src/lib/local-management-attestation.ts +51 -0
- package/src/lib/local-management-capability.ts +100 -0
- package/src/lib/local-provider-reload-contract.ts +100 -0
- package/src/lib/optional-shutdown-hooks.ts +57 -0
- package/src/lib/package-tree-integrity.ts +101 -0
- package/src/lib/pinned-http.ts +145 -26
- package/src/lib/process-control.ts +6 -2
- package/src/lib/provider-outbound.ts +49 -9
- package/src/lib/redact.ts +419 -3
- package/src/lib/self-launch-argv.ts +15 -0
- package/src/lib/server-resource-ownership.ts +71 -0
- package/src/lib/service-secrets.ts +15 -0
- package/src/lib/shadow-call.ts +35 -4
- package/src/lib/sse-decoder.ts +41 -0
- package/src/lib/state-store-registrations.ts +10 -2
- package/src/lib/system-restart-contract.ts +73 -0
- package/src/lib/token-estimate.ts +19 -2
- package/src/lib/tool-argument-integers.ts +253 -0
- package/src/lib/translator-budget.ts +44 -0
- package/src/lib/upstream-http-version.ts +57 -0
- package/src/lib/upstream-reachability.ts +95 -0
- package/src/lib/upstream-retry.ts +156 -3
- package/src/lib/windows-atomic-replace.ts +155 -0
- package/src/lib/windows-elevation.ts +70 -2
- package/src/lib/windows-secret-acl.ts +409 -69
- package/src/lib/windows-service-wrappers.ts +72 -0
- package/src/lib/windows-text.ts +106 -0
- package/src/lib/windows-user-principal.ts +341 -0
- package/src/lib/winsw.ts +33 -5
- package/src/oauth/account-import/google-antigravity-adapter.ts +74 -0
- package/src/oauth/account-import/index.ts +15 -0
- package/src/oauth/account-import/parser.ts +83 -0
- package/src/oauth/account-import/registry.ts +18 -0
- package/src/oauth/account-import/service.ts +75 -0
- package/src/oauth/account-import/types.ts +91 -0
- package/src/oauth/anthropic.ts +12 -1
- package/src/oauth/callback-server.ts +30 -4
- package/src/oauth/chatgpt.ts +12 -1
- package/src/oauth/cline.ts +203 -0
- package/src/oauth/command-code.ts +239 -0
- package/src/oauth/cursor.ts +46 -5
- package/src/oauth/generic-account-failover.ts +231 -0
- package/src/oauth/google-antigravity.ts +35 -3
- package/src/oauth/health.ts +20 -12
- package/src/oauth/index.ts +462 -71
- package/src/oauth/key-providers.ts +25 -0
- package/src/oauth/kimi.ts +25 -3
- package/src/oauth/kiro.ts +95 -6
- package/src/oauth/local-token-detect.ts +13 -2
- package/src/oauth/log.ts +3 -1
- package/src/oauth/login-cli.ts +88 -28
- package/src/oauth/nous.ts +798 -0
- package/src/oauth/open-browser-choice.ts +26 -0
- package/src/oauth/store.ts +133 -26
- package/src/oauth/token-guardian.ts +9 -3
- package/src/oauth/types.ts +15 -0
- package/src/pi/models.ts +2 -2
- package/src/providers/alibaba-region-migration.ts +1 -1
- package/src/providers/antigravity-models.ts +521 -31
- package/src/providers/auto-compact-budget.ts +65 -0
- package/src/providers/base-url-choices.ts +10 -0
- package/src/providers/codex-capacity.ts +292 -0
- package/src/providers/command-code-efforts.ts +176 -0
- package/src/providers/context-cap.ts +26 -8
- package/src/providers/cursor-pool.ts +72 -0
- package/src/providers/default-aliases.ts +65 -0
- package/src/providers/derive.ts +281 -6
- package/src/providers/fastwire.ts +507 -0
- package/src/providers/free-directory.ts +10 -7
- package/src/providers/google-vertex-location.ts +14 -0
- package/src/providers/key-failover.ts +71 -3
- package/src/providers/label.ts +35 -2
- package/src/providers/model-discovery-limits.ts +16 -0
- package/src/providers/model-discovery.ts +115 -22
- package/src/providers/model-presets.ts +119 -0
- package/src/providers/model-rename-migration.ts +255 -0
- package/src/providers/model-rename-startup.ts +28 -0
- package/src/providers/new-model-policy.ts +146 -0
- package/src/providers/openai-sidecar.ts +72 -4
- package/src/providers/openai-tier-startup.ts +31 -2
- package/src/providers/openai-tiers.ts +119 -4
- package/src/providers/openai-virtual-models.ts +1 -0
- package/src/providers/opencode-zen-rate-limit.ts +102 -0
- package/src/providers/provider-id-rewrite.ts +30 -0
- package/src/providers/quota.ts +1379 -40
- package/src/providers/registry.ts +1545 -112
- package/src/providers/request-pacing.ts +310 -0
- package/src/providers/service-tier.ts +277 -0
- package/src/providers/slug-codec.ts +94 -6
- package/src/providers/static-model-discovery.ts +86 -0
- package/src/providers/xai-responses-opt-in.ts +15 -0
- package/src/providers/xai-transport.ts +32 -4
- package/src/reasoning-effort.ts +68 -3
- package/src/responses/apply-patch-envelope.ts +63 -0
- package/src/responses/code-mode-helper-compat.ts +50 -0
- package/src/responses/compaction.ts +26 -1
- package/src/responses/custom-tool-compat.ts +384 -0
- package/src/responses/hosted-tool-policy.ts +9 -0
- package/src/responses/namespace-tool-compat.ts +435 -0
- package/src/responses/parser.ts +225 -38
- package/src/responses/provider-continuation.ts +98 -0
- package/src/responses/provider-opaque-metadata.ts +73 -0
- package/src/responses/reasoning-envelope.ts +9 -1
- package/src/responses/reasoning-replay-cache.ts +504 -0
- package/src/responses/schema.ts +12 -2
- package/src/responses/spill-store.ts +75 -10
- package/src/responses/state.ts +659 -31
- package/src/responses/thought-signature-replay.ts +364 -0
- package/src/responses/tool-search-compat.ts +301 -0
- package/src/responses/truncated-stop-reason.ts +60 -0
- package/src/responses/turn-termination.ts +107 -0
- package/src/router.ts +405 -31
- package/src/routing/analytics.ts +379 -0
- package/src/routing/capability.ts +244 -0
- package/src/routing/compatibility/assemble.ts +73 -0
- package/src/routing/compatibility/behavior.ts +278 -0
- package/src/routing/compatibility/catalog.ts +99 -0
- package/src/routing/compatibility/endpoint.ts +52 -0
- package/src/routing/compatibility/lab-evidence-provider.ts +130 -0
- package/src/routing/compatibility/policy.ts +181 -0
- package/src/routing/compatibility/provider-slot.ts +56 -0
- package/src/routing/compatibility/reader.ts +110 -0
- package/src/routing/compatibility/subject.ts +191 -0
- package/src/routing/compatibility/types.ts +64 -0
- package/src/routing/compatibility/version.ts +104 -0
- package/src/routing/cost.ts +77 -0
- package/src/routing/evaluator.ts +495 -0
- package/src/routing/health.ts +412 -0
- package/src/routing/history/cursor.ts +43 -0
- package/src/routing/history/indexer.ts +605 -0
- package/src/routing/history/schema.ts +72 -0
- package/src/routing/profile-namespace.ts +15 -0
- package/src/routing/profile.ts +547 -0
- package/src/routing/quota.ts +155 -0
- package/src/routing/request-evidence.ts +45 -0
- package/src/routing/trace.ts +776 -0
- package/src/server/adapter-resolve.ts +2 -29
- package/src/server/auth-cors.ts +289 -48
- package/src/server/background-lifecycle.ts +182 -0
- package/src/server/chat-completions.ts +154 -72
- package/src/server/chat-native-sse.ts +331 -0
- package/src/server/chat-native.ts +445 -0
- package/src/server/claude-messages.ts +160 -44
- package/src/server/direct-local-http.ts +347 -0
- package/src/server/effort-policy.ts +18 -0
- package/src/server/github-copilot-responses-repair.ts +338 -0
- package/src/server/gui-static.ts +39 -10
- package/src/server/images.ts +94 -12
- package/src/server/index.ts +1021 -190
- package/src/server/lifecycle.ts +336 -14
- package/src/server/live.ts +136 -17
- package/src/server/local-management-read-client.ts +90 -0
- package/src/server/local-provider-reload-client.ts +137 -0
- package/src/server/management/agent-settings-routes.ts +433 -116
- package/src/server/management/api-key-usage.ts +31 -5
- package/src/server/management/body.ts +6 -0
- package/src/server/management/codex-prompt-routes.ts +570 -0
- package/src/server/management/combo-routes.ts +64 -25
- package/src/server/management/config-routes.ts +511 -51
- package/src/server/management/context.ts +89 -2
- package/src/server/management/integration-routes.ts +498 -0
- package/src/server/management/lab-automation-routes.ts +206 -0
- package/src/server/management/lab-routes.ts +563 -0
- package/src/server/management/logs-usage-routes.ts +127 -52
- package/src/server/management/model-routes.ts +461 -133
- package/src/server/management/model-rows.ts +167 -0
- package/src/server/management/native-integration-routes.ts +770 -0
- package/src/server/management/oauth-account-routes.ts +90 -8
- package/src/server/management/provider-capability-config.ts +48 -0
- package/src/server/management/provider-routes.ts +836 -159
- package/src/server/management/request-history-routes.ts +191 -0
- package/src/server/management/route-registry.ts +332 -0
- package/src/server/management/routing-analytics-routes.ts +74 -0
- package/src/server/management/routing-profile-routes.ts +380 -0
- package/src/server/management/shared.ts +27 -11
- package/src/server/management/sidebar-routes.ts +47 -31
- package/src/server/management/storage-log-guard-routes.ts +186 -0
- package/src/server/management/sync-response.ts +69 -0
- package/src/server/management/system-restart.ts +289 -33
- package/src/server/management/system-routes.ts +77 -0
- package/src/server/management/usage-summary-cache.ts +9 -1
- package/src/server/management/vision-sidecar-options.ts +167 -0
- package/src/server/management/web-search-sidecar-options.ts +120 -0
- package/src/server/management-api.ts +126 -23
- package/src/server/management-auth.ts +220 -5
- package/src/server/passive-route-linker.ts +66 -0
- package/src/server/port-reclaim.ts +1 -1
- package/src/server/ports.ts +41 -1
- package/src/server/proxy-liveness.ts +161 -10
- package/src/server/readiness.ts +99 -0
- package/src/server/relay-eager.ts +221 -54
- package/src/server/relay.ts +479 -87
- package/src/server/request-decompress.ts +113 -6
- package/src/server/request-log-conversation.ts +51 -0
- package/src/server/request-log.ts +298 -31
- package/src/server/responses/agent-task-recovery-cache.ts +143 -0
- package/src/server/responses/agent-task-recovery.ts +465 -0
- package/src/server/responses/codex-auth-error.ts +55 -0
- package/src/server/responses/collaboration.ts +239 -36
- package/src/server/responses/combo-stream-preflight.ts +178 -0
- package/src/server/responses/compact.ts +444 -72
- package/src/server/responses/core.ts +3579 -436
- package/src/server/responses/empty-completion-guard.ts +333 -0
- package/src/server/responses/encrypted-payload.ts +62 -39
- package/src/server/responses/fetch-helpers.ts +89 -99
- package/src/server/responses/input-admission.ts +187 -0
- package/src/server/responses/pacing-overload.ts +13 -0
- package/src/server/responses/passthrough-error.ts +33 -9
- package/src/server/responses/policy-fallback.ts +178 -0
- package/src/server/responses/responses-field-backfill.ts +343 -0
- package/src/server/responses/terminal-guard.ts +26 -5
- package/src/server/responses/upstream-error.ts +5 -0
- package/src/server/responses/ws-upstream.ts +381 -0
- package/src/server/responses-custom-tool-repair.ts +363 -0
- package/src/server/responses-item-id-repair.ts +54 -6
- package/src/server/responses-json-events.ts +90 -0
- package/src/server/responses-model-rewrite.ts +29 -0
- package/src/server/responses-reasoning-summary-rewrite.ts +178 -0
- package/src/server/responses-snapshot-repair.ts +621 -0
- package/src/server/responses-terminal-repair.ts +363 -0
- package/src/server/responses-tool-search-repair.ts +267 -0
- package/src/server/responses-undeclared-tool-guard.ts +376 -0
- package/src/server/responses.ts +18 -2
- package/src/server/search.ts +78 -13
- package/src/server/sse-frame-buffer.ts +319 -0
- package/src/server/sse-payload-rewrite.ts +110 -22
- package/src/server/startup-action-control.ts +8 -1
- package/src/server/startup-health-cache.ts +19 -1
- package/src/server/system-env.ts +80 -9
- package/src/server/ws-bridge.ts +53 -40
- package/src/service-manager-probe.ts +892 -0
- package/src/service.ts +1153 -94
- package/src/sidecar/auth.ts +92 -0
- package/src/sidecar/candidates.ts +83 -0
- package/src/storage/cleanup.ts +2 -2
- package/src/storage/policy-job.ts +14 -4
- package/src/storage/policy.ts +88 -23
- package/src/storage/scanner.ts +1 -1
- package/src/storage/worker-lifecycle.ts +14 -14
- package/src/tray/windows-tray.ps1 +83 -9
- package/src/tray/windows.ts +43 -16
- package/src/types/accounts.ts +37 -0
- package/src/types/config.ts +911 -0
- package/src/types/provider.ts +614 -0
- package/src/types/request.ts +397 -0
- package/src/types/tools.ts +236 -0
- package/src/types/wire.ts +80 -0
- package/src/types.ts +107 -1237
- package/src/update/index.ts +37 -23
- package/src/update/job.ts +445 -68
- package/src/update/notify.ts +12 -6
- package/src/update/npm-cache-preflight.d.mts +47 -0
- package/src/update/npm-cache-preflight.mjs +201 -0
- package/src/update/transactional-install.d.mts +22 -0
- package/src/update/transactional-install.mjs +266 -0
- package/src/usage/cost.ts +0 -0
- package/src/usage/expected-prices.ts +287 -16
- package/src/usage/log.ts +666 -50
- package/src/usage/summary.ts +388 -17
- package/src/usage/user-cost-overlay-reconciler.ts +313 -0
- package/src/usage/user-cost-overlays.ts +314 -0
- package/src/vision/anthropic-describe.ts +10 -6
- package/src/vision/backends.ts +97 -0
- package/src/vision/describe.ts +27 -16
- package/src/vision/eligibility.ts +250 -0
- package/src/vision/index.ts +238 -24
- package/src/vision/reasoning.ts +55 -0
- package/src/vision/routed-describe.ts +175 -0
- package/src/vision/timeout-bounds.ts +9 -0
- package/src/web-search/anthropic-executor.ts +13 -7
- package/src/web-search/backends.ts +108 -0
- package/src/web-search/exa-executor.ts +119 -0
- package/src/web-search/executor.ts +21 -6
- package/src/web-search/gemini-executor.ts +141 -0
- package/src/web-search/index.ts +150 -15
- package/src/web-search/loop.ts +284 -54
- package/src/web-search/parse.ts +125 -30
- package/src/web-search/sources.ts +60 -0
- package/src/web-search/xai-executor.ts +219 -0
- package/gui/dist/assets/index-DTpMHS4F.js +0 -67
- package/gui/dist/assets/index-ZNVDE3C7.css +0 -1
- package/gui/dist/provider-icons/antigravity.svg +0 -1
- package/gui/dist/provider-icons/claude.svg +0 -1
- package/gui/dist/provider-icons/copilot.svg +0 -1
- package/gui/dist/provider-icons/cursor.svg +0 -2
- package/gui/dist/provider-icons/gemini.svg +0 -1
- package/gui/dist/provider-icons/grok-color.svg +0 -1
- package/gui/dist/provider-icons/kiro.svg +0 -14
- package/src/cli/internal-dispatch.ts +0 -20
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export { importAccounts } from "./service";
|
|
2
|
+
export {
|
|
3
|
+
ACCOUNT_IMPORT_DEADLINE_MS,
|
|
4
|
+
ACCOUNT_IMPORT_FORMAT,
|
|
5
|
+
ACCOUNT_IMPORT_MAX_BYTES,
|
|
6
|
+
ACCOUNT_IMPORT_MAX_REQUEST_BYTES,
|
|
7
|
+
ACCOUNT_IMPORT_PROVIDER,
|
|
8
|
+
} from "./types";
|
|
9
|
+
export type {
|
|
10
|
+
AccountImportCode,
|
|
11
|
+
AccountImportRecordResult,
|
|
12
|
+
AccountImportRequest,
|
|
13
|
+
AccountImportResult,
|
|
14
|
+
AccountImportStatus,
|
|
15
|
+
} from "./types";
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ACCOUNT_IMPORT_MAX_BYTES,
|
|
3
|
+
ACCOUNT_IMPORT_MAX_EMAIL_LENGTH,
|
|
4
|
+
ACCOUNT_IMPORT_MAX_RECORDS,
|
|
5
|
+
ACCOUNT_IMPORT_MAX_REFRESH_TOKEN_BYTES,
|
|
6
|
+
type ParsedCockpitRecord,
|
|
7
|
+
} from "./types";
|
|
8
|
+
|
|
9
|
+
const encoder = new TextEncoder();
|
|
10
|
+
const ALLOWED_RECORD_KEYS = new Set(["email", "refresh_token", "tags", "notes"]);
|
|
11
|
+
|
|
12
|
+
export type CockpitDocumentParseResult =
|
|
13
|
+
| { ok: true; records: ParsedCockpitRecord[] }
|
|
14
|
+
| { ok: false; code: "invalid_document" };
|
|
15
|
+
|
|
16
|
+
function isPlainRecord(value: unknown): value is Record<string, unknown> {
|
|
17
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
18
|
+
const prototype = Object.getPrototypeOf(value);
|
|
19
|
+
return prototype === Object.prototype || prototype === null;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function serializedDocumentSize(document: unknown): number | null {
|
|
23
|
+
try {
|
|
24
|
+
const serialized = JSON.stringify(document);
|
|
25
|
+
return serialized === undefined ? null : encoder.encode(serialized).byteLength;
|
|
26
|
+
} catch {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function validEmail(value: unknown): value is string {
|
|
32
|
+
if (typeof value !== "string" || value.length === 0 || value.length > ACCOUNT_IMPORT_MAX_EMAIL_LENGTH) return false;
|
|
33
|
+
if (value !== value.trim() || /[\x00-\x20\x7f]/.test(value)) return false;
|
|
34
|
+
const at = value.indexOf("@");
|
|
35
|
+
return at > 0 && at === value.lastIndexOf("@") && at < value.length - 1;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function validRefreshToken(value: unknown): value is string {
|
|
39
|
+
return typeof value === "string"
|
|
40
|
+
&& value.length > 0
|
|
41
|
+
&& encoder.encode(value).byteLength <= ACCOUNT_IMPORT_MAX_REFRESH_TOKEN_BYTES
|
|
42
|
+
&& !/[\s\x7f]/.test(value);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function validMetadata(record: Record<string, unknown>): boolean {
|
|
46
|
+
if (record.tags !== undefined && (
|
|
47
|
+
!Array.isArray(record.tags)
|
|
48
|
+
|| record.tags.some(tag => typeof tag !== "string")
|
|
49
|
+
)) return false;
|
|
50
|
+
return record.notes === undefined || typeof record.notes === "string";
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function parseRecord(value: unknown, index: number): ParsedCockpitRecord {
|
|
54
|
+
if (!isPlainRecord(value)) return { index, code: "invalid_record" };
|
|
55
|
+
if (Object.keys(value).some(key => !ALLOWED_RECORD_KEYS.has(key))) return { index, code: "invalid_record" };
|
|
56
|
+
if (!validEmail(value.email) || !validRefreshToken(value.refresh_token) || !validMetadata(value)) {
|
|
57
|
+
return { index, code: "invalid_record" };
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
index,
|
|
61
|
+
record: {
|
|
62
|
+
email: value.email.toLowerCase(),
|
|
63
|
+
refreshToken: value.refresh_token,
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function parseCockpitAccountDocument(document: unknown): CockpitDocumentParseResult {
|
|
69
|
+
const size = serializedDocumentSize(document);
|
|
70
|
+
if (size === null || size > ACCOUNT_IMPORT_MAX_BYTES) return { ok: false, code: "invalid_document" };
|
|
71
|
+
if (!Array.isArray(document) || document.length === 0 || document.length > ACCOUNT_IMPORT_MAX_RECORDS) {
|
|
72
|
+
return { ok: false, code: "invalid_document" };
|
|
73
|
+
}
|
|
74
|
+
const seen = new Set<string>();
|
|
75
|
+
const records = document.map((value, index): ParsedCockpitRecord => {
|
|
76
|
+
const parsed = parseRecord(value, index);
|
|
77
|
+
if ("code" in parsed) return parsed;
|
|
78
|
+
if (seen.has(parsed.record.email)) return { index, code: "invalid_record" };
|
|
79
|
+
seen.add(parsed.record.email);
|
|
80
|
+
return parsed;
|
|
81
|
+
});
|
|
82
|
+
return { ok: true, records };
|
|
83
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { createAntigravityAccountImportAdapter } from "./google-antigravity-adapter";
|
|
2
|
+
import {
|
|
3
|
+
ACCOUNT_IMPORT_FORMAT,
|
|
4
|
+
ACCOUNT_IMPORT_PROVIDER,
|
|
5
|
+
type AccountImportAdapter,
|
|
6
|
+
} from "./types";
|
|
7
|
+
|
|
8
|
+
export type AccountImportRegistryResult =
|
|
9
|
+
| { ok: true; adapter: AccountImportAdapter }
|
|
10
|
+
| { ok: false; code: "unsupported_provider" | "unsupported_format" };
|
|
11
|
+
|
|
12
|
+
const antigravityAdapter = createAntigravityAccountImportAdapter();
|
|
13
|
+
|
|
14
|
+
export function resolveAccountImportAdapter(provider: string, format: string): AccountImportRegistryResult {
|
|
15
|
+
if (provider !== ACCOUNT_IMPORT_PROVIDER) return { ok: false, code: "unsupported_provider" };
|
|
16
|
+
if (format !== ACCOUNT_IMPORT_FORMAT) return { ok: false, code: "unsupported_format" };
|
|
17
|
+
return { ok: true, adapter: antigravityAdapter };
|
|
18
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { parseCockpitAccountDocument } from "./parser";
|
|
2
|
+
import { resolveAccountImportAdapter, type AccountImportRegistryResult } from "./registry";
|
|
3
|
+
import {
|
|
4
|
+
AccountImportAbortError,
|
|
5
|
+
throwIfAccountImportAborted,
|
|
6
|
+
} from "./types";
|
|
7
|
+
import type {
|
|
8
|
+
AccountImportRequest,
|
|
9
|
+
AccountImportResult,
|
|
10
|
+
AccountImportRecordResult,
|
|
11
|
+
} from "./types";
|
|
12
|
+
|
|
13
|
+
export type AccountImportServiceResult =
|
|
14
|
+
| { ok: true; result: AccountImportResult }
|
|
15
|
+
| {
|
|
16
|
+
ok: false;
|
|
17
|
+
status: 400 | 408;
|
|
18
|
+
code: "unsupported_provider" | "unsupported_format" | "invalid_document" | "import_cancelled";
|
|
19
|
+
/** True when at least one credential was committed before the terminal failure. */
|
|
20
|
+
changed?: boolean;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export interface AccountImportServiceDeps {
|
|
24
|
+
resolveAdapter(provider: string, format: string): AccountImportRegistryResult;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export async function importAccounts(
|
|
28
|
+
request: AccountImportRequest,
|
|
29
|
+
deps: AccountImportServiceDeps = { resolveAdapter: resolveAccountImportAdapter },
|
|
30
|
+
): Promise<AccountImportServiceResult> {
|
|
31
|
+
// Provider/format admission intentionally precedes any traversal or serialization of the
|
|
32
|
+
// credential-bearing document.
|
|
33
|
+
const resolved = deps.resolveAdapter(request.provider, request.format);
|
|
34
|
+
if (!resolved.ok) return { ok: false, status: 400, code: resolved.code };
|
|
35
|
+
|
|
36
|
+
const parsed = parseCockpitAccountDocument(request.document);
|
|
37
|
+
if (!parsed.ok) return { ok: false, status: 400, code: parsed.code };
|
|
38
|
+
|
|
39
|
+
const results: AccountImportRecordResult[] = [];
|
|
40
|
+
try {
|
|
41
|
+
for (const item of parsed.records) {
|
|
42
|
+
throwIfAccountImportAborted(request.signal);
|
|
43
|
+
if ("code" in item) {
|
|
44
|
+
results.push({ index: item.index, status: "failed", code: item.code });
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
const outcome = await resolved.adapter.importRecord(item.record, request.signal);
|
|
48
|
+
results.push({ index: item.index, ...outcome });
|
|
49
|
+
// Record the committed outcome before observing cancellation. The route uses this
|
|
50
|
+
// internal signal to reconcile live stores and caches even when the public response
|
|
51
|
+
// is the terminal 408 DTO.
|
|
52
|
+
throwIfAccountImportAborted(request.signal);
|
|
53
|
+
}
|
|
54
|
+
} catch (error) {
|
|
55
|
+
if (error instanceof AccountImportAbortError) {
|
|
56
|
+
const changed = results.some(result => result.status === "imported" || result.status === "updated");
|
|
57
|
+
return { ok: false, status: 408, code: "import_cancelled", ...(changed ? { changed: true } : {}) };
|
|
58
|
+
}
|
|
59
|
+
throw error;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const count = (status: AccountImportRecordResult["status"]) =>
|
|
63
|
+
results.filter(result => result.status === status).length;
|
|
64
|
+
return {
|
|
65
|
+
ok: true,
|
|
66
|
+
result: {
|
|
67
|
+
totalCount: results.length,
|
|
68
|
+
importedCount: count("imported"),
|
|
69
|
+
updatedCount: count("updated"),
|
|
70
|
+
failedCount: count("failed"),
|
|
71
|
+
unsupportedCount: count("unsupported"),
|
|
72
|
+
results,
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type { OAuthCredentials } from "../types";
|
|
2
|
+
|
|
3
|
+
export const ACCOUNT_IMPORT_PROVIDER = "google-antigravity" as const;
|
|
4
|
+
export const ACCOUNT_IMPORT_FORMAT = "cockpit-tools" as const;
|
|
5
|
+
export const ACCOUNT_IMPORT_MAX_BYTES = 256 * 1024;
|
|
6
|
+
// The HTTP request also carries the fixed provider/format envelope. Keep that envelope bounded
|
|
7
|
+
// without making a valid document at the 256 KiB contract boundary fail at the API layer.
|
|
8
|
+
export const ACCOUNT_IMPORT_MAX_REQUEST_BYTES = ACCOUNT_IMPORT_MAX_BYTES + 1024;
|
|
9
|
+
// Shared CLI POST timeout and management-route deadline. Individual provider requests keep
|
|
10
|
+
// shorter timeouts; this bounds the full admitted batch (up to ACCOUNT_IMPORT_MAX_RECORDS).
|
|
11
|
+
export const ACCOUNT_IMPORT_DEADLINE_MS = 600_000;
|
|
12
|
+
export const ACCOUNT_IMPORT_MAX_RECORDS = 25;
|
|
13
|
+
export const ACCOUNT_IMPORT_MAX_EMAIL_LENGTH = 254;
|
|
14
|
+
export const ACCOUNT_IMPORT_MAX_REFRESH_TOKEN_BYTES = 16 * 1024;
|
|
15
|
+
|
|
16
|
+
export type AccountImportStatus = "imported" | "updated" | "failed" | "unsupported";
|
|
17
|
+
|
|
18
|
+
export type AccountImportCode =
|
|
19
|
+
| "imported"
|
|
20
|
+
| "updated"
|
|
21
|
+
| "import_cancelled"
|
|
22
|
+
| "unsupported_provider"
|
|
23
|
+
| "unsupported_format"
|
|
24
|
+
| "invalid_document"
|
|
25
|
+
| "invalid_record"
|
|
26
|
+
| "credential_rejected"
|
|
27
|
+
| "identity_mismatch"
|
|
28
|
+
| "missing_project"
|
|
29
|
+
| "persist_failed";
|
|
30
|
+
|
|
31
|
+
export interface AccountImportRecordResult {
|
|
32
|
+
index: number;
|
|
33
|
+
status: AccountImportStatus;
|
|
34
|
+
code: AccountImportCode;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface AccountImportResult {
|
|
38
|
+
totalCount: number;
|
|
39
|
+
importedCount: number;
|
|
40
|
+
updatedCount: number;
|
|
41
|
+
failedCount: number;
|
|
42
|
+
unsupportedCount: number;
|
|
43
|
+
results: AccountImportRecordResult[];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface AccountImportRequest {
|
|
47
|
+
provider: string;
|
|
48
|
+
format: string;
|
|
49
|
+
document: unknown;
|
|
50
|
+
signal?: AbortSignal;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** A secret-free terminal signal for a cancelled import request. */
|
|
54
|
+
export class AccountImportAbortError extends Error {
|
|
55
|
+
constructor() {
|
|
56
|
+
super("Account import cancelled");
|
|
57
|
+
this.name = "AccountImportAbortError";
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function throwIfAccountImportAborted(signal?: AbortSignal): void {
|
|
62
|
+
if (signal?.aborted) throw new AccountImportAbortError();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export interface CockpitAccountRecord {
|
|
66
|
+
email: string;
|
|
67
|
+
refreshToken: string;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export type ParsedCockpitRecord =
|
|
71
|
+
| { index: number; record: CockpitAccountRecord }
|
|
72
|
+
| { index: number; code: "invalid_record" };
|
|
73
|
+
|
|
74
|
+
export type AccountImportRecordOutcome =
|
|
75
|
+
| { status: "imported"; code: "imported" }
|
|
76
|
+
| { status: "updated"; code: "updated" }
|
|
77
|
+
| {
|
|
78
|
+
status: "failed";
|
|
79
|
+
code: "credential_rejected" | "identity_mismatch" | "missing_project" | "persist_failed";
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
export interface AccountImportAdapter {
|
|
83
|
+
readonly provider: typeof ACCOUNT_IMPORT_PROVIDER;
|
|
84
|
+
readonly format: typeof ACCOUNT_IMPORT_FORMAT;
|
|
85
|
+
importRecord(record: CockpitAccountRecord, signal?: AbortSignal): Promise<AccountImportRecordOutcome>;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export interface ValidatedAntigravityCredential extends OAuthCredentials {
|
|
89
|
+
email?: string;
|
|
90
|
+
projectId?: string;
|
|
91
|
+
}
|
package/src/oauth/anthropic.ts
CHANGED
|
@@ -81,10 +81,21 @@ function parseTokenResponse(responseBody: string): AnthropicTokenResponse {
|
|
|
81
81
|
function credsFrom(data: AnthropicTokenResponse, refreshFallback?: string): OAuthCredentials {
|
|
82
82
|
const accountUuid = data.account?.uuid;
|
|
83
83
|
const email = data.account?.email_address;
|
|
84
|
+
// Guard against a missing/non-finite/negative expires_in (malformed upstream
|
|
85
|
+
// response): a NaN expiry would never compare as expired, and a negative
|
|
86
|
+
// duration would stamp an already-past expiry — both block refresh semantics.
|
|
87
|
+
const expiresIn =
|
|
88
|
+
typeof data.expires_in === "number" && Number.isFinite(data.expires_in) && data.expires_in >= 0
|
|
89
|
+
? data.expires_in
|
|
90
|
+
: 3600;
|
|
91
|
+
// The computed timestamp itself must stay finite: Number.MAX_VALUE passes
|
|
92
|
+
// Number.isFinite but overflows to Infinity once multiplied by 1000.
|
|
93
|
+
const computedExpires = Date.now() + expiresIn * 1000 - 5 * 60 * 1000;
|
|
94
|
+
const expires = Number.isFinite(computedExpires) ? computedExpires : Date.now() + 3600 * 1000 - 5 * 60 * 1000;
|
|
84
95
|
return {
|
|
85
96
|
refresh: data.refresh_token || refreshFallback || "",
|
|
86
97
|
access: data.access_token,
|
|
87
|
-
expires
|
|
98
|
+
expires,
|
|
88
99
|
accountId: typeof accountUuid === "string" && accountUuid.length > 0 ? accountUuid : undefined,
|
|
89
100
|
email: typeof email === "string" && email.length > 0 ? email : undefined,
|
|
90
101
|
};
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Change vs source: the success/error page is an inline HTML constant. opencodex's GUI polls
|
|
6
6
|
* GET /api/oauth/status, so it does not need OAuth state injected into the callback page.
|
|
7
7
|
*
|
|
8
|
-
* Handles: port allocation (preferred → random fallback), callback server, CSRF state,
|
|
8
|
+
* Handles: port allocation (preferred → random/manual-only fallback), callback server, CSRF state,
|
|
9
9
|
* manual-input race, 300s timeout. Providers implement generateAuthUrl() + exchangeToken().
|
|
10
10
|
*/
|
|
11
11
|
import { isAddrInUse } from "../server/ports";
|
|
@@ -131,8 +131,14 @@ export abstract class OAuthCallbackFlow {
|
|
|
131
131
|
}
|
|
132
132
|
const redirectUri = `http://${this.callbackHostname}:${this.preferredPort}${this.callbackPath}`;
|
|
133
133
|
return { servers, redirectUri };
|
|
134
|
-
} catch {
|
|
134
|
+
} catch (error) {
|
|
135
135
|
if (this.redirectUri) {
|
|
136
|
+
// Fixed OAuth redirect URIs cannot move to a random port. Remote dashboards can
|
|
137
|
+
// still complete the same state/PKCE flow by pasting the final redirect URL or
|
|
138
|
+
// authorization code, so do not make a local listener a prerequisite for that path.
|
|
139
|
+
if (this.ctrl.onManualCodeInput && isAddrInUse(error)) {
|
|
140
|
+
return { servers: [], redirectUri: this.redirectUri };
|
|
141
|
+
}
|
|
136
142
|
throw new Error(
|
|
137
143
|
`OAuth callback port ${this.preferredPort} unavailable; cannot fall back to a random port when redirectUri is set`,
|
|
138
144
|
);
|
|
@@ -270,10 +276,30 @@ export function parseCallbackInput(input: string): { kind: "url" | "query" | "ra
|
|
|
270
276
|
|
|
271
277
|
try {
|
|
272
278
|
const url = new URL(value);
|
|
279
|
+
// Also read the fragment. No provider configured here returns one — every
|
|
280
|
+
// OAuthCallbackFlow asks for response_type=code without response_mode, so
|
|
281
|
+
// the parameters land in the query — but a full URL whose parameters sit in
|
|
282
|
+
// the hash parses as a valid URL with no code, and reading only the query
|
|
283
|
+
// rejects it as "no authorization code found in input". This is the one
|
|
284
|
+
// place a fragment-returning provider would land, and the raw branch below
|
|
285
|
+
// already understands `code#state`.
|
|
286
|
+
//
|
|
287
|
+
// The query wins as a WHOLE when it carries the response, and the two
|
|
288
|
+
// fields are never mixed across collections. Reading `code` and `state`
|
|
289
|
+
// independently would accept `?state=<expected>#code=<other>` — one
|
|
290
|
+
// response assembled from two sources — which is exactly the confusion a
|
|
291
|
+
// state check exists to prevent. An authorization response arrives in one
|
|
292
|
+
// place; treat it that way.
|
|
293
|
+
//
|
|
294
|
+
// Only `code` and `state` are read — never a token. This repo does not
|
|
295
|
+
// implement the implicit grant and a paste field must not become the place
|
|
296
|
+
// it appears.
|
|
297
|
+
const fragment = new URLSearchParams(url.hash.replace(/^#/, ""));
|
|
298
|
+
const source = url.searchParams.has("code") ? url.searchParams : fragment;
|
|
273
299
|
return {
|
|
274
300
|
kind: "url",
|
|
275
|
-
code:
|
|
276
|
-
state:
|
|
301
|
+
code: source.get("code") ?? undefined,
|
|
302
|
+
state: source.get("state") ?? undefined,
|
|
277
303
|
};
|
|
278
304
|
} catch {
|
|
279
305
|
// Not a URL - check for query string format
|
package/src/oauth/chatgpt.ts
CHANGED
|
@@ -49,10 +49,21 @@ export function extractEmail(idToken?: string, accessToken?: string): string | u
|
|
|
49
49
|
function credsFromToken(data: Record<string, unknown>): OAuthCredentials {
|
|
50
50
|
const idToken = typeof data.id_token === "string" ? data.id_token : undefined;
|
|
51
51
|
const accessToken = data.access_token as string;
|
|
52
|
+
// ?? only guards null/undefined; NaN or a string expires_in would otherwise
|
|
53
|
+
// produce a NaN expiry that never compares as expired, and a negative duration
|
|
54
|
+
// would stamp an already-past expiry — both block refresh semantics.
|
|
55
|
+
const expiresIn =
|
|
56
|
+
typeof data.expires_in === "number" && Number.isFinite(data.expires_in) && data.expires_in >= 0
|
|
57
|
+
? data.expires_in
|
|
58
|
+
: 3600;
|
|
59
|
+
// The computed timestamp itself must stay finite: Number.MAX_VALUE passes
|
|
60
|
+
// Number.isFinite but overflows to Infinity once multiplied by 1000.
|
|
61
|
+
const computedExpires = Date.now() + expiresIn * 1000;
|
|
62
|
+
const expires = Number.isFinite(computedExpires) ? computedExpires : Date.now() + 3600 * 1000;
|
|
52
63
|
return {
|
|
53
64
|
access: accessToken,
|
|
54
65
|
refresh: (data.refresh_token as string) ?? "",
|
|
55
|
-
expires
|
|
66
|
+
expires,
|
|
56
67
|
accountId: extractAccountId(idToken, accessToken),
|
|
57
68
|
email: extractEmail(idToken, accessToken),
|
|
58
69
|
};
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cline OAuth — automatic session import from local Cline CLI / VS Code extension
|
|
3
|
+
* and background WorkOS token refresh.
|
|
4
|
+
*
|
|
5
|
+
* Security: tokens are read securely from local config files and refreshed directly
|
|
6
|
+
* against WorkOS API (api.workos.com). Tokens and credentials are never logged.
|
|
7
|
+
*/
|
|
8
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
9
|
+
import { clineConfigPath } from "../clients/config-export";
|
|
10
|
+
import type { OAuthController, OAuthCredentials } from "./types";
|
|
11
|
+
|
|
12
|
+
export const WORKOS_CLIENT_ID = "client_01K3A541FN8TA3EPPHTD2325AR";
|
|
13
|
+
export const WORKOS_AUTH_URL = "https://api.workos.com/user_management/authenticate";
|
|
14
|
+
const WORKOS_TOKEN_PREFIX = "workos:";
|
|
15
|
+
|
|
16
|
+
export interface ClineLoginOptions {
|
|
17
|
+
importLocal?: "fallback" | "off";
|
|
18
|
+
forceLogin?: boolean;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface ClineProvidersJson {
|
|
22
|
+
providers?: {
|
|
23
|
+
cline?: {
|
|
24
|
+
settings?: {
|
|
25
|
+
provider?: string;
|
|
26
|
+
auth?: {
|
|
27
|
+
accessToken?: unknown;
|
|
28
|
+
refreshToken?: unknown;
|
|
29
|
+
expiresAt?: unknown;
|
|
30
|
+
accountId?: unknown;
|
|
31
|
+
metadata?: {
|
|
32
|
+
userInfo?: {
|
|
33
|
+
email?: unknown;
|
|
34
|
+
name?: unknown;
|
|
35
|
+
subject?: unknown;
|
|
36
|
+
clineUserId?: unknown;
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
interface WorkOSAuthResponse {
|
|
46
|
+
access_token?: unknown;
|
|
47
|
+
refresh_token?: unknown;
|
|
48
|
+
user?: {
|
|
49
|
+
id?: unknown;
|
|
50
|
+
external_id?: unknown;
|
|
51
|
+
email?: unknown;
|
|
52
|
+
first_name?: unknown;
|
|
53
|
+
last_name?: unknown;
|
|
54
|
+
};
|
|
55
|
+
error?: unknown;
|
|
56
|
+
error_description?: unknown;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function decodeJwtExpiry(token: string): number {
|
|
60
|
+
try {
|
|
61
|
+
const rawJwt = token.startsWith(WORKOS_TOKEN_PREFIX) ? token.slice(WORKOS_TOKEN_PREFIX.length) : token;
|
|
62
|
+
const parts = rawJwt.split(".");
|
|
63
|
+
if (parts.length === 3 && parts[1]) {
|
|
64
|
+
const payload = JSON.parse(Buffer.from(parts[1], "base64url").toString("utf-8")) as { exp?: unknown };
|
|
65
|
+
if (typeof payload.exp === "number" && Number.isFinite(payload.exp)) {
|
|
66
|
+
return payload.exp * 1000;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
} catch {
|
|
70
|
+
// fallback below
|
|
71
|
+
}
|
|
72
|
+
return Date.now() + 3600_000;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function formatClineAccessToken(token: string): string {
|
|
76
|
+
return token.startsWith(WORKOS_TOKEN_PREFIX) ? token : `${WORKOS_TOKEN_PREFIX}${token}`;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function detectLocalClineToken(): OAuthCredentials | null {
|
|
80
|
+
const configPath = clineConfigPath();
|
|
81
|
+
if (!existsSync(configPath)) return null;
|
|
82
|
+
|
|
83
|
+
try {
|
|
84
|
+
const raw = JSON.parse(readFileSync(configPath, "utf8")) as ClineProvidersJson;
|
|
85
|
+
const auth = raw.providers?.cline?.settings?.auth;
|
|
86
|
+
if (!auth || typeof auth.accessToken !== "string" || typeof auth.refreshToken !== "string") {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const accessToken = auth.accessToken.trim();
|
|
91
|
+
const refreshToken = auth.refreshToken.trim();
|
|
92
|
+
if (!accessToken || !refreshToken) return null;
|
|
93
|
+
|
|
94
|
+
const expiresAt = typeof auth.expiresAt === "number" && Number.isFinite(auth.expiresAt)
|
|
95
|
+
? auth.expiresAt
|
|
96
|
+
: decodeJwtExpiry(accessToken);
|
|
97
|
+
|
|
98
|
+
const userInfo = auth.metadata?.userInfo;
|
|
99
|
+
const accountId = typeof auth.accountId === "string" && auth.accountId.length > 0
|
|
100
|
+
? auth.accountId
|
|
101
|
+
: typeof userInfo?.clineUserId === "string" && userInfo.clineUserId.length > 0
|
|
102
|
+
? userInfo.clineUserId
|
|
103
|
+
: typeof userInfo?.subject === "string" && userInfo.subject.length > 0
|
|
104
|
+
? userInfo.subject
|
|
105
|
+
: undefined;
|
|
106
|
+
|
|
107
|
+
const email = typeof userInfo?.email === "string" && userInfo.email.length > 0
|
|
108
|
+
? userInfo.email
|
|
109
|
+
: undefined;
|
|
110
|
+
|
|
111
|
+
return {
|
|
112
|
+
access: formatClineAccessToken(accessToken),
|
|
113
|
+
refresh: refreshToken,
|
|
114
|
+
expires: expiresAt,
|
|
115
|
+
...(accountId ? { accountId } : {}),
|
|
116
|
+
...(email ? { email } : {}),
|
|
117
|
+
source: "local-cli",
|
|
118
|
+
};
|
|
119
|
+
} catch {
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export async function refreshClineToken(
|
|
125
|
+
refreshToken: string,
|
|
126
|
+
signal?: AbortSignal,
|
|
127
|
+
credential?: OAuthCredentials,
|
|
128
|
+
): Promise<OAuthCredentials> {
|
|
129
|
+
if (signal?.aborted) {
|
|
130
|
+
throw signal.reason ?? new DOMException("Cline token refresh aborted", "AbortError");
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const response = await fetch(WORKOS_AUTH_URL, {
|
|
134
|
+
method: "POST",
|
|
135
|
+
headers: {
|
|
136
|
+
"Content-Type": "application/json",
|
|
137
|
+
Accept: "application/json",
|
|
138
|
+
},
|
|
139
|
+
body: JSON.stringify({
|
|
140
|
+
client_id: WORKOS_CLIENT_ID,
|
|
141
|
+
grant_type: "refresh_token",
|
|
142
|
+
refresh_token: refreshToken,
|
|
143
|
+
}),
|
|
144
|
+
signal,
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
if (!response.ok) {
|
|
148
|
+
const body = await response.text().catch(() => "");
|
|
149
|
+
throw new Error(`Cline WorkOS token refresh failed (HTTP ${response.status}): ${body || response.statusText}`);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const data = (await response.json()) as WorkOSAuthResponse;
|
|
153
|
+
if (typeof data.access_token !== "string" || !data.access_token) {
|
|
154
|
+
throw new Error(`Cline token refresh returned no access_token: ${JSON.stringify(data)}`);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const nextRefreshToken = typeof data.refresh_token === "string" && data.refresh_token
|
|
158
|
+
? data.refresh_token
|
|
159
|
+
: refreshToken;
|
|
160
|
+
|
|
161
|
+
const access = formatClineAccessToken(data.access_token);
|
|
162
|
+
const expires = decodeJwtExpiry(data.access_token);
|
|
163
|
+
|
|
164
|
+
const accountId = typeof data.user?.external_id === "string" && data.user.external_id
|
|
165
|
+
? data.user.external_id
|
|
166
|
+
: typeof data.user?.id === "string" && data.user.id
|
|
167
|
+
? data.user.id
|
|
168
|
+
: credential?.accountId;
|
|
169
|
+
|
|
170
|
+
const email = typeof data.user?.email === "string" && data.user.email
|
|
171
|
+
? data.user.email
|
|
172
|
+
: credential?.email;
|
|
173
|
+
|
|
174
|
+
return {
|
|
175
|
+
access,
|
|
176
|
+
refresh: nextRefreshToken,
|
|
177
|
+
expires,
|
|
178
|
+
...(accountId ? { accountId } : {}),
|
|
179
|
+
...(email ? { email } : {}),
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
export async function loginCline(
|
|
184
|
+
ctrl?: OAuthController,
|
|
185
|
+
options: ClineLoginOptions = {},
|
|
186
|
+
): Promise<OAuthCredentials> {
|
|
187
|
+
if (options.importLocal !== "off") {
|
|
188
|
+
ctrl?.onProgress?.("Checking local Cline CLI and VS Code installation for active session...");
|
|
189
|
+
const local = detectLocalClineToken();
|
|
190
|
+
if (local) {
|
|
191
|
+
if (local.expires <= Date.now() + 60_000) {
|
|
192
|
+
ctrl?.onProgress?.("Local Cline session token expired; refreshing via WorkOS...");
|
|
193
|
+
return await refreshClineToken(local.refresh, ctrl?.signal, local);
|
|
194
|
+
}
|
|
195
|
+
ctrl?.onProgress?.("Imported active Cline session successfully.");
|
|
196
|
+
return local;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
throw new Error(
|
|
201
|
+
"No local Cline session found. Please log in to Cline via the VS Code extension or Cline CLI (`cline`), then re-run `ocx login cline` to import your account.",
|
|
202
|
+
);
|
|
203
|
+
}
|