@nick3/copilot-api 1.5.9 → 1.6.1

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.
Files changed (28) hide show
  1. package/README.md +33 -30
  2. package/README.zh-CN.md +953 -0
  3. package/dist/{account-CbYMFuS4.js → account-B2tSWtVS.js} +2 -2
  4. package/dist/{account-CbYMFuS4.js.map → account-B2tSWtVS.js.map} +1 -1
  5. package/dist/{accounts-manager-BKG9aZEL.js → accounts-manager-CAyZJSn8.js} +144 -111
  6. package/dist/accounts-manager-CAyZJSn8.js.map +1 -0
  7. package/dist/admin/assets/index-BESw8Vvd.css +1 -0
  8. package/dist/admin/assets/index-Ddo9RHg-.js +101 -0
  9. package/dist/admin/index.html +2 -2
  10. package/dist/{auth-Ckj1wD43.js → auth-BXCeDjRG.js} +3 -3
  11. package/dist/{auth-Ckj1wD43.js.map → auth-BXCeDjRG.js.map} +1 -1
  12. package/dist/{check-usage-bIbj_1Q_.js → check-usage-CQxXYfUx.js} +3 -3
  13. package/dist/{check-usage-bIbj_1Q_.js.map → check-usage-CQxXYfUx.js.map} +1 -1
  14. package/dist/{get-copilot-token-MAZsr5Vu.js → get-copilot-token-p17sJyPU.js} +2 -2
  15. package/dist/{get-copilot-token-MAZsr5Vu.js.map → get-copilot-token-p17sJyPU.js.map} +1 -1
  16. package/dist/main.js +3 -3
  17. package/dist/{poll-access-token-DiwBJNtK.js → poll-access-token-Bc6VwWab.js} +49 -9
  18. package/dist/poll-access-token-Bc6VwWab.js.map +1 -0
  19. package/dist/{server-DAxpfPde.js → server-BAlLdlCl.js} +112 -61
  20. package/dist/server-BAlLdlCl.js.map +1 -0
  21. package/dist/{start-8dkfsQqd.js → start-eFWi3mS4.js} +6 -6
  22. package/dist/{start-8dkfsQqd.js.map → start-eFWi3mS4.js.map} +1 -1
  23. package/package.json +1 -1
  24. package/dist/accounts-manager-BKG9aZEL.js.map +0 -1
  25. package/dist/admin/assets/index-BFN8rXmt.css +0 -1
  26. package/dist/admin/assets/index-HnEqzcKv.js +0 -101
  27. package/dist/poll-access-token-DiwBJNtK.js.map +0 -1
  28. package/dist/server-DAxpfPde.js.map +0 -1
@@ -18,8 +18,8 @@
18
18
  }
19
19
  })()
20
20
  </script>
21
- <script type="module" crossorigin src="/admin/assets/index-HnEqzcKv.js"></script>
22
- <link rel="stylesheet" crossorigin href="/admin/assets/index-BFN8rXmt.css">
21
+ <script type="module" crossorigin src="/admin/assets/index-Ddo9RHg-.js"></script>
22
+ <link rel="stylesheet" crossorigin href="/admin/assets/index-BESw8Vvd.css">
23
23
  </head>
24
24
  <body>
25
25
  <div id="root"></div>
@@ -1,5 +1,5 @@
1
- import { g as getCopilotUsage, h as getDeviceCode, k as state, m as getGitHubUser, t as pollAccessToken } from "./poll-access-token-DiwBJNtK.js";
2
- import { d as loadRegistry, g as saveRegistry, h as saveAccountToken, l as listAccountsFromRegistry, m as removeAccountToken, n as parseAccountType, p as removeAccountFromRegistry, r as addAccountToRegistry, u as loadAccountToken } from "./account-CbYMFuS4.js";
1
+ import { g as getCopilotUsage, h as getDeviceCode, k as state, m as getGitHubUser, t as pollAccessToken } from "./poll-access-token-Bc6VwWab.js";
2
+ import { d as loadRegistry, g as saveRegistry, h as saveAccountToken, l as listAccountsFromRegistry, m as removeAccountToken, n as parseAccountType, p as removeAccountFromRegistry, r as addAccountToRegistry, u as loadAccountToken } from "./account-B2tSWtVS.js";
3
3
  import { r as ensurePaths } from "./paths-DGlr310R.js";
4
4
  import { defineCommand } from "citty";
5
5
  import consola from "consola";
