@code-yeongyu/senpi-ai 2026.9.28-5 → 2026.9.28-6

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.
@@ -0,0 +1,19 @@
1
+ export declare const GITHUB_COPILOT_INDIVIDUAL_BASE_URL = "https://api.individual.githubcopilot.com";
2
+ export interface GitHubCopilotApiEndpoint {
3
+ readonly tid: string;
4
+ readonly url: string;
5
+ }
6
+ export declare function githubCopilotTokenField(token: string, key: string): string | undefined;
7
+ export declare function githubCopilotBaseUrlFromToken(token: string): string | undefined;
8
+ export declare function parseGitHubCopilotApiEndpoint(value: unknown): string | undefined;
9
+ /**
10
+ * The account's Copilot API base URL, in order: the token response's `endpoints.api` recorded for
11
+ * this exact token (matched by `tid`, so a pooled sibling account never borrows it), the token's
12
+ * `proxy-ep`, the GitHub Enterprise Server domain, then the individual host.
13
+ */
14
+ export declare function resolveGitHubCopilotBaseUrl(input: {
15
+ token?: string;
16
+ apiEndpoint?: unknown;
17
+ enterpriseDomain?: string;
18
+ }): string;
19
+ //# sourceMappingURL=github-copilot-endpoint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-copilot-endpoint.d.ts","sourceRoot":"","sources":["../../src/api/github-copilot-endpoint.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,kCAAkC,6CAA6C,CAAC;AAE7F,MAAM,WAAW,wBAAwB;IACxC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAMtF;AAED,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAG/E;AAED,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAShF;AASD;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE;IAClD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC1B,GAAG,MAAM,CAOT"}
@@ -0,0 +1,48 @@
1
+ // The Copilot API host is per account plan (individual, business, enterprise, data-residency
2
+ // tenants). A request sent to another plan's host is refused with `421 Misdirected Request`,
3
+ // so the host always comes from the account's own token; the individual host is a last resort.
4
+ export const GITHUB_COPILOT_INDIVIDUAL_BASE_URL = "https://api.individual.githubcopilot.com";
5
+ export function githubCopilotTokenField(token, key) {
6
+ for (const part of token.split(";")) {
7
+ const separator = part.indexOf("=");
8
+ if (separator > 0 && part.slice(0, separator) === key)
9
+ return part.slice(separator + 1) || undefined;
10
+ }
11
+ return undefined;
12
+ }
13
+ export function githubCopilotBaseUrlFromToken(token) {
14
+ const proxyHost = githubCopilotTokenField(token, "proxy-ep");
15
+ return proxyHost ? `https://${proxyHost.replace(/^proxy\./, "api.")}` : undefined;
16
+ }
17
+ export function parseGitHubCopilotApiEndpoint(value) {
18
+ if (typeof value !== "string")
19
+ return undefined;
20
+ try {
21
+ const url = new URL(value.trim());
22
+ if (url.protocol !== "https:" || !url.hostname || url.username || url.password)
23
+ return undefined;
24
+ return `${url.origin}${url.pathname.replace(/\/+$/, "")}`;
25
+ }
26
+ catch {
27
+ return undefined;
28
+ }
29
+ }
30
+ function endpointForToken(endpoint, token) {
31
+ if (!token || typeof endpoint !== "object" || endpoint === null)
32
+ return undefined;
33
+ const tid = Reflect.get(endpoint, "tid");
34
+ const url = parseGitHubCopilotApiEndpoint(Reflect.get(endpoint, "url"));
35
+ return typeof tid === "string" && tid === githubCopilotTokenField(token, "tid") ? url : undefined;
36
+ }
37
+ /**
38
+ * The account's Copilot API base URL, in order: the token response's `endpoints.api` recorded for
39
+ * this exact token (matched by `tid`, so a pooled sibling account never borrows it), the token's
40
+ * `proxy-ep`, the GitHub Enterprise Server domain, then the individual host.
41
+ */
42
+ export function resolveGitHubCopilotBaseUrl(input) {
43
+ return (endpointForToken(input.apiEndpoint, input.token) ??
44
+ (input.token ? githubCopilotBaseUrlFromToken(input.token) : undefined) ??
45
+ (input.enterpriseDomain ? `https://copilot-api.${input.enterpriseDomain}` : undefined) ??
46
+ GITHUB_COPILOT_INDIVIDUAL_BASE_URL);
47
+ }
48
+ //# sourceMappingURL=github-copilot-endpoint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-copilot-endpoint.js","sourceRoot":"","sources":["../../src/api/github-copilot-endpoint.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAC7F,6FAA6F;AAC7F,+FAA+F;AAE/F,MAAM,CAAC,MAAM,kCAAkC,GAAG,0CAA0C,CAAC;AAO7F,MAAM,UAAU,uBAAuB,CAAC,KAAa,EAAE,GAAW;IACjE,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QACrC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,SAAS,GAAG,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,KAAK,GAAG;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,IAAI,SAAS,CAAC;IACtG,CAAC;IACD,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,6BAA6B,CAAC,KAAa;IAC1D,MAAM,SAAS,GAAG,uBAAuB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IAC7D,OAAO,SAAS,CAAC,CAAC,CAAC,WAAW,SAAS,CAAC,OAAO,CAAC,UAAU,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AACnF,CAAC;AAED,MAAM,UAAU,6BAA6B,CAAC,KAAc;IAC3D,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAChD,IAAI,CAAC;QACJ,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QAClC,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ;YAAE,OAAO,SAAS,CAAC;QACjG,OAAO,GAAG,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC;IAC3D,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,SAAS,CAAC;IAClB,CAAC;AACF,CAAC;AAED,SAAS,gBAAgB,CAAC,QAAiB,EAAE,KAAyB;IACrE,IAAI,CAAC,KAAK,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,IAAI;QAAE,OAAO,SAAS,CAAC;IAClF,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IACzC,MAAM,GAAG,GAAG,6BAA6B,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC;IACxE,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,uBAAuB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;AACnG,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,2BAA2B,CAAC,KAI3C;IACA,OAAO,CACN,gBAAgB,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,KAAK,CAAC;QAChD,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,6BAA6B,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACtE,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,uBAAuB,KAAK,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QACtF,kCAAkC,CAClC,CAAC;AACH,CAAC","sourcesContent":["// The Copilot API host is per account plan (individual, business, enterprise, data-residency\n// tenants). A request sent to another plan's host is refused with `421 Misdirected Request`,\n// so the host always comes from the account's own token; the individual host is a last resort.\n\nexport const GITHUB_COPILOT_INDIVIDUAL_BASE_URL = \"https://api.individual.githubcopilot.com\";\n\nexport interface GitHubCopilotApiEndpoint {\n\treadonly tid: string;\n\treadonly url: string;\n}\n\nexport function githubCopilotTokenField(token: string, key: string): string | undefined {\n\tfor (const part of token.split(\";\")) {\n\t\tconst separator = part.indexOf(\"=\");\n\t\tif (separator > 0 && part.slice(0, separator) === key) return part.slice(separator + 1) || undefined;\n\t}\n\treturn undefined;\n}\n\nexport function githubCopilotBaseUrlFromToken(token: string): string | undefined {\n\tconst proxyHost = githubCopilotTokenField(token, \"proxy-ep\");\n\treturn proxyHost ? `https://${proxyHost.replace(/^proxy\\./, \"api.\")}` : undefined;\n}\n\nexport function parseGitHubCopilotApiEndpoint(value: unknown): string | undefined {\n\tif (typeof value !== \"string\") return undefined;\n\ttry {\n\t\tconst url = new URL(value.trim());\n\t\tif (url.protocol !== \"https:\" || !url.hostname || url.username || url.password) return undefined;\n\t\treturn `${url.origin}${url.pathname.replace(/\\/+$/, \"\")}`;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction endpointForToken(endpoint: unknown, token: string | undefined): string | undefined {\n\tif (!token || typeof endpoint !== \"object\" || endpoint === null) return undefined;\n\tconst tid = Reflect.get(endpoint, \"tid\");\n\tconst url = parseGitHubCopilotApiEndpoint(Reflect.get(endpoint, \"url\"));\n\treturn typeof tid === \"string\" && tid === githubCopilotTokenField(token, \"tid\") ? url : undefined;\n}\n\n/**\n * The account's Copilot API base URL, in order: the token response's `endpoints.api` recorded for\n * this exact token (matched by `tid`, so a pooled sibling account never borrows it), the token's\n * `proxy-ep`, the GitHub Enterprise Server domain, then the individual host.\n */\nexport function resolveGitHubCopilotBaseUrl(input: {\n\ttoken?: string;\n\tapiEndpoint?: unknown;\n\tenterpriseDomain?: string;\n}): string {\n\treturn (\n\t\tendpointForToken(input.apiEndpoint, input.token) ??\n\t\t(input.token ? githubCopilotBaseUrlFromToken(input.token) : undefined) ??\n\t\t(input.enterpriseDomain ? `https://copilot-api.${input.enterpriseDomain}` : undefined) ??\n\t\tGITHUB_COPILOT_INDIVIDUAL_BASE_URL\n\t);\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"github-copilot-errors.d.ts","sourceRoot":"","sources":["../../src/api/github-copilot-errors.ts"],"names":[],"mappings":"AA0CA;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAe/E;AAED,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,CAItG"}
1
+ {"version":3,"file":"github-copilot-errors.d.ts","sourceRoot":"","sources":["../../src/api/github-copilot-errors.ts"],"names":[],"mappings":"AA0CA;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAkB/E;AAED,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,CAItG"}
@@ -60,6 +60,9 @@ export function describeGitHubCopilotFailure(error) {
60
60
  if (isQuotaFailure(status, body, headerValue(headers, "x-ratelimit-exceeded"))) {
61
61
  return `GitHub Copilot quota exceeded (HTTP ${status}): the plan's included usage or its additional-usage limit is used up, so premium models are refused until it resets or the limit is raised. Usage is shown at https://github.com/settings/copilot.${reference}`;
62
62
  }
63
+ if (status === 421) {
64
+ return `GitHub Copilot sent this account to a different API host (HTTP 421 Misdirected Request): Business and Enterprise accounts are served from their own host, which senpi reads from the Copilot token. Run /login github-copilot so senpi stores the account's endpoint, and report it with the GitHub request id if it persists.${reference}`;
65
+ }
63
66
  if (status === 403) {
64
67
  const reason = body === undefined ? " with an empty body" : "";
65
68
  return `GitHub Copilot refused the request (HTTP 403${reason}). Copilot checks access per model and per client; if a fresh /login github-copilot does not help, report it with the GitHub request id.${reference}`;
@@ -1 +1 @@
1
- {"version":3,"file":"github-copilot-errors.js","sourceRoot":"","sources":["../../src/api/github-copilot-errors.ts"],"names":[],"mappings":"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","sourcesContent":["import { normalizeProviderError } from \"../utils/error-body.ts\";\nimport { formatProviderRequestId } from \"../utils/retry.ts\";\n\n// Codes VS Code Copilot Chat treats as quota exhaustion (extensions/copilot chatMLFetcher.ts).\nconst QUOTA_CODES = new Set([\n\t\"quota_exceeded\",\n\t\"free_quota_exceeded\",\n\t\"overage_limit_reached\",\n\t\"billing_not_configured\",\n\t\"additional_spend_limit_reached\",\n]);\n\nfunction headerValue(headers: unknown, name: string): string | undefined {\n\tif (headers instanceof Headers) return headers.get(name) ?? undefined;\n\tif (typeof headers !== \"object\" || headers === null) return undefined;\n\tfor (const [key, value] of Object.entries(headers)) {\n\t\tif (key.toLowerCase() === name && typeof value === \"string\") return value;\n\t}\n\treturn undefined;\n}\n\nfunction errorCode(body: string | undefined): string | undefined {\n\tif (body === undefined) return undefined;\n\ttry {\n\t\tconst parsed: unknown = JSON.parse(body);\n\t\tif (typeof parsed !== \"object\" || parsed === null) return undefined;\n\t\tconst nested = Reflect.get(parsed, \"error\");\n\t\tconst code =\n\t\t\ttypeof nested === \"object\" && nested !== null ? Reflect.get(nested, \"code\") : Reflect.get(parsed, \"code\");\n\t\treturn typeof code === \"string\" ? code : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction isQuotaFailure(status: number, body: string | undefined, limitKey: string | undefined): boolean {\n\tconst code = errorCode(body);\n\tif (code !== undefined && QUOTA_CODES.has(code)) return true;\n\tif (status === 402) return true;\n\treturn status === 429 && (limitKey?.includes(\"quota\") === true || /quota exceeded/i.test(body ?? \"\"));\n}\n\n/**\n * A plain-language note for a GitHub Copilot HTTP failure that the SDK message alone\n * leaves opaque (`403 status code (no body)`): which refusal it is, where to look, and\n * the GitHub request id support needs. `undefined` for failures the message already\n * explains. The wording avoids credential words so pool classification is unchanged.\n */\nexport function describeGitHubCopilotFailure(error: unknown): string | undefined {\n\tif (!(error instanceof Error)) return undefined;\n\tconst { status, body } = normalizeProviderError(error);\n\tif (status === undefined) return undefined;\n\tconst headers = Reflect.get(error, \"headers\");\n\tconst requestId = headerValue(headers, \"x-github-request-id\");\n\tconst reference = requestId === undefined ? \"\" : ` ${formatProviderRequestId(\"GitHub\", requestId)}.`;\n\tif (isQuotaFailure(status, body, headerValue(headers, \"x-ratelimit-exceeded\"))) {\n\t\treturn `GitHub Copilot quota exceeded (HTTP ${status}): the plan's included usage or its additional-usage limit is used up, so premium models are refused until it resets or the limit is raised. Usage is shown at https://github.com/settings/copilot.${reference}`;\n\t}\n\tif (status === 403) {\n\t\tconst reason = body === undefined ? \" with an empty body\" : \"\";\n\t\treturn `GitHub Copilot refused the request (HTTP 403${reason}). Copilot checks access per model and per client; if a fresh /login github-copilot does not help, report it with the GitHub request id.${reference}`;\n\t}\n\treturn undefined;\n}\n\nexport function withGitHubCopilotFailureNote(message: string, provider: string, error: unknown): string {\n\tif (provider !== \"github-copilot\") return message;\n\tconst note = describeGitHubCopilotFailure(error);\n\treturn note === undefined ? message : `${message}\\n${note}`;\n}\n"]}
1
+ {"version":3,"file":"github-copilot-errors.js","sourceRoot":"","sources":["../../src/api/github-copilot-errors.ts"],"names":[],"mappings":"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","sourcesContent":["import { normalizeProviderError } from \"../utils/error-body.ts\";\nimport { formatProviderRequestId } from \"../utils/retry.ts\";\n\n// Codes VS Code Copilot Chat treats as quota exhaustion (extensions/copilot chatMLFetcher.ts).\nconst QUOTA_CODES = new Set([\n\t\"quota_exceeded\",\n\t\"free_quota_exceeded\",\n\t\"overage_limit_reached\",\n\t\"billing_not_configured\",\n\t\"additional_spend_limit_reached\",\n]);\n\nfunction headerValue(headers: unknown, name: string): string | undefined {\n\tif (headers instanceof Headers) return headers.get(name) ?? undefined;\n\tif (typeof headers !== \"object\" || headers === null) return undefined;\n\tfor (const [key, value] of Object.entries(headers)) {\n\t\tif (key.toLowerCase() === name && typeof value === \"string\") return value;\n\t}\n\treturn undefined;\n}\n\nfunction errorCode(body: string | undefined): string | undefined {\n\tif (body === undefined) return undefined;\n\ttry {\n\t\tconst parsed: unknown = JSON.parse(body);\n\t\tif (typeof parsed !== \"object\" || parsed === null) return undefined;\n\t\tconst nested = Reflect.get(parsed, \"error\");\n\t\tconst code =\n\t\t\ttypeof nested === \"object\" && nested !== null ? Reflect.get(nested, \"code\") : Reflect.get(parsed, \"code\");\n\t\treturn typeof code === \"string\" ? code : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction isQuotaFailure(status: number, body: string | undefined, limitKey: string | undefined): boolean {\n\tconst code = errorCode(body);\n\tif (code !== undefined && QUOTA_CODES.has(code)) return true;\n\tif (status === 402) return true;\n\treturn status === 429 && (limitKey?.includes(\"quota\") === true || /quota exceeded/i.test(body ?? \"\"));\n}\n\n/**\n * A plain-language note for a GitHub Copilot HTTP failure that the SDK message alone\n * leaves opaque (`403 status code (no body)`): which refusal it is, where to look, and\n * the GitHub request id support needs. `undefined` for failures the message already\n * explains. The wording avoids credential words so pool classification is unchanged.\n */\nexport function describeGitHubCopilotFailure(error: unknown): string | undefined {\n\tif (!(error instanceof Error)) return undefined;\n\tconst { status, body } = normalizeProviderError(error);\n\tif (status === undefined) return undefined;\n\tconst headers = Reflect.get(error, \"headers\");\n\tconst requestId = headerValue(headers, \"x-github-request-id\");\n\tconst reference = requestId === undefined ? \"\" : ` ${formatProviderRequestId(\"GitHub\", requestId)}.`;\n\tif (isQuotaFailure(status, body, headerValue(headers, \"x-ratelimit-exceeded\"))) {\n\t\treturn `GitHub Copilot quota exceeded (HTTP ${status}): the plan's included usage or its additional-usage limit is used up, so premium models are refused until it resets or the limit is raised. Usage is shown at https://github.com/settings/copilot.${reference}`;\n\t}\n\tif (status === 421) {\n\t\treturn `GitHub Copilot sent this account to a different API host (HTTP 421 Misdirected Request): Business and Enterprise accounts are served from their own host, which senpi reads from the Copilot token. Run /login github-copilot so senpi stores the account's endpoint, and report it with the GitHub request id if it persists.${reference}`;\n\t}\n\tif (status === 403) {\n\t\tconst reason = body === undefined ? \" with an empty body\" : \"\";\n\t\treturn `GitHub Copilot refused the request (HTTP 403${reason}). Copilot checks access per model and per client; if a fresh /login github-copilot does not help, report it with the GitHub request id.${reference}`;\n\t}\n\treturn undefined;\n}\n\nexport function withGitHubCopilotFailureNote(message: string, provider: string, error: unknown): string {\n\tif (provider !== \"github-copilot\") return message;\n\tconst note = describeGitHubCopilotFailure(error);\n\treturn note === undefined ? message : `${message}\\n${note}`;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"github-copilot.d.ts","sourceRoot":"","sources":["../../../src/auth/oauth/github-copilot.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,SAAS,EAA4C,MAAM,aAAa,CAAC;AAgcvF,eAAO,MAAM,kBAAkB,EAAE,SAehC,CAAC"}
1
+ {"version":3,"file":"github-copilot.d.ts","sourceRoot":"","sources":["../../../src/auth/oauth/github-copilot.ts"],"names":[],"mappings":"AAAA;;GAEG;AAUH,OAAO,KAAK,EAAE,SAAS,EAA4C,MAAM,aAAa,CAAC;AAubvF,eAAO,MAAM,kBAAkB,EAAE,SAmBhC,CAAC"}
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * GitHub Copilot OAuth flow
3
3
  */
4
+ import { GITHUB_COPILOT_INDIVIDUAL_BASE_URL, githubCopilotTokenField, parseGitHubCopilotApiEndpoint, resolveGitHubCopilotBaseUrl, } from "../../api/github-copilot-endpoint.js";
4
5
  import { GITHUB_COPILOT_REJECTED_TOKEN_STATUSES } from "../../api/github-copilot-headers.js";
5
6
  import { sleep } from "../../utils/sleep.js";
6
7
  import { pollOAuthDeviceCodeFlow } from "./device-code.js";
@@ -33,31 +34,8 @@ function getUrls(domain) {
33
34
  copilotTokenUrl: `https://api.${domain}/copilot_internal/v2/token`,
34
35
  };
35
36
  }
36
- /**
37
- * Parse the proxy-ep from a Copilot token and convert to API base URL.
38
- * Token format: tid=...;exp=...;proxy-ep=proxy.individual.githubcopilot.com;...
39
- * Returns API URL like https://api.individual.githubcopilot.com
40
- */
41
- function getBaseUrlFromToken(token) {
42
- const match = token.match(/proxy-ep=([^;]+)/);
43
- if (!match)
44
- return null;
45
- const proxyHost = match[1];
46
- // Convert proxy.xxx to api.xxx
47
- const apiHost = proxyHost.replace(/^proxy\./, "api.");
48
- return `https://${apiHost}`;
49
- }
50
- function getGitHubCopilotBaseUrl(token, enterpriseDomain) {
51
- // If we have a token, extract the base URL from proxy-ep
52
- if (token) {
53
- const urlFromToken = getBaseUrlFromToken(token);
54
- if (urlFromToken)
55
- return urlFromToken;
56
- }
57
- // Fallback for enterprise or if token parsing fails
58
- if (enterpriseDomain)
59
- return `https://copilot-api.${enterpriseDomain}`;
60
- return "https://api.individual.githubcopilot.com";
37
+ function getGitHubCopilotBaseUrl(token, enterpriseDomain, apiEndpoint) {
38
+ return resolveGitHubCopilotBaseUrl({ token, enterpriseDomain, apiEndpoint });
61
39
  }
62
40
  async function fetchWithRateLimitRetry(url, init, signal, retryPolicy) {
63
41
  const retryBudgetSignal = retryPolicy.maxRetries > 0 && retryPolicy.maxElapsedMs > 0
@@ -87,11 +65,11 @@ async function fetchWithRateLimitRetry(url, init, signal, retryPolicy) {
87
65
  await sleep(delayMs, requestSignal);
88
66
  }
89
67
  }
90
- async function fetchGitHubCopilotModels(copilotToken, enterpriseDomain, signal, retryPolicy) {
91
- const baseUrl = getGitHubCopilotBaseUrl(copilotToken, enterpriseDomain);
68
+ async function fetchGitHubCopilotModels(copilotToken, enterpriseDomain, signal, retryPolicy, apiEndpoint) {
69
+ const baseUrl = getGitHubCopilotBaseUrl(copilotToken, enterpriseDomain, apiEndpoint);
92
70
  // Some Individual accounts return false for every picker flag despite explicit enabled policies.
93
71
  // Limit the fallback to that endpoint so other account types keep strict picker semantics.
94
- const allowPolicyFallback = baseUrl === "https://api.individual.githubcopilot.com";
72
+ const allowPolicyFallback = baseUrl === GITHUB_COPILOT_INDIVIDUAL_BASE_URL;
95
73
  const response = await fetchWithRateLimitRetry(`${baseUrl}/models`, {
96
74
  headers: {
97
75
  Accept: "application/json",
@@ -222,12 +200,16 @@ async function refreshGitHubCopilotAccessToken(refreshToken, enterpriseDomain, s
222
200
  if (typeof token !== "string" || typeof expiresAt !== "number") {
223
201
  throw new Error("Invalid Copilot token response fields");
224
202
  }
203
+ const endpoints = raw.endpoints;
204
+ const apiUrl = parseGitHubCopilotApiEndpoint(typeof endpoints === "object" && endpoints !== null ? Reflect.get(endpoints, "api") : undefined);
205
+ const tid = githubCopilotTokenField(token, "tid");
225
206
  return {
226
207
  type: "oauth",
227
208
  refresh: refreshToken,
228
209
  access: token,
229
210
  expires: expiresAt * 1000 - 5 * 60 * 1000,
230
211
  enterpriseUrl: enterpriseDomain,
212
+ ...(apiUrl !== undefined && tid !== undefined ? { copilotApiEndpoint: { tid, url: apiUrl } } : {}),
231
213
  };
232
214
  }
233
215
  /**
@@ -238,7 +220,7 @@ async function refreshGitHubCopilotToken(refreshToken, enterpriseDomain, signal)
238
220
  const { availableModelIds, modelLimits } = await fetchGitHubCopilotModels(credentials.access, enterpriseDomain, signal, {
239
221
  maxRetries: 0,
240
222
  maxElapsedMs: 0,
241
- });
223
+ }, credentials.copilotApiEndpoint);
242
224
  return {
243
225
  ...credentials,
244
226
  availableModelIds,
@@ -249,8 +231,8 @@ async function refreshGitHubCopilotToken(refreshToken, enterpriseDomain, signal)
249
231
  * Enable a model for the user's GitHub Copilot account.
250
232
  * This is required for some models (like Claude, Grok) before they can be used.
251
233
  */
252
- async function enableGitHubCopilotModel(token, modelId, enterpriseDomain, signal) {
253
- const baseUrl = getGitHubCopilotBaseUrl(token, enterpriseDomain);
234
+ async function enableGitHubCopilotModel(token, modelId, enterpriseDomain, signal, apiEndpoint) {
235
+ const baseUrl = getGitHubCopilotBaseUrl(token, enterpriseDomain, apiEndpoint);
254
236
  const url = `${baseUrl}/models/${modelId}/policy`;
255
237
  let response;
256
238
  try {
@@ -280,11 +262,11 @@ async function enableGitHubCopilotModel(token, modelId, enterpriseDomain, signal
280
262
  * Enable the requested GitHub Copilot models and return the successful IDs.
281
263
  * Policy updates are best effort; exhausted rate limiting stops the batch.
282
264
  */
283
- async function enableGitHubCopilotModels(token, modelIds, enterpriseDomain, signal) {
265
+ async function enableGitHubCopilotModels(token, modelIds, enterpriseDomain, signal, apiEndpoint) {
284
266
  const enabledModelIds = [];
285
267
  for (const modelId of modelIds) {
286
268
  try {
287
- if (await enableGitHubCopilotModel(token, modelId, enterpriseDomain, signal)) {
269
+ if (await enableGitHubCopilotModel(token, modelId, enterpriseDomain, signal, apiEndpoint)) {
288
270
  enabledModelIds.push(modelId);
289
271
  }
290
272
  }
@@ -322,11 +304,11 @@ async function loginGitHubCopilot(interaction) {
322
304
  const models = await fetchGitHubCopilotModels(credentials.access, enterpriseDomain ?? undefined, interaction.signal, {
323
305
  maxRetries: 2,
324
306
  maxElapsedMs: 5000,
325
- });
307
+ }, credentials.copilotApiEndpoint);
326
308
  let enabledModelIds = [];
327
309
  if (models.policyModelIds.length > 0) {
328
310
  interaction.notify({ type: "progress", message: "Enabling models..." });
329
- enabledModelIds = await enableGitHubCopilotModels(credentials.access, models.policyModelIds, enterpriseDomain ?? undefined, interaction.signal);
311
+ enabledModelIds = await enableGitHubCopilotModels(credentials.access, models.policyModelIds, enterpriseDomain ?? undefined, interaction.signal, credentials.copilotApiEndpoint);
330
312
  }
331
313
  return {
332
314
  ...credentials,
@@ -350,7 +332,7 @@ export const githubCopilotOAuth = {
350
332
  async toAuth(credential) {
351
333
  return {
352
334
  apiKey: credential.access,
353
- baseUrl: getGitHubCopilotBaseUrl(credential.access, copilotEnterpriseDomain(credential)),
335
+ baseUrl: getGitHubCopilotBaseUrl(credential.access, copilotEnterpriseDomain(credential), credential.copilotApiEndpoint),
354
336
  };
355
337
  },
356
338
  };
@@ -1 +1 @@
1
- {"version":3,"file":"github-copilot.js","sourceRoot":"","sources":["../../../src/auth/oauth/github-copilot.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * GitHub Copilot OAuth flow\n */\n\nimport { GITHUB_COPILOT_REJECTED_TOKEN_STATUSES } from \"../../api/github-copilot-headers.ts\";\nimport { sleep } from \"../../utils/sleep.ts\";\nimport type { OAuthAuth, OAuthCredential, ProviderAuthInteraction } from \"../types.ts\";\nimport { pollOAuthDeviceCodeFlow } from \"./device-code.ts\";\nimport { parseGitHubCopilotModelCatalog } from \"./github-copilot-model-catalog.ts\";\n\nconst decode = (s: string) => atob(s);\nconst CLIENT_ID = decode(\"SXYxLmI1MDdhMDhjODdlY2ZlOTg=\");\n\nconst COPILOT_HEADERS = {\n\t\"User-Agent\": \"GitHubCopilotChat/0.35.0\",\n\t\"Editor-Version\": \"vscode/1.107.0\",\n\t\"Editor-Plugin-Version\": \"copilot-chat/0.35.0\",\n\t\"Copilot-Integration-Id\": \"vscode-chat\",\n} as const;\nconst COPILOT_API_VERSION = \"2026-06-01\";\n\ntype DeviceCodeResponse = {\n\tdevice_code: string;\n\tuser_code: string;\n\tverification_uri: string;\n\tinterval?: number;\n\texpires_in: number;\n};\n\ntype DeviceTokenSuccessResponse = {\n\taccess_token: string;\n\ttoken_type?: string;\n\tscope?: string;\n};\n\ntype DeviceTokenErrorResponse = {\n\terror: string;\n\terror_description?: string;\n\tinterval?: number;\n};\n\nfunction normalizeDomain(input: string): string | null {\n\tconst trimmed = input.trim();\n\tif (!trimmed) return null;\n\ttry {\n\t\tconst url = trimmed.includes(\"://\") ? new URL(trimmed) : new URL(`https://${trimmed}`);\n\t\treturn url.hostname;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction getUrls(domain: string): {\n\tdeviceCodeUrl: string;\n\taccessTokenUrl: string;\n\tcopilotTokenUrl: string;\n} {\n\treturn {\n\t\tdeviceCodeUrl: `https://${domain}/login/device/code`,\n\t\taccessTokenUrl: `https://${domain}/login/oauth/access_token`,\n\t\tcopilotTokenUrl: `https://api.${domain}/copilot_internal/v2/token`,\n\t};\n}\n\n/**\n * Parse the proxy-ep from a Copilot token and convert to API base URL.\n * Token format: tid=...;exp=...;proxy-ep=proxy.individual.githubcopilot.com;...\n * Returns API URL like https://api.individual.githubcopilot.com\n */\nfunction getBaseUrlFromToken(token: string): string | null {\n\tconst match = token.match(/proxy-ep=([^;]+)/);\n\tif (!match) return null;\n\tconst proxyHost = match[1];\n\t// Convert proxy.xxx to api.xxx\n\tconst apiHost = proxyHost.replace(/^proxy\\./, \"api.\");\n\treturn `https://${apiHost}`;\n}\n\nfunction getGitHubCopilotBaseUrl(token?: string, enterpriseDomain?: string): string {\n\t// If we have a token, extract the base URL from proxy-ep\n\tif (token) {\n\t\tconst urlFromToken = getBaseUrlFromToken(token);\n\t\tif (urlFromToken) return urlFromToken;\n\t}\n\t// Fallback for enterprise or if token parsing fails\n\tif (enterpriseDomain) return `https://copilot-api.${enterpriseDomain}`;\n\treturn \"https://api.individual.githubcopilot.com\";\n}\n\nasync function fetchWithRateLimitRetry(\n\turl: string,\n\tinit: RequestInit,\n\tsignal: AbortSignal,\n\tretryPolicy: { maxRetries: number; maxElapsedMs: number },\n): Promise<Response> {\n\tconst retryBudgetSignal =\n\t\tretryPolicy.maxRetries > 0 && retryPolicy.maxElapsedMs > 0\n\t\t\t? AbortSignal.timeout(retryPolicy.maxElapsedMs)\n\t\t\t: undefined;\n\tconst requestSignal = retryBudgetSignal ? AbortSignal.any([signal, retryBudgetSignal]) : signal;\n\tconst retryDeadline = retryBudgetSignal ? Date.now() + retryPolicy.maxElapsedMs : undefined;\n\tfor (let retry = 0; ; retry++) {\n\t\tconst response = await fetch(url, {\n\t\t\t...init,\n\t\t\tsignal: AbortSignal.any([requestSignal, AbortSignal.timeout(5000)]),\n\t\t});\n\t\tif (response.status !== 429 || retry === retryPolicy.maxRetries) return response;\n\n\t\tconst retryAfter = response.headers.get(\"retry-after\");\n\t\tlet delayMs = 500 * 2 ** retry;\n\t\tif (retryAfter) {\n\t\t\tconst seconds = Number.parseFloat(retryAfter);\n\t\t\tdelayMs = Number.isNaN(seconds) ? Date.parse(retryAfter) - Date.now() : seconds * 1000;\n\t\t\tif (!Number.isFinite(delayMs)) return response;\n\t\t}\n\t\tdelayMs = Math.max(0, delayMs);\n\t\tif (retryDeadline !== undefined && delayMs >= retryDeadline - Date.now()) return response;\n\t\tawait response.body?.cancel();\n\t\tawait sleep(delayMs, requestSignal);\n\t}\n}\n\nasync function fetchGitHubCopilotModels(\n\tcopilotToken: string,\n\tenterpriseDomain: string | undefined,\n\tsignal: AbortSignal,\n\tretryPolicy: { maxRetries: number; maxElapsedMs: number },\n) {\n\tconst baseUrl = getGitHubCopilotBaseUrl(copilotToken, enterpriseDomain);\n\t// Some Individual accounts return false for every picker flag despite explicit enabled policies.\n\t// Limit the fallback to that endpoint so other account types keep strict picker semantics.\n\tconst allowPolicyFallback = baseUrl === \"https://api.individual.githubcopilot.com\";\n\tconst response = await fetchWithRateLimitRetry(\n\t\t`${baseUrl}/models`,\n\t\t{\n\t\t\theaders: {\n\t\t\t\tAccept: \"application/json\",\n\t\t\t\tAuthorization: `Bearer ${copilotToken}`,\n\t\t\t\t...COPILOT_HEADERS,\n\t\t\t\t\"X-GitHub-Api-Version\": COPILOT_API_VERSION,\n\t\t\t},\n\t\t},\n\t\tsignal,\n\t\tretryPolicy,\n\t);\n\tif (!response.ok) {\n\t\tthrow new Error(`${response.status} ${response.statusText}: ${await response.text()}`);\n\t}\n\treturn parseGitHubCopilotModelCatalog(await response.json(), allowPolicyFallback);\n}\n\nasync function fetchJson(url: string, init: RequestInit): Promise<unknown> {\n\tconst response = await fetch(url, init);\n\tif (!response.ok) {\n\t\tconst text = await response.text();\n\t\tthrow new Error(`${response.status} ${response.statusText}: ${text}`);\n\t}\n\treturn response.json();\n}\n\nasync function startDeviceFlow(domain: string, signal: AbortSignal): Promise<DeviceCodeResponse> {\n\tconst urls = getUrls(domain);\n\tconst data = await fetchJson(urls.deviceCodeUrl, {\n\t\tmethod: \"POST\",\n\t\theaders: {\n\t\t\tAccept: \"application/json\",\n\t\t\t\"Content-Type\": \"application/x-www-form-urlencoded\",\n\t\t\t\"User-Agent\": \"GitHubCopilotChat/0.35.0\",\n\t\t},\n\t\tbody: new URLSearchParams({\n\t\t\tclient_id: CLIENT_ID,\n\t\t\tscope: \"read:user\",\n\t\t}),\n\t\tsignal,\n\t});\n\n\tif (!data || typeof data !== \"object\") {\n\t\tthrow new Error(\"Invalid device code response\");\n\t}\n\n\tconst deviceCode = (data as Record<string, unknown>).device_code;\n\tconst userCode = (data as Record<string, unknown>).user_code;\n\tconst verificationUri = (data as Record<string, unknown>).verification_uri;\n\tconst interval = (data as Record<string, unknown>).interval;\n\tconst expiresIn = (data as Record<string, unknown>).expires_in;\n\n\tif (\n\t\ttypeof deviceCode !== \"string\" ||\n\t\ttypeof userCode !== \"string\" ||\n\t\ttypeof verificationUri !== \"string\" ||\n\t\t(interval !== undefined && typeof interval !== \"number\") ||\n\t\ttypeof expiresIn !== \"number\"\n\t) {\n\t\tthrow new Error(\"Invalid device code response fields\");\n\t}\n\n\t// The verification URI is opened in the user's browser and to prevent `open` from\n\t// opening an executable or similar, we force it to be a URL.\n\tlet parsedUri: URL;\n\ttry {\n\t\tparsedUri = new URL(verificationUri);\n\t} catch {\n\t\tthrow new Error(\"Untrusted verification_uri in device code response\");\n\t}\n\tif (parsedUri.protocol !== \"https:\" && parsedUri.protocol !== \"http:\") {\n\t\tthrow new Error(\"Untrusted verification_uri in device code response\");\n\t}\n\n\treturn {\n\t\tdevice_code: deviceCode,\n\t\tuser_code: userCode,\n\t\tverification_uri: parsedUri.href,\n\t\tinterval,\n\t\texpires_in: expiresIn,\n\t};\n}\n\nasync function pollForGitHubAccessToken(\n\tdomain: string,\n\tdevice: DeviceCodeResponse,\n\tsignal: AbortSignal,\n): Promise<string> {\n\tconst urls = getUrls(domain);\n\treturn pollOAuthDeviceCodeFlow<string>({\n\t\tintervalSeconds: device.interval,\n\t\texpiresInSeconds: device.expires_in,\n\t\twaitBeforeFirstPoll: true,\n\t\tsignal,\n\t\tpoll: async () => {\n\t\t\tconst raw = await fetchJson(urls.accessTokenUrl, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: {\n\t\t\t\t\tAccept: \"application/json\",\n\t\t\t\t\t\"Content-Type\": \"application/x-www-form-urlencoded\",\n\t\t\t\t\t\"User-Agent\": \"GitHubCopilotChat/0.35.0\",\n\t\t\t\t},\n\t\t\t\tbody: new URLSearchParams({\n\t\t\t\t\tclient_id: CLIENT_ID,\n\t\t\t\t\tdevice_code: device.device_code,\n\t\t\t\t\tgrant_type: \"urn:ietf:params:oauth:grant-type:device_code\",\n\t\t\t\t}),\n\t\t\t\tsignal,\n\t\t\t});\n\n\t\t\tif (raw && typeof raw === \"object\" && typeof (raw as DeviceTokenSuccessResponse).access_token === \"string\") {\n\t\t\t\treturn { status: \"complete\", value: (raw as DeviceTokenSuccessResponse).access_token };\n\t\t\t}\n\n\t\t\tif (raw && typeof raw === \"object\" && typeof (raw as DeviceTokenErrorResponse).error === \"string\") {\n\t\t\t\tconst { error, error_description: description, interval } = raw as DeviceTokenErrorResponse;\n\t\t\t\tif (error === \"authorization_pending\") {\n\t\t\t\t\treturn { status: \"pending\" };\n\t\t\t\t}\n\n\t\t\t\tif (error === \"slow_down\") {\n\t\t\t\t\treturn { status: \"slow_down\", intervalSeconds: typeof interval === \"number\" ? interval : undefined };\n\t\t\t\t}\n\n\t\t\t\tconst descriptionSuffix = description ? `: ${description}` : \"\";\n\t\t\t\treturn { status: \"failed\", message: `Device flow failed: ${error}${descriptionSuffix}` };\n\t\t\t}\n\n\t\t\treturn { status: \"failed\", message: \"Invalid device token response\" };\n\t\t},\n\t});\n}\n\nasync function refreshGitHubCopilotAccessToken(\n\trefreshToken: string,\n\tenterpriseDomain: string | undefined,\n\tsignal: AbortSignal,\n): Promise<OAuthCredential> {\n\tconst domain = enterpriseDomain || \"github.com\";\n\tconst urls = getUrls(domain);\n\n\tconst raw = await fetchJson(urls.copilotTokenUrl, {\n\t\theaders: {\n\t\t\tAccept: \"application/json\",\n\t\t\tAuthorization: `Bearer ${refreshToken}`,\n\t\t\t...COPILOT_HEADERS,\n\t\t},\n\t\tsignal,\n\t});\n\n\tif (!raw || typeof raw !== \"object\") {\n\t\tthrow new Error(\"Invalid Copilot token response\");\n\t}\n\n\tconst token = (raw as Record<string, unknown>).token;\n\tconst expiresAt = (raw as Record<string, unknown>).expires_at;\n\n\tif (typeof token !== \"string\" || typeof expiresAt !== \"number\") {\n\t\tthrow new Error(\"Invalid Copilot token response fields\");\n\t}\n\n\treturn {\n\t\ttype: \"oauth\",\n\t\trefresh: refreshToken,\n\t\taccess: token,\n\t\texpires: expiresAt * 1000 - 5 * 60 * 1000,\n\t\tenterpriseUrl: enterpriseDomain,\n\t};\n}\n\n/**\n * Refresh GitHub Copilot token\n */\nasync function refreshGitHubCopilotToken(\n\trefreshToken: string,\n\tenterpriseDomain: string | undefined,\n\tsignal: AbortSignal,\n): Promise<OAuthCredential> {\n\tconst credentials = await refreshGitHubCopilotAccessToken(refreshToken, enterpriseDomain, signal);\n\tconst { availableModelIds, modelLimits } = await fetchGitHubCopilotModels(\n\t\tcredentials.access,\n\t\tenterpriseDomain,\n\t\tsignal,\n\t\t{\n\t\t\tmaxRetries: 0,\n\t\t\tmaxElapsedMs: 0,\n\t\t},\n\t);\n\treturn {\n\t\t...credentials,\n\t\tavailableModelIds,\n\t\tcopilotModelLimits: modelLimits,\n\t};\n}\n\n/**\n * Enable a model for the user's GitHub Copilot account.\n * This is required for some models (like Claude, Grok) before they can be used.\n */\nasync function enableGitHubCopilotModel(\n\ttoken: string,\n\tmodelId: string,\n\tenterpriseDomain: string | undefined,\n\tsignal: AbortSignal,\n): Promise<boolean> {\n\tconst baseUrl = getGitHubCopilotBaseUrl(token, enterpriseDomain);\n\tconst url = `${baseUrl}/models/${modelId}/policy`;\n\n\tlet response: Response;\n\ttry {\n\t\tresponse = await fetchWithRateLimitRetry(\n\t\t\turl,\n\t\t\t{\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\tAuthorization: `Bearer ${token}`,\n\t\t\t\t\t...COPILOT_HEADERS,\n\t\t\t\t\t\"openai-intent\": \"chat-policy\",\n\t\t\t\t\t\"x-interaction-type\": \"chat-policy\",\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify({ state: \"enabled\" }),\n\t\t\t},\n\t\t\tsignal,\n\t\t\t{ maxRetries: 2, maxElapsedMs: 5000 },\n\t\t);\n\t} catch (error) {\n\t\tif (signal.aborted) throw error;\n\t\treturn false;\n\t}\n\tif (response.status === 429) {\n\t\tthrow new Error(`${response.status} ${response.statusText}: ${await response.text()}`);\n\t}\n\treturn response.ok;\n}\n\n/**\n * Enable the requested GitHub Copilot models and return the successful IDs.\n * Policy updates are best effort; exhausted rate limiting stops the batch.\n */\nasync function enableGitHubCopilotModels(\n\ttoken: string,\n\tmodelIds: readonly string[],\n\tenterpriseDomain: string | undefined,\n\tsignal: AbortSignal,\n): Promise<string[]> {\n\tconst enabledModelIds: string[] = [];\n\tfor (const modelId of modelIds) {\n\t\ttry {\n\t\t\tif (await enableGitHubCopilotModel(token, modelId, enterpriseDomain, signal)) {\n\t\t\t\tenabledModelIds.push(modelId);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tif (signal.aborted) throw error;\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn enabledModelIds;\n}\n\nasync function loginGitHubCopilot(interaction: ProviderAuthInteraction): Promise<OAuthCredential> {\n\tconst input = await interaction.prompt({\n\t\ttype: \"text\",\n\t\tmessage: \"GitHub Enterprise URL/domain (blank for github.com)\",\n\t\tplaceholder: \"company.ghe.com\",\n\t});\n\tif (interaction.signal.aborted) throw new Error(\"Login cancelled\");\n\n\tconst trimmed = input.trim();\n\tconst enterpriseDomain = normalizeDomain(input);\n\tif (trimmed && !enterpriseDomain) throw new Error(\"Invalid GitHub Enterprise URL/domain\");\n\tconst domain = enterpriseDomain || \"github.com\";\n\n\tconst device = await startDeviceFlow(domain, interaction.signal);\n\tinteraction.notify({\n\t\ttype: \"device_code\",\n\t\tuserCode: device.user_code,\n\t\tverificationUri: device.verification_uri,\n\t\tintervalSeconds: device.interval,\n\t\texpiresInSeconds: device.expires_in,\n\t});\n\n\tconst githubAccessToken = await pollForGitHubAccessToken(domain, device, interaction.signal);\n\tconst credentials = await refreshGitHubCopilotAccessToken(\n\t\tgithubAccessToken,\n\t\tenterpriseDomain ?? undefined,\n\t\tinteraction.signal,\n\t);\n\tconst models = await fetchGitHubCopilotModels(\n\t\tcredentials.access,\n\t\tenterpriseDomain ?? undefined,\n\t\tinteraction.signal,\n\t\t{\n\t\t\tmaxRetries: 2,\n\t\t\tmaxElapsedMs: 5000,\n\t\t},\n\t);\n\tlet enabledModelIds: string[] = [];\n\tif (models.policyModelIds.length > 0) {\n\t\tinteraction.notify({ type: \"progress\", message: \"Enabling models...\" });\n\t\tenabledModelIds = await enableGitHubCopilotModels(\n\t\t\tcredentials.access,\n\t\t\tmodels.policyModelIds,\n\t\t\tenterpriseDomain ?? undefined,\n\t\t\tinteraction.signal,\n\t\t);\n\t}\n\treturn {\n\t\t...credentials,\n\t\tavailableModelIds: [...new Set([...models.availableModelIds, ...enabledModelIds])],\n\t\tcopilotModelLimits: models.modelLimits,\n\t};\n}\n\nfunction copilotEnterpriseDomain(credential: OAuthCredential): string | undefined {\n\tconst enterpriseUrl = credential.enterpriseUrl;\n\tif (typeof enterpriseUrl !== \"string\" || !enterpriseUrl) return undefined;\n\treturn normalizeDomain(enterpriseUrl) ?? undefined;\n}\n\nexport const githubCopilotOAuth: OAuthAuth = {\n\tname: \"GitHub Copilot\",\n\tisSubscription: true,\n\trejectedTokenStatuses: GITHUB_COPILOT_REJECTED_TOKEN_STATUSES,\n\tlogin: loginGitHubCopilot,\n\trefresh: (credential, signal) =>\n\t\trefreshGitHubCopilotToken(credential.refresh, copilotEnterpriseDomain(credential), signal),\n\n\t/** Derive the credential-specific proxy endpoint for each request. */\n\tasync toAuth(credential) {\n\t\treturn {\n\t\t\tapiKey: credential.access,\n\t\t\tbaseUrl: getGitHubCopilotBaseUrl(credential.access, copilotEnterpriseDomain(credential)),\n\t\t};\n\t},\n};\n"]}
1
+ {"version":3,"file":"github-copilot.js","sourceRoot":"","sources":["../../../src/auth/oauth/github-copilot.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACN,kCAAkC,EAClC,uBAAuB,EACvB,6BAA6B,EAC7B,2BAA2B,GAC3B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,sCAAsC,EAAE,MAAM,qCAAqC,CAAC;AAC7F,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAE7C,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,8BAA8B,EAAE,MAAM,mCAAmC,CAAC;AAEnF,MAAM,MAAM,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACtC,MAAM,SAAS,GAAG,MAAM,CAAC,8BAA8B,CAAC,CAAC;AAEzD,MAAM,eAAe,GAAG;IACvB,YAAY,EAAE,0BAA0B;IACxC,gBAAgB,EAAE,gBAAgB;IAClC,uBAAuB,EAAE,qBAAqB;IAC9C,wBAAwB,EAAE,aAAa;CAC9B,CAAC;AACX,MAAM,mBAAmB,GAAG,YAAY,CAAC;AAsBzC,SAAS,eAAe,CAAC,KAAa;IACrC,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,IAAI,CAAC;QACJ,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,WAAW,OAAO,EAAE,CAAC,CAAC;QACvF,OAAO,GAAG,CAAC,QAAQ,CAAC;IACrB,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,IAAI,CAAC;IACb,CAAC;AACF,CAAC;AAED,SAAS,OAAO,CAAC,MAAc;IAK9B,OAAO;QACN,aAAa,EAAE,WAAW,MAAM,oBAAoB;QACpD,cAAc,EAAE,WAAW,MAAM,2BAA2B;QAC5D,eAAe,EAAE,eAAe,MAAM,4BAA4B;KAClE,CAAC;AACH,CAAC;AAED,SAAS,uBAAuB,CAAC,KAAc,EAAE,gBAAyB,EAAE,WAAqB;IAChG,OAAO,2BAA2B,CAAC,EAAE,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,CAAC,CAAC;AAC9E,CAAC;AAED,KAAK,UAAU,uBAAuB,CACrC,GAAW,EACX,IAAiB,EACjB,MAAmB,EACnB,WAAyD;IAEzD,MAAM,iBAAiB,GACtB,WAAW,CAAC,UAAU,GAAG,CAAC,IAAI,WAAW,CAAC,YAAY,GAAG,CAAC;QACzD,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,WAAW,CAAC,YAAY,CAAC;QAC/C,CAAC,CAAC,SAAS,CAAC;IACd,MAAM,aAAa,GAAG,iBAAiB,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAChG,MAAM,aAAa,GAAG,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,WAAW,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5F,KAAK,IAAI,KAAK,GAAG,CAAC,GAAI,KAAK,EAAE,EAAE,CAAC;QAC/B,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YACjC,GAAG,IAAI;YACP,MAAM,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,aAAa,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;SACnE,CAAC,CAAC;QACH,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,KAAK,KAAK,WAAW,CAAC,UAAU;YAAE,OAAO,QAAQ,CAAC;QAEjF,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QACvD,IAAI,OAAO,GAAG,GAAG,GAAG,CAAC,IAAI,KAAK,CAAC;QAC/B,IAAI,UAAU,EAAE,CAAC;YAChB,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;YAC9C,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC;YACvF,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAAE,OAAO,QAAQ,CAAC;QAChD,CAAC;QACD,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QAC/B,IAAI,aAAa,KAAK,SAAS,IAAI,OAAO,IAAI,aAAa,GAAG,IAAI,CAAC,GAAG,EAAE;YAAE,OAAO,QAAQ,CAAC;QAC1F,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC;QAC9B,MAAM,KAAK,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;IACrC,CAAC;AACF,CAAC;AAED,KAAK,UAAU,wBAAwB,CACtC,YAAoB,EACpB,gBAAoC,EACpC,MAAmB,EACnB,WAAyD,EACzD,WAAqB;IAErB,MAAM,OAAO,GAAG,uBAAuB,CAAC,YAAY,EAAE,gBAAgB,EAAE,WAAW,CAAC,CAAC;IACrF,iGAAiG;IACjG,2FAA2F;IAC3F,MAAM,mBAAmB,GAAG,OAAO,KAAK,kCAAkC,CAAC;IAC3E,MAAM,QAAQ,GAAG,MAAM,uBAAuB,CAC7C,GAAG,OAAO,SAAS,EACnB;QACC,OAAO,EAAE;YACR,MAAM,EAAE,kBAAkB;YAC1B,aAAa,EAAE,UAAU,YAAY,EAAE;YACvC,GAAG,eAAe;YAClB,sBAAsB,EAAE,mBAAmB;SAC3C;KACD,EACD,MAAM,EACN,WAAW,CACX,CAAC;IACF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,GAAG,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,KAAK,MAAM,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACxF,CAAC;IACD,OAAO,8BAA8B,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,EAAE,mBAAmB,CAAC,CAAC;AACnF,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,GAAW,EAAE,IAAiB;IACtD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACxC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QAClB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,GAAG,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC,CAAC;IACvE,CAAC;IACD,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC;AACxB,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,MAAc,EAAE,MAAmB;IACjE,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7B,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,aAAa,EAAE;QAChD,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACR,MAAM,EAAE,kBAAkB;YAC1B,cAAc,EAAE,mCAAmC;YACnD,YAAY,EAAE,0BAA0B;SACxC;QACD,IAAI,EAAE,IAAI,eAAe,CAAC;YACzB,SAAS,EAAE,SAAS;YACpB,KAAK,EAAE,WAAW;SAClB,CAAC;QACF,MAAM;KACN,CAAC,CAAC;IAEH,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IACjD,CAAC;IAED,MAAM,UAAU,GAAI,IAAgC,CAAC,WAAW,CAAC;IACjE,MAAM,QAAQ,GAAI,IAAgC,CAAC,SAAS,CAAC;IAC7D,MAAM,eAAe,GAAI,IAAgC,CAAC,gBAAgB,CAAC;IAC3E,MAAM,QAAQ,GAAI,IAAgC,CAAC,QAAQ,CAAC;IAC5D,MAAM,SAAS,GAAI,IAAgC,CAAC,UAAU,CAAC;IAE/D,IACC,OAAO,UAAU,KAAK,QAAQ;QAC9B,OAAO,QAAQ,KAAK,QAAQ;QAC5B,OAAO,eAAe,KAAK,QAAQ;QACnC,CAAC,QAAQ,KAAK,SAAS,IAAI,OAAO,QAAQ,KAAK,QAAQ,CAAC;QACxD,OAAO,SAAS,KAAK,QAAQ,EAC5B,CAAC;QACF,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IACxD,CAAC;IAED,kFAAkF;IAClF,6DAA6D;IAC7D,IAAI,SAAc,CAAC;IACnB,IAAI,CAAC;QACJ,SAAS,GAAG,IAAI,GAAG,CAAC,eAAe,CAAC,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACR,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;IACvE,CAAC;IACD,IAAI,SAAS,CAAC,QAAQ,KAAK,QAAQ,IAAI,SAAS,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACvE,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;IACvE,CAAC;IAED,OAAO;QACN,WAAW,EAAE,UAAU;QACvB,SAAS,EAAE,QAAQ;QACnB,gBAAgB,EAAE,SAAS,CAAC,IAAI;QAChC,QAAQ;QACR,UAAU,EAAE,SAAS;KACrB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,wBAAwB,CACtC,MAAc,EACd,MAA0B,EAC1B,MAAmB;IAEnB,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7B,OAAO,uBAAuB,CAAS;QACtC,eAAe,EAAE,MAAM,CAAC,QAAQ;QAChC,gBAAgB,EAAE,MAAM,CAAC,UAAU;QACnC,mBAAmB,EAAE,IAAI;QACzB,MAAM;QACN,IAAI,EAAE,KAAK,IAAI,EAAE;YAChB,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,cAAc,EAAE;gBAChD,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACR,MAAM,EAAE,kBAAkB;oBAC1B,cAAc,EAAE,mCAAmC;oBACnD,YAAY,EAAE,0BAA0B;iBACxC;gBACD,IAAI,EAAE,IAAI,eAAe,CAAC;oBACzB,SAAS,EAAE,SAAS;oBACpB,WAAW,EAAE,MAAM,CAAC,WAAW;oBAC/B,UAAU,EAAE,8CAA8C;iBAC1D,CAAC;gBACF,MAAM;aACN,CAAC,CAAC;YAEH,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,OAAQ,GAAkC,CAAC,YAAY,KAAK,QAAQ,EAAE,CAAC;gBAC5G,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAG,GAAkC,CAAC,YAAY,EAAE,CAAC;YACxF,CAAC;YAED,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,OAAQ,GAAgC,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;gBACnG,MAAM,EAAE,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,QAAQ,EAAE,GAAG,GAA+B,CAAC;gBAC5F,IAAI,KAAK,KAAK,uBAAuB,EAAE,CAAC;oBACvC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;gBAC9B,CAAC;gBAED,IAAI,KAAK,KAAK,WAAW,EAAE,CAAC;oBAC3B,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,eAAe,EAAE,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;gBACtG,CAAC;gBAED,MAAM,iBAAiB,GAAG,WAAW,CAAC,CAAC,CAAC,KAAK,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAChE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,uBAAuB,KAAK,GAAG,iBAAiB,EAAE,EAAE,CAAC;YAC1F,CAAC;YAED,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,+BAA+B,EAAE,CAAC;QACvE,CAAC;KACD,CAAC,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,+BAA+B,CAC7C,YAAoB,EACpB,gBAAoC,EACpC,MAAmB;IAEnB,MAAM,MAAM,GAAG,gBAAgB,IAAI,YAAY,CAAC;IAChD,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAE7B,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,eAAe,EAAE;QACjD,OAAO,EAAE;YACR,MAAM,EAAE,kBAAkB;YAC1B,aAAa,EAAE,UAAU,YAAY,EAAE;YACvC,GAAG,eAAe;SAClB;QACD,MAAM;KACN,CAAC,CAAC;IAEH,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACnD,CAAC;IAED,MAAM,KAAK,GAAI,GAA+B,CAAC,KAAK,CAAC;IACrD,MAAM,SAAS,GAAI,GAA+B,CAAC,UAAU,CAAC;IAE9D,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;QAChE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,SAAS,GAAI,GAA+B,CAAC,SAAS,CAAC;IAC7D,MAAM,MAAM,GAAG,6BAA6B,CAC3C,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAC/F,CAAC;IACF,MAAM,GAAG,GAAG,uBAAuB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAClD,OAAO;QACN,IAAI,EAAE,OAAO;QACb,OAAO,EAAE,YAAY;QACrB,MAAM,EAAE,KAAK;QACb,OAAO,EAAE,SAAS,GAAG,IAAI,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI;QACzC,aAAa,EAAE,gBAAgB;QAC/B,GAAG,CAAC,MAAM,KAAK,SAAS,IAAI,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,kBAAkB,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAClG,CAAC;AACH,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,yBAAyB,CACvC,YAAoB,EACpB,gBAAoC,EACpC,MAAmB;IAEnB,MAAM,WAAW,GAAG,MAAM,+BAA+B,CAAC,YAAY,EAAE,gBAAgB,EAAE,MAAM,CAAC,CAAC;IAClG,MAAM,EAAE,iBAAiB,EAAE,WAAW,EAAE,GAAG,MAAM,wBAAwB,CACxE,WAAW,CAAC,MAAM,EAClB,gBAAgB,EAChB,MAAM,EACN;QACC,UAAU,EAAE,CAAC;QACb,YAAY,EAAE,CAAC;KACf,EACD,WAAW,CAAC,kBAAkB,CAC9B,CAAC;IACF,OAAO;QACN,GAAG,WAAW;QACd,iBAAiB;QACjB,kBAAkB,EAAE,WAAW;KAC/B,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,wBAAwB,CACtC,KAAa,EACb,OAAe,EACf,gBAAoC,EACpC,MAAmB,EACnB,WAAqB;IAErB,MAAM,OAAO,GAAG,uBAAuB,CAAC,KAAK,EAAE,gBAAgB,EAAE,WAAW,CAAC,CAAC;IAC9E,MAAM,GAAG,GAAG,GAAG,OAAO,WAAW,OAAO,SAAS,CAAC;IAElD,IAAI,QAAkB,CAAC;IACvB,IAAI,CAAC;QACJ,QAAQ,GAAG,MAAM,uBAAuB,CACvC,GAAG,EACH;YACC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACR,cAAc,EAAE,kBAAkB;gBAClC,aAAa,EAAE,UAAU,KAAK,EAAE;gBAChC,GAAG,eAAe;gBAClB,eAAe,EAAE,aAAa;gBAC9B,oBAAoB,EAAE,aAAa;aACnC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;SAC1C,EACD,MAAM,EACN,EAAE,UAAU,EAAE,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,CACrC,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,IAAI,MAAM,CAAC,OAAO;YAAE,MAAM,KAAK,CAAC;QAChC,OAAO,KAAK,CAAC;IACd,CAAC;IACD,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,GAAG,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,KAAK,MAAM,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACxF,CAAC;IACD,OAAO,QAAQ,CAAC,EAAE,CAAC;AACpB,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,yBAAyB,CACvC,KAAa,EACb,QAA2B,EAC3B,gBAAoC,EACpC,MAAmB,EACnB,WAAqB;IAErB,MAAM,eAAe,GAAa,EAAE,CAAC;IACrC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAChC,IAAI,CAAC;YACJ,IAAI,MAAM,wBAAwB,CAAC,KAAK,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,CAAC;gBAC3F,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC/B,CAAC;QACF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,IAAI,MAAM,CAAC,OAAO;gBAAE,MAAM,KAAK,CAAC;YAChC,MAAM;QACP,CAAC;IACF,CAAC;IACD,OAAO,eAAe,CAAC;AACxB,CAAC;AAED,KAAK,UAAU,kBAAkB,CAAC,WAAoC;IACrE,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,MAAM,CAAC;QACtC,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,qDAAqD;QAC9D,WAAW,EAAE,iBAAiB;KAC9B,CAAC,CAAC;IACH,IAAI,WAAW,CAAC,MAAM,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;IAEnE,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,MAAM,gBAAgB,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IAChD,IAAI,OAAO,IAAI,CAAC,gBAAgB;QAAE,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;IAC1F,MAAM,MAAM,GAAG,gBAAgB,IAAI,YAAY,CAAC;IAEhD,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACjE,WAAW,CAAC,MAAM,CAAC;QAClB,IAAI,EAAE,aAAa;QACnB,QAAQ,EAAE,MAAM,CAAC,SAAS;QAC1B,eAAe,EAAE,MAAM,CAAC,gBAAgB;QACxC,eAAe,EAAE,MAAM,CAAC,QAAQ;QAChC,gBAAgB,EAAE,MAAM,CAAC,UAAU;KACnC,CAAC,CAAC;IAEH,MAAM,iBAAiB,GAAG,MAAM,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC7F,MAAM,WAAW,GAAG,MAAM,+BAA+B,CACxD,iBAAiB,EACjB,gBAAgB,IAAI,SAAS,EAC7B,WAAW,CAAC,MAAM,CAClB,CAAC;IACF,MAAM,MAAM,GAAG,MAAM,wBAAwB,CAC5C,WAAW,CAAC,MAAM,EAClB,gBAAgB,IAAI,SAAS,EAC7B,WAAW,CAAC,MAAM,EAClB;QACC,UAAU,EAAE,CAAC;QACb,YAAY,EAAE,IAAI;KAClB,EACD,WAAW,CAAC,kBAAkB,CAC9B,CAAC;IACF,IAAI,eAAe,GAAa,EAAE,CAAC;IACnC,IAAI,MAAM,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtC,WAAW,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,oBAAoB,EAAE,CAAC,CAAC;QACxE,eAAe,GAAG,MAAM,yBAAyB,CAChD,WAAW,CAAC,MAAM,EAClB,MAAM,CAAC,cAAc,EACrB,gBAAgB,IAAI,SAAS,EAC7B,WAAW,CAAC,MAAM,EAClB,WAAW,CAAC,kBAAkB,CAC9B,CAAC;IACH,CAAC;IACD,OAAO;QACN,GAAG,WAAW;QACd,iBAAiB,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,iBAAiB,EAAE,GAAG,eAAe,CAAC,CAAC,CAAC;QAClF,kBAAkB,EAAE,MAAM,CAAC,WAAW;KACtC,CAAC;AACH,CAAC;AAED,SAAS,uBAAuB,CAAC,UAA2B;IAC3D,MAAM,aAAa,GAAG,UAAU,CAAC,aAAa,CAAC;IAC/C,IAAI,OAAO,aAAa,KAAK,QAAQ,IAAI,CAAC,aAAa;QAAE,OAAO,SAAS,CAAC;IAC1E,OAAO,eAAe,CAAC,aAAa,CAAC,IAAI,SAAS,CAAC;AACpD,CAAC;AAED,MAAM,CAAC,MAAM,kBAAkB,GAAc;IAC5C,IAAI,EAAE,gBAAgB;IACtB,cAAc,EAAE,IAAI;IACpB,qBAAqB,EAAE,sCAAsC;IAC7D,KAAK,EAAE,kBAAkB;IACzB,OAAO,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,CAC/B,yBAAyB,CAAC,UAAU,CAAC,OAAO,EAAE,uBAAuB,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAE3F,sEAAsE;IACtE,KAAK,CAAC,MAAM,CAAC,UAAU;QACtB,OAAO;YACN,MAAM,EAAE,UAAU,CAAC,MAAM;YACzB,OAAO,EAAE,uBAAuB,CAC/B,UAAU,CAAC,MAAM,EACjB,uBAAuB,CAAC,UAAU,CAAC,EACnC,UAAU,CAAC,kBAAkB,CAC7B;SACD,CAAC;IACH,CAAC;CACD,CAAC","sourcesContent":["/**\n * GitHub Copilot OAuth flow\n */\n\nimport {\n\tGITHUB_COPILOT_INDIVIDUAL_BASE_URL,\n\tgithubCopilotTokenField,\n\tparseGitHubCopilotApiEndpoint,\n\tresolveGitHubCopilotBaseUrl,\n} from \"../../api/github-copilot-endpoint.ts\";\nimport { GITHUB_COPILOT_REJECTED_TOKEN_STATUSES } from \"../../api/github-copilot-headers.ts\";\nimport { sleep } from \"../../utils/sleep.ts\";\nimport type { OAuthAuth, OAuthCredential, ProviderAuthInteraction } from \"../types.ts\";\nimport { pollOAuthDeviceCodeFlow } from \"./device-code.ts\";\nimport { parseGitHubCopilotModelCatalog } from \"./github-copilot-model-catalog.ts\";\n\nconst decode = (s: string) => atob(s);\nconst CLIENT_ID = decode(\"SXYxLmI1MDdhMDhjODdlY2ZlOTg=\");\n\nconst COPILOT_HEADERS = {\n\t\"User-Agent\": \"GitHubCopilotChat/0.35.0\",\n\t\"Editor-Version\": \"vscode/1.107.0\",\n\t\"Editor-Plugin-Version\": \"copilot-chat/0.35.0\",\n\t\"Copilot-Integration-Id\": \"vscode-chat\",\n} as const;\nconst COPILOT_API_VERSION = \"2026-06-01\";\n\ntype DeviceCodeResponse = {\n\tdevice_code: string;\n\tuser_code: string;\n\tverification_uri: string;\n\tinterval?: number;\n\texpires_in: number;\n};\n\ntype DeviceTokenSuccessResponse = {\n\taccess_token: string;\n\ttoken_type?: string;\n\tscope?: string;\n};\n\ntype DeviceTokenErrorResponse = {\n\terror: string;\n\terror_description?: string;\n\tinterval?: number;\n};\n\nfunction normalizeDomain(input: string): string | null {\n\tconst trimmed = input.trim();\n\tif (!trimmed) return null;\n\ttry {\n\t\tconst url = trimmed.includes(\"://\") ? new URL(trimmed) : new URL(`https://${trimmed}`);\n\t\treturn url.hostname;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction getUrls(domain: string): {\n\tdeviceCodeUrl: string;\n\taccessTokenUrl: string;\n\tcopilotTokenUrl: string;\n} {\n\treturn {\n\t\tdeviceCodeUrl: `https://${domain}/login/device/code`,\n\t\taccessTokenUrl: `https://${domain}/login/oauth/access_token`,\n\t\tcopilotTokenUrl: `https://api.${domain}/copilot_internal/v2/token`,\n\t};\n}\n\nfunction getGitHubCopilotBaseUrl(token?: string, enterpriseDomain?: string, apiEndpoint?: unknown): string {\n\treturn resolveGitHubCopilotBaseUrl({ token, enterpriseDomain, apiEndpoint });\n}\n\nasync function fetchWithRateLimitRetry(\n\turl: string,\n\tinit: RequestInit,\n\tsignal: AbortSignal,\n\tretryPolicy: { maxRetries: number; maxElapsedMs: number },\n): Promise<Response> {\n\tconst retryBudgetSignal =\n\t\tretryPolicy.maxRetries > 0 && retryPolicy.maxElapsedMs > 0\n\t\t\t? AbortSignal.timeout(retryPolicy.maxElapsedMs)\n\t\t\t: undefined;\n\tconst requestSignal = retryBudgetSignal ? AbortSignal.any([signal, retryBudgetSignal]) : signal;\n\tconst retryDeadline = retryBudgetSignal ? Date.now() + retryPolicy.maxElapsedMs : undefined;\n\tfor (let retry = 0; ; retry++) {\n\t\tconst response = await fetch(url, {\n\t\t\t...init,\n\t\t\tsignal: AbortSignal.any([requestSignal, AbortSignal.timeout(5000)]),\n\t\t});\n\t\tif (response.status !== 429 || retry === retryPolicy.maxRetries) return response;\n\n\t\tconst retryAfter = response.headers.get(\"retry-after\");\n\t\tlet delayMs = 500 * 2 ** retry;\n\t\tif (retryAfter) {\n\t\t\tconst seconds = Number.parseFloat(retryAfter);\n\t\t\tdelayMs = Number.isNaN(seconds) ? Date.parse(retryAfter) - Date.now() : seconds * 1000;\n\t\t\tif (!Number.isFinite(delayMs)) return response;\n\t\t}\n\t\tdelayMs = Math.max(0, delayMs);\n\t\tif (retryDeadline !== undefined && delayMs >= retryDeadline - Date.now()) return response;\n\t\tawait response.body?.cancel();\n\t\tawait sleep(delayMs, requestSignal);\n\t}\n}\n\nasync function fetchGitHubCopilotModels(\n\tcopilotToken: string,\n\tenterpriseDomain: string | undefined,\n\tsignal: AbortSignal,\n\tretryPolicy: { maxRetries: number; maxElapsedMs: number },\n\tapiEndpoint?: unknown,\n) {\n\tconst baseUrl = getGitHubCopilotBaseUrl(copilotToken, enterpriseDomain, apiEndpoint);\n\t// Some Individual accounts return false for every picker flag despite explicit enabled policies.\n\t// Limit the fallback to that endpoint so other account types keep strict picker semantics.\n\tconst allowPolicyFallback = baseUrl === GITHUB_COPILOT_INDIVIDUAL_BASE_URL;\n\tconst response = await fetchWithRateLimitRetry(\n\t\t`${baseUrl}/models`,\n\t\t{\n\t\t\theaders: {\n\t\t\t\tAccept: \"application/json\",\n\t\t\t\tAuthorization: `Bearer ${copilotToken}`,\n\t\t\t\t...COPILOT_HEADERS,\n\t\t\t\t\"X-GitHub-Api-Version\": COPILOT_API_VERSION,\n\t\t\t},\n\t\t},\n\t\tsignal,\n\t\tretryPolicy,\n\t);\n\tif (!response.ok) {\n\t\tthrow new Error(`${response.status} ${response.statusText}: ${await response.text()}`);\n\t}\n\treturn parseGitHubCopilotModelCatalog(await response.json(), allowPolicyFallback);\n}\n\nasync function fetchJson(url: string, init: RequestInit): Promise<unknown> {\n\tconst response = await fetch(url, init);\n\tif (!response.ok) {\n\t\tconst text = await response.text();\n\t\tthrow new Error(`${response.status} ${response.statusText}: ${text}`);\n\t}\n\treturn response.json();\n}\n\nasync function startDeviceFlow(domain: string, signal: AbortSignal): Promise<DeviceCodeResponse> {\n\tconst urls = getUrls(domain);\n\tconst data = await fetchJson(urls.deviceCodeUrl, {\n\t\tmethod: \"POST\",\n\t\theaders: {\n\t\t\tAccept: \"application/json\",\n\t\t\t\"Content-Type\": \"application/x-www-form-urlencoded\",\n\t\t\t\"User-Agent\": \"GitHubCopilotChat/0.35.0\",\n\t\t},\n\t\tbody: new URLSearchParams({\n\t\t\tclient_id: CLIENT_ID,\n\t\t\tscope: \"read:user\",\n\t\t}),\n\t\tsignal,\n\t});\n\n\tif (!data || typeof data !== \"object\") {\n\t\tthrow new Error(\"Invalid device code response\");\n\t}\n\n\tconst deviceCode = (data as Record<string, unknown>).device_code;\n\tconst userCode = (data as Record<string, unknown>).user_code;\n\tconst verificationUri = (data as Record<string, unknown>).verification_uri;\n\tconst interval = (data as Record<string, unknown>).interval;\n\tconst expiresIn = (data as Record<string, unknown>).expires_in;\n\n\tif (\n\t\ttypeof deviceCode !== \"string\" ||\n\t\ttypeof userCode !== \"string\" ||\n\t\ttypeof verificationUri !== \"string\" ||\n\t\t(interval !== undefined && typeof interval !== \"number\") ||\n\t\ttypeof expiresIn !== \"number\"\n\t) {\n\t\tthrow new Error(\"Invalid device code response fields\");\n\t}\n\n\t// The verification URI is opened in the user's browser and to prevent `open` from\n\t// opening an executable or similar, we force it to be a URL.\n\tlet parsedUri: URL;\n\ttry {\n\t\tparsedUri = new URL(verificationUri);\n\t} catch {\n\t\tthrow new Error(\"Untrusted verification_uri in device code response\");\n\t}\n\tif (parsedUri.protocol !== \"https:\" && parsedUri.protocol !== \"http:\") {\n\t\tthrow new Error(\"Untrusted verification_uri in device code response\");\n\t}\n\n\treturn {\n\t\tdevice_code: deviceCode,\n\t\tuser_code: userCode,\n\t\tverification_uri: parsedUri.href,\n\t\tinterval,\n\t\texpires_in: expiresIn,\n\t};\n}\n\nasync function pollForGitHubAccessToken(\n\tdomain: string,\n\tdevice: DeviceCodeResponse,\n\tsignal: AbortSignal,\n): Promise<string> {\n\tconst urls = getUrls(domain);\n\treturn pollOAuthDeviceCodeFlow<string>({\n\t\tintervalSeconds: device.interval,\n\t\texpiresInSeconds: device.expires_in,\n\t\twaitBeforeFirstPoll: true,\n\t\tsignal,\n\t\tpoll: async () => {\n\t\t\tconst raw = await fetchJson(urls.accessTokenUrl, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: {\n\t\t\t\t\tAccept: \"application/json\",\n\t\t\t\t\t\"Content-Type\": \"application/x-www-form-urlencoded\",\n\t\t\t\t\t\"User-Agent\": \"GitHubCopilotChat/0.35.0\",\n\t\t\t\t},\n\t\t\t\tbody: new URLSearchParams({\n\t\t\t\t\tclient_id: CLIENT_ID,\n\t\t\t\t\tdevice_code: device.device_code,\n\t\t\t\t\tgrant_type: \"urn:ietf:params:oauth:grant-type:device_code\",\n\t\t\t\t}),\n\t\t\t\tsignal,\n\t\t\t});\n\n\t\t\tif (raw && typeof raw === \"object\" && typeof (raw as DeviceTokenSuccessResponse).access_token === \"string\") {\n\t\t\t\treturn { status: \"complete\", value: (raw as DeviceTokenSuccessResponse).access_token };\n\t\t\t}\n\n\t\t\tif (raw && typeof raw === \"object\" && typeof (raw as DeviceTokenErrorResponse).error === \"string\") {\n\t\t\t\tconst { error, error_description: description, interval } = raw as DeviceTokenErrorResponse;\n\t\t\t\tif (error === \"authorization_pending\") {\n\t\t\t\t\treturn { status: \"pending\" };\n\t\t\t\t}\n\n\t\t\t\tif (error === \"slow_down\") {\n\t\t\t\t\treturn { status: \"slow_down\", intervalSeconds: typeof interval === \"number\" ? interval : undefined };\n\t\t\t\t}\n\n\t\t\t\tconst descriptionSuffix = description ? `: ${description}` : \"\";\n\t\t\t\treturn { status: \"failed\", message: `Device flow failed: ${error}${descriptionSuffix}` };\n\t\t\t}\n\n\t\t\treturn { status: \"failed\", message: \"Invalid device token response\" };\n\t\t},\n\t});\n}\n\nasync function refreshGitHubCopilotAccessToken(\n\trefreshToken: string,\n\tenterpriseDomain: string | undefined,\n\tsignal: AbortSignal,\n): Promise<OAuthCredential> {\n\tconst domain = enterpriseDomain || \"github.com\";\n\tconst urls = getUrls(domain);\n\n\tconst raw = await fetchJson(urls.copilotTokenUrl, {\n\t\theaders: {\n\t\t\tAccept: \"application/json\",\n\t\t\tAuthorization: `Bearer ${refreshToken}`,\n\t\t\t...COPILOT_HEADERS,\n\t\t},\n\t\tsignal,\n\t});\n\n\tif (!raw || typeof raw !== \"object\") {\n\t\tthrow new Error(\"Invalid Copilot token response\");\n\t}\n\n\tconst token = (raw as Record<string, unknown>).token;\n\tconst expiresAt = (raw as Record<string, unknown>).expires_at;\n\n\tif (typeof token !== \"string\" || typeof expiresAt !== \"number\") {\n\t\tthrow new Error(\"Invalid Copilot token response fields\");\n\t}\n\n\tconst endpoints = (raw as Record<string, unknown>).endpoints;\n\tconst apiUrl = parseGitHubCopilotApiEndpoint(\n\t\ttypeof endpoints === \"object\" && endpoints !== null ? Reflect.get(endpoints, \"api\") : undefined,\n\t);\n\tconst tid = githubCopilotTokenField(token, \"tid\");\n\treturn {\n\t\ttype: \"oauth\",\n\t\trefresh: refreshToken,\n\t\taccess: token,\n\t\texpires: expiresAt * 1000 - 5 * 60 * 1000,\n\t\tenterpriseUrl: enterpriseDomain,\n\t\t...(apiUrl !== undefined && tid !== undefined ? { copilotApiEndpoint: { tid, url: apiUrl } } : {}),\n\t};\n}\n\n/**\n * Refresh GitHub Copilot token\n */\nasync function refreshGitHubCopilotToken(\n\trefreshToken: string,\n\tenterpriseDomain: string | undefined,\n\tsignal: AbortSignal,\n): Promise<OAuthCredential> {\n\tconst credentials = await refreshGitHubCopilotAccessToken(refreshToken, enterpriseDomain, signal);\n\tconst { availableModelIds, modelLimits } = await fetchGitHubCopilotModels(\n\t\tcredentials.access,\n\t\tenterpriseDomain,\n\t\tsignal,\n\t\t{\n\t\t\tmaxRetries: 0,\n\t\t\tmaxElapsedMs: 0,\n\t\t},\n\t\tcredentials.copilotApiEndpoint,\n\t);\n\treturn {\n\t\t...credentials,\n\t\tavailableModelIds,\n\t\tcopilotModelLimits: modelLimits,\n\t};\n}\n\n/**\n * Enable a model for the user's GitHub Copilot account.\n * This is required for some models (like Claude, Grok) before they can be used.\n */\nasync function enableGitHubCopilotModel(\n\ttoken: string,\n\tmodelId: string,\n\tenterpriseDomain: string | undefined,\n\tsignal: AbortSignal,\n\tapiEndpoint?: unknown,\n): Promise<boolean> {\n\tconst baseUrl = getGitHubCopilotBaseUrl(token, enterpriseDomain, apiEndpoint);\n\tconst url = `${baseUrl}/models/${modelId}/policy`;\n\n\tlet response: Response;\n\ttry {\n\t\tresponse = await fetchWithRateLimitRetry(\n\t\t\turl,\n\t\t\t{\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\tAuthorization: `Bearer ${token}`,\n\t\t\t\t\t...COPILOT_HEADERS,\n\t\t\t\t\t\"openai-intent\": \"chat-policy\",\n\t\t\t\t\t\"x-interaction-type\": \"chat-policy\",\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify({ state: \"enabled\" }),\n\t\t\t},\n\t\t\tsignal,\n\t\t\t{ maxRetries: 2, maxElapsedMs: 5000 },\n\t\t);\n\t} catch (error) {\n\t\tif (signal.aborted) throw error;\n\t\treturn false;\n\t}\n\tif (response.status === 429) {\n\t\tthrow new Error(`${response.status} ${response.statusText}: ${await response.text()}`);\n\t}\n\treturn response.ok;\n}\n\n/**\n * Enable the requested GitHub Copilot models and return the successful IDs.\n * Policy updates are best effort; exhausted rate limiting stops the batch.\n */\nasync function enableGitHubCopilotModels(\n\ttoken: string,\n\tmodelIds: readonly string[],\n\tenterpriseDomain: string | undefined,\n\tsignal: AbortSignal,\n\tapiEndpoint?: unknown,\n): Promise<string[]> {\n\tconst enabledModelIds: string[] = [];\n\tfor (const modelId of modelIds) {\n\t\ttry {\n\t\t\tif (await enableGitHubCopilotModel(token, modelId, enterpriseDomain, signal, apiEndpoint)) {\n\t\t\t\tenabledModelIds.push(modelId);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tif (signal.aborted) throw error;\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn enabledModelIds;\n}\n\nasync function loginGitHubCopilot(interaction: ProviderAuthInteraction): Promise<OAuthCredential> {\n\tconst input = await interaction.prompt({\n\t\ttype: \"text\",\n\t\tmessage: \"GitHub Enterprise URL/domain (blank for github.com)\",\n\t\tplaceholder: \"company.ghe.com\",\n\t});\n\tif (interaction.signal.aborted) throw new Error(\"Login cancelled\");\n\n\tconst trimmed = input.trim();\n\tconst enterpriseDomain = normalizeDomain(input);\n\tif (trimmed && !enterpriseDomain) throw new Error(\"Invalid GitHub Enterprise URL/domain\");\n\tconst domain = enterpriseDomain || \"github.com\";\n\n\tconst device = await startDeviceFlow(domain, interaction.signal);\n\tinteraction.notify({\n\t\ttype: \"device_code\",\n\t\tuserCode: device.user_code,\n\t\tverificationUri: device.verification_uri,\n\t\tintervalSeconds: device.interval,\n\t\texpiresInSeconds: device.expires_in,\n\t});\n\n\tconst githubAccessToken = await pollForGitHubAccessToken(domain, device, interaction.signal);\n\tconst credentials = await refreshGitHubCopilotAccessToken(\n\t\tgithubAccessToken,\n\t\tenterpriseDomain ?? undefined,\n\t\tinteraction.signal,\n\t);\n\tconst models = await fetchGitHubCopilotModels(\n\t\tcredentials.access,\n\t\tenterpriseDomain ?? undefined,\n\t\tinteraction.signal,\n\t\t{\n\t\t\tmaxRetries: 2,\n\t\t\tmaxElapsedMs: 5000,\n\t\t},\n\t\tcredentials.copilotApiEndpoint,\n\t);\n\tlet enabledModelIds: string[] = [];\n\tif (models.policyModelIds.length > 0) {\n\t\tinteraction.notify({ type: \"progress\", message: \"Enabling models...\" });\n\t\tenabledModelIds = await enableGitHubCopilotModels(\n\t\t\tcredentials.access,\n\t\t\tmodels.policyModelIds,\n\t\t\tenterpriseDomain ?? undefined,\n\t\t\tinteraction.signal,\n\t\t\tcredentials.copilotApiEndpoint,\n\t\t);\n\t}\n\treturn {\n\t\t...credentials,\n\t\tavailableModelIds: [...new Set([...models.availableModelIds, ...enabledModelIds])],\n\t\tcopilotModelLimits: models.modelLimits,\n\t};\n}\n\nfunction copilotEnterpriseDomain(credential: OAuthCredential): string | undefined {\n\tconst enterpriseUrl = credential.enterpriseUrl;\n\tif (typeof enterpriseUrl !== \"string\" || !enterpriseUrl) return undefined;\n\treturn normalizeDomain(enterpriseUrl) ?? undefined;\n}\n\nexport const githubCopilotOAuth: OAuthAuth = {\n\tname: \"GitHub Copilot\",\n\tisSubscription: true,\n\trejectedTokenStatuses: GITHUB_COPILOT_REJECTED_TOKEN_STATUSES,\n\tlogin: loginGitHubCopilot,\n\trefresh: (credential, signal) =>\n\t\trefreshGitHubCopilotToken(credential.refresh, copilotEnterpriseDomain(credential), signal),\n\n\t/** Derive the credential-specific proxy endpoint for each request. */\n\tasync toAuth(credential) {\n\t\treturn {\n\t\t\tapiKey: credential.access,\n\t\t\tbaseUrl: getGitHubCopilotBaseUrl(\n\t\t\t\tcredential.access,\n\t\t\t\tcopilotEnterpriseDomain(credential),\n\t\t\t\tcredential.copilotApiEndpoint,\n\t\t\t),\n\t\t};\n\t},\n};\n"]}
@@ -1 +1 @@
1
- {"schemaVersion":3,"generatedAt":"2026-09-28T13:22:49.784Z","structureHash":"2cf77dab1c71bac9aeb59ac1539f0750b51fa1c20c9df0a7cd7fca7886d7db9b","files":{"alibaba-token-plan.json":"3a9c1be76d47459371e9fa2feeffc31e7edbbfec65fa9cc41236988efc4cf6d9","amazon-bedrock.json":"848e38fd1ade9c6e94c3037c1c6104ac515809a6f190d264eafd9f48ab0ae1ae","ant-ling.json":"4979fe79d99ed97382d7ce40170c6132e932e77906de1eb54464c042e7d63633","anthropic.json":"f9db437d92449fb860a2d457a6019cdfd51c11180c08df2b5f14d75ade773953","azure-openai-responses.json":"d97b98b63595dd30c138a5bcba724017f5c09c489b56be254828a298cfa087e1","bai.json":"2b12b15bd43462e60711944dd7283db8676611d9d76c82c2a01f64913e16a67e","baseten.json":"d155c434294b5167244cffb6dea6793f9669e91e8ab65b564f9510d81b330e37","cerebras.json":"3be228c613905c215c9da3d0b3535e10cc594ff2351b05390744c7c34de89b6c","chatgpt-subscription.json":"421c6ad932de4259c8f0c08589da278bed99ec80c042f2490d8ffd2a86f4da99","cloudflare-ai-gateway.json":"b64cc5c7c0df4bfce0c3c2b14fe5290636553914b09718634668ad98276a9bc5","cloudflare-workers-ai.json":"8ee15540a01cf79d0e4063c493ae3c436af2fc1d456f9faf1b066418247183e9","deepseek.json":"b5f9693ec641e9a957dc5f7a22042b3bb928bac3d7268406619b6f18e21c4b83","fireworks.json":"bbb8149854a2658f221afa47ae8e2617e6b58a8e2784aa822faaf54f0c0f18c3","github-copilot.json":"5c9fc5b1b553a26aa7bc843a3e36fa14cf220d528ecd89528c601c5090c88a2d","google-vertex.json":"97d80ac909d256cc1bf19ac54d9d8131c492e7c0c102ad89f68ade528544e0ad","google.json":"68f6cf6283cc0d69b77b0fa79e9c94774e96524f61ebba616319f05d5c9db56c","groq.json":"e4728fd72e358cd8f25e9a518e9b49a521ef44523d3debe38a7db9e0663c4077","huggingface.json":"2f93082144a7b2a1cbf79148244ce7559e0428d6310c5eb0648bca89b15a8b4b","minimax-cn.json":"4f636b47b28a507ad33b5eaba33fc4889e5956504d10f2a0d9c61167ae01ff1d","minimax.json":"9fd1764ffeefebded8579039cf0c48854a43e4c5b724f62361fc2ac54f705aa1","mistral.json":"be522597b22bceeb0bb9a0ba1781647649ffd19637d0c8e67b056d7b0ec33d52","moonshotai-cn.json":"326de79b46f6fdbf0879f005b3040d1b14049e81fa678de407b73ed1bd3bce9c","moonshotai.json":"4b917a375e9c880b903927cf5fe1ae1052c74b64d5027a007bb1e67ad0410755","nvidia.json":"6493e09b5db8b8fe9c8fae5bc15dc287645f37f83a4ed3a1ad1181e5830b5ff7","openai.json":"1856254ecf9b016193c34c9081e2fd87b95bfb837d9ee6dbf6c0e30c94044fd5","opencode-go.json":"d8bb59f10e2ba10fe6f1e36828fecbbfd92804352e89f28506ee468e69657f78","opencode.json":"1655e248e76f919fd14ca4b8a6201d1dd89b2190b295028c5d7a4a2a03809946","opengateway.json":"4f5254d6c51f1f2fc6ec05133b19db4429908b10a16a9122cdf6528067e2a8ac","openrouter.json":"318ea9b6b5b2b635d95e8887620cd7bc5d010cebd97e8c8e30dbc79b49198079","qwen-token-plan-cn.json":"4bf520ed38e5c3045680d2ec2816fa8a69079dbe97f7b929767a63172288da6b","qwen-token-plan-individual.json":"eb040e78595853e980011308b1bf9caacae6dc8a91abbac5ffebd402515dd2a6","qwen-token-plan.json":"a5c67213745329ec3ba79f712f31c1c32a781d7ffb8c04f9819f36c27672531f","together.json":"200fa2cc0b4666e3818c260e41b9925b925180e2d0931d7c900e16494b2314b4","venice.json":"d34b566ee6e7a2ed31abd9099a1c0448f1d521fc696382d03d86c90634270cf1","vercel-ai-gateway.json":"95a697cd6f9eba46972dbfa301e80f18f45c701e6068c0326d2f36da10b7ce7e","xai.json":"9b23faa5218e966a17108c05d2498a617ade1eae9b0d0684284c77d67949a3f1","xiaomi-token-plan-ams.json":"7df74a255259fc1d5be8e682c3ffb0908eaaf0af711f6433dedcf345ce3e8393","xiaomi-token-plan-cn.json":"7dc672723d5b37e5b92605752f74f46f44eba10be2b0cb959790260b9e0c2a4e","xiaomi-token-plan-sgp.json":"69b333b158be038459a511a673f4536a5b03d4931c3119339f1ac741bc03d502","xiaomi.json":"333299657f211ad9edac0f3d4298b7e5776626914c9c80e22305a87533f23966","zai-coding-cn.json":"69c572aa75104f16ccbddbaace60c267f4bcc74f86d34891ca43110d312fb1ad","zai.json":"15c8182a88e58bdc1b1c3eb0603c690475342c8a826ceddfe9af1b36b28345ee"}}
1
+ {"schemaVersion":3,"generatedAt":"2026-09-28T15:13:00.701Z","structureHash":"2cf77dab1c71bac9aeb59ac1539f0750b51fa1c20c9df0a7cd7fca7886d7db9b","files":{"alibaba-token-plan.json":"3a9c1be76d47459371e9fa2feeffc31e7edbbfec65fa9cc41236988efc4cf6d9","amazon-bedrock.json":"848e38fd1ade9c6e94c3037c1c6104ac515809a6f190d264eafd9f48ab0ae1ae","ant-ling.json":"4979fe79d99ed97382d7ce40170c6132e932e77906de1eb54464c042e7d63633","anthropic.json":"f9db437d92449fb860a2d457a6019cdfd51c11180c08df2b5f14d75ade773953","azure-openai-responses.json":"d97b98b63595dd30c138a5bcba724017f5c09c489b56be254828a298cfa087e1","bai.json":"2b12b15bd43462e60711944dd7283db8676611d9d76c82c2a01f64913e16a67e","baseten.json":"d155c434294b5167244cffb6dea6793f9669e91e8ab65b564f9510d81b330e37","cerebras.json":"3be228c613905c215c9da3d0b3535e10cc594ff2351b05390744c7c34de89b6c","chatgpt-subscription.json":"421c6ad932de4259c8f0c08589da278bed99ec80c042f2490d8ffd2a86f4da99","cloudflare-ai-gateway.json":"b64cc5c7c0df4bfce0c3c2b14fe5290636553914b09718634668ad98276a9bc5","cloudflare-workers-ai.json":"8ee15540a01cf79d0e4063c493ae3c436af2fc1d456f9faf1b066418247183e9","deepseek.json":"b5f9693ec641e9a957dc5f7a22042b3bb928bac3d7268406619b6f18e21c4b83","fireworks.json":"bbb8149854a2658f221afa47ae8e2617e6b58a8e2784aa822faaf54f0c0f18c3","github-copilot.json":"5c9fc5b1b553a26aa7bc843a3e36fa14cf220d528ecd89528c601c5090c88a2d","google-vertex.json":"97d80ac909d256cc1bf19ac54d9d8131c492e7c0c102ad89f68ade528544e0ad","google.json":"68f6cf6283cc0d69b77b0fa79e9c94774e96524f61ebba616319f05d5c9db56c","groq.json":"e4728fd72e358cd8f25e9a518e9b49a521ef44523d3debe38a7db9e0663c4077","huggingface.json":"2f93082144a7b2a1cbf79148244ce7559e0428d6310c5eb0648bca89b15a8b4b","minimax-cn.json":"4f636b47b28a507ad33b5eaba33fc4889e5956504d10f2a0d9c61167ae01ff1d","minimax.json":"9fd1764ffeefebded8579039cf0c48854a43e4c5b724f62361fc2ac54f705aa1","mistral.json":"be522597b22bceeb0bb9a0ba1781647649ffd19637d0c8e67b056d7b0ec33d52","moonshotai-cn.json":"326de79b46f6fdbf0879f005b3040d1b14049e81fa678de407b73ed1bd3bce9c","moonshotai.json":"4b917a375e9c880b903927cf5fe1ae1052c74b64d5027a007bb1e67ad0410755","nvidia.json":"6493e09b5db8b8fe9c8fae5bc15dc287645f37f83a4ed3a1ad1181e5830b5ff7","openai.json":"1856254ecf9b016193c34c9081e2fd87b95bfb837d9ee6dbf6c0e30c94044fd5","opencode-go.json":"d8bb59f10e2ba10fe6f1e36828fecbbfd92804352e89f28506ee468e69657f78","opencode.json":"1655e248e76f919fd14ca4b8a6201d1dd89b2190b295028c5d7a4a2a03809946","opengateway.json":"4f5254d6c51f1f2fc6ec05133b19db4429908b10a16a9122cdf6528067e2a8ac","openrouter.json":"769a221dbf0a81de8066b8a037f34f137c77a38679ae6306f26da20a360a7ff9","qwen-token-plan-cn.json":"4bf520ed38e5c3045680d2ec2816fa8a69079dbe97f7b929767a63172288da6b","qwen-token-plan-individual.json":"eb040e78595853e980011308b1bf9caacae6dc8a91abbac5ffebd402515dd2a6","qwen-token-plan.json":"a5c67213745329ec3ba79f712f31c1c32a781d7ffb8c04f9819f36c27672531f","together.json":"200fa2cc0b4666e3818c260e41b9925b925180e2d0931d7c900e16494b2314b4","venice.json":"d34b566ee6e7a2ed31abd9099a1c0448f1d521fc696382d03d86c90634270cf1","vercel-ai-gateway.json":"95a697cd6f9eba46972dbfa301e80f18f45c701e6068c0326d2f36da10b7ce7e","xai.json":"9b23faa5218e966a17108c05d2498a617ade1eae9b0d0684284c77d67949a3f1","xiaomi-token-plan-ams.json":"7df74a255259fc1d5be8e682c3ffb0908eaaf0af711f6433dedcf345ce3e8393","xiaomi-token-plan-cn.json":"7dc672723d5b37e5b92605752f74f46f44eba10be2b0cb959790260b9e0c2a4e","xiaomi-token-plan-sgp.json":"69b333b158be038459a511a673f4536a5b03d4931c3119339f1ac741bc03d502","xiaomi.json":"333299657f211ad9edac0f3d4298b7e5776626914c9c80e22305a87533f23966","zai-coding-cn.json":"69c572aa75104f16ccbddbaace60c267f4bcc74f86d34891ca43110d312fb1ad","zai.json":"15c8182a88e58bdc1b1c3eb0603c690475342c8a826ceddfe9af1b36b28345ee"}}