@mastra/code-sdk 0.0.0-esbuild-bundle-worker-20260807173433
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 +1349 -0
- package/LICENSE.md +30 -0
- package/README.md +70 -0
- package/dist/acp/agent.d.ts +35 -0
- package/dist/acp/agent.d.ts.map +1 -0
- package/dist/acp/agent.js +161 -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 +214 -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 +65 -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 +35 -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 +2 -0
- package/dist/agents/credential-resolver.d.ts +51 -0
- package/dist/agents/credential-resolver.d.ts.map +1 -0
- package/dist/agents/credential-resolver.js +52 -0
- package/dist/agents/credential-resolver.js.map +1 -0
- package/dist/agents/custom-provider-source.d.ts +35 -0
- package/dist/agents/custom-provider-source.d.ts.map +1 -0
- package/dist/agents/custom-provider-source.js +25 -0
- package/dist/agents/custom-provider-source.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 +32 -0
- package/dist/agents/instructions.js.map +1 -0
- package/dist/agents/mastracode-gateway.d.ts +74 -0
- package/dist/agents/mastracode-gateway.d.ts.map +1 -0
- package/dist/agents/mastracode-gateway.js +400 -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 +116 -0
- package/dist/agents/memory.js.map +1 -0
- package/dist/agents/model.d.ts +59 -0
- package/dist/agents/model.d.ts.map +1 -0
- package/dist/agents/model.js +132 -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 +44 -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 +39 -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 +37 -0
- package/dist/agents/modes/plan.js.map +1 -0
- package/dist/agents/prompts/agent-instructions.d.ts +61 -0
- package/dist/agents/prompts/agent-instructions.d.ts.map +1 -0
- package/dist/agents/prompts/agent-instructions.js +201 -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 +76 -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 +26 -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 +65 -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 +23 -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 +111 -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 +149 -0
- package/dist/agents/prompts/tool-guidance.js.map +1 -0
- package/dist/agents/sandbox-filesystem.d.ts +99 -0
- package/dist/agents/sandbox-filesystem.d.ts.map +1 -0
- package/dist/agents/sandbox-filesystem.js +328 -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 +15 -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 +107 -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 +87 -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 +105 -0
- package/dist/agents/tools.js.map +1 -0
- package/dist/agents/workspace.d.ts +32 -0
- package/dist/agents/workspace.d.ts.map +1 -0
- package/dist/agents/workspace.js +251 -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 +163 -0
- package/dist/analytics.js.map +1 -0
- package/dist/auth/authorization-input.d.ts +16 -0
- package/dist/auth/authorization-input.d.ts.map +1 -0
- package/dist/auth/authorization-input.js +42 -0
- package/dist/auth/authorization-input.js.map +1 -0
- package/dist/auth/device-code.d.ts +93 -0
- package/dist/auth/device-code.d.ts.map +1 -0
- package/dist/auth/device-code.js +129 -0
- package/dist/auth/device-code.js.map +1 -0
- package/dist/auth/index.d.ts +10 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +6 -0
- package/dist/auth/pkce.d.ts +13 -0
- package/dist/auth/pkce.d.ts.map +1 -0
- package/dist/auth/pkce.js +32 -0
- package/dist/auth/pkce.js.map +1 -0
- package/dist/auth/providers/anthropic.d.ts +40 -0
- package/dist/auth/providers/anthropic.d.ts.map +1 -0
- package/dist/auth/providers/anthropic.js +126 -0
- package/dist/auth/providers/anthropic.js.map +1 -0
- package/dist/auth/providers/github-copilot.d.ts +154 -0
- package/dist/auth/providers/github-copilot.d.ts.map +1 -0
- package/dist/auth/providers/github-copilot.js +340 -0
- package/dist/auth/providers/github-copilot.js.map +1 -0
- package/dist/auth/providers/openai-codex.d.ts +139 -0
- package/dist/auth/providers/openai-codex.d.ts.map +1 -0
- package/dist/auth/providers/openai-codex.js +519 -0
- package/dist/auth/providers/openai-codex.js.map +1 -0
- package/dist/auth/providers/xai.d.ts +64 -0
- package/dist/auth/providers/xai.d.ts.map +1 -0
- package/dist/auth/providers/xai.js +205 -0
- package/dist/auth/providers/xai.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 +197 -0
- package/dist/auth/storage.js.map +1 -0
- package/dist/auth/types.d.ts +89 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/auth/types.js +1 -0
- package/dist/clipboard/index.d.ts +26 -0
- package/dist/clipboard/index.d.ts.map +1 -0
- package/dist/clipboard/index.js +226 -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 +18 -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 +22 -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 +161 -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 +5 -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 +73 -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 +259 -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 +60 -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 +3 -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 +347 -0
- package/dist/evals/scorers/outcome.js.map +1 -0
- package/dist/goal-manager.d.ts +78 -0
- package/dist/goal-manager.d.ts.map +1 -0
- package/dist/goal-manager.js +273 -0
- package/dist/goal-manager.js.map +1 -0
- package/dist/goal-signal.d.ts +14 -0
- package/dist/goal-signal.d.ts.map +1 -0
- package/dist/goal-signal.js +17 -0
- package/dist/goal-signal.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 +195 -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 +190 -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 +89 -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 +6 -0
- package/dist/headless/policy.d.ts +17 -0
- package/dist/headless/policy.d.ts.map +1 -0
- package/dist/headless/policy.js +42 -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 +346 -0
- package/dist/headless/run-mc.js.map +1 -0
- package/dist/headless/types.d.ts +158 -0
- package/dist/headless/types.d.ts.map +1 -0
- package/dist/headless/types.js +18 -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 +73 -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 +128 -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 +5 -0
- package/dist/hooks/manager.d.ts +47 -0
- package/dist/hooks/manager.d.ts.map +1 -0
- package/dist/hooks/manager.js +225 -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 +8 -0
- package/dist/hooks/types.js.map +1 -0
- package/dist/index.d.ts +258 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +740 -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 +21 -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 +251 -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 +4 -0
- package/dist/lsp/language.d.ts +9 -0
- package/dist/lsp/language.d.ts.map +1 -0
- package/dist/lsp/language.js +44 -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 +82 -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 +159 -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 +55 -0
- package/dist/lsp/workspace.js.map +1 -0
- package/dist/mcp/config.d.ts +54 -0
- package/dist/mcp/config.d.ts.map +1 -0
- package/dist/mcp/config.js +240 -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 +3 -0
- package/dist/mcp/manager.d.ts +98 -0
- package/dist/mcp/manager.d.ts.map +1 -0
- package/dist/mcp/manager.js +612 -0
- package/dist/mcp/manager.js.map +1 -0
- package/dist/mcp/state.d.ts +33 -0
- package/dist/mcp/state.d.ts.map +1 -0
- package/dist/mcp/state.js +88 -0
- package/dist/mcp/state.js.map +1 -0
- package/dist/mcp/types.d.ts +120 -0
- package/dist/mcp/types.d.ts.map +1 -0
- package/dist/mcp/types.js +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 +17 -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 +30 -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 +3 -0
- package/dist/onboarding/om-settings.d.ts +25 -0
- package/dist/onboarding/om-settings.d.ts.map +1 -0
- package/dist/onboarding/om-settings.js +47 -0
- package/dist/onboarding/om-settings.js.map +1 -0
- package/dist/onboarding/packs.d.ts +46 -0
- package/dist/onboarding/packs.d.ts.map +1 -0
- package/dist/onboarding/packs.js +160 -0
- package/dist/onboarding/packs.js.map +1 -0
- package/dist/onboarding/settings.d.ts +338 -0
- package/dist/onboarding/settings.d.ts.map +1 -0
- package/dist/onboarding/settings.js +673 -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 +132 -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 +28 -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 +88 -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 +190 -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 +206 -0
- package/dist/plugins/loader.js.map +1 -0
- package/dist/plugins/manager.d.ts +64 -0
- package/dist/plugins/manager.d.ts.map +1 -0
- package/dist/plugins/manager.js +384 -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 +50 -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 +61 -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 +25 -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 +112 -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 +116 -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/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 +54 -0
- package/dist/processors/plan-rejection-abort.js.map +1 -0
- package/dist/providers/amazon-bedrock-gateway.d.ts +47 -0
- package/dist/providers/amazon-bedrock-gateway.d.ts.map +1 -0
- package/dist/providers/amazon-bedrock-gateway.js +152 -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 +83 -0
- package/dist/providers/amazon-bedrock.js.map +1 -0
- package/dist/providers/claude-max.d.ts +52 -0
- package/dist/providers/claude-max.d.ts.map +1 -0
- package/dist/providers/claude-max.js +171 -0
- package/dist/providers/claude-max.js.map +1 -0
- package/dist/providers/github-copilot.d.ts +60 -0
- package/dist/providers/github-copilot.d.ts.map +1 -0
- package/dist/providers/github-copilot.js +265 -0
- package/dist/providers/github-copilot.js.map +1 -0
- package/dist/providers/openai-codex.d.ts +72 -0
- package/dist/providers/openai-codex.d.ts.map +1 -0
- package/dist/providers/openai-codex.js +302 -0
- package/dist/providers/openai-codex.js.map +1 -0
- package/dist/providers/xai.d.ts +33 -0
- package/dist/providers/xai.d.ts.map +1 -0
- package/dist/providers/xai.js +70 -0
- package/dist/providers/xai.js.map +1 -0
- package/dist/schema.d.ts +192 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +98 -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 +21 -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 +52 -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 +3 -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 +79 -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 +32 -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 +61 -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 +78 -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 +59 -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 +172 -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 +61 -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 +10 -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 +62 -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 +117 -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 +364 -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 +122 -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 +141 -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 +105 -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 +96 -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 +121 -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 +274 -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 +112 -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 +101 -0
- package/dist/utils/update-check.d.ts.map +1 -0
- package/dist/utils/update-check.js +383 -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 +144 -0
- package/dist/voice/stt-registry.js.map +1 -0
- package/package.json +96 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { parseAuthorizationInput } from "../authorization-input.js";
|
|
2
|
+
import { generatePKCE } from "../pkce.js";
|
|
3
|
+
//#region src/auth/providers/anthropic.ts
|
|
4
|
+
/**
|
|
5
|
+
* Anthropic OAuth flow (Claude Pro/Max)
|
|
6
|
+
*
|
|
7
|
+
* Inspired by pi-mono's OAuth implementation:
|
|
8
|
+
* https://github.com/badlogic/pi-mono/blob/main/packages/ai/src/utils/oauth/anthropic.ts
|
|
9
|
+
*
|
|
10
|
+
* The flow is a paste-code PKCE flow: the redirect lands on Anthropic's hosted
|
|
11
|
+
* callback page which displays `code#state` for the user to paste back. That
|
|
12
|
+
* makes it deployable without any inbound connection to the server, so the
|
|
13
|
+
* primitives are split into `startAnthropicLogin()` / `completeAnthropicLogin()`
|
|
14
|
+
* which can span separate HTTP requests (only the PKCE verifier needs to be
|
|
15
|
+
* persisted in between).
|
|
16
|
+
*/
|
|
17
|
+
const decode = (s) => atob(s);
|
|
18
|
+
const CLIENT_ID = decode("OWQxYzI1MGEtZTYxYi00NGQ5LTg4ZWQtNTk0NGQxOTYyZjVl");
|
|
19
|
+
const AUTHORIZE_URL = "https://claude.ai/oauth/authorize";
|
|
20
|
+
const TOKEN_URL = "https://console.anthropic.com/v1/oauth/token";
|
|
21
|
+
const REDIRECT_URI = "https://console.anthropic.com/oauth/code/callback";
|
|
22
|
+
const SCOPES = "org:create_api_key user:profile user:inference";
|
|
23
|
+
/**
|
|
24
|
+
* Start an Anthropic login: generate PKCE state and build the authorization URL.
|
|
25
|
+
*/
|
|
26
|
+
async function startAnthropicLogin() {
|
|
27
|
+
const { verifier, challenge } = await generatePKCE();
|
|
28
|
+
const authParams = new URLSearchParams({
|
|
29
|
+
code: "true",
|
|
30
|
+
client_id: CLIENT_ID,
|
|
31
|
+
response_type: "code",
|
|
32
|
+
redirect_uri: REDIRECT_URI,
|
|
33
|
+
scope: SCOPES,
|
|
34
|
+
code_challenge: challenge,
|
|
35
|
+
code_challenge_method: "S256",
|
|
36
|
+
state: verifier
|
|
37
|
+
});
|
|
38
|
+
return {
|
|
39
|
+
url: `${AUTHORIZE_URL}?${authParams.toString()}`,
|
|
40
|
+
verifier
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Complete an Anthropic login: parse the pasted authorization input
|
|
45
|
+
* (full URL, `code#state`, or query string), validate its state, and exchange
|
|
46
|
+
* it for tokens using the verifier from `startAnthropicLogin()`.
|
|
47
|
+
*/
|
|
48
|
+
async function completeAnthropicLogin(input, verifier) {
|
|
49
|
+
const { code, state } = parseAuthorizationInput(input);
|
|
50
|
+
if (!code) throw new Error("Missing authorization code");
|
|
51
|
+
if (!state || state !== verifier) throw new Error("Invalid authorization state");
|
|
52
|
+
const tokenResponse = await fetch(TOKEN_URL, {
|
|
53
|
+
method: "POST",
|
|
54
|
+
signal: AbortSignal.timeout(15e3),
|
|
55
|
+
headers: { "Content-Type": "application/json" },
|
|
56
|
+
body: JSON.stringify({
|
|
57
|
+
grant_type: "authorization_code",
|
|
58
|
+
client_id: CLIENT_ID,
|
|
59
|
+
code,
|
|
60
|
+
state,
|
|
61
|
+
redirect_uri: REDIRECT_URI,
|
|
62
|
+
code_verifier: verifier
|
|
63
|
+
})
|
|
64
|
+
});
|
|
65
|
+
if (!tokenResponse.ok) {
|
|
66
|
+
const error = await tokenResponse.text();
|
|
67
|
+
throw new Error(`Token exchange failed: ${error}`);
|
|
68
|
+
}
|
|
69
|
+
const tokenData = await tokenResponse.json();
|
|
70
|
+
const expiresAt = Date.now() + tokenData.expires_in * 1e3 - 300 * 1e3;
|
|
71
|
+
return {
|
|
72
|
+
refresh: tokenData.refresh_token,
|
|
73
|
+
access: tokenData.access_token,
|
|
74
|
+
expires: expiresAt
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Login with Anthropic OAuth (paste-code flow), blocking on the prompt callback.
|
|
79
|
+
*/
|
|
80
|
+
async function loginAnthropic(onAuthUrl, onPromptCode) {
|
|
81
|
+
const { url, verifier } = await startAnthropicLogin();
|
|
82
|
+
onAuthUrl(url);
|
|
83
|
+
return completeAnthropicLogin(await onPromptCode(), verifier);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Refresh Anthropic OAuth token
|
|
87
|
+
*/
|
|
88
|
+
async function refreshAnthropicToken(refreshToken) {
|
|
89
|
+
const response = await fetch(TOKEN_URL, {
|
|
90
|
+
method: "POST",
|
|
91
|
+
signal: AbortSignal.timeout(15e3),
|
|
92
|
+
headers: { "Content-Type": "application/json" },
|
|
93
|
+
body: JSON.stringify({
|
|
94
|
+
grant_type: "refresh_token",
|
|
95
|
+
client_id: CLIENT_ID,
|
|
96
|
+
refresh_token: refreshToken
|
|
97
|
+
})
|
|
98
|
+
});
|
|
99
|
+
if (!response.ok) {
|
|
100
|
+
const error = await response.text();
|
|
101
|
+
throw new Error(`Anthropic token refresh failed: ${error}`);
|
|
102
|
+
}
|
|
103
|
+
const data = await response.json();
|
|
104
|
+
return {
|
|
105
|
+
refresh: data.refresh_token,
|
|
106
|
+
access: data.access_token,
|
|
107
|
+
expires: Date.now() + data.expires_in * 1e3 - 300 * 1e3
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
const anthropicOAuthProvider = {
|
|
111
|
+
id: "anthropic",
|
|
112
|
+
name: "Anthropic (Claude Pro/Max)",
|
|
113
|
+
async login(callbacks) {
|
|
114
|
+
return loginAnthropic((url) => callbacks.onAuth({ url }), () => callbacks.onPrompt({ message: "Paste the authorization code:" }));
|
|
115
|
+
},
|
|
116
|
+
async refreshToken(credentials) {
|
|
117
|
+
return refreshAnthropicToken(credentials.refresh);
|
|
118
|
+
},
|
|
119
|
+
getApiKey(credentials) {
|
|
120
|
+
return credentials.access;
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
//#endregion
|
|
124
|
+
export { anthropicOAuthProvider, completeAnthropicLogin, loginAnthropic, refreshAnthropicToken, startAnthropicLogin };
|
|
125
|
+
|
|
126
|
+
//# sourceMappingURL=anthropic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic.js","names":[],"sources":["../../../src/auth/providers/anthropic.ts"],"sourcesContent":["/**\n * Anthropic OAuth flow (Claude Pro/Max)\n *\n * Inspired by pi-mono's OAuth implementation:\n * https://github.com/badlogic/pi-mono/blob/main/packages/ai/src/utils/oauth/anthropic.ts\n *\n * The flow is a paste-code PKCE flow: the redirect lands on Anthropic's hosted\n * callback page which displays `code#state` for the user to paste back. That\n * makes it deployable without any inbound connection to the server, so the\n * primitives are split into `startAnthropicLogin()` / `completeAnthropicLogin()`\n * which can span separate HTTP requests (only the PKCE verifier needs to be\n * persisted in between).\n */\n\nimport { parseAuthorizationInput } from '../authorization-input.js';\nimport { generatePKCE } from '../pkce.js';\nimport type { OAuthCredentials, OAuthLoginCallbacks, OAuthProviderInterface } from '../types.js';\n\nconst decode = (s: string) => atob(s);\nconst CLIENT_ID = decode('OWQxYzI1MGEtZTYxYi00NGQ5LTg4ZWQtNTk0NGQxOTYyZjVl');\nconst AUTHORIZE_URL = 'https://claude.ai/oauth/authorize';\n// pi-mono uses `https://platform.claude.com/v1/oauth/token` with extra scopes\n// (user:sessions:claude_code, user:mcp_servers, user:file_upload); we keep the\n// console.anthropic.com endpoints that are known to work for our scope set.\nconst TOKEN_URL = 'https://console.anthropic.com/v1/oauth/token';\nconst REDIRECT_URI = 'https://console.anthropic.com/oauth/code/callback';\nconst SCOPES = 'org:create_api_key user:profile user:inference';\n\nexport interface AnthropicLoginStart {\n /** Authorization URL for the user to open. */\n url: string;\n /** PKCE code verifier — persist it to complete the login later. */\n verifier: string;\n}\n\n/**\n * Start an Anthropic login: generate PKCE state and build the authorization URL.\n */\nexport async function startAnthropicLogin(): Promise<AnthropicLoginStart> {\n const { verifier, challenge } = await generatePKCE();\n\n const authParams = new URLSearchParams({\n code: 'true',\n client_id: CLIENT_ID,\n response_type: 'code',\n redirect_uri: REDIRECT_URI,\n scope: SCOPES,\n code_challenge: challenge,\n code_challenge_method: 'S256',\n state: verifier,\n });\n\n return { url: `${AUTHORIZE_URL}?${authParams.toString()}`, verifier };\n}\n\n/**\n * Complete an Anthropic login: parse the pasted authorization input\n * (full URL, `code#state`, or query string), validate its state, and exchange\n * it for tokens using the verifier from `startAnthropicLogin()`.\n */\nexport async function completeAnthropicLogin(input: string, verifier: string): Promise<OAuthCredentials> {\n const { code, state } = parseAuthorizationInput(input);\n if (!code) {\n throw new Error('Missing authorization code');\n }\n if (!state || state !== verifier) {\n throw new Error('Invalid authorization state');\n }\n\n const tokenResponse = await fetch(TOKEN_URL, {\n method: 'POST',\n // Bound the OAuth exchange so an unresponsive upstream cannot pin the\n // caller (and, in the shipyard server, the containing project lock)\n // indefinitely. See 2025-07-23 shipyard latency incident.\n signal: AbortSignal.timeout(15_000),\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n grant_type: 'authorization_code',\n client_id: CLIENT_ID,\n code,\n state,\n redirect_uri: REDIRECT_URI,\n code_verifier: verifier,\n }),\n });\n\n if (!tokenResponse.ok) {\n const error = await tokenResponse.text();\n throw new Error(`Token exchange failed: ${error}`);\n }\n\n const tokenData = (await tokenResponse.json()) as {\n access_token: string;\n refresh_token: string;\n expires_in: number;\n };\n\n // Calculate expiry time (current time + expires_in seconds - 5 min buffer)\n const expiresAt = Date.now() + tokenData.expires_in * 1000 - 5 * 60 * 1000;\n\n return {\n refresh: tokenData.refresh_token,\n access: tokenData.access_token,\n expires: expiresAt,\n };\n}\n\n/**\n * Login with Anthropic OAuth (paste-code flow), blocking on the prompt callback.\n */\nexport async function loginAnthropic(\n onAuthUrl: (url: string) => void,\n onPromptCode: () => Promise<string>,\n): Promise<OAuthCredentials> {\n const { url, verifier } = await startAnthropicLogin();\n\n // Notify caller with URL to open\n onAuthUrl(url);\n\n // Wait for user to paste authorization code (format: code#state)\n const authCode = await onPromptCode();\n\n return completeAnthropicLogin(authCode, verifier);\n}\n\n/**\n * Refresh Anthropic OAuth token\n */\nexport async function refreshAnthropicToken(refreshToken: string): Promise<OAuthCredentials> {\n const response = await fetch(TOKEN_URL, {\n method: 'POST',\n signal: AbortSignal.timeout(15_000),\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n grant_type: 'refresh_token',\n client_id: CLIENT_ID,\n refresh_token: refreshToken,\n }),\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`Anthropic token refresh failed: ${error}`);\n }\n\n const data = (await response.json()) as {\n access_token: string;\n refresh_token: string;\n expires_in: number;\n };\n\n return {\n refresh: data.refresh_token,\n access: data.access_token,\n expires: Date.now() + data.expires_in * 1000 - 5 * 60 * 1000,\n };\n}\n\nexport const anthropicOAuthProvider: OAuthProviderInterface = {\n id: 'anthropic',\n name: 'Anthropic (Claude Pro/Max)',\n\n async login(callbacks: OAuthLoginCallbacks): Promise<OAuthCredentials> {\n return loginAnthropic(\n url => callbacks.onAuth({ url }),\n () => callbacks.onPrompt({ message: 'Paste the authorization code:' }),\n );\n },\n\n async refreshToken(credentials: OAuthCredentials): Promise<OAuthCredentials> {\n return refreshAnthropicToken(credentials.refresh);\n },\n\n getApiKey(credentials: OAuthCredentials): string {\n return credentials.access;\n },\n};\n"],"mappings":";;;;;;;;;;;;;;;;AAkBA,MAAM,UAAU,MAAc,KAAK,CAAC;AACpC,MAAM,YAAY,OAAO,kDAAkD;AAC3E,MAAM,gBAAgB;AAItB,MAAM,YAAY;AAClB,MAAM,eAAe;AACrB,MAAM,SAAS;;;;AAYf,eAAsB,sBAAoD;CACxE,MAAM,EAAE,UAAU,cAAc,MAAM,aAAa;CAEnD,MAAM,aAAa,IAAI,gBAAgB;EACrC,MAAM;EACN,WAAW;EACX,eAAe;EACf,cAAc;EACd,OAAO;EACP,gBAAgB;EAChB,uBAAuB;EACvB,OAAO;CACT,CAAC;CAED,OAAO;EAAE,KAAK,GAAG,cAAc,GAAG,WAAW,SAAS;EAAK;CAAS;AACtE;;;;;;AAOA,eAAsB,uBAAuB,OAAe,UAA6C;CACvG,MAAM,EAAE,MAAM,UAAU,wBAAwB,KAAK;CACrD,IAAI,CAAC,MACH,MAAM,IAAI,MAAM,4BAA4B;CAE9C,IAAI,CAAC,SAAS,UAAU,UACtB,MAAM,IAAI,MAAM,6BAA6B;CAG/C,MAAM,gBAAgB,MAAM,MAAM,WAAW;EAC3C,QAAQ;EAIR,QAAQ,YAAY,QAAQ,IAAM;EAClC,SAAS,EACP,gBAAgB,mBAClB;EACA,MAAM,KAAK,UAAU;GACnB,YAAY;GACZ,WAAW;GACX;GACA;GACA,cAAc;GACd,eAAe;EACjB,CAAC;CACH,CAAC;CAED,IAAI,CAAC,cAAc,IAAI;EACrB,MAAM,QAAQ,MAAM,cAAc,KAAK;EACvC,MAAM,IAAI,MAAM,0BAA0B,OAAO;CACnD;CAEA,MAAM,YAAa,MAAM,cAAc,KAAK;CAO5C,MAAM,YAAY,KAAK,IAAI,IAAI,UAAU,aAAa,MAAO,MAAS;CAEtE,OAAO;EACL,SAAS,UAAU;EACnB,QAAQ,UAAU;EAClB,SAAS;CACX;AACF;;;;AAKA,eAAsB,eACpB,WACA,cAC2B;CAC3B,MAAM,EAAE,KAAK,aAAa,MAAM,oBAAoB;CAGpD,UAAU,GAAG;CAKb,OAAO,uBAAuB,MAFP,aAAa,GAEI,QAAQ;AAClD;;;;AAKA,eAAsB,sBAAsB,cAAiD;CAC3F,MAAM,WAAW,MAAM,MAAM,WAAW;EACtC,QAAQ;EACR,QAAQ,YAAY,QAAQ,IAAM;EAClC,SAAS,EAAE,gBAAgB,mBAAmB;EAC9C,MAAM,KAAK,UAAU;GACnB,YAAY;GACZ,WAAW;GACX,eAAe;EACjB,CAAC;CACH,CAAC;CAED,IAAI,CAAC,SAAS,IAAI;EAChB,MAAM,QAAQ,MAAM,SAAS,KAAK;EAClC,MAAM,IAAI,MAAM,mCAAmC,OAAO;CAC5D;CAEA,MAAM,OAAQ,MAAM,SAAS,KAAK;CAMlC,OAAO;EACL,SAAS,KAAK;EACd,QAAQ,KAAK;EACb,SAAS,KAAK,IAAI,IAAI,KAAK,aAAa,MAAO,MAAS;CAC1D;AACF;AAEA,MAAa,yBAAiD;CAC5D,IAAI;CACJ,MAAM;CAEN,MAAM,MAAM,WAA2D;EACrE,OAAO,gBACL,QAAO,UAAU,OAAO,EAAE,IAAI,CAAC,SACzB,UAAU,SAAS,EAAE,SAAS,gCAAgC,CAAC,CACvE;CACF;CAEA,MAAM,aAAa,aAA0D;EAC3E,OAAO,sBAAsB,YAAY,OAAO;CAClD;CAEA,UAAU,aAAuC;EAC/C,OAAO,YAAY;CACrB;AACF"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitHub Copilot OAuth flow
|
|
3
|
+
*
|
|
4
|
+
* Inspired by:
|
|
5
|
+
* - pi-mono: https://github.com/badlogic/pi-mono/blob/main/packages/ai/src/utils/oauth/github-copilot.ts
|
|
6
|
+
* - opencode: https://github.com/anomalyco/opencode/blob/dev/packages/opencode/src/plugin/github-copilot/copilot.ts
|
|
7
|
+
*
|
|
8
|
+
* Storage layout in AuthStorage:
|
|
9
|
+
* - `refresh` holds the long-lived GitHub OAuth access token (used to mint Copilot tokens).
|
|
10
|
+
* - `access` holds the short-lived Copilot bearer token (~30 minutes).
|
|
11
|
+
* - `expires` is the Copilot bearer expiry (ms epoch, with a 5-minute safety buffer).
|
|
12
|
+
* - `enterpriseUrl` is the GitHub Enterprise hostname, or undefined for github.com.
|
|
13
|
+
*/
|
|
14
|
+
import type { OAuthCredentials, OAuthProviderInterface } from '../types.js';
|
|
15
|
+
export type GitHubCopilotCredentials = OAuthCredentials & {
|
|
16
|
+
enterpriseUrl?: string;
|
|
17
|
+
};
|
|
18
|
+
export declare const COPILOT_USER_AGENT = "GitHubCopilotChat/0.35.0";
|
|
19
|
+
/** Headers that Copilot endpoints expect from a VS Code-like client. */
|
|
20
|
+
export declare const COPILOT_HEADERS: {
|
|
21
|
+
readonly 'User-Agent': "GitHubCopilotChat/0.35.0";
|
|
22
|
+
readonly 'Editor-Version': "vscode/1.107.0";
|
|
23
|
+
readonly 'Editor-Plugin-Version': "copilot-chat/0.35.0";
|
|
24
|
+
readonly 'Copilot-Integration-Id': "vscode-chat";
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Normalize a user-entered Enterprise URL/domain into a hostname (e.g. `company.ghe.com`).
|
|
28
|
+
* Returns null for an empty input or an unparseable URL.
|
|
29
|
+
*/
|
|
30
|
+
export declare function normalizeDomain(input: string): string | null;
|
|
31
|
+
/**
|
|
32
|
+
* Resolve the Copilot API base URL.
|
|
33
|
+
* Prefers the `proxy-ep` parsed from the bearer token, then falls back to enterprise/individual defaults.
|
|
34
|
+
*/
|
|
35
|
+
export declare function getGitHubCopilotBaseUrl(token?: string, enterpriseDomain?: string): string;
|
|
36
|
+
/**
|
|
37
|
+
* Serializable pending state for a Copilot device-code login. Safe to persist
|
|
38
|
+
* (e.g. a `pending jsonb` column) so polling can span HTTP requests/replicas.
|
|
39
|
+
*/
|
|
40
|
+
export interface CopilotDeviceLoginPending {
|
|
41
|
+
/** GitHub host performing the flow (`github.com` or an Enterprise hostname). */
|
|
42
|
+
domain: string;
|
|
43
|
+
/** Enterprise hostname, or undefined for github.com. Recorded on the final credentials. */
|
|
44
|
+
enterpriseDomain?: string;
|
|
45
|
+
deviceCode: string;
|
|
46
|
+
userCode: string;
|
|
47
|
+
/** Verification URL for the user to open. */
|
|
48
|
+
url: string;
|
|
49
|
+
instructions: string;
|
|
50
|
+
/** Current base poll interval in ms (grows on slow_down). */
|
|
51
|
+
intervalMs: number;
|
|
52
|
+
/** Safety margin applied to intervalMs when computing the next wait. */
|
|
53
|
+
intervalMultiplier: number;
|
|
54
|
+
/** Number of slow_down responses seen (used for the clock-drift hint). */
|
|
55
|
+
slowDownCount: number;
|
|
56
|
+
/** ms epoch after which the device authorization expires. */
|
|
57
|
+
deadlineAt: number;
|
|
58
|
+
}
|
|
59
|
+
export type CopilotDevicePollResult = {
|
|
60
|
+
status: 'complete';
|
|
61
|
+
credentials: GitHubCopilotCredentials;
|
|
62
|
+
} | {
|
|
63
|
+
status: 'pending';
|
|
64
|
+
pending: CopilotDeviceLoginPending;
|
|
65
|
+
nextPollMs: number;
|
|
66
|
+
} | {
|
|
67
|
+
status: 'failed';
|
|
68
|
+
error: string;
|
|
69
|
+
};
|
|
70
|
+
/** Delay to wait before the next upstream poll for a pending Copilot device login. */
|
|
71
|
+
export declare function copilotNextPollDelayMs(pending: CopilotDeviceLoginPending): number;
|
|
72
|
+
/**
|
|
73
|
+
* Start a Copilot device-code login: request a user code and return the
|
|
74
|
+
* serializable pending state for subsequent polls. Wait `copilotNextPollDelayMs`
|
|
75
|
+
* before the first poll.
|
|
76
|
+
*/
|
|
77
|
+
export declare function startGitHubCopilotDeviceLogin(enterpriseDomain?: string, options?: {
|
|
78
|
+
signal?: AbortSignal;
|
|
79
|
+
}): Promise<CopilotDeviceLoginPending>;
|
|
80
|
+
/**
|
|
81
|
+
* Perform exactly one upstream poll for a pending Copilot device login.
|
|
82
|
+
* On success, exchanges the GitHub OAuth token for a Copilot bearer token and
|
|
83
|
+
* returns full credentials. Never throws for flow-level conditions; network
|
|
84
|
+
* errors from fetch still propagate.
|
|
85
|
+
*/
|
|
86
|
+
export declare function pollGitHubCopilotDeviceLogin(pending: CopilotDeviceLoginPending, options?: {
|
|
87
|
+
signal?: AbortSignal;
|
|
88
|
+
onProgress?: (message: string) => void;
|
|
89
|
+
}): Promise<CopilotDevicePollResult>;
|
|
90
|
+
/**
|
|
91
|
+
* Refresh the short-lived Copilot bearer token using the long-lived GitHub OAuth token.
|
|
92
|
+
*
|
|
93
|
+
* `refreshToken` here is the GitHub OAuth access token; the Copilot endpoint returns a
|
|
94
|
+
* fresh bearer token (`token`) and absolute expiry (`expires_at`, seconds since epoch).
|
|
95
|
+
*/
|
|
96
|
+
export declare function refreshGitHubCopilotToken(refreshToken: string, enterpriseDomain?: string, signal?: AbortSignal): Promise<GitHubCopilotCredentials>;
|
|
97
|
+
/**
|
|
98
|
+
* Login with GitHub Copilot OAuth (device-code flow).
|
|
99
|
+
*
|
|
100
|
+
* Prompts for an optional GitHub Enterprise URL/domain, performs the device-code flow,
|
|
101
|
+
* then exchanges the GitHub OAuth token for a Copilot bearer token.
|
|
102
|
+
*/
|
|
103
|
+
export declare function loginGitHubCopilot(options: {
|
|
104
|
+
onAuth: (url: string, instructions?: string) => void;
|
|
105
|
+
onPrompt: (prompt: {
|
|
106
|
+
message: string;
|
|
107
|
+
placeholder?: string;
|
|
108
|
+
allowEmpty?: boolean;
|
|
109
|
+
}) => Promise<string>;
|
|
110
|
+
onProgress?: (message: string) => void;
|
|
111
|
+
signal?: AbortSignal;
|
|
112
|
+
}): Promise<GitHubCopilotCredentials>;
|
|
113
|
+
/**
|
|
114
|
+
* Filtered, normalized entry from the Copilot `/models` API.
|
|
115
|
+
*
|
|
116
|
+
* The full API payload includes a lot of capability metadata; we only keep the bits
|
|
117
|
+
* we need to expose models in `listAvailableModels()` and route requests sensibly.
|
|
118
|
+
*/
|
|
119
|
+
export type CopilotModelEntry = {
|
|
120
|
+
/** Stable model id (e.g. `claude-sonnet-4.5`, `gpt-4.1`). */
|
|
121
|
+
id: string;
|
|
122
|
+
/** Human-readable display name (e.g. `Claude Sonnet 4.5`). */
|
|
123
|
+
name: string;
|
|
124
|
+
/** Vendor field from the API (e.g. `Anthropic`, `OpenAI`). */
|
|
125
|
+
vendor: string;
|
|
126
|
+
/**
|
|
127
|
+
* Endpoints the model exposes (e.g. `/chat/completions`, `/responses`, `/v1/messages`).
|
|
128
|
+
* Empty when the API didn't return `supported_endpoints` for this entry.
|
|
129
|
+
*/
|
|
130
|
+
supportedEndpoints: string[];
|
|
131
|
+
/** True when `supported_endpoints` includes `/v1/messages` (Anthropic-shaped Copilot model). */
|
|
132
|
+
isAnthropicShaped: boolean;
|
|
133
|
+
/** True when `capabilities.supports.vision` is true. */
|
|
134
|
+
supportsVision: boolean;
|
|
135
|
+
/** True when the model supports tool calling. */
|
|
136
|
+
supportsToolCalls: boolean;
|
|
137
|
+
};
|
|
138
|
+
/**
|
|
139
|
+
* Fetch the Copilot model list available to the current subscription.
|
|
140
|
+
*
|
|
141
|
+
* Hits `${baseURL}/models` with the Copilot bearer token, filters to
|
|
142
|
+
* `model_picker_enabled === true && policy.state !== 'disabled'`, and returns
|
|
143
|
+
* a normalized list. Mirrors opencode's filtering rules.
|
|
144
|
+
*
|
|
145
|
+
* Inspired by:
|
|
146
|
+
* - opencode: https://github.com/anomalyco/opencode/blob/dev/packages/opencode/src/plugin/github-copilot/models.ts
|
|
147
|
+
*/
|
|
148
|
+
export declare function fetchCopilotModels(opts: {
|
|
149
|
+
baseUrl: string;
|
|
150
|
+
bearerToken: string;
|
|
151
|
+
signal?: AbortSignal;
|
|
152
|
+
}): Promise<CopilotModelEntry[]>;
|
|
153
|
+
export declare const githubCopilotOAuthProvider: OAuthProviderInterface;
|
|
154
|
+
//# sourceMappingURL=github-copilot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github-copilot.d.ts","sourceRoot":"","sources":["../../../src/auth/providers/github-copilot.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
//#region src/auth/providers/github-copilot.ts
|
|
2
|
+
const decode = (s) => atob(s);
|
|
3
|
+
const CLIENT_ID = decode("SXYxLmI1MDdhMDhjODdlY2ZlOTg=");
|
|
4
|
+
const COPILOT_USER_AGENT = "GitHubCopilotChat/0.35.0";
|
|
5
|
+
/** Headers that Copilot endpoints expect from a VS Code-like client. */
|
|
6
|
+
const COPILOT_HEADERS = {
|
|
7
|
+
"User-Agent": COPILOT_USER_AGENT,
|
|
8
|
+
"Editor-Version": "vscode/1.107.0",
|
|
9
|
+
"Editor-Plugin-Version": "copilot-chat/0.35.0",
|
|
10
|
+
"Copilot-Integration-Id": "vscode-chat"
|
|
11
|
+
};
|
|
12
|
+
const INITIAL_POLL_INTERVAL_MULTIPLIER = 1.2;
|
|
13
|
+
const SLOW_DOWN_POLL_INTERVAL_MULTIPLIER = 1.4;
|
|
14
|
+
/**
|
|
15
|
+
* Normalize a user-entered Enterprise URL/domain into a hostname (e.g. `company.ghe.com`).
|
|
16
|
+
* Returns null for an empty input or an unparseable URL.
|
|
17
|
+
*/
|
|
18
|
+
function normalizeDomain(input) {
|
|
19
|
+
const trimmed = input.trim();
|
|
20
|
+
if (!trimmed) return null;
|
|
21
|
+
try {
|
|
22
|
+
return (trimmed.includes("://") ? new URL(trimmed) : new URL(`https://${trimmed}`)).hostname || null;
|
|
23
|
+
} catch {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function getUrls(domain) {
|
|
28
|
+
return {
|
|
29
|
+
deviceCodeUrl: `https://${domain}/login/device/code`,
|
|
30
|
+
accessTokenUrl: `https://${domain}/login/oauth/access_token`,
|
|
31
|
+
copilotTokenUrl: `https://api.${domain}/copilot_internal/v2/token`
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Parse the `proxy-ep` segment from a Copilot bearer token and convert to its API base URL.
|
|
36
|
+
* Token shape: `tid=...;exp=...;proxy-ep=proxy.individual.githubcopilot.com;...`
|
|
37
|
+
*/
|
|
38
|
+
function getBaseUrlFromToken(token) {
|
|
39
|
+
const match = token.match(/proxy-ep=([^;]+)/);
|
|
40
|
+
if (!match) return null;
|
|
41
|
+
return `https://${match[1].replace(/^proxy\./, "api.")}`;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Resolve the Copilot API base URL.
|
|
45
|
+
* Prefers the `proxy-ep` parsed from the bearer token, then falls back to enterprise/individual defaults.
|
|
46
|
+
*/
|
|
47
|
+
function getGitHubCopilotBaseUrl(token, enterpriseDomain) {
|
|
48
|
+
if (token) {
|
|
49
|
+
const fromToken = getBaseUrlFromToken(token);
|
|
50
|
+
if (fromToken) return fromToken;
|
|
51
|
+
}
|
|
52
|
+
if (enterpriseDomain) return `https://copilot-api.${enterpriseDomain}`;
|
|
53
|
+
return "https://api.individual.githubcopilot.com";
|
|
54
|
+
}
|
|
55
|
+
async function fetchJson(url, init, signal) {
|
|
56
|
+
const response = await fetch(url, signal ? {
|
|
57
|
+
...init,
|
|
58
|
+
signal
|
|
59
|
+
} : init);
|
|
60
|
+
if (!response.ok) {
|
|
61
|
+
const text = await response.text().catch(() => "");
|
|
62
|
+
throw new Error(`${response.status} ${response.statusText}: ${text}`);
|
|
63
|
+
}
|
|
64
|
+
return response.json();
|
|
65
|
+
}
|
|
66
|
+
async function startDeviceFlow(domain, signal) {
|
|
67
|
+
const data = await fetchJson(getUrls(domain).deviceCodeUrl, {
|
|
68
|
+
method: "POST",
|
|
69
|
+
headers: {
|
|
70
|
+
Accept: "application/json",
|
|
71
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
72
|
+
"User-Agent": COPILOT_USER_AGENT
|
|
73
|
+
},
|
|
74
|
+
body: new URLSearchParams({
|
|
75
|
+
client_id: CLIENT_ID,
|
|
76
|
+
scope: "read:user"
|
|
77
|
+
})
|
|
78
|
+
}, signal);
|
|
79
|
+
if (!data || typeof data !== "object") throw new Error("Invalid device code response");
|
|
80
|
+
const obj = data;
|
|
81
|
+
const deviceCode = obj.device_code;
|
|
82
|
+
const userCode = obj.user_code;
|
|
83
|
+
const verificationUri = obj.verification_uri;
|
|
84
|
+
const interval = obj.interval;
|
|
85
|
+
const expiresIn = obj.expires_in;
|
|
86
|
+
if (typeof deviceCode !== "string" || typeof userCode !== "string" || typeof verificationUri !== "string" || typeof interval !== "number" || typeof expiresIn !== "number") throw new Error("Invalid device code response fields");
|
|
87
|
+
return {
|
|
88
|
+
device_code: deviceCode,
|
|
89
|
+
user_code: userCode,
|
|
90
|
+
verification_uri: verificationUri,
|
|
91
|
+
interval,
|
|
92
|
+
expires_in: expiresIn
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
/** Sleep that can be interrupted by an AbortSignal. */
|
|
96
|
+
function abortableSleep(ms, signal) {
|
|
97
|
+
return new Promise((resolve, reject) => {
|
|
98
|
+
if (signal?.aborted) {
|
|
99
|
+
reject(/* @__PURE__ */ new Error("Login cancelled"));
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
let timeout;
|
|
103
|
+
const onAbort = () => {
|
|
104
|
+
clearTimeout(timeout);
|
|
105
|
+
reject(/* @__PURE__ */ new Error("Login cancelled"));
|
|
106
|
+
};
|
|
107
|
+
timeout = setTimeout(() => {
|
|
108
|
+
signal?.removeEventListener("abort", onAbort);
|
|
109
|
+
resolve();
|
|
110
|
+
}, ms);
|
|
111
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
/** Delay to wait before the next upstream poll for a pending Copilot device login. */
|
|
115
|
+
function copilotNextPollDelayMs(pending) {
|
|
116
|
+
return Math.ceil(pending.intervalMs * pending.intervalMultiplier);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Start a Copilot device-code login: request a user code and return the
|
|
120
|
+
* serializable pending state for subsequent polls. Wait `copilotNextPollDelayMs`
|
|
121
|
+
* before the first poll.
|
|
122
|
+
*/
|
|
123
|
+
async function startGitHubCopilotDeviceLogin(enterpriseDomain, options) {
|
|
124
|
+
const domain = enterpriseDomain || "github.com";
|
|
125
|
+
const device = await startDeviceFlow(domain, options?.signal);
|
|
126
|
+
return {
|
|
127
|
+
domain,
|
|
128
|
+
...enterpriseDomain ? { enterpriseDomain } : {},
|
|
129
|
+
deviceCode: device.device_code,
|
|
130
|
+
userCode: device.user_code,
|
|
131
|
+
url: device.verification_uri,
|
|
132
|
+
instructions: `Enter code: ${device.user_code}`,
|
|
133
|
+
intervalMs: Math.max(1e3, Math.floor(device.interval * 1e3)),
|
|
134
|
+
intervalMultiplier: INITIAL_POLL_INTERVAL_MULTIPLIER,
|
|
135
|
+
slowDownCount: 0,
|
|
136
|
+
deadlineAt: Date.now() + device.expires_in * 1e3
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Perform exactly one upstream poll for a pending Copilot device login.
|
|
141
|
+
* On success, exchanges the GitHub OAuth token for a Copilot bearer token and
|
|
142
|
+
* returns full credentials. Never throws for flow-level conditions; network
|
|
143
|
+
* errors from fetch still propagate.
|
|
144
|
+
*/
|
|
145
|
+
async function pollGitHubCopilotDeviceLogin(pending, options) {
|
|
146
|
+
if (Date.now() >= pending.deadlineAt) {
|
|
147
|
+
if (pending.slowDownCount > 0) return {
|
|
148
|
+
status: "failed",
|
|
149
|
+
error: "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."
|
|
150
|
+
};
|
|
151
|
+
return {
|
|
152
|
+
status: "failed",
|
|
153
|
+
error: "Device flow timed out"
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
const raw = await fetchJson(getUrls(pending.domain).accessTokenUrl, {
|
|
157
|
+
method: "POST",
|
|
158
|
+
headers: {
|
|
159
|
+
Accept: "application/json",
|
|
160
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
161
|
+
"User-Agent": COPILOT_USER_AGENT
|
|
162
|
+
},
|
|
163
|
+
body: new URLSearchParams({
|
|
164
|
+
client_id: CLIENT_ID,
|
|
165
|
+
device_code: pending.deviceCode,
|
|
166
|
+
grant_type: "urn:ietf:params:oauth:grant-type:device_code"
|
|
167
|
+
})
|
|
168
|
+
}, options?.signal);
|
|
169
|
+
if (raw && typeof raw === "object" && typeof raw.access_token === "string") {
|
|
170
|
+
const githubAccessToken = raw.access_token;
|
|
171
|
+
options?.onProgress?.("Fetching Copilot token...");
|
|
172
|
+
return {
|
|
173
|
+
status: "complete",
|
|
174
|
+
credentials: await refreshGitHubCopilotToken(githubAccessToken, pending.enterpriseDomain, options?.signal)
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
if (raw && typeof raw === "object" && typeof raw.error === "string") {
|
|
178
|
+
const { error, error_description: description, interval } = raw;
|
|
179
|
+
if (error === "slow_down") {
|
|
180
|
+
const next = {
|
|
181
|
+
...pending,
|
|
182
|
+
slowDownCount: pending.slowDownCount + 1,
|
|
183
|
+
intervalMs: typeof interval === "number" && interval > 0 ? interval * 1e3 : Math.max(1e3, pending.intervalMs + 5e3),
|
|
184
|
+
intervalMultiplier: SLOW_DOWN_POLL_INTERVAL_MULTIPLIER
|
|
185
|
+
};
|
|
186
|
+
return {
|
|
187
|
+
status: "pending",
|
|
188
|
+
pending: next,
|
|
189
|
+
nextPollMs: copilotNextPollDelayMs(next)
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
if (error !== "authorization_pending") return {
|
|
193
|
+
status: "failed",
|
|
194
|
+
error: `Device flow failed: ${error}${description ? `: ${description}` : ""}`
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
return {
|
|
198
|
+
status: "pending",
|
|
199
|
+
pending,
|
|
200
|
+
nextPollMs: copilotNextPollDelayMs(pending)
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Refresh the short-lived Copilot bearer token using the long-lived GitHub OAuth token.
|
|
205
|
+
*
|
|
206
|
+
* `refreshToken` here is the GitHub OAuth access token; the Copilot endpoint returns a
|
|
207
|
+
* fresh bearer token (`token`) and absolute expiry (`expires_at`, seconds since epoch).
|
|
208
|
+
*/
|
|
209
|
+
async function refreshGitHubCopilotToken(refreshToken, enterpriseDomain, signal) {
|
|
210
|
+
const raw = await fetchJson(getUrls(enterpriseDomain || "github.com").copilotTokenUrl, { headers: {
|
|
211
|
+
Accept: "application/json",
|
|
212
|
+
Authorization: `Bearer ${refreshToken}`,
|
|
213
|
+
...COPILOT_HEADERS
|
|
214
|
+
} }, signal);
|
|
215
|
+
if (!raw || typeof raw !== "object") throw new Error("Invalid Copilot token response");
|
|
216
|
+
const obj = raw;
|
|
217
|
+
const token = obj.token;
|
|
218
|
+
const expiresAt = obj.expires_at;
|
|
219
|
+
if (typeof token !== "string" || typeof expiresAt !== "number") throw new Error("Invalid Copilot token response fields");
|
|
220
|
+
const credentials = {
|
|
221
|
+
refresh: refreshToken,
|
|
222
|
+
access: token,
|
|
223
|
+
expires: expiresAt * 1e3 - 300 * 1e3
|
|
224
|
+
};
|
|
225
|
+
if (enterpriseDomain) credentials.enterpriseUrl = enterpriseDomain;
|
|
226
|
+
return credentials;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Login with GitHub Copilot OAuth (device-code flow).
|
|
230
|
+
*
|
|
231
|
+
* Prompts for an optional GitHub Enterprise URL/domain, performs the device-code flow,
|
|
232
|
+
* then exchanges the GitHub OAuth token for a Copilot bearer token.
|
|
233
|
+
*/
|
|
234
|
+
async function loginGitHubCopilot(options) {
|
|
235
|
+
const input = await options.onPrompt({
|
|
236
|
+
message: "GitHub Enterprise URL/domain (blank for github.com)",
|
|
237
|
+
placeholder: "company.ghe.com",
|
|
238
|
+
allowEmpty: true
|
|
239
|
+
});
|
|
240
|
+
if (options.signal?.aborted) throw new Error("Login cancelled");
|
|
241
|
+
const trimmed = input.trim();
|
|
242
|
+
const enterpriseDomain = normalizeDomain(input);
|
|
243
|
+
if (trimmed && !enterpriseDomain) throw new Error("Invalid GitHub Enterprise URL/domain");
|
|
244
|
+
let pending = await startGitHubCopilotDeviceLogin(enterpriseDomain ?? void 0, { signal: options.signal });
|
|
245
|
+
options.onAuth(pending.url, pending.instructions);
|
|
246
|
+
while (true) {
|
|
247
|
+
if (options.signal?.aborted) throw new Error("Login cancelled");
|
|
248
|
+
const remainingMs = Math.max(pending.deadlineAt - Date.now(), 0);
|
|
249
|
+
await abortableSleep(Math.min(copilotNextPollDelayMs(pending), remainingMs), options.signal);
|
|
250
|
+
const result = await pollGitHubCopilotDeviceLogin(pending, {
|
|
251
|
+
signal: options.signal,
|
|
252
|
+
onProgress: options.onProgress
|
|
253
|
+
});
|
|
254
|
+
if (result.status === "complete") return result.credentials;
|
|
255
|
+
if (result.status === "failed") throw new Error(result.error);
|
|
256
|
+
pending = result.pending;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Fetch the Copilot model list available to the current subscription.
|
|
261
|
+
*
|
|
262
|
+
* Hits `${baseURL}/models` with the Copilot bearer token, filters to
|
|
263
|
+
* `model_picker_enabled === true && policy.state !== 'disabled'`, and returns
|
|
264
|
+
* a normalized list. Mirrors opencode's filtering rules.
|
|
265
|
+
*
|
|
266
|
+
* Inspired by:
|
|
267
|
+
* - opencode: https://github.com/anomalyco/opencode/blob/dev/packages/opencode/src/plugin/github-copilot/models.ts
|
|
268
|
+
*/
|
|
269
|
+
async function fetchCopilotModels(opts) {
|
|
270
|
+
const url = `${opts.baseUrl.replace(/\/$/, "")}/models`;
|
|
271
|
+
const response = await fetch(url, {
|
|
272
|
+
headers: {
|
|
273
|
+
Accept: "application/json",
|
|
274
|
+
Authorization: `Bearer ${opts.bearerToken}`,
|
|
275
|
+
...COPILOT_HEADERS
|
|
276
|
+
},
|
|
277
|
+
signal: opts.signal
|
|
278
|
+
});
|
|
279
|
+
if (!response.ok) {
|
|
280
|
+
const text = await response.text().catch(() => "");
|
|
281
|
+
throw new Error(`Failed to fetch Copilot models: ${response.status} ${response.statusText}: ${text}`);
|
|
282
|
+
}
|
|
283
|
+
const json = await response.json().catch(() => null);
|
|
284
|
+
if (!json || typeof json !== "object" || !Array.isArray(json.data)) throw new Error("Invalid Copilot models response: missing `data` array");
|
|
285
|
+
const data = json.data;
|
|
286
|
+
const result = [];
|
|
287
|
+
for (const item of data) {
|
|
288
|
+
if (!item || typeof item !== "object") continue;
|
|
289
|
+
const obj = item;
|
|
290
|
+
if (obj.model_picker_enabled !== true) continue;
|
|
291
|
+
const policy = obj.policy;
|
|
292
|
+
if (policy && policy.state === "disabled") continue;
|
|
293
|
+
const id = obj.id;
|
|
294
|
+
if (typeof id !== "string" || !id) continue;
|
|
295
|
+
const name = typeof obj.name === "string" ? obj.name : id;
|
|
296
|
+
const vendor = typeof obj.vendor === "string" ? obj.vendor : "";
|
|
297
|
+
const supports = obj.capabilities?.supports;
|
|
298
|
+
const supportsVision = supports?.vision === true;
|
|
299
|
+
const supportsToolCalls = supports?.tool_calls === true;
|
|
300
|
+
const rawEndpoints = obj.supported_endpoints;
|
|
301
|
+
const supportedEndpoints = Array.isArray(rawEndpoints) ? rawEndpoints.filter((e) => typeof e === "string") : [];
|
|
302
|
+
const isAnthropicShaped = supportedEndpoints.includes("/v1/messages");
|
|
303
|
+
result.push({
|
|
304
|
+
id,
|
|
305
|
+
name,
|
|
306
|
+
vendor,
|
|
307
|
+
supportedEndpoints,
|
|
308
|
+
isAnthropicShaped,
|
|
309
|
+
supportsVision,
|
|
310
|
+
supportsToolCalls
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
return result;
|
|
314
|
+
}
|
|
315
|
+
const githubCopilotOAuthProvider = {
|
|
316
|
+
id: "github-copilot",
|
|
317
|
+
name: "GitHub Copilot",
|
|
318
|
+
async login(callbacks) {
|
|
319
|
+
return loginGitHubCopilot({
|
|
320
|
+
onAuth: (url, instructions) => callbacks.onAuth({
|
|
321
|
+
url,
|
|
322
|
+
instructions
|
|
323
|
+
}),
|
|
324
|
+
onPrompt: callbacks.onPrompt,
|
|
325
|
+
onProgress: callbacks.onProgress,
|
|
326
|
+
signal: callbacks.signal
|
|
327
|
+
});
|
|
328
|
+
},
|
|
329
|
+
async refreshToken(credentials) {
|
|
330
|
+
const creds = credentials;
|
|
331
|
+
return refreshGitHubCopilotToken(creds.refresh, creds.enterpriseUrl);
|
|
332
|
+
},
|
|
333
|
+
getApiKey(credentials) {
|
|
334
|
+
return credentials.access;
|
|
335
|
+
}
|
|
336
|
+
};
|
|
337
|
+
//#endregion
|
|
338
|
+
export { COPILOT_HEADERS, COPILOT_USER_AGENT, copilotNextPollDelayMs, fetchCopilotModels, getGitHubCopilotBaseUrl, githubCopilotOAuthProvider, loginGitHubCopilot, normalizeDomain, pollGitHubCopilotDeviceLogin, refreshGitHubCopilotToken, startGitHubCopilotDeviceLogin };
|
|
339
|
+
|
|
340
|
+
//# sourceMappingURL=github-copilot.js.map
|