@@ -232,4 +232,4 @@ const auth = defineCommand({
232
232
 
233
233
  //#endregion
234
234
  export { auth };
235
- //# sourceMappingURL=auth-Ckj1wD43.js.map
235
+ //# sourceMappingURL=auth-BXCeDjRG.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth-Ckj1wD43.js","names":["accountType: AccountType","accountToRemove: { id: string; index: number } | undefined"],"sources":["../src/auth.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { defineCommand } from \"citty\"\nimport consola from \"consola\"\n\nimport {\n addAccountToRegistry,\n listAccountsFromRegistry,\n loadAccountToken,\n loadRegistry,\n removeAccountFromRegistry,\n removeAccountToken,\n saveAccountToken,\n saveRegistry,\n} from \"./lib/accounts-registry\"\nimport { ensurePaths } from \"./lib/paths\"\nimport { state } from \"./lib/state\"\nimport {\n parseAccountType,\n type AccountMeta,\n type AccountType,\n} from \"./lib/types/account\"\nimport { getCopilotUsage } from \"./services/github/get-copilot-usage\"\nimport { getDeviceCode } from \"./services/github/get-device-code\"\nimport { getGitHubUser } from \"./services/github/get-user\"\nimport { pollAccessToken } from \"./services/github/poll-access-token\"\n\n/**\n * Fetch quota info for an account (used by auth ls -q)\n */\nasync function fetchQuotaInfo(account: AccountMeta): Promise<string> {\n try {\n const token = await loadAccountToken(account.id)\n if (!token) {\n return \" | Quota: (no token)\"\n }\n\n const usage = await getCopilotUsage({\n githubToken: token,\n accountType: account.accountType,\n })\n const premium = usage.quota_snapshots.premium_interactions\n\n return premium.unlimited ?\n \" | Quota: unlimited\"\n : ` | Quota: ${premium.remaining}/${premium.entitlement}`\n } catch (error) {\n consola.debug(`Failed to fetch quota for ${account.id}:`, error)\n return \" | Quota: (failed to fetch)\"\n }\n}\n\n/**\n * auth add - Add a new GitHub Copilot account\n */\nconst authAdd = defineCommand({\n meta: {\n name: \"add\",\n description: \"Add a new GitHub Copilot account\",\n },\n args: {\n \"account-type\": {\n alias: \"a\",\n type: \"string\",\n default: \"individual\",\n description: \"Account type (individual, business, enterprise)\",\n },\n verbose: {\n alias: \"v\",\n type: \"boolean\",\n default: false,\n description: \"Enable verbose logging\",\n },\n \"show-token\": {\n type: \"boolean\",\n default: false,\n description: \"Show GitHub token after auth\",\n },\n },\n async run({ args }) {\n if (args.verbose) {\n consola.level = 5\n consola.info(\"Verbose logging enabled\")\n }\n\n state.showToken = args[\"show-token\"]\n\n let accountType: AccountType\n try {\n accountType = parseAccountType(args[\"account-type\"])\n } catch (error) {\n consola.error(error instanceof Error ? error.message : String(error))\n process.exit(1)\n }\n\n await ensurePaths()\n\n // Start device code flow\n consola.info(\"Starting GitHub device code authentication...\")\n const deviceResponse = await getDeviceCode()\n consola.debug(\"Device code response:\", deviceResponse)\n\n consola.info(\n `Please enter the code \"${deviceResponse.user_code}\" at ${deviceResponse.verification_uri}`,\n )\n\n // Poll for access token\n const token = await pollAccessToken(deviceResponse)\n\n if (state.showToken) {\n consola.info(\"GitHub token:\", token)\n }\n\n // Get user info to determine account ID\n const user = await getGitHubUser({ githubToken: token, accountType })\n const accountId = user.login\n\n // Save token and check if account already exists\n await saveAccountToken(accountId, token)\n const existingAccounts = await listAccountsFromRegistry()\n const alreadyExists = existingAccounts.some((acc) => acc.id === accountId)\n\n if (alreadyExists) {\n // Touch registry file so a running server can hot-reload updated tokens.\n await saveRegistry(await loadRegistry())\n\n consola.success(\n `Account \"${accountId}\" already exists. Token has been updated.`,\n )\n } else {\n await addAccountToRegistry({\n id: accountId,\n accountType,\n addedAt: Date.now(),\n })\n consola.success(`Account \"${accountId}\" added successfully!`)\n }\n\n consola.info(`Account type: ${accountType}`)\n },\n})\n\n/**\n * auth ls - List all registered accounts\n */\nconst authLs = defineCommand({\n meta: {\n name: \"ls\",\n description: \"List all registered accounts\",\n },\n args: {\n \"show-quota\": {\n alias: \"q\",\n type: \"boolean\",\n default: false,\n description: \"Show quota information (requires API call)\",\n },\n verbose: {\n alias: \"v\",\n type: \"boolean\",\n default: false,\n description: \"Enable verbose logging\",\n },\n },\n async run({ args }) {\n if (args.verbose) {\n consola.level = 5\n }\n\n await ensurePaths()\n\n const accounts = await listAccountsFromRegistry()\n\n if (accounts.length === 0) {\n consola.info(\"No accounts registered. Use 'auth add' to add an account.\")\n return\n }\n\n consola.info(`Found ${accounts.length} account(s):\\n`)\n\n for (const [i, account] of accounts.entries()) {\n const addedDate = new Date(account.addedAt).toLocaleString()\n\n const quotaInfo = args[\"show-quota\"] ? await fetchQuotaInfo(account) : \"\"\n\n console.log(\n ` ${i + 1}. ${account.id} (${account.accountType})${quotaInfo}`,\n )\n console.log(` Added: ${addedDate}\\n`)\n }\n },\n})\n\n/**\n * auth rm - Remove an account\n */\nconst authRm = defineCommand({\n meta: {\n name: \"rm\",\n description: \"Remove an account\",\n },\n args: {\n target: {\n type: \"positional\",\n description: \"Account ID or index (1-based)\",\n required: true,\n },\n force: {\n alias: \"f\",\n type: \"boolean\",\n default: false,\n description: \"Skip confirmation prompt\",\n },\n verbose: {\n alias: \"v\",\n type: \"boolean\",\n default: false,\n description: \"Enable verbose logging\",\n },\n },\n async run({ args }) {\n if (args.verbose) {\n consola.level = 5\n }\n\n await ensurePaths()\n\n const target = args.target\n const accounts = await listAccountsFromRegistry()\n\n if (accounts.length === 0) {\n consola.error(\"No accounts to remove.\")\n return\n }\n\n // Determine account to remove (by ID or index)\n let accountToRemove: { id: string; index: number } | undefined\n\n // Try parsing as index (1-based)\n const index = Number.parseInt(target, 10)\n if (!Number.isNaN(index) && index >= 1 && index <= accounts.length) {\n accountToRemove = { id: accounts[index - 1].id, index: index - 1 }\n } else {\n // Try finding by ID\n const foundIndex = accounts.findIndex((acc) => acc.id === target)\n if (foundIndex !== -1) {\n accountToRemove = { id: accounts[foundIndex].id, index: foundIndex }\n }\n }\n\n if (!accountToRemove) {\n consola.error(`Account \"${target}\" not found.`)\n consola.info(\"Use 'auth ls' to see available accounts.\")\n return\n }\n\n // Confirmation\n if (!args.force) {\n const confirmed = await consola.prompt(\n `Are you sure you want to remove account \"${accountToRemove.id}\"?`,\n { type: \"confirm\" },\n )\n if (!confirmed) {\n consola.info(\"Cancelled.\")\n return\n }\n }\n\n // Remove token file and registry entry\n await removeAccountToken(accountToRemove.id)\n await removeAccountFromRegistry(accountToRemove.id)\n\n consola.success(`Account \"${accountToRemove.id}\" removed.`)\n },\n})\n\n/**\n * Main auth command with subcommands\n */\nexport const auth = defineCommand({\n meta: {\n name: \"auth\",\n description: \"Manage GitHub Copilot accounts\",\n },\n subCommands: {\n add: authAdd,\n ls: authLs,\n rm: authRm,\n },\n args: {\n // Legacy args for backward compatibility (when no subcommand)\n \"account-type\": {\n alias: \"a\",\n type: \"string\",\n default: \"individual\",\n description: \"Account type (individual, business, enterprise)\",\n },\n verbose: {\n alias: \"v\",\n type: \"boolean\",\n default: false,\n description: \"Enable verbose logging\",\n },\n \"show-token\": {\n type: \"boolean\",\n default: false,\n description: \"Show GitHub token after auth\",\n },\n },\n async run(ctx) {\n // Check if a subcommand was specified in rawArgs.\n // Only treat the *first* raw arg as a subcommand to avoid false positives\n // when flags accept values like \"add\"/\"ls\"/\"rm\".\n const firstArg = ctx.rawArgs[0]\n const hasSubCommand =\n firstArg === \"add\" || firstArg === \"ls\" || firstArg === \"rm\"\n\n // Backward compatibility: if no subcommand, run 'add'\n if (!hasSubCommand && authAdd.run) {\n await authAdd.run(ctx)\n }\n },\n})\n"],"mappings":"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"}
1
+ {"version":3,"file":"auth-BXCeDjRG.js","names":["accountType: AccountType","accountToRemove: { id: string; index: number } | undefined"],"sources":["../src/auth.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { defineCommand } from \"citty\"\nimport consola from \"consola\"\n\nimport {\n addAccountToRegistry,\n listAccountsFromRegistry,\n loadAccountToken,\n loadRegistry,\n removeAccountFromRegistry,\n removeAccountToken,\n saveAccountToken,\n saveRegistry,\n} from \"./lib/accounts-registry\"\nimport { ensurePaths } from \"./lib/paths\"\nimport { state } from \"./lib/state\"\nimport {\n parseAccountType,\n type AccountMeta,\n type AccountType,\n} from \"./lib/types/account\"\nimport { getCopilotUsage } from \"./services/github/get-copilot-usage\"\nimport { getDeviceCode } from \"./services/github/get-device-code\"\nimport { getGitHubUser } from \"./services/github/get-user\"\nimport { pollAccessToken } from \"./services/github/poll-access-token\"\n\n/**\n * Fetch quota info for an account (used by auth ls -q)\n */\nasync function fetchQuotaInfo(account: AccountMeta): Promise<string> {\n try {\n const token = await loadAccountToken(account.id)\n if (!token) {\n return \" | Quota: (no token)\"\n }\n\n const usage = await getCopilotUsage({\n githubToken: token,\n accountType: account.accountType,\n })\n const premium = usage.quota_snapshots.premium_interactions\n\n return premium.unlimited ?\n \" | Quota: unlimited\"\n : ` | Quota: ${premium.remaining}/${premium.entitlement}`\n } catch (error) {\n consola.debug(`Failed to fetch quota for ${account.id}:`, error)\n return \" | Quota: (failed to fetch)\"\n }\n}\n\n/**\n * auth add - Add a new GitHub Copilot account\n */\nconst authAdd = defineCommand({\n meta: {\n name: \"add\",\n description: \"Add a new GitHub Copilot account\",\n },\n args: {\n \"account-type\": {\n alias: \"a\",\n type: \"string\",\n default: \"individual\",\n description: \"Account type (individual, business, enterprise)\",\n },\n verbose: {\n alias: \"v\",\n type: \"boolean\",\n default: false,\n description: \"Enable verbose logging\",\n },\n \"show-token\": {\n type: \"boolean\",\n default: false,\n description: \"Show GitHub token after auth\",\n },\n },\n async run({ args }) {\n if (args.verbose) {\n consola.level = 5\n consola.info(\"Verbose logging enabled\")\n }\n\n state.showToken = args[\"show-token\"]\n\n let accountType: AccountType\n try {\n accountType = parseAccountType(args[\"account-type\"])\n } catch (error) {\n consola.error(error instanceof Error ? error.message : String(error))\n process.exit(1)\n }\n\n await ensurePaths()\n\n // Start device code flow\n consola.info(\"Starting GitHub device code authentication...\")\n const deviceResponse = await getDeviceCode()\n consola.debug(\"Device code response:\", deviceResponse)\n\n consola.info(\n `Please enter the code \"${deviceResponse.user_code}\" at ${deviceResponse.verification_uri}`,\n )\n\n // Poll for access token\n const token = await pollAccessToken(deviceResponse)\n\n if (state.showToken) {\n consola.info(\"GitHub token:\", token)\n }\n\n // Get user info to determine account ID\n const user = await getGitHubUser({ githubToken: token, accountType })\n const accountId = user.login\n\n // Save token and check if account already exists\n await saveAccountToken(accountId, token)\n const existingAccounts = await listAccountsFromRegistry()\n const alreadyExists = existingAccounts.some((acc) => acc.id === accountId)\n\n if (alreadyExists) {\n // Touch registry file so a running server can hot-reload updated tokens.\n await saveRegistry(await loadRegistry())\n\n consola.success(\n `Account \"${accountId}\" already exists. Token has been updated.`,\n )\n } else {\n await addAccountToRegistry({\n id: accountId,\n accountType,\n addedAt: Date.now(),\n })\n consola.success(`Account \"${accountId}\" added successfully!`)\n }\n\n consola.info(`Account type: ${accountType}`)\n },\n})\n\n/**\n * auth ls - List all registered accounts\n */\nconst authLs = defineCommand({\n meta: {\n name: \"ls\",\n description: \"List all registered accounts\",\n },\n args: {\n \"show-quota\": {\n alias: \"q\",\n type: \"boolean\",\n default: false,\n description: \"Show quota information (requires API call)\",\n },\n verbose: {\n alias: \"v\",\n type: \"boolean\",\n default: false,\n description: \"Enable verbose logging\",\n },\n },\n async run({ args }) {\n if (args.verbose) {\n consola.level = 5\n }\n\n await ensurePaths()\n\n const accounts = await listAccountsFromRegistry()\n\n if (accounts.length === 0) {\n consola.info(\"No accounts registered. Use 'auth add' to add an account.\")\n return\n }\n\n consola.info(`Found ${accounts.length} account(s):\\n`)\n\n for (const [i, account] of accounts.entries()) {\n const addedDate = new Date(account.addedAt).toLocaleString()\n\n const quotaInfo = args[\"show-quota\"] ? await fetchQuotaInfo(account) : \"\"\n\n console.log(\n ` ${i + 1}. ${account.id} (${account.accountType})${quotaInfo}`,\n )\n console.log(` Added: ${addedDate}\\n`)\n }\n },\n})\n\n/**\n * auth rm - Remove an account\n */\nconst authRm = defineCommand({\n meta: {\n name: \"rm\",\n description: \"Remove an account\",\n },\n args: {\n target: {\n type: \"positional\",\n description: \"Account ID or index (1-based)\",\n required: true,\n },\n force: {\n alias: \"f\",\n type: \"boolean\",\n default: false,\n description: \"Skip confirmation prompt\",\n },\n verbose: {\n alias: \"v\",\n type: \"boolean\",\n default: false,\n description: \"Enable verbose logging\",\n },\n },\n async run({ args }) {\n if (args.verbose) {\n consola.level = 5\n }\n\n await ensurePaths()\n\n const target = args.target\n const accounts = await listAccountsFromRegistry()\n\n if (accounts.length === 0) {\n consola.error(\"No accounts to remove.\")\n return\n }\n\n // Determine account to remove (by ID or index)\n let accountToRemove: { id: string; index: number } | undefined\n\n // Try parsing as index (1-based)\n const index = Number.parseInt(target, 10)\n if (!Number.isNaN(index) && index >= 1 && index <= accounts.length) {\n accountToRemove = { id: accounts[index - 1].id, index: index - 1 }\n } else {\n // Try finding by ID\n const foundIndex = accounts.findIndex((acc) => acc.id === target)\n if (foundIndex !== -1) {\n accountToRemove = { id: accounts[foundIndex].id, index: foundIndex }\n }\n }\n\n if (!accountToRemove) {\n consola.error(`Account \"${target}\" not found.`)\n consola.info(\"Use 'auth ls' to see available accounts.\")\n return\n }\n\n // Confirmation\n if (!args.force) {\n const confirmed = await consola.prompt(\n `Are you sure you want to remove account \"${accountToRemove.id}\"?`,\n { type: \"confirm\" },\n )\n if (!confirmed) {\n consola.info(\"Cancelled.\")\n return\n }\n }\n\n // Remove token file and registry entry\n await removeAccountToken(accountToRemove.id)\n await removeAccountFromRegistry(accountToRemove.id)\n\n consola.success(`Account \"${accountToRemove.id}\" removed.`)\n },\n})\n\n/**\n * Main auth command with subcommands\n */\nexport const auth = defineCommand({\n meta: {\n name: \"auth\",\n description: \"Manage GitHub Copilot accounts\",\n },\n subCommands: {\n add: authAdd,\n ls: authLs,\n rm: authRm,\n },\n args: {\n // Legacy args for backward compatibility (when no subcommand)\n \"account-type\": {\n alias: \"a\",\n type: \"string\",\n default: \"individual\",\n description: \"Account type (individual, business, enterprise)\",\n },\n verbose: {\n alias: \"v\",\n type: \"boolean\",\n default: false,\n description: \"Enable verbose logging\",\n },\n \"show-token\": {\n type: \"boolean\",\n default: false,\n description: \"Show GitHub token after auth\",\n },\n },\n async run(ctx) {\n // Check if a subcommand was specified in rawArgs.\n // Only treat the *first* raw arg as a subcommand to avoid false positives\n // when flags accept values like \"add\"/\"ls\"/\"rm\".\n const firstArg = ctx.rawArgs[0]\n const hasSubCommand =\n firstArg === \"add\" || firstArg === \"ls\" || firstArg === \"rm\"\n\n // Backward compatibility: if no subcommand, run 'add'\n if (!hasSubCommand && authAdd.run) {\n await authAdd.run(ctx)\n }\n },\n})\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
- import { _ as HTTPError, g as getCopilotUsage, h as getDeviceCode, k as state, m as getGitHubUser, t as pollAccessToken } from "./poll-access-token-DiwBJNtK.js";
1
+ import { _ as HTTPError, g as getCopilotUsage, h as getDeviceCode, k as state, m as getGitHubUser, t as pollAccessToken } from "./poll-access-token-Bc6VwWab.js";
2
2
  import { r as ensurePaths, t as PATHS } from "./paths-DGlr310R.js";
3
- import "./get-copilot-token-MAZsr5Vu.js";
3
+ import "./get-copilot-token-p17sJyPU.js";
4
4
  import { defineCommand } from "citty";
5
5
  import consola from "consola";
6
6
  import fs from "node:fs/promises";
@@ -79,4 +79,4 @@ const checkUsage = defineCommand({
79
79
 
80
80
  //#endregion
81
81
  export { checkUsage };
82
- //# sourceMappingURL=check-usage-bIbj_1Q_.js.map
82
+ //# sourceMappingURL=check-usage-CQxXYfUx.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"check-usage-bIbj_1Q_.js","names":[],"sources":["../src/lib/token.ts","../src/check-usage.ts"],"sourcesContent":["import consola from \"consola\"\nimport fs from \"node:fs/promises\"\nimport { setTimeout as delay } from \"node:timers/promises\"\n\nimport { isOpencodeOauthApp } from \"~/lib/api-config\"\nimport { PATHS } from \"~/lib/paths\"\nimport { getCopilotToken } from \"~/services/github/get-copilot-token\"\nimport { getCopilotUsage } from \"~/services/github/get-copilot-usage\"\nimport { getDeviceCode } from \"~/services/github/get-device-code\"\nimport { getGitHubUser } from \"~/services/github/get-user\"\nimport { pollAccessToken } from \"~/services/github/poll-access-token\"\n\nimport { HTTPError } from \"./error\"\nimport { state } from \"./state\"\n\nlet copilotRefreshLoopController: AbortController | null = null\n\nexport const stopCopilotRefreshLoop = () => {\n if (!copilotRefreshLoopController) {\n return\n }\n\n copilotRefreshLoopController.abort()\n copilotRefreshLoopController = null\n}\n\nconst readGithubToken = () => fs.readFile(PATHS.GITHUB_TOKEN_PATH, \"utf8\")\n\nconst writeGithubToken = (token: string) =>\n fs.writeFile(PATHS.GITHUB_TOKEN_PATH, token)\n\nexport const setupCopilotToken = async () => {\n if (isOpencodeOauthApp()) {\n if (!state.githubToken) throw new Error(`opencode token not found`)\n\n state.copilotToken = state.githubToken\n\n consola.debug(\"GitHub Copilot token set from opencode auth token\")\n if (state.showToken) {\n consola.info(\"Copilot token:\", state.copilotToken)\n }\n\n stopCopilotRefreshLoop()\n return\n }\n\n const { token, refresh_in } = await getCopilotToken()\n state.copilotToken = token\n\n // Display the Copilot token to the screen\n consola.debug(\"GitHub Copilot Token fetched successfully!\")\n if (state.showToken) {\n consola.info(\"Copilot token:\", token)\n }\n\n stopCopilotRefreshLoop()\n\n const controller = new AbortController()\n copilotRefreshLoopController = controller\n\n runCopilotRefreshLoop(refresh_in, controller.signal)\n .catch(() => {\n consola.warn(\"Copilot token refresh loop stopped\")\n })\n .finally(() => {\n if (copilotRefreshLoopController === controller) {\n copilotRefreshLoopController = null\n }\n })\n}\n\nconst REFRESH_POLL_INTERVAL_MS = 15_000\nconst EARLY_REFRESH_BUFFER_MS = 60_000\nconst RETRY_REFRESH_DELAY_MS = 15_000\nconst MIN_REFRESH_DELAY_MS = 1_000\n\nexport const getRefreshDeadlineMs = (\n refreshIn: number,\n nowMs: number = Date.now(),\n) =>\n nowMs\n + Math.max(refreshIn * 1000 - EARLY_REFRESH_BUFFER_MS, MIN_REFRESH_DELAY_MS)\n\n// Use short wall-clock chunks so the next wake after sleep notices elapsed time\n// quickly, without relying on the server's absolute expires_at matching local time.\nexport const getRefreshPollDelayMs = (\n refreshAtMs: number,\n nowMs: number = Date.now(),\n) => Math.min(Math.max(refreshAtMs - nowMs, 0), REFRESH_POLL_INTERVAL_MS)\n\nconst runCopilotRefreshLoop = async (\n refreshIn: number,\n signal: AbortSignal,\n) => {\n let refreshAtMs = getRefreshDeadlineMs(refreshIn)\n\n while (!signal.aborted) {\n const nextDelayMs = getRefreshPollDelayMs(refreshAtMs)\n if (nextDelayMs > 0) {\n await delay(nextDelayMs, undefined, { signal })\n continue\n }\n\n consola.debug(\"Refreshing Copilot token\")\n\n try {\n const { token, refresh_in } = await getCopilotToken()\n state.copilotToken = token\n refreshAtMs = getRefreshDeadlineMs(refresh_in)\n consola.debug(\"Copilot token refreshed\")\n if (state.showToken) {\n consola.info(\"Refreshed Copilot token:\", token)\n }\n } catch (error) {\n consola.error(\"Failed to refresh Copilot token:\", error)\n refreshAtMs = Date.now() + RETRY_REFRESH_DELAY_MS\n consola.warn(\n `Retrying Copilot token refresh in ${RETRY_REFRESH_DELAY_MS / 1000}s`,\n )\n }\n }\n}\n\ninterface SetupGitHubTokenOptions {\n force?: boolean\n}\n\nexport async function setupGitHubToken(\n options?: SetupGitHubTokenOptions,\n): Promise<void> {\n try {\n const githubToken = await readGithubToken()\n\n if (githubToken && !options?.force) {\n state.githubToken = githubToken\n if (state.showToken) {\n consola.info(\"GitHub token:\", githubToken)\n }\n await logUser()\n\n return\n }\n\n consola.info(\"Not logged in, getting new access token\")\n const response = await getDeviceCode()\n consola.debug(\"Device code response:\", response)\n\n consola.info(\n `Please enter the code \"${response.user_code}\" in ${response.verification_uri}`,\n )\n\n const token = await pollAccessToken(response)\n await writeGithubToken(token)\n state.githubToken = token\n\n if (state.showToken) {\n consola.info(\"GitHub token:\", token)\n }\n await logUser()\n } catch (error) {\n if (error instanceof HTTPError) {\n consola.error(\"Failed to get GitHub token:\", await error.response.json())\n throw error\n }\n\n consola.error(\"Failed to get GitHub token:\", error)\n throw error\n }\n}\n\nexport async function logUser() {\n const user = await getGitHubUser()\n consola.info(`Logged in as ${user.login}`)\n\n const copilotUser = await getCopilotUsage()\n state.copilotApiUrl = copilotUser.endpoints.api\n}\n","import { defineCommand } from \"citty\"\nimport consola from \"consola\"\n\nimport { ensurePaths } from \"./lib/paths\"\nimport { setupGitHubToken } from \"./lib/token\"\nimport {\n getCopilotUsage,\n type QuotaDetail,\n} from \"./services/github/get-copilot-usage\"\n\nexport const checkUsage = defineCommand({\n meta: {\n name: \"check-usage\",\n description: \"Show current GitHub Copilot usage/quota information\",\n },\n async run() {\n await ensurePaths()\n await setupGitHubToken()\n try {\n const usage = await getCopilotUsage()\n const premium = usage.quota_snapshots.premium_interactions\n const premiumTotal = premium.entitlement\n const premiumUsed = premiumTotal - premium.remaining\n const premiumPercentUsed =\n premiumTotal > 0 ? (premiumUsed / premiumTotal) * 100 : 0\n const premiumPercentRemaining = premium.percent_remaining\n\n // Helper to summarize a quota snapshot\n function summarizeQuota(name: string, snap: QuotaDetail | undefined) {\n if (!snap) return `${name}: N/A`\n const total = snap.entitlement\n const used = total - snap.remaining\n const percentUsed = total > 0 ? (used / total) * 100 : 0\n const percentRemaining = snap.percent_remaining\n return `${name}: ${used}/${total} used (${percentUsed.toFixed(1)}% used, ${percentRemaining.toFixed(1)}% remaining)`\n }\n\n const premiumLine = `Premium: ${premiumUsed}/${premiumTotal} used (${premiumPercentUsed.toFixed(1)}% used, ${premiumPercentRemaining.toFixed(1)}% remaining)`\n const chatLine = summarizeQuota(\"Chat\", usage.quota_snapshots.chat)\n const completionsLine = summarizeQuota(\n \"Completions\",\n usage.quota_snapshots.completions,\n )\n\n consola.box(\n `Copilot Usage (plan: ${usage.copilot_plan})\\n`\n + `Quota resets: ${usage.quota_reset_date}\\n`\n + `\\nQuotas:\\n`\n + ` ${premiumLine}\\n`\n + ` ${chatLine}\\n`\n + ` ${completionsLine}`,\n )\n } catch (err) {\n consola.error(\"Failed to fetch Copilot usage:\", err)\n process.exit(1)\n }\n },\n})\n"],"mappings":";;;;;;;;AA0BA,MAAM,wBAAwB,GAAG,SAAS,MAAM,mBAAmB,OAAO;AAE1E,MAAM,oBAAoB,UACxB,GAAG,UAAU,MAAM,mBAAmB,MAAM;AAkG9C,eAAsB,iBACpB,SACe;AACf,KAAI;EACF,MAAM,cAAc,MAAM,iBAAiB;AAE3C,MAAI,eAAe,CAAC,SAAS,OAAO;AAClC,SAAM,cAAc;AACpB,OAAI,MAAM,UACR,SAAQ,KAAK,iBAAiB,YAAY;AAE5C,SAAM,SAAS;AAEf;;AAGF,UAAQ,KAAK,0CAA0C;EACvD,MAAM,WAAW,MAAM,eAAe;AACtC,UAAQ,MAAM,yBAAyB,SAAS;AAEhD,UAAQ,KACN,0BAA0B,SAAS,UAAU,OAAO,SAAS,mBAC9D;EAED,MAAM,QAAQ,MAAM,gBAAgB,SAAS;AAC7C,QAAM,iBAAiB,MAAM;AAC7B,QAAM,cAAc;AAEpB,MAAI,MAAM,UACR,SAAQ,KAAK,iBAAiB,MAAM;AAEtC,QAAM,SAAS;UACR,OAAO;AACd,MAAI,iBAAiB,WAAW;AAC9B,WAAQ,MAAM,+BAA+B,MAAM,MAAM,SAAS,MAAM,CAAC;AACzE,SAAM;;AAGR,UAAQ,MAAM,+BAA+B,MAAM;AACnD,QAAM;;;AAIV,eAAsB,UAAU;CAC9B,MAAM,OAAO,MAAM,eAAe;AAClC,SAAQ,KAAK,gBAAgB,KAAK,QAAQ;AAG1C,OAAM,iBADc,MAAM,iBAAiB,EACT,UAAU;;;;;ACrK9C,MAAa,aAAa,cAAc;CACtC,MAAM;EACJ,MAAM;EACN,aAAa;EACd;CACD,MAAM,MAAM;AACV,QAAM,aAAa;AACnB,QAAM,kBAAkB;AACxB,MAAI;GACF,MAAM,QAAQ,MAAM,iBAAiB;GACrC,MAAM,UAAU,MAAM,gBAAgB;GACtC,MAAM,eAAe,QAAQ;GAC7B,MAAM,cAAc,eAAe,QAAQ;GAC3C,MAAM,qBACJ,eAAe,IAAK,cAAc,eAAgB,MAAM;GAC1D,MAAM,0BAA0B,QAAQ;GAGxC,SAAS,eAAe,MAAc,MAA+B;AACnE,QAAI,CAAC,KAAM,QAAO,GAAG,KAAK;IAC1B,MAAM,QAAQ,KAAK;IACnB,MAAM,OAAO,QAAQ,KAAK;IAC1B,MAAM,cAAc,QAAQ,IAAK,OAAO,QAAS,MAAM;IACvD,MAAM,mBAAmB,KAAK;AAC9B,WAAO,GAAG,KAAK,IAAI,KAAK,GAAG,MAAM,SAAS,YAAY,QAAQ,EAAE,CAAC,UAAU,iBAAiB,QAAQ,EAAE,CAAC;;GAGzG,MAAM,cAAc,YAAY,YAAY,GAAG,aAAa,SAAS,mBAAmB,QAAQ,EAAE,CAAC,UAAU,wBAAwB,QAAQ,EAAE,CAAC;GAChJ,MAAM,WAAW,eAAe,QAAQ,MAAM,gBAAgB,KAAK;GACnE,MAAM,kBAAkB,eACtB,eACA,MAAM,gBAAgB,YACvB;AAED,WAAQ,IACN,wBAAwB,MAAM,aAAa,mBACtB,MAAM,iBAAiB,iBAEnC,YAAY,MACZ,SAAS,MACT,kBACV;WACM,KAAK;AACZ,WAAQ,MAAM,kCAAkC,IAAI;AACpD,WAAQ,KAAK,EAAE;;;CAGpB,CAAC"}
1
+ {"version":3,"file":"check-usage-CQxXYfUx.js","names":[],"sources":["../src/lib/token.ts","../src/check-usage.ts"],"sourcesContent":["import consola from \"consola\"\nimport fs from \"node:fs/promises\"\nimport { setTimeout as delay } from \"node:timers/promises\"\n\nimport { isOpencodeOauthApp } from \"~/lib/api-config\"\nimport { PATHS } from \"~/lib/paths\"\nimport { getCopilotToken } from \"~/services/github/get-copilot-token\"\nimport { getCopilotUsage } from \"~/services/github/get-copilot-usage\"\nimport { getDeviceCode } from \"~/services/github/get-device-code\"\nimport { getGitHubUser } from \"~/services/github/get-user\"\nimport { pollAccessToken } from \"~/services/github/poll-access-token\"\n\nimport { HTTPError } from \"./error\"\nimport { state } from \"./state\"\n\nlet copilotRefreshLoopController: AbortController | null = null\n\nexport const stopCopilotRefreshLoop = () => {\n if (!copilotRefreshLoopController) {\n return\n }\n\n copilotRefreshLoopController.abort()\n copilotRefreshLoopController = null\n}\n\nconst readGithubToken = () => fs.readFile(PATHS.GITHUB_TOKEN_PATH, \"utf8\")\n\nconst writeGithubToken = (token: string) =>\n fs.writeFile(PATHS.GITHUB_TOKEN_PATH, token)\n\nexport const setupCopilotToken = async () => {\n if (isOpencodeOauthApp()) {\n if (!state.githubToken) throw new Error(`opencode token not found`)\n\n state.copilotToken = state.githubToken\n\n consola.debug(\"GitHub Copilot token set from opencode auth token\")\n if (state.showToken) {\n consola.info(\"Copilot token:\", state.copilotToken)\n }\n\n stopCopilotRefreshLoop()\n return\n }\n\n const { token, refresh_in } = await getCopilotToken()\n state.copilotToken = token\n\n // Display the Copilot token to the screen\n consola.debug(\"GitHub Copilot Token fetched successfully!\")\n if (state.showToken) {\n consola.info(\"Copilot token:\", token)\n }\n\n stopCopilotRefreshLoop()\n\n const controller = new AbortController()\n copilotRefreshLoopController = controller\n\n runCopilotRefreshLoop(refresh_in, controller.signal)\n .catch(() => {\n consola.warn(\"Copilot token refresh loop stopped\")\n })\n .finally(() => {\n if (copilotRefreshLoopController === controller) {\n copilotRefreshLoopController = null\n }\n })\n}\n\nconst REFRESH_POLL_INTERVAL_MS = 15_000\nconst EARLY_REFRESH_BUFFER_MS = 60_000\nconst RETRY_REFRESH_DELAY_MS = 15_000\nconst MIN_REFRESH_DELAY_MS = 1_000\n\nexport const getRefreshDeadlineMs = (\n refreshIn: number,\n nowMs: number = Date.now(),\n) =>\n nowMs\n + Math.max(refreshIn * 1000 - EARLY_REFRESH_BUFFER_MS, MIN_REFRESH_DELAY_MS)\n\n// Use short wall-clock chunks so the next wake after sleep notices elapsed time\n// quickly, without relying on the server's absolute expires_at matching local time.\nexport const getRefreshPollDelayMs = (\n refreshAtMs: number,\n nowMs: number = Date.now(),\n) => Math.min(Math.max(refreshAtMs - nowMs, 0), REFRESH_POLL_INTERVAL_MS)\n\nconst runCopilotRefreshLoop = async (\n refreshIn: number,\n signal: AbortSignal,\n) => {\n let refreshAtMs = getRefreshDeadlineMs(refreshIn)\n\n while (!signal.aborted) {\n const nextDelayMs = getRefreshPollDelayMs(refreshAtMs)\n if (nextDelayMs > 0) {\n await delay(nextDelayMs, undefined, { signal })\n continue\n }\n\n consola.debug(\"Refreshing Copilot token\")\n\n try {\n const { token, refresh_in } = await getCopilotToken()\n state.copilotToken = token\n refreshAtMs = getRefreshDeadlineMs(refresh_in)\n consola.debug(\"Copilot token refreshed\")\n if (state.showToken) {\n consola.info(\"Refreshed Copilot token:\", token)\n }\n } catch (error) {\n consola.error(\"Failed to refresh Copilot token:\", error)\n refreshAtMs = Date.now() + RETRY_REFRESH_DELAY_MS\n consola.warn(\n `Retrying Copilot token refresh in ${RETRY_REFRESH_DELAY_MS / 1000}s`,\n )\n }\n }\n}\n\ninterface SetupGitHubTokenOptions {\n force?: boolean\n}\n\nexport async function setupGitHubToken(\n options?: SetupGitHubTokenOptions,\n): Promise<void> {\n try {\n const githubToken = await readGithubToken()\n\n if (githubToken && !options?.force) {\n state.githubToken = githubToken\n if (state.showToken) {\n consola.info(\"GitHub token:\", githubToken)\n }\n await logUser()\n\n return\n }\n\n consola.info(\"Not logged in, getting new access token\")\n const response = await getDeviceCode()\n consola.debug(\"Device code response:\", response)\n\n consola.info(\n `Please enter the code \"${response.user_code}\" in ${response.verification_uri}`,\n )\n\n const token = await pollAccessToken(response)\n await writeGithubToken(token)\n state.githubToken = token\n\n if (state.showToken) {\n consola.info(\"GitHub token:\", token)\n }\n await logUser()\n } catch (error) {\n if (error instanceof HTTPError) {\n consola.error(\"Failed to get GitHub token:\", await error.response.json())\n throw error\n }\n\n consola.error(\"Failed to get GitHub token:\", error)\n throw error\n }\n}\n\nexport async function logUser() {\n const user = await getGitHubUser()\n consola.info(`Logged in as ${user.login}`)\n\n const copilotUser = await getCopilotUsage()\n state.copilotApiUrl = copilotUser.endpoints.api\n}\n","import { defineCommand } from \"citty\"\nimport consola from \"consola\"\n\nimport { ensurePaths } from \"./lib/paths\"\nimport { setupGitHubToken } from \"./lib/token\"\nimport {\n getCopilotUsage,\n type QuotaDetail,\n} from \"./services/github/get-copilot-usage\"\n\nexport const checkUsage = defineCommand({\n meta: {\n name: \"check-usage\",\n description: \"Show current GitHub Copilot usage/quota information\",\n },\n async run() {\n await ensurePaths()\n await setupGitHubToken()\n try {\n const usage = await getCopilotUsage()\n const premium = usage.quota_snapshots.premium_interactions\n const premiumTotal = premium.entitlement\n const premiumUsed = premiumTotal - premium.remaining\n const premiumPercentUsed =\n premiumTotal > 0 ? (premiumUsed / premiumTotal) * 100 : 0\n const premiumPercentRemaining = premium.percent_remaining\n\n // Helper to summarize a quota snapshot\n function summarizeQuota(name: string, snap: QuotaDetail | undefined) {\n if (!snap) return `${name}: N/A`\n const total = snap.entitlement\n const used = total - snap.remaining\n const percentUsed = total > 0 ? (used / total) * 100 : 0\n const percentRemaining = snap.percent_remaining\n return `${name}: ${used}/${total} used (${percentUsed.toFixed(1)}% used, ${percentRemaining.toFixed(1)}% remaining)`\n }\n\n const premiumLine = `Premium: ${premiumUsed}/${premiumTotal} used (${premiumPercentUsed.toFixed(1)}% used, ${premiumPercentRemaining.toFixed(1)}% remaining)`\n const chatLine = summarizeQuota(\"Chat\", usage.quota_snapshots.chat)\n const completionsLine = summarizeQuota(\n \"Completions\",\n usage.quota_snapshots.completions,\n )\n\n consola.box(\n `Copilot Usage (plan: ${usage.copilot_plan})\\n`\n + `Quota resets: ${usage.quota_reset_date}\\n`\n + `\\nQuotas:\\n`\n + ` ${premiumLine}\\n`\n + ` ${chatLine}\\n`\n + ` ${completionsLine}`,\n )\n } catch (err) {\n consola.error(\"Failed to fetch Copilot usage:\", err)\n process.exit(1)\n }\n },\n})\n"],"mappings":";;;;;;;;AA0BA,MAAM,wBAAwB,GAAG,SAAS,MAAM,mBAAmB,OAAO;AAE1E,MAAM,oBAAoB,UACxB,GAAG,UAAU,MAAM,mBAAmB,MAAM;AAkG9C,eAAsB,iBACpB,SACe;AACf,KAAI;EACF,MAAM,cAAc,MAAM,iBAAiB;AAE3C,MAAI,eAAe,CAAC,SAAS,OAAO;AAClC,SAAM,cAAc;AACpB,OAAI,MAAM,UACR,SAAQ,KAAK,iBAAiB,YAAY;AAE5C,SAAM,SAAS;AAEf;;AAGF,UAAQ,KAAK,0CAA0C;EACvD,MAAM,WAAW,MAAM,eAAe;AACtC,UAAQ,MAAM,yBAAyB,SAAS;AAEhD,UAAQ,KACN,0BAA0B,SAAS,UAAU,OAAO,SAAS,mBAC9D;EAED,MAAM,QAAQ,MAAM,gBAAgB,SAAS;AAC7C,QAAM,iBAAiB,MAAM;AAC7B,QAAM,cAAc;AAEpB,MAAI,MAAM,UACR,SAAQ,KAAK,iBAAiB,MAAM;AAEtC,QAAM,SAAS;UACR,OAAO;AACd,MAAI,iBAAiB,WAAW;AAC9B,WAAQ,MAAM,+BAA+B,MAAM,MAAM,SAAS,MAAM,CAAC;AACzE,SAAM;;AAGR,UAAQ,MAAM,+BAA+B,MAAM;AACnD,QAAM;;;AAIV,eAAsB,UAAU;CAC9B,MAAM,OAAO,MAAM,eAAe;AAClC,SAAQ,KAAK,gBAAgB,KAAK,QAAQ;AAG1C,OAAM,iBADc,MAAM,iBAAiB,EACT,UAAU;;;;;ACrK9C,MAAa,aAAa,cAAc;CACtC,MAAM;EACJ,MAAM;EACN,aAAa;EACd;CACD,MAAM,MAAM;AACV,QAAM,aAAa;AACnB,QAAM,kBAAkB;AACxB,MAAI;GACF,MAAM,QAAQ,MAAM,iBAAiB;GACrC,MAAM,UAAU,MAAM,gBAAgB;GACtC,MAAM,eAAe,QAAQ;GAC7B,MAAM,cAAc,eAAe,QAAQ;GAC3C,MAAM,qBACJ,eAAe,IAAK,cAAc,eAAgB,MAAM;GAC1D,MAAM,0BAA0B,QAAQ;GAGxC,SAAS,eAAe,MAAc,MAA+B;AACnE,QAAI,CAAC,KAAM,QAAO,GAAG,KAAK;IAC1B,MAAM,QAAQ,KAAK;IACnB,MAAM,OAAO,QAAQ,KAAK;IAC1B,MAAM,cAAc,QAAQ,IAAK,OAAO,QAAS,MAAM;IACvD,MAAM,mBAAmB,KAAK;AAC9B,WAAO,GAAG,KAAK,IAAI,KAAK,GAAG,MAAM,SAAS,YAAY,QAAQ,EAAE,CAAC,UAAU,iBAAiB,QAAQ,EAAE,CAAC;;GAGzG,MAAM,cAAc,YAAY,YAAY,GAAG,aAAa,SAAS,mBAAmB,QAAQ,EAAE,CAAC,UAAU,wBAAwB,QAAQ,EAAE,CAAC;GAChJ,MAAM,WAAW,eAAe,QAAQ,MAAM,gBAAgB,KAAK;GACnE,MAAM,kBAAkB,eACtB,eACA,MAAM,gBAAgB,YACvB;AAED,WAAQ,IACN,wBAAwB,MAAM,aAAa,mBACtB,MAAM,iBAAiB,iBAEnC,YAAY,MACZ,SAAS,MACT,kBACV;WACM,KAAK;AACZ,WAAQ,MAAM,kCAAkC,IAAI;AACpD,WAAQ,KAAK,EAAE;;;CAGpB,CAAC"}
@@ -1,4 +1,4 @@
1
- import { C as githubHeaders, O as accountFromState, S as getGitHubApiBaseUrl, _ as HTTPError } from "./poll-access-token-DiwBJNtK.js";
1
+ import { C as githubHeaders, O as accountFromState, S as getGitHubApiBaseUrl, _ as HTTPError } from "./poll-access-token-Bc6VwWab.js";
2
2
 
3
3
  //#region src/services/github/get-copilot-token.ts
4
4
  const getCopilotToken = async (account) => {
@@ -10,4 +10,4 @@ const getCopilotToken = async (account) => {
10
10
 
11
11
  //#endregion
12
12
  export { getCopilotToken as t };
13
- //# sourceMappingURL=get-copilot-token-MAZsr5Vu.js.map
13
+ //# sourceMappingURL=get-copilot-token-p17sJyPU.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"get-copilot-token-MAZsr5Vu.js","names":[],"sources":["../src/services/github/get-copilot-token.ts"],"sourcesContent":["import type { AccountContext } from \"~/lib/types/account\"\n\nimport { getGitHubApiBaseUrl, githubHeaders } from \"~/lib/api-config\"\nimport { HTTPError } from \"~/lib/error\"\nimport { accountFromState } from \"~/lib/state\"\n\nexport const getCopilotToken = async (account?: AccountContext) => {\n const ctx = account ?? accountFromState()\n const response = await fetch(\n `${getGitHubApiBaseUrl()}/copilot_internal/v2/token`,\n {\n headers: githubHeaders(ctx),\n },\n )\n\n if (!response.ok) throw new HTTPError(\"Failed to get Copilot token\", response)\n\n return (await response.json()) as GetCopilotTokenResponse\n}\n\n// Trimmed for the sake of simplicity\nexport interface GetCopilotTokenResponse {\n expires_at: number\n refresh_in: number\n token: string\n}\n"],"mappings":";;;AAMA,MAAa,kBAAkB,OAAO,YAA6B;CACjE,MAAM,MAAM,WAAW,kBAAkB;CACzC,MAAM,WAAW,MAAM,MACrB,GAAG,qBAAqB,CAAC,6BACzB,EACE,SAAS,cAAc,IAAI,EAC5B,CACF;AAED,KAAI,CAAC,SAAS,GAAI,OAAM,IAAI,UAAU,+BAA+B,SAAS;AAE9E,QAAQ,MAAM,SAAS,MAAM"}
1
+ {"version":3,"file":"get-copilot-token-p17sJyPU.js","names":[],"sources":["../src/services/github/get-copilot-token.ts"],"sourcesContent":["import type { AccountContext } from \"~/lib/types/account\"\n\nimport { getGitHubApiBaseUrl, githubHeaders } from \"~/lib/api-config\"\nimport { HTTPError } from \"~/lib/error\"\nimport { accountFromState } from \"~/lib/state\"\n\nexport const getCopilotToken = async (account?: AccountContext) => {\n const ctx = account ?? accountFromState()\n const response = await fetch(\n `${getGitHubApiBaseUrl()}/copilot_internal/v2/token`,\n {\n headers: githubHeaders(ctx),\n },\n )\n\n if (!response.ok) throw new HTTPError(\"Failed to get Copilot token\", response)\n\n return (await response.json()) as GetCopilotTokenResponse\n}\n\n// Trimmed for the sake of simplicity\nexport interface GetCopilotTokenResponse {\n expires_at: number\n refresh_in: number\n token: string\n}\n"],"mappings":";;;AAMA,MAAa,kBAAkB,OAAO,YAA6B;CACjE,MAAM,MAAM,WAAW,kBAAkB;CACzC,MAAM,WAAW,MAAM,MACrB,GAAG,qBAAqB,CAAC,6BACzB,EACE,SAAS,cAAc,IAAI,EAC5B,CACF;AAED,KAAI,CAAC,SAAS,GAAI,OAAM,IAAI,UAAU,+BAA+B,SAAS;AAE9E,QAAQ,MAAM,SAAS,MAAM"}
package/dist/main.js CHANGED
@@ -20,10 +20,10 @@ const args = parseArgs(process.argv, cliArgs);
20
20
  if (typeof args["api-home"] === "string") process.env.COPILOT_API_HOME = args["api-home"];
21
21
  if (typeof args["oauth-app"] === "string") process.env.COPILOT_API_OAUTH_APP = args["oauth-app"];
22
22
  if (typeof args["enterprise-url"] === "string") process.env.COPILOT_API_ENTERPRISE_URL = args["enterprise-url"];
23
- const { auth } = await import("./auth-Ckj1wD43.js");
24
- const { checkUsage } = await import("./check-usage-bIbj_1Q_.js");
23
+ const { auth } = await import("./auth-BXCeDjRG.js");
24
+ const { checkUsage } = await import("./check-usage-CQxXYfUx.js");
25
25
  const { debug } = await import("./debug-BJfZVBB7.js");
26
- const { start } = await import("./start-8dkfsQqd.js");
26
+ const { start } = await import("./start-eFWi3mS4.js");
27
27
  await runMain(defineCommand({
28
28
  meta: {
29
29
  name: "copilot-api",
@@ -52,6 +52,45 @@ const requestContext = {
52
52
  function generateTraceId() {
53
53
  return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
54
54
  }
55
+ function buildOutboundHeadersSnapshot(headers) {
56
+ const snapshot = {
57
+ xRequestId: void 0,
58
+ xAgentTaskId: void 0,
59
+ xInteractionType: void 0,
60
+ openaiIntent: void 0,
61
+ userAgent: void 0
62
+ };
63
+ for (const [name, value] of Object.entries(headers)) switch (name.toLowerCase()) {
64
+ case "x-request-id":
65
+ snapshot.xRequestId = value;
66
+ break;
67
+ case "x-agent-task-id":
68
+ snapshot.xAgentTaskId = value;
69
+ break;
70
+ case "x-interaction-type":
71
+ snapshot.xInteractionType = value;
72
+ break;
73
+ case "openai-intent":
74
+ snapshot.openaiIntent = value;
75
+ break;
76
+ case "user-agent":
77
+ snapshot.userAgent = value;
78
+ break;
79
+ default: break;
80
+ }
81
+ return snapshot;
82
+ }
83
+ function captureOutboundHeadersSnapshot(headers) {
84
+ const store = asyncLocalStorage.getStore();
85
+ if (!store) return;
86
+ store.outboundHeaders = buildOutboundHeadersSnapshot(headers);
87
+ }
88
+ function consumeOutboundHeadersSnapshot() {
89
+ const store = asyncLocalStorage.getStore();
90
+ const snapshot = store?.outboundHeaders;
91
+ if (store) store.outboundHeaders = void 0;
92
+ return snapshot;
93
+ }
55
94
  function resolveTraceId(traceId) {
56
95
  const candidate = traceId?.trim();
57
96
  if (!candidate || candidate.length > TRACE_ID_MAX_LENGTH || !TRACE_ID_PATTERN.test(candidate)) return generateTraceId();
@@ -147,8 +186,8 @@ const getOauthAppConfig = () => {
147
186
  scope: GITHUB_APP_SCOPES
148
187
  };
149
188
  };
150
- const prepareForCompact = (headers, isCompact) => {
151
- if (isCompact) headers["x-initiator"] = "agent";
189
+ const prepareForCompact = (headers, compactType) => {
190
+ if (compactType) headers["x-initiator"] = "agent";
152
191
  };
153
192
  const prepareInteractionHeaders = (sessionId, isSubagent, headers) => {
154
193
  const sendInteractionHeaders = !isOpencodeOauthApp();
@@ -169,10 +208,10 @@ const getOpencodeVersion = () => {
169
208
  };
170
209
  const OPENCODE_VERSION = "opencode/1.3.15";
171
210
  const OPENCODE_LLM_USER_AGENT = "opencode/1.3.15 ai-sdk/provider-utils/4.0.21 runtime/bun/1.3.11, opencode/1.3.15";
172
- const COPILOT_VERSION = "0.42.3";
211
+ const COPILOT_VERSION = "0.44.0";
173
212
  const EDITOR_PLUGIN_VERSION = `copilot-chat/${COPILOT_VERSION}`;
174
213
  const USER_AGENT = `GitHubCopilotChat/${COPILOT_VERSION}`;
175
- const CLAUDE_AGENT_USER_AGENT = "vscode_claude_code/2.1.81 (external, sdk-ts, agent-sdk/0.2.81)";
214
+ const CLAUDE_AGENT_USER_AGENT = "vscode_claude_code/2.1.98 (external, sdk-ts, agent-sdk/0.2.98)";
176
215
  const API_VERSION = "2025-10-01";
177
216
  const copilotBaseUrl = (account) => {
178
217
  const enterpriseDomain = getEnterpriseDomain();
@@ -189,6 +228,7 @@ const prepareMessageProxyHeaders = (headers) => {
189
228
  headers["x-interaction-type"] = "messages-proxy";
190
229
  headers["openai-intent"] = "messages-proxy";
191
230
  headers["user-agent"] = CLAUDE_AGENT_USER_AGENT;
231
+ delete headers["copilot-integration-id"];
192
232
  };
193
233
  const githubUserHeaders = (account) => {
194
234
  if (isOpencodeOauthApp()) return {
@@ -230,9 +270,9 @@ const copilotHeaders = (account, vision = false, requestId) => {
230
270
  if (vision) headers["Copilot-Vision-Request"] = "true";
231
271
  return headers;
232
272
  }
233
- return githubCopilotHeaders(account, requestId, vision);
273
+ return githubCopilotHeaders(account, vision, requestId);
234
274
  };
235
- const githubCopilotHeaders = (account, requestId, vision = false) => {
275
+ const githubCopilotHeaders = (account, vision = false, requestId) => {
236
276
  const resolvedRequestId = requestId ?? randomUUID();
237
277
  const resolvedDeviceId = account.clientDeviceId ?? state.vsCodeDeviceId;
238
278
  const resolvedMachineId = account.clientMachineId ?? state.macMachineId;
@@ -370,7 +410,7 @@ async function getGitHubUser(account) {
370
410
 
371
411
  //#endregion
372
412
  //#region src/services/get-vscode-version.ts
373
- const FALLBACK = "1.114.0";
413
+ const FALLBACK = "1.116.0";
374
414
  async function getVSCodeVersion() {
375
415
  await Promise.resolve();
376
416
  return FALLBACK;
@@ -717,5 +757,5 @@ async function pollAccessToken(deviceCode, options) {
717
757
  }
718
758
 
719
759
  //#endregion
720
- export { requestContext as A, githubHeaders as C, prepareMessageProxyHeaders as D, prepareInteractionHeaders as E, initOpencodeVersion as M, accountFromState as O, getGitHubApiBaseUrl as S, prepareForCompact as T, HTTPError as _, cacheVsCodeSessionId as a, copilotHeaders as b, getUUID as c, parseUserIdMetadata as d, resolveAffinityKey as f, getCopilotUsage as g, getDeviceCode as h, cacheVsCodeDeviceId as i, resolveTraceId as j, state as k, isNullish as l, getGitHubUser as m, cacheMacMachineId as n, generateRequestIdFromPayload as o, sleep as p, cacheVSCodeVersion as r, getRootSessionId as s, pollAccessToken as t, normalizeStableSessionId as u, forwardError as v, normalizeDomain as w, copilotModelsHeaders as x, copilotBaseUrl as y };
721
- //# sourceMappingURL=poll-access-token-DiwBJNtK.js.map
760
+ export { captureOutboundHeadersSnapshot as A, githubHeaders as C, prepareMessageProxyHeaders as D, prepareInteractionHeaders as E, requestContext as M, resolveTraceId as N, accountFromState as O, initOpencodeVersion as P, getGitHubApiBaseUrl as S, prepareForCompact as T, HTTPError as _, cacheVsCodeSessionId as a, copilotHeaders as b, getUUID as c, parseUserIdMetadata as d, resolveAffinityKey as f, getCopilotUsage as g, getDeviceCode as h, cacheVsCodeDeviceId as i, consumeOutboundHeadersSnapshot as j, state as k, isNullish as l, getGitHubUser as m, cacheMacMachineId as n, generateRequestIdFromPayload as o, sleep as p, cacheVSCodeVersion as r, getRootSessionId as s, pollAccessToken as t, normalizeStableSessionId as u, forwardError as v, normalizeDomain as w, copilotModelsHeaders as x, copilotBaseUrl as y };
761
+ //# sourceMappingURL=poll-access-token-Bc6VwWab.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"poll-access-token-Bc6VwWab.js","names":["opencodeVersionCache: string | undefined","snapshot: OutboundHeadersSnapshot","state: State","headers: Record<string, string>","errorJson: unknown","folder: string","readFile","deviceId: string | undefined","vsCodeSessionRefreshTimer: ReturnType<typeof setTimeout> | null","parsed: unknown"],"sources":["../src/lib/opencode.ts","../src/lib/request-context.ts","../src/lib/state.ts","../src/lib/api-config.ts","../src/lib/error.ts","../src/services/github/get-copilot-usage.ts","../src/services/github/get-device-code.ts","../src/services/github/get-user.ts","../src/services/get-vscode-version.ts","../src/lib/deviceid.ts","../src/lib/utils.ts","../src/services/github/poll-access-token.ts"],"sourcesContent":["import consola from \"consola\"\nimport { exec } from \"node:child_process\"\nimport { readFile } from \"node:fs/promises\"\nimport path from \"node:path\"\n\nconst execAsync = (command: string): Promise<string> => {\n return new Promise((resolve, reject) => {\n exec(command, (error, stdout) => {\n if (error) {\n reject(error)\n return\n }\n\n resolve(stdout)\n })\n })\n}\n\nlet opencodeVersionCache: string | undefined\n\nconst getGlobalNpmRoot = async (): Promise<string> => {\n const stdout = await execAsync(\"npm root -g\")\n return stdout.trim()\n}\n\nasync function resolveOpencodeVersion(): Promise<void> {\n try {\n const npmRootPath = await getGlobalNpmRoot()\n const opencodePackagePath = path.join(\n npmRootPath,\n \"opencode-ai\",\n \"package.json\",\n )\n const packageJson = await readFile(opencodePackagePath, \"utf8\")\n const { version } = JSON.parse(packageJson) as { version: string }\n opencodeVersionCache = version\n } catch (error) {\n consola.warn(`Failed to resolve opencode version`, error)\n }\n}\n\nexport const initOpencodeVersion = (): Promise<void> => {\n if (process.env.COPILOT_API_OAUTH_APP?.trim() !== \"opencode\") {\n return Promise.resolve()\n }\n return resolveOpencodeVersion()\n}\n\nexport const getCachedOpencodeVersion = (): string | undefined => {\n return opencodeVersionCache\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\"\n\nexport interface OutboundHeadersSnapshot {\n xRequestId?: string\n xAgentTaskId?: string\n xInteractionType?: string\n openaiIntent?: string\n userAgent?: string\n}\n\nexport interface RequestContext {\n traceId: string\n startTime: number\n userAgent: string\n sessionAffinity: string | undefined\n parentSessionId: string | undefined\n outboundHeaders?: OutboundHeadersSnapshot\n}\n\nconst TRACE_ID_MAX_LENGTH = 64\nconst TRACE_ID_PATTERN = /^\\w[\\w.-]*$/\n\nconst asyncLocalStorage = new AsyncLocalStorage<RequestContext>()\n\nexport const requestContext = {\n getStore: () => asyncLocalStorage.getStore(),\n run: <T>(context: RequestContext, callback: () => T) =>\n asyncLocalStorage.run(context, callback),\n}\n\nexport function generateTraceId(): string {\n const timestamp = Date.now().toString(36)\n const random = Math.random().toString(36).slice(2, 8)\n return `${timestamp}-${random}`\n}\n\nfunction buildOutboundHeadersSnapshot(\n headers: Record<string, string>,\n): OutboundHeadersSnapshot {\n const snapshot: OutboundHeadersSnapshot = {\n xRequestId: undefined,\n xAgentTaskId: undefined,\n xInteractionType: undefined,\n openaiIntent: undefined,\n userAgent: undefined,\n }\n\n for (const [name, value] of Object.entries(headers)) {\n switch (name.toLowerCase()) {\n case \"x-request-id\": {\n snapshot.xRequestId = value\n break\n }\n case \"x-agent-task-id\": {\n snapshot.xAgentTaskId = value\n break\n }\n case \"x-interaction-type\": {\n snapshot.xInteractionType = value\n break\n }\n case \"openai-intent\": {\n snapshot.openaiIntent = value\n break\n }\n case \"user-agent\": {\n snapshot.userAgent = value\n break\n }\n default: {\n break\n }\n }\n }\n\n return snapshot\n}\n\nexport function captureOutboundHeadersSnapshot(\n headers: Record<string, string>,\n): void {\n const store = asyncLocalStorage.getStore()\n if (!store) return\n\n store.outboundHeaders = buildOutboundHeadersSnapshot(headers)\n}\n\nexport function getOutboundHeadersSnapshot():\n | OutboundHeadersSnapshot\n | undefined {\n return asyncLocalStorage.getStore()?.outboundHeaders\n}\n\nexport function consumeOutboundHeadersSnapshot():\n | OutboundHeadersSnapshot\n | undefined {\n const store = asyncLocalStorage.getStore()\n const snapshot = store?.outboundHeaders\n\n if (store) {\n store.outboundHeaders = undefined\n }\n\n return snapshot\n}\n\nexport function resolveTraceId(traceId: string | null | undefined): string {\n const candidate = traceId?.trim()\n\n if (\n !candidate\n || candidate.length > TRACE_ID_MAX_LENGTH\n || !TRACE_ID_PATTERN.test(candidate)\n ) {\n return generateTraceId()\n }\n\n return candidate\n}\n","import { randomUUID } from \"node:crypto\"\n\nimport type { AccountContext, AccountType } from \"./types/account\"\n\nexport interface State {\n githubToken?: string\n copilotToken?: string\n\n accountType: AccountType\n vsCodeVersion?: string\n\n macMachineId?: string\n vsCodeSessionId?: string\n vsCodeDeviceId: string\n\n manualApprove: boolean\n rateLimitWait: boolean\n showToken: boolean\n\n // Rate limiting configuration\n rateLimitSeconds?: number\n lastRequestTimestamp?: number\n verbose: boolean\n\n copilotApiUrl?: string\n}\n\nexport const state: State = {\n accountType: \"individual\",\n manualApprove: false,\n rateLimitWait: false,\n showToken: false,\n verbose: false,\n vsCodeDeviceId: randomUUID(),\n}\n\n/**\n * Create an AccountContext from the current global state.\n * This is a compatibility layer for transitioning to multi-account support.\n * @throws Error if githubToken is not set in state\n */\nexport function accountFromState(): AccountContext {\n if (!state.githubToken) {\n throw new Error(\"GitHub token not set in state\")\n }\n return {\n githubToken: state.githubToken,\n copilotToken: state.copilotToken,\n ...(state.copilotApiUrl !== undefined ?\n { copilotApiUrl: state.copilotApiUrl }\n : {}),\n accountType: state.accountType,\n vsCodeVersion: state.vsCodeVersion,\n clientDeviceId: state.vsCodeDeviceId,\n clientMachineId: state.macMachineId,\n clientSessionId: state.vsCodeSessionId,\n }\n}\n","import { randomUUID } from \"node:crypto\"\n\nimport type { CompactType } from \"./compact\"\nimport type { AccountContext } from \"./types/account\"\n\nimport { getCachedOpencodeVersion } from \"./opencode\"\nimport { requestContext } from \"./request-context\"\nimport { state } from \"./state\"\n\nexport const isOpencodeOauthApp = (): boolean => {\n return process.env.COPILOT_API_OAUTH_APP?.trim() === \"opencode\"\n}\n\nexport const normalizeDomain = (input: string): string => {\n return input\n .trim()\n .replace(/^https?:\\/\\//u, \"\")\n .replace(/\\/+$/u, \"\")\n}\n\nexport const getEnterpriseDomain = (): string | null => {\n const raw = (process.env.COPILOT_API_ENTERPRISE_URL ?? \"\").trim()\n if (!raw) return null\n const normalized = normalizeDomain(raw)\n return normalized || null\n}\n\nexport const getGitHubBaseUrl = (): string => {\n const resolvedDomain = getEnterpriseDomain()\n return resolvedDomain ? `https://${resolvedDomain}` : GITHUB_BASE_URL\n}\n\nexport const getGitHubApiBaseUrl = (): string => {\n const resolvedDomain = getEnterpriseDomain()\n return resolvedDomain ? `https://api.${resolvedDomain}` : GITHUB_API_BASE_URL\n}\n\nconst getOpencodeOauthHeaders = (): Record<string, string> => {\n return {\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\",\n \"User-Agent\": getOpencodeVersion(),\n }\n}\n\nconst getOpencodeLLMHeaders = (): Record<string, string> => {\n return {\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\",\n \"User-Agent\": OPENCODE_LLM_USER_AGENT,\n }\n}\n\nconst normalizeOpencodeUserAgent = (userAgent: string): string => {\n const candidate = userAgent.trim()\n const opencodeProduct = candidate.match(/^opencode\\/[^\\s,]+/u)?.[0]\n\n if (!opencodeProduct || candidate.includes(`, ${opencodeProduct}`)) {\n return candidate\n }\n\n return `${candidate}, ${opencodeProduct}`\n}\n\nexport const getOauthUrls = (): {\n deviceCodeUrl: string\n accessTokenUrl: string\n} => {\n const githubBaseUrl = getGitHubBaseUrl()\n\n return {\n deviceCodeUrl: `${githubBaseUrl}/login/device/code`,\n accessTokenUrl: `${githubBaseUrl}/login/oauth/access_token`,\n }\n}\n\ninterface OauthAppConfig {\n clientId: string\n headers: Record<string, string>\n scope: string\n}\n\nexport const getOauthAppConfig = (): OauthAppConfig => {\n if (isOpencodeOauthApp()) {\n return {\n clientId: OPENCODE_GITHUB_CLIENT_ID,\n headers: getOpencodeOauthHeaders(),\n scope: GITHUB_APP_SCOPES,\n }\n }\n\n return {\n clientId: GITHUB_CLIENT_ID,\n headers: standardHeaders(),\n scope: GITHUB_APP_SCOPES,\n }\n}\n\nexport const prepareForCompact = (\n headers: Record<string, string>,\n compactType?: CompactType,\n) => {\n if (compactType) {\n headers[\"x-initiator\"] = \"agent\"\n }\n}\n\nexport const prepareInteractionHeaders = (\n sessionId: string | undefined,\n isSubagent: boolean,\n headers: Record<string, string>,\n) => {\n const sendInteractionHeaders = !isOpencodeOauthApp()\n\n if (isSubagent) {\n headers[\"x-initiator\"] = \"agent\"\n if (sendInteractionHeaders) {\n headers[\"x-interaction-type\"] = \"conversation-subagent\"\n }\n }\n\n if (sessionId && sendInteractionHeaders) {\n headers[\"x-interaction-id\"] = sessionId\n }\n}\n\nexport const standardHeaders = () => ({\n \"content-type\": \"application/json\",\n accept: \"application/json\",\n})\n\nexport const getOpencodeVersion = () => {\n const version = getCachedOpencodeVersion()\n if (version) {\n return \"opencode/\" + version\n }\n return OPENCODE_VERSION\n}\n\nconst OPENCODE_VERSION = \"opencode/1.3.15\"\nconst OPENCODE_LLM_USER_AGENT =\n \"opencode/1.3.15 ai-sdk/provider-utils/4.0.21 runtime/bun/1.3.11, opencode/1.3.15\"\n\nconst COPILOT_VERSION = \"0.44.0\"\nconst EDITOR_PLUGIN_VERSION = `copilot-chat/${COPILOT_VERSION}`\nconst USER_AGENT = `GitHubCopilotChat/${COPILOT_VERSION}`\nconst CLAUDE_AGENT_USER_AGENT =\n \"vscode_claude_code/2.1.98 (external, sdk-ts, agent-sdk/0.2.98)\"\n\nconst API_VERSION = \"2025-10-01\"\n\nexport const copilotBaseUrl = (account: AccountContext): string => {\n const enterpriseDomain = getEnterpriseDomain()\n if (enterpriseDomain) {\n return `https://copilot-api.${enterpriseDomain}`\n }\n\n if (isOpencodeOauthApp()) {\n return \"https://api.githubcopilot.com\"\n }\n\n if (account.copilotApiUrl) {\n return account.copilotApiUrl\n }\n\n return account.accountType === \"individual\" ?\n \"https://api.githubcopilot.com\"\n : `https://api.${account.accountType}.githubcopilot.com`\n}\n\nexport const prepareMessageProxyHeaders = (headers: Record<string, string>) => {\n if (isOpencodeOauthApp()) {\n return\n }\n\n // vscode copilot claude agent regenerates request id for\n // each request, keeping it consistent\n const requestIdValue = randomUUID()\n headers[\"x-agent-task-id\"] = requestIdValue\n headers[\"x-request-id\"] = requestIdValue\n\n // Consistent with vscode copilot claude agent\n headers[\"x-interaction-type\"] = \"messages-proxy\"\n headers[\"openai-intent\"] = \"messages-proxy\"\n headers[\"user-agent\"] = CLAUDE_AGENT_USER_AGENT\n\n delete headers[\"copilot-integration-id\"]\n}\n\nexport const githubUserHeaders = (\n account: AccountContext,\n): Record<string, string> => {\n if (isOpencodeOauthApp()) {\n return {\n Authorization: `Bearer ${account.githubToken}`,\n \"User-Agent\": getOpencodeVersion(),\n }\n }\n\n return {\n accept: \"application/vnd.github+json\",\n authorization: `token ${account.githubToken}`,\n \"user-agent\": USER_AGENT,\n \"x-github-api-version\": \"2022-11-28\",\n \"x-vscode-user-agent-library-version\": \"electron-fetch\",\n }\n}\n\nexport const copilotModelsHeaders = (\n account: AccountContext,\n): Record<string, string> => {\n if (isOpencodeOauthApp()) {\n const token = account.copilotToken ?? account.githubToken\n return {\n Authorization: `Bearer ${token}`,\n \"User-Agent\": getOpencodeVersion(),\n }\n }\n const headers = githubCopilotHeaders(account)\n headers[\"x-interaction-type\"] = \"model-access\"\n headers[\"openai-intent\"] = \"model-access\"\n delete headers[\"x-interaction-id\"]\n delete headers[\"content-type\"]\n return headers\n}\n\nexport const copilotHeaders = (\n account: AccountContext,\n vision: boolean = false,\n requestId?: string,\n): Record<string, string> => {\n if (isOpencodeOauthApp()) {\n const token = account.copilotToken ?? account.githubToken\n const headers: Record<string, string> = {\n Authorization: `Bearer ${token}`,\n ...getOpencodeLLMHeaders(),\n \"Openai-Intent\": \"conversation-edits\",\n }\n\n const store = requestContext.getStore()\n const userAgent = store?.userAgent.trim()\n // Real opencode traffic already carries a versioned opencode/* UA,\n // so prefer the inbound header to keep upstream behavior aligned.\n if (userAgent?.startsWith(\"opencode/\")) {\n headers[\"User-Agent\"] = normalizeOpencodeUserAgent(userAgent)\n }\n\n if (store?.sessionAffinity) {\n headers[\"x-session-affinity\"] = store.sessionAffinity\n }\n\n if (store?.parentSessionId) {\n headers[\"x-parent-session-id\"] = store.parentSessionId\n }\n\n if (vision) headers[\"Copilot-Vision-Request\"] = \"true\"\n\n return headers\n }\n\n return githubCopilotHeaders(account, vision, requestId)\n}\n\nconst githubCopilotHeaders = (\n account: AccountContext,\n vision: boolean = false,\n requestId?: string,\n): Record<string, string> => {\n const resolvedRequestId = requestId ?? randomUUID()\n const resolvedDeviceId = account.clientDeviceId ?? state.vsCodeDeviceId\n const resolvedMachineId = account.clientMachineId ?? state.macMachineId\n const resolvedSessionId = account.clientSessionId ?? state.vsCodeSessionId\n const headers: Record<string, string> = {\n Authorization: `Bearer ${account.copilotToken}`,\n \"content-type\": standardHeaders()[\"content-type\"],\n \"copilot-integration-id\": \"vscode-chat\",\n \"editor-version\": `vscode/${account.vsCodeVersion}`,\n \"editor-device-id\": resolvedDeviceId,\n \"editor-plugin-version\": EDITOR_PLUGIN_VERSION,\n \"user-agent\": USER_AGENT,\n \"openai-intent\": \"conversation-agent\",\n \"x-github-api-version\": API_VERSION,\n \"x-request-id\": resolvedRequestId,\n \"x-vscode-user-agent-library-version\": \"electron-fetch\",\n \"x-agent-task-id\": resolvedRequestId,\n \"x-interaction-type\": \"conversation-agent\",\n }\n\n if (vision) headers[\"copilot-vision-request\"] = \"true\"\n\n if (resolvedMachineId) {\n headers[\"vscode-machineid\"] = resolvedMachineId\n }\n\n if (resolvedSessionId) {\n headers[\"vscode-sessionid\"] = resolvedSessionId\n }\n\n return headers\n}\n\nexport const GITHUB_API_BASE_URL = \"https://api.github.com\"\nexport const githubHeaders = (\n account: AccountContext,\n): Record<string, string> => {\n if (isOpencodeOauthApp()) {\n return {\n Authorization: `Bearer ${account.githubToken}`,\n ...getOpencodeOauthHeaders(),\n }\n }\n\n return {\n authorization: `token ${account.githubToken}`,\n \"user-agent\": USER_AGENT,\n \"x-github-api-version\": API_VERSION,\n \"x-vscode-user-agent-library-version\": \"electron-fetch\",\n }\n}\n\nexport const GITHUB_BASE_URL = \"https://github.com\"\nexport const GITHUB_CLIENT_ID = \"Iv1.b507a08c87ecfe98\"\nexport const GITHUB_APP_SCOPES = [\"read:user\"].join(\" \")\nexport const OPENCODE_GITHUB_CLIENT_ID = \"Ov23li8tweQw6odWQebz\"\n","import type { Context } from \"hono\"\nimport type { ContentfulStatusCode } from \"hono/utils/http-status\"\n\nimport consola from \"consola\"\n\nexport class HTTPError extends Error {\n response: Response\n\n constructor(message: string, response: Response) {\n super(message)\n this.response = response\n }\n}\n\nexport class CancelledError extends Error {}\n\nfunction getFallbackHttpErrorMessage(error: HTTPError): string {\n return error.message || `HTTP ${error.response.status}`\n}\n\nasync function readHttpErrorText(error: HTTPError): Promise<string> {\n try {\n const text = await error.response.text()\n return text || getFallbackHttpErrorMessage(error)\n } catch (readError) {\n consola.warn(\"Failed to read HTTP error response body:\", readError)\n return getFallbackHttpErrorMessage(error)\n }\n}\n\nfunction getErrorMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message || \"Unknown error\"\n }\n\n if (typeof error === \"string\") {\n return error\n }\n\n if (\n typeof error === \"number\"\n || typeof error === \"boolean\"\n || typeof error === \"bigint\"\n ) {\n return `${error}`\n }\n\n return \"Unknown error\"\n}\n\nexport async function forwardError(c: Context, error: unknown) {\n consola.error(\"Error occurred:\", error)\n\n if (error instanceof HTTPError) {\n if (error.response.status === 429) {\n for (const [name, value] of error.response.headers) {\n const lowerName = name.toLowerCase()\n if (lowerName === \"retry-after\" || lowerName.startsWith(\"x-\")) {\n c.header(name, value)\n }\n }\n }\n\n const errorText = await readHttpErrorText(error)\n let errorJson: unknown\n try {\n errorJson = JSON.parse(errorText)\n } catch {\n errorJson = errorText\n }\n consola.error(\"HTTP error:\", errorJson)\n return c.json(\n {\n error: {\n message: errorText,\n type: \"error\",\n },\n },\n error.response.status as ContentfulStatusCode,\n )\n }\n\n return c.json(\n {\n error: {\n message: getErrorMessage(error),\n type: \"error\",\n },\n },\n 500,\n )\n}\n","import type { AccountContext } from \"~/lib/types/account\"\n\nimport { getGitHubApiBaseUrl, githubHeaders } from \"~/lib/api-config\"\nimport { HTTPError } from \"~/lib/error\"\nimport { accountFromState } from \"~/lib/state\"\n\nexport const getCopilotUsage = async (\n account?: AccountContext,\n): Promise<CopilotUsageResponse> => {\n const ctx = account ?? accountFromState()\n const response = await fetch(\n `${getGitHubApiBaseUrl()}/copilot_internal/user`,\n {\n headers: githubHeaders(ctx),\n },\n )\n\n if (!response.ok) {\n throw new HTTPError(\"Failed to get Copilot usage\", response)\n }\n\n return (await response.json()) as CopilotUsageResponse\n}\n\nexport interface QuotaDetail {\n entitlement: number\n overage_count: number\n overage_permitted: boolean\n percent_remaining: number\n quota_id: string\n quota_remaining: number\n remaining: number\n unlimited: boolean\n}\n\ninterface QuotaSnapshots {\n chat: QuotaDetail\n completions: QuotaDetail\n premium_interactions: QuotaDetail\n}\n\ninterface CopilotUsageResponse {\n login: string\n access_type_sku: string\n analytics_tracking_id: string\n assigned_date: string\n can_signup_for_limited: boolean\n chat_enabled: boolean\n copilot_plan: string\n organization_login_list: Array<unknown>\n organization_list: Array<unknown>\n quota_reset_date: string\n quota_snapshots: QuotaSnapshots\n endpoints: {\n api: string\n telemetry: string\n }\n}\n","import { getOauthAppConfig, getOauthUrls } from \"~/lib/api-config\"\nimport { HTTPError } from \"~/lib/error\"\n\nexport interface DeviceCodeOptions {\n overrideUrls?: {\n deviceCodeUrl: string\n accessTokenUrl: string\n }\n}\n\nexport async function getDeviceCode(\n options?: DeviceCodeOptions,\n): Promise<DeviceCodeResponse> {\n const { clientId, headers, scope } = getOauthAppConfig()\n const { deviceCodeUrl } = options?.overrideUrls ?? getOauthUrls()\n\n const response = await fetch(deviceCodeUrl, {\n method: \"POST\",\n headers,\n body: JSON.stringify({\n client_id: clientId,\n scope,\n }),\n })\n\n if (!response.ok) throw new HTTPError(\"Failed to get device code\", response)\n\n return (await response.json()) as DeviceCodeResponse\n}\n\nexport interface DeviceCodeResponse {\n device_code: string\n user_code: string\n verification_uri: string\n expires_in: number\n interval: number\n}\n","import type { AccountContext } from \"~/lib/types/account\"\n\nimport { getGitHubApiBaseUrl, githubUserHeaders } from \"~/lib/api-config\"\nimport { HTTPError } from \"~/lib/error\"\nimport { accountFromState, state } from \"~/lib/state\"\n\nconst resolveGitHubUserAccount = (account?: AccountContext): AccountContext => {\n if (account) {\n return account\n }\n\n if (!state.githubToken) {\n throw new Error(\"GitHub token not set\")\n }\n\n return accountFromState()\n}\n\nexport async function getGitHubUser(account?: AccountContext) {\n const resolvedAccount = resolveGitHubUserAccount(account)\n\n const response = await fetch(`${getGitHubApiBaseUrl()}/user`, {\n headers: githubUserHeaders(resolvedAccount),\n })\n\n if (!response.ok) throw new HTTPError(\"Failed to get GitHub user\", response)\n\n return (await response.json()) as GithubUserResponse\n}\n\n// Trimmed for the sake of simplicity\nexport interface GithubUserResponse {\n login: string\n}\n","const FALLBACK = \"1.116.0\"\n\nexport async function getVSCodeVersion() {\n await Promise.resolve()\n return FALLBACK\n}\n","import consola from \"consola\"\nimport { randomUUID } from \"node:crypto\"\nimport path from \"node:path\"\n\nconst WINDOWS_DEVICE_ID_KEY = String.raw`\\SOFTWARE\\Microsoft\\DeveloperTools`\nconst WINDOWS_DEVICE_ID_NAME = \"deviceid\"\n\ntype RegistryArch = \"x86\" | \"x64\"\n\ninterface WinregConstructor {\n new (options: {\n hive: string\n key: string\n arch?: RegistryArch\n }): WinregRegistry\n HKCU: string\n REG_SZ: string\n}\n\ninterface WinregRegistry {\n get(\n name: string,\n callback: (error: RegistryError | null, item: RegistryItem | null) => void,\n ): void\n set(\n name: string,\n type: string,\n value: string,\n callback: (error: RegistryError | null) => void,\n ): void\n}\n\ninterface RegistryItem {\n value?: string\n}\n\ninterface RegistryError extends Error {\n code?: number | string\n}\n\nconst windows64Architectures = new Set([\"AMD64\", \"ARM64\", \"IA64\"])\n\nconst getPosixHomeDir = (): string => {\n if (!process.env.HOME) {\n throw new Error(\"Home directory not found\")\n }\n\n return process.env.HOME\n}\n\nconst getDeviceIdFilePath = (): string => {\n let folder: string\n\n switch (process.platform) {\n case \"darwin\": {\n folder = path.posix.join(\n getPosixHomeDir(),\n \"Library\",\n \"Application Support\",\n )\n break\n }\n case \"linux\": {\n folder =\n process.env.XDG_CACHE_HOME\n ?? path.posix.join(getPosixHomeDir(), \".cache\")\n break\n }\n default: {\n throw new Error(\"Unsupported platform\")\n }\n }\n\n return path.posix.join(folder, \"Microsoft\", \"DeveloperTools\", \"deviceid\")\n}\n\nconst isMissingFileError = (error: unknown): error is NodeJS.ErrnoException => {\n return error instanceof Error && \"code\" in error && error.code === \"ENOENT\"\n}\n\nconst readStoredDeviceIdFile = async (\n filePath: string,\n): Promise<string | undefined> => {\n const { readFile } = await import(\"node:fs/promises\")\n\n try {\n return await readFile(filePath, \"utf8\")\n } catch (error) {\n if (isMissingFileError(error)) {\n return undefined\n }\n\n throw error\n }\n}\n\nconst writeStoredDeviceIdFile = async (\n filePath: string,\n deviceId: string,\n): Promise<void> => {\n const { mkdir, writeFile } = await import(\"node:fs/promises\")\n\n await mkdir(path.posix.dirname(filePath), { recursive: true })\n await writeFile(filePath, deviceId, \"utf8\")\n}\n\nconst getWindowsRegistryArch = (): RegistryArch | undefined => {\n const architecture = (\n process.env.PROCESSOR_ARCHITEW6432 ?? process.env.PROCESSOR_ARCHITECTURE\n )?.toUpperCase()\n\n return architecture && windows64Architectures.has(architecture) ?\n \"x64\"\n : undefined\n}\n\nconst loadWinreg = async (): Promise<WinregConstructor> => {\n const module = await import(\"winreg\")\n const winreg =\n \"default\" in module ? (module.default as unknown) : (module as unknown)\n\n return winreg as WinregConstructor\n}\n\nconst isMissingRegistryError = (error: RegistryError | null): boolean => {\n if (!error) {\n return false\n }\n\n const errorCode = Number(error.code)\n\n return Number.isFinite(errorCode) && errorCode === 1\n}\n\nconst createWindowsRegistry = async (): Promise<{\n registry: WinregRegistry\n regSz: string\n}> => {\n const Winreg = await loadWinreg()\n\n return {\n registry: new Winreg({\n hive: Winreg.HKCU,\n key: WINDOWS_DEVICE_ID_KEY,\n arch: getWindowsRegistryArch(),\n }),\n regSz: Winreg.REG_SZ,\n }\n}\n\nconst readRegistryString = async (\n registry: WinregRegistry,\n name: string,\n): Promise<string | undefined> => {\n return new Promise((resolve, reject) => {\n registry.get(name, (error, item) => {\n if (isMissingRegistryError(error)) {\n resolve(undefined)\n return\n }\n\n if (error) {\n reject(\n error instanceof Error ? error : new Error(\"Unknown registry error\"),\n )\n return\n }\n\n resolve(item?.value)\n })\n })\n}\n\nconst writeRegistryString = async ({\n registry,\n regSz,\n name,\n value,\n}: {\n registry: WinregRegistry\n regSz: string\n name: string\n value: string\n}): Promise<void> => {\n return new Promise((resolve, reject) => {\n registry.set(name, regSz, value, (error) => {\n if (error) {\n reject(\n error instanceof Error ? error : new Error(\"Unknown registry error\"),\n )\n return\n }\n\n resolve()\n })\n })\n}\n\nexport const getStoredVSCodeDeviceId = async (): Promise<\n string | undefined\n> => {\n switch (process.platform) {\n case \"win32\": {\n const { registry } = await createWindowsRegistry()\n\n return readRegistryString(registry, WINDOWS_DEVICE_ID_NAME)\n }\n case \"darwin\":\n case \"linux\": {\n return readStoredDeviceIdFile(getDeviceIdFilePath())\n }\n default: {\n throw new Error(\"Unsupported platform\")\n }\n }\n}\n\nconst setStoredVSCodeDeviceId = async (deviceId: string): Promise<void> => {\n switch (process.platform) {\n case \"win32\": {\n const { registry, regSz } = await createWindowsRegistry()\n\n await writeRegistryString({\n registry,\n regSz,\n name: WINDOWS_DEVICE_ID_NAME,\n value: deviceId,\n })\n return\n }\n case \"darwin\":\n case \"linux\": {\n await writeStoredDeviceIdFile(getDeviceIdFilePath(), deviceId)\n return\n }\n default: {\n throw new Error(\"Unsupported platform\")\n }\n }\n}\n\nconst createVSCodeDeviceId = (): string => randomUUID().toLowerCase()\n\nexport async function getVSCodeDeviceId(): Promise<string> {\n let deviceId: string | undefined\n\n try {\n deviceId = await getStoredVSCodeDeviceId()\n } catch (error) {\n consola.debug(\"Failed to read VSCode device id\", error)\n }\n\n if (deviceId) {\n return deviceId\n }\n\n const newDeviceId = createVSCodeDeviceId()\n\n try {\n await setStoredVSCodeDeviceId(newDeviceId)\n } catch (error) {\n consola.warn(\n \"Failed to persist VSCode device id, using ephemeral id\",\n error,\n )\n }\n\n return newDeviceId\n}\n","import type { Context } from \"hono\"\n\nimport consola from \"consola\"\nimport { createHash, randomUUID } from \"node:crypto\"\nimport { networkInterfaces } from \"node:os\"\n\nimport type { AnthropicMessagesPayload } from \"~/routes/messages/anthropic-types\"\n\nimport { getVSCodeVersion } from \"~/services/get-vscode-version\"\n\nimport { getVSCodeDeviceId } from \"./deviceid\"\nimport { state } from \"./state\"\n\nexport const sleep = (ms: number) =>\n new Promise((resolve) => {\n setTimeout(resolve, ms)\n })\n\nexport const isNullish = (value: unknown): value is null | undefined =>\n value === null || value === undefined\n\nexport const cacheVSCodeVersion = async () => {\n const response = await getVSCodeVersion()\n state.vsCodeVersion = response\n\n consola.info(`Using VSCode version: ${response}`)\n}\n\nconst invalidMacAddresses = new Set([\n \"00:00:00:00:00:00\",\n \"ff:ff:ff:ff:ff:ff\",\n \"ac:de:48:00:11:22\",\n])\n\nfunction validateMacAddress(candidate: string): boolean {\n const tempCandidate = candidate.replaceAll(\"-\", \":\").toLowerCase()\n return !invalidMacAddresses.has(tempCandidate)\n}\n\nexport function getMac(): string | null {\n const ifaces = networkInterfaces()\n // eslint-disable-next-line guard-for-in\n for (const name in ifaces) {\n const networkInterface = ifaces[name]\n if (networkInterface) {\n for (const { mac } of networkInterface) {\n if (validateMacAddress(mac)) {\n return mac\n }\n }\n }\n }\n return null\n}\n\nexport const cacheMacMachineId = () => {\n const macAddress = getMac() ?? randomUUID()\n state.macMachineId = createHash(\"sha256\")\n .update(macAddress, \"utf8\")\n .digest(\"hex\")\n consola.debug(`Using machine ID: ${state.macMachineId}`)\n}\n\nexport const cacheVsCodeDeviceId = async () => {\n state.vsCodeDeviceId = await getVSCodeDeviceId()\n consola.debug(`Using VSCode device ID: ${state.vsCodeDeviceId}`)\n}\n\nconst SESSION_REFRESH_BASE_MS = 60 * 60 * 1000\nconst SESSION_REFRESH_JITTER_MS = 20 * 60 * 1000\nlet vsCodeSessionRefreshTimer: ReturnType<typeof setTimeout> | null = null\n\nconst generateSessionId = () => {\n state.vsCodeSessionId = randomUUID() + Date.now().toString()\n consola.debug(`Generated VSCode session ID: ${state.vsCodeSessionId}`)\n}\n\nexport const stopVsCodeSessionRefreshLoop = () => {\n if (vsCodeSessionRefreshTimer) {\n clearTimeout(vsCodeSessionRefreshTimer)\n vsCodeSessionRefreshTimer = null\n }\n}\n\nconst scheduleSessionIdRefresh = () => {\n const randomDelay = Math.floor(Math.random() * SESSION_REFRESH_JITTER_MS)\n const delay = SESSION_REFRESH_BASE_MS + randomDelay\n consola.debug(\n `Scheduling next VSCode session ID refresh in ${Math.round(\n delay / 1000,\n )} seconds`,\n )\n\n stopVsCodeSessionRefreshLoop()\n vsCodeSessionRefreshTimer = setTimeout(() => {\n try {\n generateSessionId()\n } catch (error) {\n consola.error(\"Failed to refresh session ID, rescheduling...\", error)\n } finally {\n scheduleSessionIdRefresh()\n }\n }, delay)\n}\n\nexport const cacheVsCodeSessionId = () => {\n stopVsCodeSessionRefreshLoop()\n generateSessionId()\n scheduleSessionIdRefresh()\n}\n\ninterface PayloadMessage {\n role?: string\n content?: string | Array<{ type?: string; text?: string }> | null\n type?: string\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null\n\nconst getUserIdJsonField = (\n userIdPayload: Record<string, unknown> | null,\n field: string,\n): string | null => {\n const value = userIdPayload?.[field]\n return typeof value === \"string\" && value.length > 0 ? value : null\n}\n\nconst parseJsonUserId = (userId: string): Record<string, unknown> | null => {\n try {\n const parsed: unknown = JSON.parse(userId)\n return isRecord(parsed) ? parsed : null\n } catch {\n return null\n }\n}\n\nexport const parseUserIdMetadata = (\n userId: string | undefined,\n): { safetyIdentifier: string | null; sessionId: string | null } => {\n if (!userId || typeof userId !== \"string\") {\n return { safetyIdentifier: null, sessionId: null }\n }\n\n const legacySafetyIdentifier =\n userId.match(/user_([^_]+)_account/)?.[1] ?? null\n const legacySessionId = userId.match(/_session_(.+)$/)?.[1] ?? null\n\n const parsedUserId =\n legacySafetyIdentifier && legacySessionId ? null : parseJsonUserId(userId)\n\n const safetyIdentifier =\n legacySafetyIdentifier\n ?? getUserIdJsonField(parsedUserId, \"device_id\")\n ?? getUserIdJsonField(parsedUserId, \"account_uuid\")\n const sessionId =\n legacySessionId ?? getUserIdJsonField(parsedUserId, \"session_id\")\n\n return { safetyIdentifier, sessionId }\n}\n\nconst findLastUserContent = (\n messages: Array<PayloadMessage>,\n): string | null => {\n for (let i = messages.length - 1; i >= 0; i--) {\n const msg = messages[i]\n if (msg.role === \"user\" && msg.content) {\n if (typeof msg.content === \"string\") {\n return msg.content\n } else if (Array.isArray(msg.content)) {\n const array = msg.content\n .filter((n) => n.type !== \"tool_result\")\n .map((n) => ({ ...n, cache_control: undefined }))\n if (array.length > 0) {\n return JSON.stringify(array)\n }\n }\n }\n }\n return null\n}\n\nexport const generateRequestIdFromPayload = (\n payload: {\n messages: string | Array<PayloadMessage> | undefined\n },\n sessionId?: string,\n): string => {\n const messages = payload.messages\n if (messages) {\n const lastUserContent =\n typeof messages === \"string\" ? messages : findLastUserContent(messages)\n\n if (lastUserContent) {\n return getUUID((sessionId ?? \"\") + lastUserContent)\n }\n }\n\n return randomUUID()\n}\n\nexport const normalizeStableSessionId = (\n sessionId?: string | null,\n): string | undefined => {\n const trimmedSessionId = sessionId?.trim()\n return trimmedSessionId ? getUUID(trimmedSessionId) : undefined\n}\n\nexport const getRootSessionId = (\n anthropicPayload: AnthropicMessagesPayload,\n c: Context,\n): string | undefined => {\n const userId = anthropicPayload.metadata?.user_id\n const sessionId =\n userId ?\n parseUserIdMetadata(userId).sessionId || undefined\n : c.req.header(\"x-session-id\")\n\n return normalizeStableSessionId(sessionId)\n}\n\nexport const getUUID = (content: string): string => {\n const uuidBytes = createHash(\"sha256\")\n .update(content)\n .digest()\n .subarray(0, 16)\n\n uuidBytes[6] = (uuidBytes[6] & 0x0f) | 0x40\n uuidBytes[8] = (uuidBytes[8] & 0x3f) | 0x80\n\n const uuidHex = uuidBytes.toString(\"hex\")\n\n return `${uuidHex.slice(0, 8)}-${uuidHex.slice(8, 12)}-${uuidHex.slice(12, 16)}-${uuidHex.slice(16, 20)}-${uuidHex.slice(20)}`\n}\n\nexport type AffinityKeySource =\n | \"prompt_cache_key\"\n | \"metadata_session_id\"\n | \"x_session_id\"\n | \"upstream_request_id_fallback\"\n\nexport interface ResolvedAffinityKey {\n requestId: string\n affinityKeyUsed: string\n affinityKeySource: AffinityKeySource\n}\n\n/**\n * Unified affinity key resolution with fixed priority:\n * 1. payload.prompt_cache_key (used as-is)\n * 2. metadata.user_id.session_id (normalized via getUUID)\n * 3. x-session-id header (normalized via getUUID)\n * 4. generateRequestIdFromPayload fallback (used as-is)\n */\nexport const resolveAffinityKey = (params: {\n promptCacheKey?: string | null\n metadataSessionId?: string | null\n headerSessionId?: string | null\n upstreamRequestId: string\n}): ResolvedAffinityKey => {\n const {\n promptCacheKey,\n metadataSessionId,\n headerSessionId,\n upstreamRequestId,\n } = params\n\n if (promptCacheKey) {\n return {\n requestId: promptCacheKey,\n affinityKeyUsed: promptCacheKey,\n affinityKeySource: \"prompt_cache_key\",\n }\n }\n\n if (metadataSessionId) {\n return {\n requestId: getUUID(metadataSessionId),\n affinityKeyUsed: metadataSessionId,\n affinityKeySource: \"metadata_session_id\",\n }\n }\n\n if (headerSessionId) {\n return {\n requestId: getUUID(headerSessionId),\n affinityKeyUsed: headerSessionId,\n affinityKeySource: \"x_session_id\",\n }\n }\n\n return {\n requestId: upstreamRequestId,\n affinityKeyUsed: upstreamRequestId,\n affinityKeySource: \"upstream_request_id_fallback\",\n }\n}\n","import consola from \"consola\"\n\nimport { getOauthAppConfig, getOauthUrls } from \"~/lib/api-config\"\nimport { CancelledError } from \"~/lib/error\"\nimport { sleep } from \"~/lib/utils\"\n\nimport type { DeviceCodeResponse } from \"./get-device-code\"\n\nexport interface PollAccessTokenOptions {\n overrideUrls?: {\n deviceCodeUrl: string\n accessTokenUrl: string\n }\n signal?: AbortSignal\n}\n\nexport async function pollAccessToken(\n deviceCode: DeviceCodeResponse,\n options?: PollAccessTokenOptions,\n): Promise<string> {\n const { clientId, headers } = getOauthAppConfig()\n const { accessTokenUrl } = options?.overrideUrls ?? getOauthUrls()\n\n // Interval is in seconds, we need to multiply by 1000 to get milliseconds\n // I'm also adding another second, just to be safe\n const sleepDuration = (deviceCode.interval + 1) * 1000\n consola.debug(`Polling access token with interval of ${sleepDuration}ms`)\n\n while (true) {\n if (options?.signal?.aborted) {\n throw new CancelledError(\"Authentication cancelled\")\n }\n\n const response = await fetch(accessTokenUrl, {\n method: \"POST\",\n headers,\n body: JSON.stringify({\n client_id: clientId,\n device_code: deviceCode.device_code,\n grant_type: \"urn:ietf:params:oauth:grant-type:device_code\",\n }),\n signal: options?.signal,\n })\n\n if (!response.ok) {\n await sleep(sleepDuration)\n consola.error(\"Failed to poll access token:\", await response.text())\n\n continue\n }\n\n const json = await response.json()\n consola.debug(\"Polling access token response:\", json)\n\n const { access_token } = json as AccessTokenResponse\n\n if (access_token) {\n return access_token\n } else {\n await sleep(sleepDuration)\n }\n }\n}\n\ninterface AccessTokenResponse {\n access_token: string\n token_type: string\n scope: string\n}\n"],"mappings":"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"}