@mastra/code-sdk 0.0.0-fix-workflow-step-timing-and-parallel-status-20260715180716
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 +285 -0
- package/LICENSE.md +30 -0
- package/README.md +50 -0
- package/dist/acp/agent.d.ts +35 -0
- package/dist/acp/agent.d.ts.map +1 -0
- package/dist/acp/agent.js +173 -0
- package/dist/acp/agent.js.map +1 -0
- package/dist/acp/event-mapper.d.ts +22 -0
- package/dist/acp/event-mapper.d.ts.map +1 -0
- package/dist/acp/event-mapper.js +166 -0
- package/dist/acp/event-mapper.js.map +1 -0
- package/dist/acp/index.d.ts +8 -0
- package/dist/acp/index.d.ts.map +1 -0
- package/dist/acp/index.js +54 -0
- package/dist/acp/index.js.map +1 -0
- package/dist/acp/server.d.ts +7 -0
- package/dist/acp/server.d.ts.map +1 -0
- package/dist/acp/server.js +34 -0
- package/dist/acp/server.js.map +1 -0
- package/dist/acp.d.ts +2 -0
- package/dist/acp.d.ts.map +1 -0
- package/dist/acp.js +5 -0
- package/dist/acp.js.map +1 -0
- package/dist/agents/instructions.d.ts +6 -0
- package/dist/agents/instructions.d.ts.map +1 -0
- package/dist/agents/instructions.js +41 -0
- package/dist/agents/instructions.js.map +1 -0
- package/dist/agents/mastracode-gateway.d.ts +67 -0
- package/dist/agents/mastracode-gateway.d.ts.map +1 -0
- package/dist/agents/mastracode-gateway.js +446 -0
- package/dist/agents/mastracode-gateway.js.map +1 -0
- package/dist/agents/memory.d.ts +13 -0
- package/dist/agents/memory.d.ts.map +1 -0
- package/dist/agents/memory.js +107 -0
- package/dist/agents/memory.js.map +1 -0
- package/dist/agents/model.d.ts +55 -0
- package/dist/agents/model.d.ts.map +1 -0
- package/dist/agents/model.js +115 -0
- package/dist/agents/model.js.map +1 -0
- package/dist/agents/modes/build.d.ts +10 -0
- package/dist/agents/modes/build.d.ts.map +1 -0
- package/dist/agents/modes/build.js +45 -0
- package/dist/agents/modes/build.js.map +1 -0
- package/dist/agents/modes/explore.d.ts +10 -0
- package/dist/agents/modes/explore.d.ts.map +1 -0
- package/dist/agents/modes/explore.js +38 -0
- package/dist/agents/modes/explore.js.map +1 -0
- package/dist/agents/modes/plan.d.ts +6 -0
- package/dist/agents/modes/plan.d.ts.map +1 -0
- package/dist/agents/modes/plan.js +38 -0
- package/dist/agents/modes/plan.js.map +1 -0
- package/dist/agents/prompts/agent-instructions.d.ts +20 -0
- package/dist/agents/prompts/agent-instructions.d.ts.map +1 -0
- package/dist/agents/prompts/agent-instructions.js +82 -0
- package/dist/agents/prompts/agent-instructions.js.map +1 -0
- package/dist/agents/prompts/build.d.ts +12 -0
- package/dist/agents/prompts/build.d.ts.map +1 -0
- package/dist/agents/prompts/build.js +73 -0
- package/dist/agents/prompts/build.js.map +1 -0
- package/dist/agents/prompts/fast.d.ts +5 -0
- package/dist/agents/prompts/fast.d.ts.map +1 -0
- package/dist/agents/prompts/fast.js +22 -0
- package/dist/agents/prompts/fast.js.map +1 -0
- package/dist/agents/prompts/index.d.ts +19 -0
- package/dist/agents/prompts/index.d.ts.map +1 -0
- package/dist/agents/prompts/index.js +57 -0
- package/dist/agents/prompts/index.js.map +1 -0
- package/dist/agents/prompts/model.d.ts +5 -0
- package/dist/agents/prompts/model.d.ts.map +1 -0
- package/dist/agents/prompts/model.js +22 -0
- package/dist/agents/prompts/model.js.map +1 -0
- package/dist/agents/prompts/plan.d.ts +6 -0
- package/dist/agents/prompts/plan.d.ts.map +1 -0
- package/dist/agents/prompts/plan.js +107 -0
- package/dist/agents/prompts/plan.js.map +1 -0
- package/dist/agents/prompts/tool-guidance.d.ts +13 -0
- package/dist/agents/prompts/tool-guidance.d.ts.map +1 -0
- package/dist/agents/prompts/tool-guidance.js +181 -0
- package/dist/agents/prompts/tool-guidance.js.map +1 -0
- package/dist/agents/sandbox-filesystem.d.ts +89 -0
- package/dist/agents/sandbox-filesystem.d.ts.map +1 -0
- package/dist/agents/sandbox-filesystem.js +268 -0
- package/dist/agents/sandbox-filesystem.js.map +1 -0
- package/dist/agents/sandbox-reattach.d.ts +19 -0
- package/dist/agents/sandbox-reattach.d.ts.map +1 -0
- package/dist/agents/sandbox-reattach.js +17 -0
- package/dist/agents/sandbox-reattach.js.map +1 -0
- package/dist/agents/thread-caveman-state.d.ts +17 -0
- package/dist/agents/thread-caveman-state.d.ts.map +1 -0
- package/dist/agents/thread-caveman-state.js +96 -0
- package/dist/agents/thread-caveman-state.js.map +1 -0
- package/dist/agents/tool-availability.d.ts +10 -0
- package/dist/agents/tool-availability.d.ts.map +1 -0
- package/dist/agents/tool-availability.js +105 -0
- package/dist/agents/tool-availability.js.map +1 -0
- package/dist/agents/tools.d.ts +19 -0
- package/dist/agents/tools.d.ts.map +1 -0
- package/dist/agents/tools.js +145 -0
- package/dist/agents/tools.js.map +1 -0
- package/dist/agents/workspace.d.ts +22 -0
- package/dist/agents/workspace.d.ts.map +1 -0
- package/dist/agents/workspace.js +226 -0
- package/dist/agents/workspace.js.map +1 -0
- package/dist/analytics.d.ts +18 -0
- package/dist/analytics.d.ts.map +1 -0
- package/dist/analytics.js +152 -0
- package/dist/analytics.js.map +1 -0
- package/dist/auth/index.d.ts +9 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +11 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/pkce.d.ts +13 -0
- package/dist/auth/pkce.d.ts.map +1 -0
- package/dist/auth/pkce.js +21 -0
- package/dist/auth/pkce.js.map +1 -0
- package/dist/auth/providers/anthropic.d.ts +17 -0
- package/dist/auth/providers/anthropic.d.ts.map +1 -0
- package/dist/auth/providers/anthropic.js +94 -0
- package/dist/auth/providers/anthropic.js.map +1 -0
- package/dist/auth/providers/github-copilot.d.ts +100 -0
- package/dist/auth/providers/github-copilot.d.ts.map +1 -0
- package/dist/auth/providers/github-copilot.js +302 -0
- package/dist/auth/providers/github-copilot.js.map +1 -0
- package/dist/auth/providers/openai-codex.d.ts +95 -0
- package/dist/auth/providers/openai-codex.d.ts.map +1 -0
- package/dist/auth/providers/openai-codex.js +527 -0
- package/dist/auth/providers/openai-codex.js.map +1 -0
- package/dist/auth/storage.d.ts +91 -0
- package/dist/auth/storage.d.ts.map +1 -0
- package/dist/auth/storage.js +187 -0
- package/dist/auth/storage.js.map +1 -0
- package/dist/auth/types.d.ts +68 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/auth/types.js +1 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/clipboard/index.d.ts +26 -0
- package/dist/clipboard/index.d.ts.map +1 -0
- package/dist/clipboard/index.js +192 -0
- package/dist/clipboard/index.js.map +1 -0
- package/dist/constants.d.ts +10 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +23 -0
- package/dist/constants.js.map +1 -0
- package/dist/error-classification.d.ts +10 -0
- package/dist/error-classification.d.ts.map +1 -0
- package/dist/error-classification.js +14 -0
- package/dist/error-classification.js.map +1 -0
- package/dist/evals/context-builder.d.ts +41 -0
- package/dist/evals/context-builder.d.ts.map +1 -0
- package/dist/evals/context-builder.js +120 -0
- package/dist/evals/context-builder.js.map +1 -0
- package/dist/evals/index.d.ts +4 -0
- package/dist/evals/index.d.ts.map +1 -0
- package/dist/evals/index.js +8 -0
- package/dist/evals/index.js.map +1 -0
- package/dist/evals/scorers/classify-command.d.ts +31 -0
- package/dist/evals/scorers/classify-command.d.ts.map +1 -0
- package/dist/evals/scorers/classify-command.js +52 -0
- package/dist/evals/scorers/classify-command.js.map +1 -0
- package/dist/evals/scorers/efficiency.d.ts +44 -0
- package/dist/evals/scorers/efficiency.d.ts.map +1 -0
- package/dist/evals/scorers/efficiency.js +201 -0
- package/dist/evals/scorers/efficiency.js.map +1 -0
- package/dist/evals/scorers/extract-tools.d.ts +25 -0
- package/dist/evals/scorers/extract-tools.d.ts.map +1 -0
- package/dist/evals/scorers/extract-tools.js +56 -0
- package/dist/evals/scorers/extract-tools.js.map +1 -0
- package/dist/evals/scorers/index.d.ts +3 -0
- package/dist/evals/scorers/index.d.ts.map +1 -0
- package/dist/evals/scorers/index.js +7 -0
- package/dist/evals/scorers/index.js.map +1 -0
- package/dist/evals/scorers/outcome.d.ts +49 -0
- package/dist/evals/scorers/outcome.d.ts.map +1 -0
- package/dist/evals/scorers/outcome.js +238 -0
- package/dist/evals/scorers/outcome.js.map +1 -0
- package/dist/headless/cli.d.ts +42 -0
- package/dist/headless/cli.d.ts.map +1 -0
- package/dist/headless/cli.js +196 -0
- package/dist/headless/cli.js.map +1 -0
- package/dist/headless/flags.d.ts +33 -0
- package/dist/headless/flags.d.ts.map +1 -0
- package/dist/headless/flags.js +188 -0
- package/dist/headless/flags.js.map +1 -0
- package/dist/headless/format.d.ts +38 -0
- package/dist/headless/format.d.ts.map +1 -0
- package/dist/headless/format.js +85 -0
- package/dist/headless/format.js.map +1 -0
- package/dist/headless/index.d.ts +25 -0
- package/dist/headless/index.d.ts.map +1 -0
- package/dist/headless/index.js +32 -0
- package/dist/headless/index.js.map +1 -0
- package/dist/headless/policy.d.ts +17 -0
- package/dist/headless/policy.d.ts.map +1 -0
- package/dist/headless/policy.js +38 -0
- package/dist/headless/policy.js.map +1 -0
- package/dist/headless/run-mc.d.ts +7 -0
- package/dist/headless/run-mc.d.ts.map +1 -0
- package/dist/headless/run-mc.js +296 -0
- package/dist/headless/run-mc.js.map +1 -0
- package/dist/headless/types.d.ts +134 -0
- package/dist/headless/types.d.ts.map +1 -0
- package/dist/headless/types.js +9 -0
- package/dist/headless/types.js.map +1 -0
- package/dist/hooks/config.d.ts +11 -0
- package/dist/hooks/config.d.ts.map +1 -0
- package/dist/hooks/config.js +78 -0
- package/dist/hooks/config.js.map +1 -0
- package/dist/hooks/executor.d.ts +13 -0
- package/dist/hooks/executor.d.ts.map +1 -0
- package/dist/hooks/executor.js +125 -0
- package/dist/hooks/executor.js.map +1 -0
- package/dist/hooks/index.d.ts +6 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +16 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/manager.d.ts +47 -0
- package/dist/hooks/manager.d.ts.map +1 -0
- package/dist/hooks/manager.js +284 -0
- package/dist/hooks/manager.js.map +1 -0
- package/dist/hooks/types.d.ts +152 -0
- package/dist/hooks/types.d.ts.map +1 -0
- package/dist/hooks/types.js +7 -0
- package/dist/hooks/types.js.map +1 -0
- package/dist/index.d.ts +243 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +730 -0
- package/dist/index.js.map +1 -0
- package/dist/ipc/ipc-reporter.d.ts +14 -0
- package/dist/ipc/ipc-reporter.d.ts.map +1 -0
- package/dist/ipc/ipc-reporter.js +24 -0
- package/dist/ipc/ipc-reporter.js.map +1 -0
- package/dist/lsp/client.d.ts +56 -0
- package/dist/lsp/client.d.ts.map +1 -0
- package/dist/lsp/client.js +309 -0
- package/dist/lsp/client.js.map +1 -0
- package/dist/lsp/index.d.ts +4 -0
- package/dist/lsp/index.d.ts.map +1 -0
- package/dist/lsp/index.js +9 -0
- package/dist/lsp/index.js.map +1 -0
- package/dist/lsp/language.d.ts +9 -0
- package/dist/lsp/language.d.ts.map +1 -0
- package/dist/lsp/language.js +48 -0
- package/dist/lsp/language.js.map +1 -0
- package/dist/lsp/manager.d.ts +34 -0
- package/dist/lsp/manager.d.ts.map +1 -0
- package/dist/lsp/manager.js +97 -0
- package/dist/lsp/manager.js.map +1 -0
- package/dist/lsp/server.d.ts +27 -0
- package/dist/lsp/server.d.ts.map +1 -0
- package/dist/lsp/server.js +128 -0
- package/dist/lsp/server.js.map +1 -0
- package/dist/lsp/workspace.d.ts +9 -0
- package/dist/lsp/workspace.d.ts.map +1 -0
- package/dist/lsp/workspace.js +52 -0
- package/dist/lsp/workspace.js.map +1 -0
- package/dist/mcp/config.d.ts +34 -0
- package/dist/mcp/config.d.ts.map +1 -0
- package/dist/mcp/config.js +205 -0
- package/dist/mcp/config.js.map +1 -0
- package/dist/mcp/index.d.ts +5 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +10 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/manager.d.ts +49 -0
- package/dist/mcp/manager.d.ts.map +1 -0
- package/dist/mcp/manager.js +374 -0
- package/dist/mcp/manager.js.map +1 -0
- package/dist/mcp/types.d.ts +85 -0
- package/dist/mcp/types.d.ts.map +1 -0
- package/dist/mcp/types.js +1 -0
- package/dist/mcp/types.js.map +1 -0
- package/dist/onboarding/custom-packs.d.ts +7 -0
- package/dist/onboarding/custom-packs.d.ts.map +1 -0
- package/dist/onboarding/custom-packs.js +20 -0
- package/dist/onboarding/custom-packs.js.map +1 -0
- package/dist/onboarding/custom-providers.d.ts +4 -0
- package/dist/onboarding/custom-providers.d.ts.map +1 -0
- package/dist/onboarding/custom-providers.js +28 -0
- package/dist/onboarding/custom-providers.js.map +1 -0
- package/dist/onboarding/index.d.ts +5 -0
- package/dist/onboarding/index.d.ts.map +1 -0
- package/dist/onboarding/index.js +21 -0
- package/dist/onboarding/index.js.map +1 -0
- package/dist/onboarding/om-settings.d.ts +20 -0
- package/dist/onboarding/om-settings.d.ts.map +1 -0
- package/dist/onboarding/om-settings.js +26 -0
- package/dist/onboarding/om-settings.js.map +1 -0
- package/dist/onboarding/packs.d.ts +48 -0
- package/dist/onboarding/packs.d.ts.map +1 -0
- package/dist/onboarding/packs.js +111 -0
- package/dist/onboarding/packs.js.map +1 -0
- package/dist/onboarding/settings.d.ts +327 -0
- package/dist/onboarding/settings.d.ts.map +1 -0
- package/dist/onboarding/settings.js +598 -0
- package/dist/onboarding/settings.js.map +1 -0
- package/dist/permissions.d.ts +55 -0
- package/dist/permissions.d.ts.map +1 -0
- package/dist/permissions.js +119 -0
- package/dist/permissions.js.map +1 -0
- package/dist/plugin.d.ts +81 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +30 -0
- package/dist/plugin.js.map +1 -0
- package/dist/plugins/dependencies.d.ts +9 -0
- package/dist/plugins/dependencies.d.ts.map +1 -0
- package/dist/plugins/dependencies.js +111 -0
- package/dist/plugins/dependencies.js.map +1 -0
- package/dist/plugins/install.d.ts +21 -0
- package/dist/plugins/install.d.ts.map +1 -0
- package/dist/plugins/install.js +200 -0
- package/dist/plugins/install.js.map +1 -0
- package/dist/plugins/loader.d.ts +15 -0
- package/dist/plugins/loader.d.ts.map +1 -0
- package/dist/plugins/loader.js +221 -0
- package/dist/plugins/loader.js.map +1 -0
- package/dist/plugins/manager.d.ts +60 -0
- package/dist/plugins/manager.d.ts.map +1 -0
- package/dist/plugins/manager.js +378 -0
- package/dist/plugins/manager.js.map +1 -0
- package/dist/plugins/manifest.d.ts +14 -0
- package/dist/plugins/manifest.d.ts.map +1 -0
- package/dist/plugins/manifest.js +75 -0
- package/dist/plugins/manifest.js.map +1 -0
- package/dist/plugins/package-link.d.ts +3 -0
- package/dist/plugins/package-link.d.ts.map +1 -0
- package/dist/plugins/package-link.js +77 -0
- package/dist/plugins/package-link.js.map +1 -0
- package/dist/plugins/paths.d.ts +10 -0
- package/dist/plugins/paths.d.ts.map +1 -0
- package/dist/plugins/paths.js +26 -0
- package/dist/plugins/paths.js.map +1 -0
- package/dist/plugins/registry.d.ts +8 -0
- package/dist/plugins/registry.d.ts.map +1 -0
- package/dist/plugins/registry.js +96 -0
- package/dist/plugins/registry.js.map +1 -0
- package/dist/plugins/scaffold.d.ts +10 -0
- package/dist/plugins/scaffold.d.ts.map +1 -0
- package/dist/plugins/scaffold.js +152 -0
- package/dist/plugins/scaffold.js.map +1 -0
- package/dist/plugins/types.d.ts +45 -0
- package/dist/plugins/types.d.ts.map +1 -0
- package/dist/plugins/types.js +1 -0
- package/dist/plugins/types.js.map +1 -0
- package/dist/processors/plan-rejection-abort.d.ts +12 -0
- package/dist/processors/plan-rejection-abort.d.ts.map +1 -0
- package/dist/processors/plan-rejection-abort.js +53 -0
- package/dist/processors/plan-rejection-abort.js.map +1 -0
- package/dist/providers/amazon-bedrock-gateway.d.ts +40 -0
- package/dist/providers/amazon-bedrock-gateway.d.ts.map +1 -0
- package/dist/providers/amazon-bedrock-gateway.js +79 -0
- package/dist/providers/amazon-bedrock-gateway.js.map +1 -0
- package/dist/providers/amazon-bedrock.d.ts +28 -0
- package/dist/providers/amazon-bedrock.d.ts.map +1 -0
- package/dist/providers/amazon-bedrock.js +62 -0
- package/dist/providers/amazon-bedrock.js.map +1 -0
- package/dist/providers/claude-max.d.ts +50 -0
- package/dist/providers/claude-max.d.ts.map +1 -0
- package/dist/providers/claude-max.js +151 -0
- package/dist/providers/claude-max.js.map +1 -0
- package/dist/providers/github-copilot.d.ts +58 -0
- package/dist/providers/github-copilot.d.ts.map +1 -0
- package/dist/providers/github-copilot.js +263 -0
- package/dist/providers/github-copilot.js.map +1 -0
- package/dist/providers/openai-codex.d.ts +70 -0
- package/dist/providers/openai-codex.d.ts.map +1 -0
- package/dist/providers/openai-codex.js +291 -0
- package/dist/providers/openai-codex.js.map +1 -0
- package/dist/schema.d.ts +167 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +92 -0
- package/dist/schema.js.map +1 -0
- package/dist/theme-palette.d.ts +17 -0
- package/dist/theme-palette.d.ts.map +1 -0
- package/dist/theme-palette.js +17 -0
- package/dist/theme-palette.js.map +1 -0
- package/dist/tool-names.d.ts +73 -0
- package/dist/tool-names.d.ts.map +1 -0
- package/dist/tool-names.js +43 -0
- package/dist/tool-names.js.map +1 -0
- package/dist/tools/index.d.ts +6 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +9 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/request-sandbox-access.d.ts +6 -0
- package/dist/tools/request-sandbox-access.d.ts.map +1 -0
- package/dist/tools/request-sandbox-access.js +88 -0
- package/dist/tools/request-sandbox-access.js.map +1 -0
- package/dist/tools/utils.d.ts +20 -0
- package/dist/tools/utils.d.ts.map +1 -0
- package/dist/tools/utils.js +22 -0
- package/dist/tools/utils.js.map +1 -0
- package/dist/tools/web-search.d.ts +35 -0
- package/dist/tools/web-search.d.ts.map +1 -0
- package/dist/tools/web-search.js +65 -0
- package/dist/tools/web-search.js.map +1 -0
- package/dist/utils/binaries.d.ts +7 -0
- package/dist/utils/binaries.d.ts.map +1 -0
- package/dist/utils/binaries.js +74 -0
- package/dist/utils/binaries.js.map +1 -0
- package/dist/utils/debug-log.d.ts +12 -0
- package/dist/utils/debug-log.d.ts.map +1 -0
- package/dist/utils/debug-log.js +55 -0
- package/dist/utils/debug-log.js.map +1 -0
- package/dist/utils/errors.d.ts +36 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +207 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/gateway-sync.d.ts +26 -0
- package/dist/utils/gateway-sync.d.ts.map +1 -0
- package/dist/utils/gateway-sync.js +49 -0
- package/dist/utils/gateway-sync.js.map +1 -0
- package/dist/utils/path-security.d.ts +2 -0
- package/dist/utils/path-security.d.ts.map +1 -0
- package/dist/utils/path-security.js +9 -0
- package/dist/utils/path-security.js.map +1 -0
- package/dist/utils/plan-diff.d.ts +25 -0
- package/dist/utils/plan-diff.d.ts.map +1 -0
- package/dist/utils/plan-diff.js +43 -0
- package/dist/utils/plan-diff.js.map +1 -0
- package/dist/utils/plans.d.ts +56 -0
- package/dist/utils/plans.d.ts.map +1 -0
- package/dist/utils/plans.js +99 -0
- package/dist/utils/plans.js.map +1 -0
- package/dist/utils/project.d.ts +160 -0
- package/dist/utils/project.d.ts.map +1 -0
- package/dist/utils/project.js +302 -0
- package/dist/utils/project.js.map +1 -0
- package/dist/utils/signals-pubsub.d.ts +41 -0
- package/dist/utils/signals-pubsub.d.ts.map +1 -0
- package/dist/utils/signals-pubsub.js +104 -0
- package/dist/utils/signals-pubsub.js.map +1 -0
- package/dist/utils/slash-command-loader.d.ts +52 -0
- package/dist/utils/slash-command-loader.d.ts.map +1 -0
- package/dist/utils/slash-command-loader.js +177 -0
- package/dist/utils/slash-command-loader.js.map +1 -0
- package/dist/utils/slash-command-processor.d.ts +14 -0
- package/dist/utils/slash-command-processor.d.ts.map +1 -0
- package/dist/utils/slash-command-processor.js +96 -0
- package/dist/utils/slash-command-processor.js.map +1 -0
- package/dist/utils/stdin-pipe.d.ts +33 -0
- package/dist/utils/stdin-pipe.d.ts.map +1 -0
- package/dist/utils/stdin-pipe.js +72 -0
- package/dist/utils/stdin-pipe.js.map +1 -0
- package/dist/utils/storage-factory.d.ts +50 -0
- package/dist/utils/storage-factory.d.ts.map +1 -0
- package/dist/utils/storage-factory.js +101 -0
- package/dist/utils/storage-factory.js.map +1 -0
- package/dist/utils/storage-maintenance.d.ts +103 -0
- package/dist/utils/storage-maintenance.d.ts.map +1 -0
- package/dist/utils/storage-maintenance.js +236 -0
- package/dist/utils/storage-maintenance.js.map +1 -0
- package/dist/utils/thread-lock.d.ts +26 -0
- package/dist/utils/thread-lock.d.ts.map +1 -0
- package/dist/utils/thread-lock.js +108 -0
- package/dist/utils/thread-lock.js.map +1 -0
- package/dist/utils/token-estimator.d.ts +3 -0
- package/dist/utils/token-estimator.d.ts.map +1 -0
- package/dist/utils/token-estimator.js +21 -0
- package/dist/utils/token-estimator.js.map +1 -0
- package/dist/utils/update-check.d.ts +52 -0
- package/dist/utils/update-check.d.ts.map +1 -0
- package/dist/utils/update-check.js +177 -0
- package/dist/utils/update-check.js.map +1 -0
- package/dist/voice/stt-registry.d.ts +64 -0
- package/dist/voice/stt-registry.d.ts.map +1 -0
- package/dist/voice/stt-registry.js +126 -0
- package/dist/voice/stt-registry.js.map +1 -0
- package/package.json +94 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/auth/providers/github-copilot.ts"],"sourcesContent":["/**\n * GitHub Copilot OAuth flow\n *\n * Inspired by:\n * - pi-mono: https://github.com/badlogic/pi-mono/blob/main/packages/ai/src/utils/oauth/github-copilot.ts\n * - opencode: https://github.com/anomalyco/opencode/blob/dev/packages/opencode/src/plugin/github-copilot/copilot.ts\n *\n * Storage layout in AuthStorage:\n * - `refresh` holds the long-lived GitHub OAuth access token (used to mint Copilot tokens).\n * - `access` holds the short-lived Copilot bearer token (~30 minutes).\n * - `expires` is the Copilot bearer expiry (ms epoch, with a 5-minute safety buffer).\n * - `enterpriseUrl` is the GitHub Enterprise hostname, or undefined for github.com.\n */\n\nimport type { OAuthCredentials, OAuthLoginCallbacks, OAuthProviderInterface } from '../types.js';\n\nexport type GitHubCopilotCredentials = OAuthCredentials & {\n enterpriseUrl?: string;\n};\n\nconst decode = (s: string): string => atob(s);\n// Copilot's public client ID, encoded to mirror the upstream references.\nconst CLIENT_ID = decode('SXYxLmI1MDdhMDhjODdlY2ZlOTg=');\n\nexport const COPILOT_USER_AGENT = 'GitHubCopilotChat/0.35.0';\n\n/** Headers that Copilot endpoints expect from a VS Code-like client. */\nexport const COPILOT_HEADERS = {\n 'User-Agent': COPILOT_USER_AGENT,\n 'Editor-Version': 'vscode/1.107.0',\n 'Editor-Plugin-Version': 'copilot-chat/0.35.0',\n 'Copilot-Integration-Id': 'vscode-chat',\n} as const;\n\nconst INITIAL_POLL_INTERVAL_MULTIPLIER = 1.2;\nconst SLOW_DOWN_POLL_INTERVAL_MULTIPLIER = 1.4;\n\ntype DeviceCodeResponse = {\n device_code: string;\n user_code: string;\n verification_uri: string;\n interval: number;\n expires_in: number;\n};\n\ntype DeviceTokenSuccessResponse = {\n access_token: string;\n token_type?: string;\n scope?: string;\n};\n\ntype DeviceTokenErrorResponse = {\n error: string;\n error_description?: string;\n interval?: number;\n};\n\n/**\n * Normalize a user-entered Enterprise URL/domain into a hostname (e.g. `company.ghe.com`).\n * Returns null for an empty input or an unparseable URL.\n */\nexport function normalizeDomain(input: string): string | null {\n const trimmed = input.trim();\n if (!trimmed) return null;\n try {\n const url = trimmed.includes('://') ? new URL(trimmed) : new URL(`https://${trimmed}`);\n return url.hostname || null;\n } catch {\n return null;\n }\n}\n\nfunction getUrls(domain: string): {\n deviceCodeUrl: string;\n accessTokenUrl: string;\n copilotTokenUrl: string;\n} {\n return {\n deviceCodeUrl: `https://${domain}/login/device/code`,\n accessTokenUrl: `https://${domain}/login/oauth/access_token`,\n copilotTokenUrl: `https://api.${domain}/copilot_internal/v2/token`,\n };\n}\n\n/**\n * Parse the `proxy-ep` segment from a Copilot bearer token and convert to its API base URL.\n * Token shape: `tid=...;exp=...;proxy-ep=proxy.individual.githubcopilot.com;...`\n */\nfunction getBaseUrlFromToken(token: string): string | null {\n const match = token.match(/proxy-ep=([^;]+)/);\n if (!match) return null;\n const proxyHost = match[1]!;\n const apiHost = proxyHost.replace(/^proxy\\./, 'api.');\n return `https://${apiHost}`;\n}\n\n/**\n * Resolve the Copilot API base URL.\n * Prefers the `proxy-ep` parsed from the bearer token, then falls back to enterprise/individual defaults.\n */\nexport function getGitHubCopilotBaseUrl(token?: string, enterpriseDomain?: string): string {\n if (token) {\n const fromToken = getBaseUrlFromToken(token);\n if (fromToken) return fromToken;\n }\n if (enterpriseDomain) return `https://copilot-api.${enterpriseDomain}`;\n return 'https://api.individual.githubcopilot.com';\n}\n\nasync function fetchJson(url: string, init: RequestInit, signal?: AbortSignal): Promise<unknown> {\n const response = await fetch(url, signal ? { ...init, signal } : init);\n if (!response.ok) {\n const text = await response.text().catch(() => '');\n throw new Error(`${response.status} ${response.statusText}: ${text}`);\n }\n return response.json();\n}\n\nasync function startDeviceFlow(domain: string, signal?: AbortSignal): Promise<DeviceCodeResponse> {\n const urls = getUrls(domain);\n const data = await fetchJson(\n urls.deviceCodeUrl,\n {\n method: 'POST',\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/x-www-form-urlencoded',\n 'User-Agent': COPILOT_USER_AGENT,\n },\n body: new URLSearchParams({\n client_id: CLIENT_ID,\n scope: 'read:user',\n }),\n },\n signal,\n );\n\n if (!data || typeof data !== 'object') {\n throw new Error('Invalid device code response');\n }\n\n const obj = data as Record<string, unknown>;\n const deviceCode = obj.device_code;\n const userCode = obj.user_code;\n const verificationUri = obj.verification_uri;\n const interval = obj.interval;\n const expiresIn = obj.expires_in;\n\n if (\n typeof deviceCode !== 'string' ||\n typeof userCode !== 'string' ||\n typeof verificationUri !== 'string' ||\n typeof interval !== 'number' ||\n typeof expiresIn !== 'number'\n ) {\n throw new Error('Invalid device code response fields');\n }\n\n return {\n device_code: deviceCode,\n user_code: userCode,\n verification_uri: verificationUri,\n interval,\n expires_in: expiresIn,\n };\n}\n\n/** Sleep that can be interrupted by an AbortSignal. */\nfunction abortableSleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(new Error('Login cancelled'));\n return;\n }\n\n let timeout: ReturnType<typeof setTimeout>;\n const onAbort = () => {\n clearTimeout(timeout);\n reject(new Error('Login cancelled'));\n };\n\n timeout = setTimeout(() => {\n signal?.removeEventListener('abort', onAbort);\n resolve();\n }, ms);\n\n signal?.addEventListener('abort', onAbort, { once: true });\n });\n}\n\nasync function pollForGitHubAccessToken(\n domain: string,\n deviceCode: string,\n intervalSeconds: number,\n expiresIn: number,\n signal?: AbortSignal,\n): Promise<string> {\n const urls = getUrls(domain);\n const deadline = Date.now() + expiresIn * 1000;\n let intervalMs = Math.max(1000, Math.floor(intervalSeconds * 1000));\n let intervalMultiplier = INITIAL_POLL_INTERVAL_MULTIPLIER;\n let slowDownResponses = 0;\n\n while (Date.now() < deadline) {\n if (signal?.aborted) {\n throw new Error('Login cancelled');\n }\n\n const remainingMs = deadline - Date.now();\n const waitMs = Math.min(Math.ceil(intervalMs * intervalMultiplier), remainingMs);\n await abortableSleep(waitMs, signal);\n\n const raw = await fetchJson(\n urls.accessTokenUrl,\n {\n method: 'POST',\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/x-www-form-urlencoded',\n 'User-Agent': COPILOT_USER_AGENT,\n },\n body: new URLSearchParams({\n client_id: CLIENT_ID,\n device_code: deviceCode,\n grant_type: 'urn:ietf:params:oauth:grant-type:device_code',\n }),\n },\n signal,\n );\n\n if (raw && typeof raw === 'object' && typeof (raw as DeviceTokenSuccessResponse).access_token === 'string') {\n return (raw as DeviceTokenSuccessResponse).access_token;\n }\n\n if (raw && typeof raw === 'object' && typeof (raw as DeviceTokenErrorResponse).error === 'string') {\n const { error, error_description: description, interval } = raw as DeviceTokenErrorResponse;\n if (error === 'authorization_pending') {\n continue;\n }\n\n if (error === 'slow_down') {\n slowDownResponses += 1;\n intervalMs = typeof interval === 'number' && interval > 0 ? interval * 1000 : Math.max(1000, intervalMs + 5000);\n intervalMultiplier = SLOW_DOWN_POLL_INTERVAL_MULTIPLIER;\n continue;\n }\n\n const descriptionSuffix = description ? `: ${description}` : '';\n throw new Error(`Device flow failed: ${error}${descriptionSuffix}`);\n }\n }\n\n if (slowDownResponses > 0) {\n throw new Error(\n 'Device flow timed out after one or more slow_down responses. This is often caused by clock drift in WSL or VM environments. Please sync or restart the VM clock and try again.',\n );\n }\n\n throw new Error('Device flow timed out');\n}\n\n/**\n * Refresh the short-lived Copilot bearer token using the long-lived GitHub OAuth token.\n *\n * `refreshToken` here is the GitHub OAuth access token; the Copilot endpoint returns a\n * fresh bearer token (`token`) and absolute expiry (`expires_at`, seconds since epoch).\n */\nexport async function refreshGitHubCopilotToken(\n refreshToken: string,\n enterpriseDomain?: string,\n signal?: AbortSignal,\n): Promise<GitHubCopilotCredentials> {\n const domain = enterpriseDomain || 'github.com';\n const urls = getUrls(domain);\n\n const raw = await fetchJson(\n urls.copilotTokenUrl,\n {\n headers: {\n Accept: 'application/json',\n Authorization: `Bearer ${refreshToken}`,\n ...COPILOT_HEADERS,\n },\n },\n signal,\n );\n\n if (!raw || typeof raw !== 'object') {\n throw new Error('Invalid Copilot token response');\n }\n\n const obj = raw as Record<string, unknown>;\n const token = obj.token;\n const expiresAt = obj.expires_at;\n\n if (typeof token !== 'string' || typeof expiresAt !== 'number') {\n throw new Error('Invalid Copilot token response fields');\n }\n\n const credentials: GitHubCopilotCredentials = {\n refresh: refreshToken,\n access: token,\n // expires_at is seconds; subtract 5 minutes so we refresh before actual expiry.\n expires: expiresAt * 1000 - 5 * 60 * 1000,\n };\n if (enterpriseDomain) {\n credentials.enterpriseUrl = enterpriseDomain;\n }\n return credentials;\n}\n\n/**\n * Login with GitHub Copilot OAuth (device-code flow).\n *\n * Prompts for an optional GitHub Enterprise URL/domain, performs the device-code flow,\n * then exchanges the GitHub OAuth token for a Copilot bearer token.\n */\nexport async function loginGitHubCopilot(options: {\n onAuth: (url: string, instructions?: string) => void;\n onPrompt: (prompt: { message: string; placeholder?: string; allowEmpty?: boolean }) => Promise<string>;\n onProgress?: (message: string) => void;\n signal?: AbortSignal;\n}): Promise<GitHubCopilotCredentials> {\n const input = await options.onPrompt({\n message: 'GitHub Enterprise URL/domain (blank for github.com)',\n placeholder: 'company.ghe.com',\n allowEmpty: true,\n });\n\n if (options.signal?.aborted) {\n throw new Error('Login cancelled');\n }\n\n const trimmed = input.trim();\n const enterpriseDomain = normalizeDomain(input);\n if (trimmed && !enterpriseDomain) {\n throw new Error('Invalid GitHub Enterprise URL/domain');\n }\n const domain = enterpriseDomain || 'github.com';\n\n const device = await startDeviceFlow(domain, options.signal);\n options.onAuth(device.verification_uri, `Enter code: ${device.user_code}`);\n\n const githubAccessToken = await pollForGitHubAccessToken(\n domain,\n device.device_code,\n device.interval,\n device.expires_in,\n options.signal,\n );\n\n options.onProgress?.('Fetching Copilot token...');\n return refreshGitHubCopilotToken(githubAccessToken, enterpriseDomain ?? undefined, options.signal);\n}\n\n/**\n * Filtered, normalized entry from the Copilot `/models` API.\n *\n * The full API payload includes a lot of capability metadata; we only keep the bits\n * we need to expose models in `listAvailableModels()` and route requests sensibly.\n */\nexport type CopilotModelEntry = {\n /** Stable model id (e.g. `claude-sonnet-4.5`, `gpt-4.1`). */\n id: string;\n /** Human-readable display name (e.g. `Claude Sonnet 4.5`). */\n name: string;\n /** Vendor field from the API (e.g. `Anthropic`, `OpenAI`). */\n vendor: string;\n /**\n * Endpoints the model exposes (e.g. `/chat/completions`, `/responses`, `/v1/messages`).\n * Empty when the API didn't return `supported_endpoints` for this entry.\n */\n supportedEndpoints: string[];\n /** True when `supported_endpoints` includes `/v1/messages` (Anthropic-shaped Copilot model). */\n isAnthropicShaped: boolean;\n /** True when `capabilities.supports.vision` is true. */\n supportsVision: boolean;\n /** True when the model supports tool calling. */\n supportsToolCalls: boolean;\n};\n\n/**\n * Fetch the Copilot model list available to the current subscription.\n *\n * Hits `${baseURL}/models` with the Copilot bearer token, filters to\n * `model_picker_enabled === true && policy.state !== 'disabled'`, and returns\n * a normalized list. Mirrors opencode's filtering rules.\n *\n * Inspired by:\n * - opencode: https://github.com/anomalyco/opencode/blob/dev/packages/opencode/src/plugin/github-copilot/models.ts\n */\nexport async function fetchCopilotModels(opts: {\n baseUrl: string;\n bearerToken: string;\n signal?: AbortSignal;\n}): Promise<CopilotModelEntry[]> {\n const url = `${opts.baseUrl.replace(/\\/$/, '')}/models`;\n const response = await fetch(url, {\n headers: {\n Accept: 'application/json',\n Authorization: `Bearer ${opts.bearerToken}`,\n ...COPILOT_HEADERS,\n },\n signal: opts.signal,\n });\n\n if (!response.ok) {\n const text = await response.text().catch(() => '');\n throw new Error(`Failed to fetch Copilot models: ${response.status} ${response.statusText}: ${text}`);\n }\n\n const json = await response.json().catch(() => null);\n if (!json || typeof json !== 'object' || !Array.isArray((json as { data?: unknown }).data)) {\n throw new Error('Invalid Copilot models response: missing `data` array');\n }\n\n const data = (json as { data: unknown[] }).data;\n const result: CopilotModelEntry[] = [];\n\n for (const item of data) {\n if (!item || typeof item !== 'object') continue;\n const obj = item as Record<string, unknown>;\n\n if (obj.model_picker_enabled !== true) continue;\n\n const policy = obj.policy as Record<string, unknown> | undefined;\n if (policy && policy.state === 'disabled') continue;\n\n const id = obj.id;\n if (typeof id !== 'string' || !id) continue;\n\n const name = typeof obj.name === 'string' ? obj.name : id;\n const vendor = typeof obj.vendor === 'string' ? obj.vendor : '';\n\n const capabilities = obj.capabilities as Record<string, unknown> | undefined;\n const supports = capabilities?.supports as Record<string, unknown> | undefined;\n const supportsVision = supports?.vision === true;\n const supportsToolCalls = supports?.tool_calls === true;\n\n const rawEndpoints = obj.supported_endpoints;\n const supportedEndpoints = Array.isArray(rawEndpoints)\n ? rawEndpoints.filter((e): e is string => typeof e === 'string')\n : [];\n const isAnthropicShaped = supportedEndpoints.includes('/v1/messages');\n\n result.push({\n id,\n name,\n vendor,\n supportedEndpoints,\n isAnthropicShaped,\n supportsVision,\n supportsToolCalls,\n });\n }\n\n return result;\n}\n\nexport const githubCopilotOAuthProvider: OAuthProviderInterface = {\n id: 'github-copilot',\n name: 'GitHub Copilot',\n\n async login(callbacks: OAuthLoginCallbacks): Promise<OAuthCredentials> {\n return loginGitHubCopilot({\n onAuth: (url, instructions) => callbacks.onAuth({ url, instructions }),\n onPrompt: callbacks.onPrompt,\n onProgress: callbacks.onProgress,\n signal: callbacks.signal,\n });\n },\n\n async refreshToken(credentials: OAuthCredentials): Promise<OAuthCredentials> {\n const creds = credentials as GitHubCopilotCredentials;\n return refreshGitHubCopilotToken(creds.refresh, creds.enterpriseUrl);\n },\n\n getApiKey(credentials: OAuthCredentials): string {\n return credentials.access;\n },\n};\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI Codex (ChatGPT OAuth) flow
|
|
3
|
+
*
|
|
4
|
+
* Inspired by pi-mono's OAuth implementation:
|
|
5
|
+
* https://github.com/badlogic/pi-mono/blob/main/packages/ai/src/utils/oauth/openai-codex.ts
|
|
6
|
+
*
|
|
7
|
+
* NOTE: This module uses Node.js crypto and http for the OAuth callback.
|
|
8
|
+
* It is only intended for CLI use, not browser environments.
|
|
9
|
+
*/
|
|
10
|
+
import type { AuthMode, OAuthCredentials, OAuthPrompt, OAuthProviderInterface } from '../types.js';
|
|
11
|
+
export declare const OPENAI_CODEX_AUTH_MODES: ReadonlyArray<AuthMode>;
|
|
12
|
+
declare const JWT_CLAIM_PATH = "https://api.openai.com/auth";
|
|
13
|
+
type JwtPayload = {
|
|
14
|
+
chatgpt_account_id?: string;
|
|
15
|
+
[JWT_CLAIM_PATH]?: {
|
|
16
|
+
chatgpt_account_id?: string;
|
|
17
|
+
};
|
|
18
|
+
[key: string]: unknown;
|
|
19
|
+
};
|
|
20
|
+
declare function decodeJwt(token: string): JwtPayload | null;
|
|
21
|
+
declare function extractAccountIdFromClaims(payload: JwtPayload | null | undefined): string | null;
|
|
22
|
+
declare function getAccountId(tokens: {
|
|
23
|
+
idToken?: string;
|
|
24
|
+
access: string;
|
|
25
|
+
}, fallback?: string): string | undefined;
|
|
26
|
+
declare function requireAccountId(tokens: {
|
|
27
|
+
idToken?: string;
|
|
28
|
+
access: string;
|
|
29
|
+
}, fallback?: string): string;
|
|
30
|
+
declare function createAuthorizationFlow(redirectUri: string, state: string, originator?: string): Promise<{
|
|
31
|
+
verifier: string;
|
|
32
|
+
url: string;
|
|
33
|
+
}>;
|
|
34
|
+
type OAuthServerInfo = {
|
|
35
|
+
redirectUri: string;
|
|
36
|
+
warning?: string;
|
|
37
|
+
close: () => void;
|
|
38
|
+
cancelWait: () => void;
|
|
39
|
+
waitForCode: () => Promise<{
|
|
40
|
+
code: string;
|
|
41
|
+
} | null>;
|
|
42
|
+
};
|
|
43
|
+
type CallbackPorts = {
|
|
44
|
+
defaultPort: number;
|
|
45
|
+
fallbackPort: number;
|
|
46
|
+
};
|
|
47
|
+
declare function startLocalOAuthServer(state: string, ports?: CallbackPorts): Promise<OAuthServerInfo>;
|
|
48
|
+
declare function loginOpenAICodexDevice(options: {
|
|
49
|
+
onAuth: (info: {
|
|
50
|
+
url: string;
|
|
51
|
+
instructions?: string;
|
|
52
|
+
}) => void;
|
|
53
|
+
onProgress?: (message: string) => void;
|
|
54
|
+
signal?: AbortSignal;
|
|
55
|
+
sleep?: (ms: number) => Promise<void>;
|
|
56
|
+
}): Promise<OAuthCredentials>;
|
|
57
|
+
/**
|
|
58
|
+
* Login with OpenAI Codex OAuth
|
|
59
|
+
*
|
|
60
|
+
* @param options.onAuth - Called with URL and instructions when auth starts
|
|
61
|
+
* @param options.onPrompt - Called to prompt user for manual code paste (fallback if no onManualCodeInput)
|
|
62
|
+
* @param options.onProgress - Optional progress messages
|
|
63
|
+
* @param options.onManualCodeInput - Optional promise that resolves with user-pasted code.
|
|
64
|
+
* Races with browser callback - whichever completes first wins.
|
|
65
|
+
* Useful for showing paste input immediately alongside browser flow.
|
|
66
|
+
* @param options.originator - OAuth originator parameter (defaults to "mastracode")
|
|
67
|
+
*/
|
|
68
|
+
export declare function loginOpenAICodex(options: {
|
|
69
|
+
onAuth: (info: {
|
|
70
|
+
url: string;
|
|
71
|
+
instructions?: string;
|
|
72
|
+
}) => void;
|
|
73
|
+
onPrompt: (prompt: OAuthPrompt) => Promise<string>;
|
|
74
|
+
onProgress?: (message: string) => void;
|
|
75
|
+
onManualCodeInput?: () => Promise<string>;
|
|
76
|
+
signal?: AbortSignal;
|
|
77
|
+
originator?: string;
|
|
78
|
+
mode?: 'browser' | 'device';
|
|
79
|
+
}): Promise<OAuthCredentials>;
|
|
80
|
+
export declare const __testing: {
|
|
81
|
+
createAuthorizationFlow: typeof createAuthorizationFlow;
|
|
82
|
+
decodeJwt: typeof decodeJwt;
|
|
83
|
+
extractAccountIdFromClaims: typeof extractAccountIdFromClaims;
|
|
84
|
+
getAccountId: typeof getAccountId;
|
|
85
|
+
loginOpenAICodexDevice: typeof loginOpenAICodexDevice;
|
|
86
|
+
requireAccountId: typeof requireAccountId;
|
|
87
|
+
startLocalOAuthServer: typeof startLocalOAuthServer;
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* Refresh OpenAI Codex OAuth token
|
|
91
|
+
*/
|
|
92
|
+
export declare function refreshOpenAICodexToken(refreshToken: string, previousAccountId?: string): Promise<OAuthCredentials>;
|
|
93
|
+
export declare const openaiCodexOAuthProvider: OAuthProviderInterface;
|
|
94
|
+
export {};
|
|
95
|
+
//# sourceMappingURL=openai-codex.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-codex.d.ts","sourceRoot":"","sources":["../../../src/auth/providers/openai-codex.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,527 @@
|
|
|
1
|
+
let _randomBytes = null;
|
|
2
|
+
let _cryptoPromise = null;
|
|
3
|
+
let _httpPromise = null;
|
|
4
|
+
let _http = null;
|
|
5
|
+
if (typeof process !== "undefined" && (process.versions?.node || process.versions?.bun)) {
|
|
6
|
+
_cryptoPromise = import("node:crypto").then((m) => {
|
|
7
|
+
_randomBytes = m.randomBytes;
|
|
8
|
+
return m;
|
|
9
|
+
});
|
|
10
|
+
_httpPromise = import("node:http").then((m) => {
|
|
11
|
+
_http = m;
|
|
12
|
+
return m;
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
import { generatePKCE } from "../pkce.js";
|
|
16
|
+
const OPENAI_CODEX_AUTH_MODES = [
|
|
17
|
+
{
|
|
18
|
+
id: "browser",
|
|
19
|
+
name: "Browser (local callback)",
|
|
20
|
+
description: "Opens the browser and waits for the OAuth callback on localhost."
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
id: "device",
|
|
24
|
+
name: "Device code (headless)",
|
|
25
|
+
description: "Shows a code to enter at openai.com \u2014 for SSH, remote, or no-browser environments."
|
|
26
|
+
}
|
|
27
|
+
];
|
|
28
|
+
const CLIENT_ID = "app_EMoamEEZ73f0CkXaXp7hrann";
|
|
29
|
+
const ISSUER = "https://auth.openai.com";
|
|
30
|
+
const AUTHORIZE_URL = `${ISSUER}/oauth/authorize`;
|
|
31
|
+
const TOKEN_URL = `${ISSUER}/oauth/token`;
|
|
32
|
+
const DEVICE_USER_CODE_URL = `${ISSUER}/api/accounts/deviceauth/usercode`;
|
|
33
|
+
const DEVICE_TOKEN_URL = `${ISSUER}/api/accounts/deviceauth/token`;
|
|
34
|
+
const DEVICE_AUTHORIZE_URL = `${ISSUER}/codex/device`;
|
|
35
|
+
const DEVICE_REDIRECT_URI = `${ISSUER}/deviceauth/callback`;
|
|
36
|
+
const DEFAULT_CALLBACK_PORT = 1455;
|
|
37
|
+
const FALLBACK_CALLBACK_PORT = 1457;
|
|
38
|
+
const DEFAULT_TOKEN_EXPIRES_IN_SECONDS = 3600;
|
|
39
|
+
const DEVICE_AUTH_TIMEOUT_MS = 15 * 60 * 1e3;
|
|
40
|
+
const SCOPE = "openid profile email offline_access api.connectors.read api.connectors.invoke";
|
|
41
|
+
const JWT_CLAIM_PATH = "https://api.openai.com/auth";
|
|
42
|
+
const SUCCESS_HTML = `<!doctype html>
|
|
43
|
+
<html lang="en">
|
|
44
|
+
<head>
|
|
45
|
+
<meta charset="utf-8" />
|
|
46
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
47
|
+
<title>Authentication successful</title>
|
|
48
|
+
</head>
|
|
49
|
+
<body>
|
|
50
|
+
<p>Authentication successful. Return to your terminal to continue.</p>
|
|
51
|
+
</body>
|
|
52
|
+
</html>`;
|
|
53
|
+
async function createState() {
|
|
54
|
+
const randomBytes = await getRandomBytes();
|
|
55
|
+
return randomBytes(16).toString("hex");
|
|
56
|
+
}
|
|
57
|
+
function parseAuthorizationInput(input) {
|
|
58
|
+
const value = input.trim();
|
|
59
|
+
if (!value) return {};
|
|
60
|
+
try {
|
|
61
|
+
const url = new URL(value);
|
|
62
|
+
return {
|
|
63
|
+
code: url.searchParams.get("code") ?? void 0,
|
|
64
|
+
state: url.searchParams.get("state") ?? void 0
|
|
65
|
+
};
|
|
66
|
+
} catch {
|
|
67
|
+
}
|
|
68
|
+
if (value.includes("#")) {
|
|
69
|
+
const [code, state] = value.split("#", 2);
|
|
70
|
+
return { code, state };
|
|
71
|
+
}
|
|
72
|
+
if (value.includes("code=")) {
|
|
73
|
+
const params = new URLSearchParams(value);
|
|
74
|
+
return {
|
|
75
|
+
code: params.get("code") ?? void 0,
|
|
76
|
+
state: params.get("state") ?? void 0
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
return { code: value };
|
|
80
|
+
}
|
|
81
|
+
function decodeJwt(token) {
|
|
82
|
+
try {
|
|
83
|
+
const parts = token.split(".");
|
|
84
|
+
if (parts.length !== 3) return null;
|
|
85
|
+
const payload = parts[1] ?? "";
|
|
86
|
+
const padded = payload.replace(/-/g, "+").replace(/_/g, "/").padEnd(Math.ceil(payload.length / 4) * 4, "=");
|
|
87
|
+
const decoded = atob(padded);
|
|
88
|
+
return JSON.parse(decoded);
|
|
89
|
+
} catch {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
function extractAccountIdFromClaims(payload) {
|
|
94
|
+
if (!payload) return null;
|
|
95
|
+
const accountId = payload.chatgpt_account_id ?? payload[JWT_CLAIM_PATH]?.chatgpt_account_id;
|
|
96
|
+
return typeof accountId === "string" && accountId.length > 0 ? accountId : null;
|
|
97
|
+
}
|
|
98
|
+
function getAccountId(tokens, fallback) {
|
|
99
|
+
const fromIdToken = tokens.idToken ? extractAccountIdFromClaims(decodeJwt(tokens.idToken)) : null;
|
|
100
|
+
if (fromIdToken) return fromIdToken;
|
|
101
|
+
const fromAccessToken = extractAccountIdFromClaims(decodeJwt(tokens.access));
|
|
102
|
+
if (fromAccessToken) return fromAccessToken;
|
|
103
|
+
return fallback;
|
|
104
|
+
}
|
|
105
|
+
function requireAccountId(tokens, fallback) {
|
|
106
|
+
const accountId = getAccountId(tokens, fallback);
|
|
107
|
+
if (!accountId) {
|
|
108
|
+
throw new Error("Failed to extract ChatGPT account id from OpenAI Codex token");
|
|
109
|
+
}
|
|
110
|
+
return accountId;
|
|
111
|
+
}
|
|
112
|
+
function tokenResponseToResult(json, logPrefix) {
|
|
113
|
+
if (!json.access_token || !json.refresh_token) {
|
|
114
|
+
console.error(`[openai-codex] ${logPrefix} response missing fields:`, json);
|
|
115
|
+
return { type: "failed" };
|
|
116
|
+
}
|
|
117
|
+
return {
|
|
118
|
+
type: "success",
|
|
119
|
+
access: json.access_token,
|
|
120
|
+
refresh: json.refresh_token,
|
|
121
|
+
expires: Date.now() + (json.expires_in ?? DEFAULT_TOKEN_EXPIRES_IN_SECONDS) * 1e3,
|
|
122
|
+
idToken: json.id_token
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
async function exchangeAuthorizationCode(code, verifier, redirectUri) {
|
|
126
|
+
const response = await fetch(TOKEN_URL, {
|
|
127
|
+
method: "POST",
|
|
128
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
129
|
+
body: new URLSearchParams({
|
|
130
|
+
grant_type: "authorization_code",
|
|
131
|
+
client_id: CLIENT_ID,
|
|
132
|
+
code,
|
|
133
|
+
code_verifier: verifier,
|
|
134
|
+
redirect_uri: redirectUri
|
|
135
|
+
})
|
|
136
|
+
});
|
|
137
|
+
if (!response.ok) {
|
|
138
|
+
const text = await response.text().catch(() => "");
|
|
139
|
+
console.error("[openai-codex] code->token failed:", response.status, text);
|
|
140
|
+
return { type: "failed" };
|
|
141
|
+
}
|
|
142
|
+
return tokenResponseToResult(await response.json(), "token");
|
|
143
|
+
}
|
|
144
|
+
async function refreshAccessToken(refreshToken) {
|
|
145
|
+
try {
|
|
146
|
+
const response = await fetch(TOKEN_URL, {
|
|
147
|
+
method: "POST",
|
|
148
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
149
|
+
body: new URLSearchParams({
|
|
150
|
+
grant_type: "refresh_token",
|
|
151
|
+
refresh_token: refreshToken,
|
|
152
|
+
client_id: CLIENT_ID
|
|
153
|
+
})
|
|
154
|
+
});
|
|
155
|
+
if (!response.ok) {
|
|
156
|
+
const text = await response.text().catch(() => "");
|
|
157
|
+
console.error("[openai-codex] Token refresh failed:", response.status, text);
|
|
158
|
+
return { type: "failed" };
|
|
159
|
+
}
|
|
160
|
+
return tokenResponseToResult(await response.json(), "Token refresh");
|
|
161
|
+
} catch (error) {
|
|
162
|
+
console.error("[openai-codex] Token refresh error:", error);
|
|
163
|
+
return { type: "failed" };
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
async function getRandomBytes() {
|
|
167
|
+
if (!_randomBytes && _cryptoPromise) {
|
|
168
|
+
_randomBytes = (await _cryptoPromise).randomBytes;
|
|
169
|
+
}
|
|
170
|
+
if (!_randomBytes) {
|
|
171
|
+
throw new Error("OpenAI Codex OAuth is only available in Node.js environments");
|
|
172
|
+
}
|
|
173
|
+
return _randomBytes;
|
|
174
|
+
}
|
|
175
|
+
async function createAuthorizationFlow(redirectUri, state, originator = "mastracode") {
|
|
176
|
+
const { verifier, challenge } = await generatePKCE();
|
|
177
|
+
const url = new URL(AUTHORIZE_URL);
|
|
178
|
+
url.searchParams.set("response_type", "code");
|
|
179
|
+
url.searchParams.set("client_id", CLIENT_ID);
|
|
180
|
+
url.searchParams.set("redirect_uri", redirectUri);
|
|
181
|
+
url.searchParams.set("scope", SCOPE);
|
|
182
|
+
url.searchParams.set("code_challenge", challenge);
|
|
183
|
+
url.searchParams.set("code_challenge_method", "S256");
|
|
184
|
+
url.searchParams.set("state", state);
|
|
185
|
+
url.searchParams.set("id_token_add_organizations", "true");
|
|
186
|
+
url.searchParams.set("codex_cli_simplified_flow", "true");
|
|
187
|
+
url.searchParams.set("originator", originator);
|
|
188
|
+
return { verifier, url: url.toString() };
|
|
189
|
+
}
|
|
190
|
+
const CODEX_CALLBACK_PORTS = {
|
|
191
|
+
defaultPort: DEFAULT_CALLBACK_PORT,
|
|
192
|
+
fallbackPort: FALLBACK_CALLBACK_PORT
|
|
193
|
+
};
|
|
194
|
+
async function requestCancel(port) {
|
|
195
|
+
try {
|
|
196
|
+
await fetch(`http://127.0.0.1:${port}/cancel`, { signal: AbortSignal.timeout(200) });
|
|
197
|
+
} catch {
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
function listen(server, port) {
|
|
201
|
+
return new Promise((resolve) => {
|
|
202
|
+
const onError = () => {
|
|
203
|
+
server.off("listening", onListening);
|
|
204
|
+
resolve(false);
|
|
205
|
+
};
|
|
206
|
+
const onListening = () => {
|
|
207
|
+
server.off("error", onError);
|
|
208
|
+
resolve(true);
|
|
209
|
+
};
|
|
210
|
+
server.once("error", onError);
|
|
211
|
+
server.once("listening", onListening);
|
|
212
|
+
server.listen(port, "127.0.0.1");
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
async function bindOAuthServer(server, ports) {
|
|
216
|
+
await requestCancel(ports.defaultPort);
|
|
217
|
+
if (await listen(server, ports.defaultPort)) return ports.defaultPort;
|
|
218
|
+
if (await listen(server, ports.fallbackPort)) return ports.fallbackPort;
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
async function getHttpModule() {
|
|
222
|
+
if (!_http && _httpPromise) {
|
|
223
|
+
_http = await _httpPromise;
|
|
224
|
+
}
|
|
225
|
+
if (!_http) {
|
|
226
|
+
throw new Error("OpenAI Codex OAuth is only available in Node.js environments");
|
|
227
|
+
}
|
|
228
|
+
return _http;
|
|
229
|
+
}
|
|
230
|
+
async function startLocalOAuthServer(state, ports = CODEX_CALLBACK_PORTS) {
|
|
231
|
+
const http = await getHttpModule();
|
|
232
|
+
let lastCode = null;
|
|
233
|
+
let cancelled = false;
|
|
234
|
+
const server = http.createServer((req, res) => {
|
|
235
|
+
try {
|
|
236
|
+
const url = new URL(req.url || "", "http://localhost");
|
|
237
|
+
if (url.pathname === "/cancel") {
|
|
238
|
+
cancelled = true;
|
|
239
|
+
res.statusCode = 200;
|
|
240
|
+
res.end("Cancelled");
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
if (url.pathname !== "/auth/callback") {
|
|
244
|
+
res.statusCode = 404;
|
|
245
|
+
res.end("Not found");
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
if (url.searchParams.get("state") !== state) {
|
|
249
|
+
res.statusCode = 400;
|
|
250
|
+
res.end("State mismatch");
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
const code = url.searchParams.get("code");
|
|
254
|
+
if (!code) {
|
|
255
|
+
res.statusCode = 400;
|
|
256
|
+
res.end("Missing authorization code");
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
res.statusCode = 200;
|
|
260
|
+
res.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
261
|
+
res.end(SUCCESS_HTML);
|
|
262
|
+
lastCode = code;
|
|
263
|
+
} catch {
|
|
264
|
+
res.statusCode = 500;
|
|
265
|
+
res.end("Internal error");
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
return new Promise((resolve) => {
|
|
269
|
+
bindOAuthServer(server, ports).then((port) => {
|
|
270
|
+
if (!port) {
|
|
271
|
+
resolve({
|
|
272
|
+
redirectUri: `http://localhost:${ports.fallbackPort}/auth/callback`,
|
|
273
|
+
warning: `OpenAI Codex OAuth requires localhost port ${ports.defaultPort} or ${ports.fallbackPort}, but both are in use. Automatic browser callback will not work until one is freed.`,
|
|
274
|
+
close: () => {
|
|
275
|
+
try {
|
|
276
|
+
server.close();
|
|
277
|
+
} catch {
|
|
278
|
+
}
|
|
279
|
+
},
|
|
280
|
+
cancelWait: () => {
|
|
281
|
+
},
|
|
282
|
+
waitForCode: async () => null
|
|
283
|
+
});
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
resolve({
|
|
287
|
+
redirectUri: `http://localhost:${port}/auth/callback`,
|
|
288
|
+
close: () => server.close(),
|
|
289
|
+
cancelWait: () => {
|
|
290
|
+
cancelled = true;
|
|
291
|
+
},
|
|
292
|
+
waitForCode: async () => {
|
|
293
|
+
const sleep = () => new Promise((r) => setTimeout(r, 100));
|
|
294
|
+
for (let i = 0; i < 600; i += 1) {
|
|
295
|
+
if (lastCode) return { code: lastCode };
|
|
296
|
+
if (cancelled) return null;
|
|
297
|
+
await sleep();
|
|
298
|
+
}
|
|
299
|
+
return null;
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
});
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
async function loginOpenAICodexDevice(options) {
|
|
306
|
+
const response = await fetch(DEVICE_USER_CODE_URL, {
|
|
307
|
+
method: "POST",
|
|
308
|
+
headers: {
|
|
309
|
+
"Content-Type": "application/json",
|
|
310
|
+
"User-Agent": "mastracode"
|
|
311
|
+
},
|
|
312
|
+
body: JSON.stringify({ client_id: CLIENT_ID, originator: "mastracode" }),
|
|
313
|
+
signal: options.signal
|
|
314
|
+
});
|
|
315
|
+
if (!response.ok) {
|
|
316
|
+
throw new Error(`Failed to initiate OpenAI Codex device authorization: ${response.status}`);
|
|
317
|
+
}
|
|
318
|
+
const deviceData = await response.json();
|
|
319
|
+
const userCode = deviceData.user_code ?? deviceData.usercode;
|
|
320
|
+
if (!deviceData.device_auth_id || !userCode) {
|
|
321
|
+
throw new Error("OpenAI Codex device authorization response missing required fields");
|
|
322
|
+
}
|
|
323
|
+
const intervalSeconds = typeof deviceData.interval === "number" ? deviceData.interval : Number.parseInt(deviceData.interval ?? "", 10) || 5;
|
|
324
|
+
const pollDelayMs = Math.max(intervalSeconds, 1) * 1e3;
|
|
325
|
+
const sleep = options.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
|
|
326
|
+
const startedAt = Date.now();
|
|
327
|
+
options.onAuth({
|
|
328
|
+
url: DEVICE_AUTHORIZE_URL,
|
|
329
|
+
instructions: `Enter code: ${userCode}`
|
|
330
|
+
});
|
|
331
|
+
while (true) {
|
|
332
|
+
if (options.signal?.aborted) {
|
|
333
|
+
throw new Error("Login cancelled");
|
|
334
|
+
}
|
|
335
|
+
if (Date.now() - startedAt >= DEVICE_AUTH_TIMEOUT_MS) {
|
|
336
|
+
throw new Error("OpenAI Codex device authorization timed out after 15 minutes");
|
|
337
|
+
}
|
|
338
|
+
const pollResponse = await fetch(DEVICE_TOKEN_URL, {
|
|
339
|
+
method: "POST",
|
|
340
|
+
headers: {
|
|
341
|
+
"Content-Type": "application/json",
|
|
342
|
+
"User-Agent": "mastracode"
|
|
343
|
+
},
|
|
344
|
+
body: JSON.stringify({
|
|
345
|
+
device_auth_id: deviceData.device_auth_id,
|
|
346
|
+
user_code: userCode
|
|
347
|
+
}),
|
|
348
|
+
signal: options.signal
|
|
349
|
+
});
|
|
350
|
+
if (pollResponse.ok) {
|
|
351
|
+
const data = await pollResponse.json();
|
|
352
|
+
if (!data.authorization_code || !data.code_verifier) {
|
|
353
|
+
throw new Error("OpenAI Codex device token response missing required fields");
|
|
354
|
+
}
|
|
355
|
+
const tokenResult = await exchangeAuthorizationCode(
|
|
356
|
+
data.authorization_code,
|
|
357
|
+
data.code_verifier,
|
|
358
|
+
DEVICE_REDIRECT_URI
|
|
359
|
+
);
|
|
360
|
+
if (tokenResult.type !== "success") {
|
|
361
|
+
throw new Error("Token exchange failed");
|
|
362
|
+
}
|
|
363
|
+
const accountId = requireAccountId(tokenResult);
|
|
364
|
+
return {
|
|
365
|
+
access: tokenResult.access,
|
|
366
|
+
refresh: tokenResult.refresh,
|
|
367
|
+
expires: tokenResult.expires,
|
|
368
|
+
accountId
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
if (pollResponse.status !== 403 && pollResponse.status !== 404) {
|
|
372
|
+
const text = await pollResponse.text().catch(() => "");
|
|
373
|
+
throw new Error(`OpenAI Codex device authorization failed: ${pollResponse.status}${text ? ` ${text}` : ""}`);
|
|
374
|
+
}
|
|
375
|
+
options.onProgress?.("Waiting for OpenAI Codex device authorization...");
|
|
376
|
+
await sleep(pollDelayMs);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
async function loginOpenAICodex(options) {
|
|
380
|
+
const envMode = typeof process !== "undefined" && process.env?.MASTRACODE_OPENAI_CODEX_AUTH_MODE === "device" ? "device" : void 0;
|
|
381
|
+
const mode = options.mode ?? envMode ?? "browser";
|
|
382
|
+
if (mode === "device") {
|
|
383
|
+
return loginOpenAICodexDevice({
|
|
384
|
+
onAuth: options.onAuth,
|
|
385
|
+
onProgress: options.onProgress,
|
|
386
|
+
signal: options.signal
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
const state = await createState();
|
|
390
|
+
const server = await startLocalOAuthServer(state);
|
|
391
|
+
if (server.warning) {
|
|
392
|
+
options.onProgress?.(server.warning);
|
|
393
|
+
}
|
|
394
|
+
const { verifier, url } = await createAuthorizationFlow(
|
|
395
|
+
server.redirectUri,
|
|
396
|
+
state,
|
|
397
|
+
options.originator ?? "mastracode"
|
|
398
|
+
);
|
|
399
|
+
options.onAuth({
|
|
400
|
+
url,
|
|
401
|
+
instructions: server.warning ? `${server.warning} You can still paste the authorization code or full redirect URL manually.` : "A browser window should open. Complete login to finish."
|
|
402
|
+
});
|
|
403
|
+
let code;
|
|
404
|
+
try {
|
|
405
|
+
if (options.onManualCodeInput) {
|
|
406
|
+
let manualCode;
|
|
407
|
+
let manualError;
|
|
408
|
+
const manualPromise = options.onManualCodeInput().then((input) => {
|
|
409
|
+
manualCode = input;
|
|
410
|
+
server.cancelWait();
|
|
411
|
+
}).catch((err) => {
|
|
412
|
+
manualError = err instanceof Error ? err : new Error(String(err));
|
|
413
|
+
server.cancelWait();
|
|
414
|
+
});
|
|
415
|
+
const result = await server.waitForCode();
|
|
416
|
+
if (manualError) {
|
|
417
|
+
throw manualError;
|
|
418
|
+
}
|
|
419
|
+
if (result?.code) {
|
|
420
|
+
code = result.code;
|
|
421
|
+
} else if (manualCode) {
|
|
422
|
+
const parsed = parseAuthorizationInput(manualCode);
|
|
423
|
+
if (parsed.state && parsed.state !== state) {
|
|
424
|
+
throw new Error("State mismatch");
|
|
425
|
+
}
|
|
426
|
+
code = parsed.code;
|
|
427
|
+
}
|
|
428
|
+
if (!code) {
|
|
429
|
+
await manualPromise;
|
|
430
|
+
if (manualError) {
|
|
431
|
+
throw manualError;
|
|
432
|
+
}
|
|
433
|
+
if (manualCode) {
|
|
434
|
+
const parsed = parseAuthorizationInput(manualCode);
|
|
435
|
+
if (parsed.state && parsed.state !== state) {
|
|
436
|
+
throw new Error("State mismatch");
|
|
437
|
+
}
|
|
438
|
+
code = parsed.code;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
} else {
|
|
442
|
+
const result = await server.waitForCode();
|
|
443
|
+
if (result?.code) {
|
|
444
|
+
code = result.code;
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
if (!code) {
|
|
448
|
+
const input = await options.onPrompt({
|
|
449
|
+
message: "Paste the authorization code (or full redirect URL):"
|
|
450
|
+
});
|
|
451
|
+
const parsed = parseAuthorizationInput(input);
|
|
452
|
+
if (parsed.state && parsed.state !== state) {
|
|
453
|
+
throw new Error("State mismatch");
|
|
454
|
+
}
|
|
455
|
+
code = parsed.code;
|
|
456
|
+
}
|
|
457
|
+
if (!code) {
|
|
458
|
+
throw new Error("Missing authorization code");
|
|
459
|
+
}
|
|
460
|
+
const tokenResult = await exchangeAuthorizationCode(code, verifier, server.redirectUri);
|
|
461
|
+
if (tokenResult.type !== "success") {
|
|
462
|
+
throw new Error("Token exchange failed");
|
|
463
|
+
}
|
|
464
|
+
const accountId = requireAccountId(tokenResult);
|
|
465
|
+
return {
|
|
466
|
+
access: tokenResult.access,
|
|
467
|
+
refresh: tokenResult.refresh,
|
|
468
|
+
expires: tokenResult.expires,
|
|
469
|
+
accountId
|
|
470
|
+
};
|
|
471
|
+
} finally {
|
|
472
|
+
server.close();
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
const __testing = {
|
|
476
|
+
createAuthorizationFlow,
|
|
477
|
+
decodeJwt,
|
|
478
|
+
extractAccountIdFromClaims,
|
|
479
|
+
getAccountId,
|
|
480
|
+
loginOpenAICodexDevice,
|
|
481
|
+
requireAccountId,
|
|
482
|
+
startLocalOAuthServer
|
|
483
|
+
};
|
|
484
|
+
async function refreshOpenAICodexToken(refreshToken, previousAccountId) {
|
|
485
|
+
const result = await refreshAccessToken(refreshToken);
|
|
486
|
+
if (result.type !== "success") {
|
|
487
|
+
throw new Error("Failed to refresh OpenAI Codex token");
|
|
488
|
+
}
|
|
489
|
+
const accountId = requireAccountId(result, previousAccountId);
|
|
490
|
+
return {
|
|
491
|
+
access: result.access,
|
|
492
|
+
refresh: result.refresh,
|
|
493
|
+
expires: result.expires,
|
|
494
|
+
accountId
|
|
495
|
+
};
|
|
496
|
+
}
|
|
497
|
+
const openaiCodexOAuthProvider = {
|
|
498
|
+
id: "openai-codex",
|
|
499
|
+
name: "ChatGPT Plus/Pro (Codex Subscription)",
|
|
500
|
+
usesCallbackServer: true,
|
|
501
|
+
authModes: OPENAI_CODEX_AUTH_MODES,
|
|
502
|
+
async login(callbacks) {
|
|
503
|
+
const mode = callbacks.authMode === "device" || callbacks.authMode === "browser" ? callbacks.authMode : void 0;
|
|
504
|
+
return loginOpenAICodex({
|
|
505
|
+
onAuth: callbacks.onAuth,
|
|
506
|
+
onPrompt: callbacks.onPrompt,
|
|
507
|
+
onProgress: callbacks.onProgress,
|
|
508
|
+
onManualCodeInput: callbacks.onManualCodeInput,
|
|
509
|
+
signal: callbacks.signal,
|
|
510
|
+
mode
|
|
511
|
+
});
|
|
512
|
+
},
|
|
513
|
+
async refreshToken(credentials) {
|
|
514
|
+
return refreshOpenAICodexToken(credentials.refresh, credentials.accountId);
|
|
515
|
+
},
|
|
516
|
+
getApiKey(credentials) {
|
|
517
|
+
return credentials.access;
|
|
518
|
+
}
|
|
519
|
+
};
|
|
520
|
+
export {
|
|
521
|
+
OPENAI_CODEX_AUTH_MODES,
|
|
522
|
+
__testing,
|
|
523
|
+
loginOpenAICodex,
|
|
524
|
+
openaiCodexOAuthProvider,
|
|
525
|
+
refreshOpenAICodexToken
|
|
526
|
+
};
|
|
527
|
+
//# sourceMappingURL=openai-codex.js.map
|