xc-copilot-api
Advanced tools
+3
-3
| #!/usr/bin/env node | ||
| import{defineCommand as e,runMain as t}from"citty";import n from"consola";import r,{copyFile as i,mkdir as a,readFile as o,writeFile as s}from"node:fs/promises";import c,{homedir as l}from"node:os";import u,{join as d}from"node:path";import{randomUUID as ee}from"node:crypto";import{serve as f}from"srvx";import{getProxyForUrl as te}from"proxy-from-env";import{Agent as ne,ProxyAgent as re,setGlobalDispatcher as ie}from"undici";import{Hono as p}from"hono";import{cors as ae}from"hono/cors";import{streamSSE as m}from"hono/streaming";import{events as oe}from"fetch-event-stream";var se=`xc-copilot-api`,ce=`1.2.5`,le=`Turn GitHub Copilot into OpenAI/Anthropic API compatible server. Usable with Claude Code and Codex`,ue=[`proxy`,`github-copilot`,`openai-compatible`],de=`https://github.com/billxc/copilot-api`,fe=`https://github.com/billxc/copilot-api/issues`,pe={type:`git`,url:`git+https://github.com/billxc/copilot-api.git`},me=`Xiaochen <wxc9312@gmail.com>`,he=`module`,ge={"xc-copilot-api":`./dist/main.js`},_e=[`dist`],ve={build:`bun run scripts/generate-page.ts && tsdown`,dev:`bun run scripts/generate-page.ts && bun run --watch ./src/main.ts start`,knip:`knip-bun`,lint:`eslint --cache`,"lint:all":`eslint --cache .`,prepack:`bun run build`,prepare:`simple-git-hooks`,release:`bumpp && bun publish --access public`,start:`NODE_ENV=production bun run ./src/main.ts start`,typecheck:`tsc`},ye={},be={},xe={citty:`^0.1.6`,consola:`^3.4.2`,"fetch-event-stream":`^0.1.5`,"gpt-tokenizer":`^3.0.1`,hono:`^4.9.9`,"proxy-from-env":`^1.1.0`,srvx:`^0.8.9`,undici:`^7.16.0`},Se={"@echristian/eslint-config":`^0.0.54`,"@types/bun":`^1.2.23`,"@types/proxy-from-env":`^1.0.4`,bumpp:`^10.2.3`,eslint:`^9.37.0`,knip:`^5.64.1`,"simple-git-hooks":`^2.13.1`,tsdown:`^0.15.6`,typescript:`^5.9.3`},h={name:se,version:ce,description:le,keywords:ue,homepage:de,bugs:fe,repository:pe,author:me,type:he,bin:ge,files:_e,scripts:ve,"simple-git-hooks":ye,"lint-staged":be,dependencies:xe,devDependencies:Se};const g=u.join(c.homedir(),`.local`,`share`,`copilot-api`),Ce=u.join(g,`github_token`),_={APP_DIR:g,GITHUB_TOKEN_PATH:Ce};async function v(){await r.mkdir(_.APP_DIR,{recursive:!0}),await we(_.GITHUB_TOKEN_PATH)}async function we(e){try{await r.access(e,r.constants.W_OK)}catch{await r.writeFile(e,``),await r.chmod(e,384)}}const y={accountType:`individual`,manualApprove:!1,rateLimitWait:!1,showToken:!1},b=()=>({"content-type":`application/json`,accept:`application/json`}),x=`0.26.7`,Te=`copilot-chat/${x}`,Ee=`GitHubCopilotChat/${x}`,De=`2025-04-01`,S=e=>e.accountType===`individual`?`https://api.githubcopilot.com`:`https://api.${e.accountType}.githubcopilot.com`,C=(e,t=!1)=>{let n={Authorization:`Bearer ${e.copilotToken}`,"content-type":b()[`content-type`],"copilot-integration-id":`vscode-chat`,"editor-version":`vscode/${e.vsCodeVersion}`,"editor-plugin-version":Te,"user-agent":Ee,"openai-intent":`conversation-panel`,"x-github-api-version":De,"x-request-id":ee(),"x-vscode-user-agent-library-version":`electron-fetch`};return t&&(n[`copilot-vision-request`]=`true`),n},w=`https://api.github.com`,Oe=e=>({...b(),authorization:`token ${e.githubToken}`,"editor-version":`vscode/${e.vsCodeVersion}`,"editor-plugin-version":Te,"user-agent":Ee,"x-github-api-version":De,"x-vscode-user-agent-library-version":`electron-fetch`}),T=`https://github.com`,E=`Iv1.b507a08c87ecfe98`,ke=[`read:user`].join(` `);var D=class extends Error{response;constructor(e,t){super(e),this.response=t}};async function O(e,t){if(n.error(`Error occurred:`,t),t instanceof D){let r=await t.response.text(),i;try{i=JSON.parse(r)}catch{i=r}return n.error(`HTTP error:`,i),e.json({error:{message:r,type:`error`}},t.response.status)}return e.json({error:{message:t.message,type:`error`}},500)}const Ae=async()=>{let e=await fetch(`${w}/copilot_internal/v2/token`,{headers:Oe(y)});if(!e.ok)throw new D(`Failed to get Copilot token`,e);return await e.json()};async function je(){let e=await fetch(`${T}/login/device/code`,{method:`POST`,headers:b(),body:JSON.stringify({client_id:E,scope:ke})});if(!e.ok)throw new D(`Failed to get device code`,e);return await e.json()}async function Me(){let e=await fetch(`${w}/user`,{headers:{authorization:`token ${y.githubToken}`,...b()}});if(!e.ok)throw new D(`Failed to get GitHub user`,e);return await e.json()}const Ne=async()=>{let e=await fetch(`${S(y)}/models`,{headers:C(y)});if(!e.ok)throw new D(`Failed to get models`,e);return await e.json()},Pe=`1.104.3`;async function Fe(){let e=new AbortController,t=setTimeout(()=>{e.abort()},5e3);try{let t=(await(await fetch(`https://aur.archlinux.org/cgit/aur.git/plain/PKGBUILD?h=visual-studio-code-bin`,{signal:e.signal})).text()).match(/pkgver=([0-9.]+)/);return t?t[1]:Pe}catch{return Pe}finally{clearTimeout(t)}}await Fe();const k=e=>new Promise(t=>{setTimeout(t,e)}),Ie=e=>e==null;async function A(){y.models=await Ne()}const Le=async()=>{let e=await Fe();y.vsCodeVersion=e,n.info(`Using VSCode version: ${e}`)};async function Re(e){let t=(e.interval+1)*1e3;for(n.debug(`Polling access token with interval of ${t}ms`);;){let r=await fetch(`${T}/login/oauth/access_token`,{method:`POST`,headers:b(),body:JSON.stringify({client_id:E,device_code:e.device_code,grant_type:`urn:ietf:params:oauth:grant-type:device_code`})});if(!r.ok){await k(t),n.error(`Failed to poll access token:`,await r.text());continue}let i=await r.json();n.debug(`Polling access token response:`,i);let{access_token:a}=i;if(a)return a;await k(t)}}const ze=()=>r.readFile(_.GITHUB_TOKEN_PATH,`utf8`),Be=e=>r.writeFile(_.GITHUB_TOKEN_PATH,e),Ve=e=>new Promise(t=>{setTimeout(t,e)}),j=async(e=3,t=1e3)=>{let r=null;for(let i=0;i<e;i++)try{return await Ae()}catch(a){r=a;let o=t*2**i;n.warn(`Token refresh attempt ${i+1}/${e} failed, retrying in ${o}ms:`,r.message),i<e-1&&await Ve(o)}throw r||Error(`Failed to refresh Copilot token`)},M=async()=>{try{n.debug(`Force refreshing Copilot token due to 401 response`);let{token:e}=await j();y.copilotToken=e,n.debug(`Copilot token force refreshed successfully`)}catch(e){n.error(`Failed to force refresh Copilot token:`,e)}},He=async()=>{let{token:e,refresh_in:t}=await Ae();y.copilotToken=e,n.debug(`GitHub Copilot Token fetched successfully!`),y.showToken&&n.info(`Copilot token:`,e);let r=(t-60)*1e3;setInterval(async()=>{try{n.debug(`Refreshing Copilot token`);let{token:e}=await j();y.copilotToken=e,n.debug(`Copilot token refreshed successfully`),y.showToken&&n.info(`Refreshed Copilot token:`,e)}catch(e){n.error(`Failed to refresh Copilot token, will retry on next interval:`,e)}},r)};async function N(e){try{let t=await ze();if(t&&!e?.force){y.githubToken=t,y.showToken&&n.info(`GitHub token:`,t),await P();return}n.info(`Not logged in, getting new access token`);let r=await je();n.debug(`Device code response:`,r),n.info(`Please enter the code "${r.user_code}" in ${r.verification_uri}`);let i=await Re(r);await Be(i),y.githubToken=i,y.showToken&&n.info(`GitHub token:`,i),await P()}catch(e){throw e instanceof D?(n.error(`Failed to get GitHub token:`,await e.response.json()),e):(n.error(`Failed to get GitHub token:`,e),e)}}async function P(){let e=await Me();y.githubLogin=e.login,n.info(`Logged in as ${e.login}`)}async function Ue(e){e.verbose&&(n.level=5,n.info(`Verbose logging enabled`)),y.showToken=e.showToken,await v(),await N({force:!0}),n.success(`GitHub token written to`,_.GITHUB_TOKEN_PATH)}const We=e({meta:{name:`auth`,description:`Run GitHub auth flow without running the server`},args:{verbose:{alias:`v`,type:`boolean`,default:!1,description:`Enable verbose logging`},"show-token":{type:`boolean`,default:!1,description:`Show GitHub token on auth`}},run({args:e}){return Ue({verbose:e.verbose,showToken:e[`show-token`]})}}),F=async()=>{let e=await fetch(`${w}/copilot_internal/user`,{headers:Oe(y)});if(!e.ok)throw new D(`Failed to get Copilot usage`,e);return await e.json()},Ge=e({meta:{name:`check-usage`,description:`Show current GitHub Copilot usage/quota information`},async run(){await v(),await N();try{let e=await F(),t=e.quota_snapshots.premium_interactions,r=t.entitlement,i=r-t.remaining,a=r>0?i/r*100:0,o=t.percent_remaining;function s(e,t){if(!t)return`${e}: N/A`;let n=t.entitlement,r=n-t.remaining,i=n>0?r/n*100:0,a=t.percent_remaining;return`${e}: ${r}/${n} used (${i.toFixed(1)}% used, ${a.toFixed(1)}% remaining)`}let c=`Premium: ${i}/${r} used (${a.toFixed(1)}% used, ${o.toFixed(1)}% remaining)`,l=s(`Chat`,e.quota_snapshots.chat),u=s(`Completions`,e.quota_snapshots.completions);n.box(`Copilot Usage (plan: ${e.copilot_plan})\nQuota resets: ${e.quota_reset_date}\n\nQuotas:\n ${c}\n ${l}\n ${u}`)}catch(e){n.error(`Failed to fetch Copilot usage:`,e),process.exit(1)}}});async function I(e){try{let t=`${e}.bak`;await i(e,t),n.info(`Backup saved: ${t}`)}catch{}}const L={"4.7":`claude-opus-4.7-1m-internal`,"4.6":`claude-opus-4.6-1m`};async function Ke(e,t){let r=L[t];r||(n.error(`Unknown Claude model version: ${t}. Supported: ${Object.keys(L).join(`, `)}`),process.exit(1));let i=d(l(),`.claude`),c=d(i,`settings.json`);await a(i,{recursive:!0});let u={};try{let e=await o(c,`utf-8`);u=JSON.parse(e)}catch(e){e.code!==`ENOENT`&&(n.error(`Failed to parse ${c}. Please fix it manually.`),process.exit(1))}let ee=typeof u.env==`object`&&u.env!==null?u.env:{},f={...u,env:{...ee,ANTHROPIC_BASE_URL:`http://localhost:${e}`,ANTHROPIC_AUTH_TOKEN:`Powered by xc copilot`,ANTHROPIC_DEFAULT_OPUS_MODEL:r,CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS:`1`},model:`opus[1m]`};await I(c),await s(c,JSON.stringify(f,null,2)+` | ||
| import{defineCommand as e,runMain as t}from"citty";import n from"consola";import r,{copyFile as i,mkdir as a,readFile as o,writeFile as s}from"node:fs/promises";import c,{homedir as l}from"node:os";import u,{join as d}from"node:path";import{randomUUID as ee}from"node:crypto";import{serve as f}from"srvx";import{getProxyForUrl as te}from"proxy-from-env";import{Agent as ne,ProxyAgent as re,setGlobalDispatcher as ie}from"undici";import{Hono as p}from"hono";import{cors as ae}from"hono/cors";import{streamSSE as m}from"hono/streaming";import{events as oe}from"fetch-event-stream";var se=`xc-copilot-api`,ce=`1.2.6`,le=`Turn GitHub Copilot into OpenAI/Anthropic API compatible server. Usable with Claude Code and Codex`,ue=[`proxy`,`github-copilot`,`openai-compatible`],de=`https://github.com/billxc/copilot-api`,fe=`https://github.com/billxc/copilot-api/issues`,pe={type:`git`,url:`git+https://github.com/billxc/copilot-api.git`},me=`Xiaochen <wxc9312@gmail.com>`,he=`module`,ge={"xc-copilot-api":`./dist/main.js`},_e=[`dist`],ve={build:`bun run scripts/generate-page.ts && tsdown`,dev:`bun run scripts/generate-page.ts && bun run --watch ./src/main.ts start`,knip:`knip-bun`,lint:`eslint --cache`,"lint:all":`eslint --cache .`,prepack:`bun run build`,prepare:`simple-git-hooks`,release:`bumpp && bun publish --access public`,start:`NODE_ENV=production bun run ./src/main.ts start`,typecheck:`tsc`},ye={},be={},xe={citty:`^0.1.6`,consola:`^3.4.2`,"fetch-event-stream":`^0.1.5`,"gpt-tokenizer":`^3.0.1`,hono:`^4.9.9`,"proxy-from-env":`^1.1.0`,srvx:`^0.8.9`,undici:`^7.16.0`},Se={"@echristian/eslint-config":`^0.0.54`,"@types/bun":`^1.2.23`,"@types/proxy-from-env":`^1.0.4`,bumpp:`^10.2.3`,eslint:`^9.37.0`,knip:`^5.64.1`,"simple-git-hooks":`^2.13.1`,tsdown:`^0.15.6`,typescript:`^5.9.3`},h={name:se,version:ce,description:le,keywords:ue,homepage:de,bugs:fe,repository:pe,author:me,type:he,bin:ge,files:_e,scripts:ve,"simple-git-hooks":ye,"lint-staged":be,dependencies:xe,devDependencies:Se};const g=u.join(c.homedir(),`.local`,`share`,`copilot-api`),Ce=u.join(g,`github_token`),_={APP_DIR:g,GITHUB_TOKEN_PATH:Ce};async function v(){await r.mkdir(_.APP_DIR,{recursive:!0}),await we(_.GITHUB_TOKEN_PATH)}async function we(e){try{await r.access(e,r.constants.W_OK)}catch{await r.writeFile(e,``),await r.chmod(e,384)}}const y={accountType:`individual`,manualApprove:!1,rateLimitWait:!1,showToken:!1},b=()=>({"content-type":`application/json`,accept:`application/json`}),x=`0.26.7`,Te=`copilot-chat/${x}`,Ee=`GitHubCopilotChat/${x}`,De=`2025-04-01`,S=e=>e.accountType===`individual`?`https://api.githubcopilot.com`:`https://api.${e.accountType}.githubcopilot.com`,C=(e,t=!1)=>{let n={Authorization:`Bearer ${e.copilotToken}`,"content-type":b()[`content-type`],"copilot-integration-id":`vscode-chat`,"editor-version":`vscode/${e.vsCodeVersion}`,"editor-plugin-version":Te,"user-agent":Ee,"openai-intent":`conversation-panel`,"x-github-api-version":De,"x-request-id":ee(),"x-vscode-user-agent-library-version":`electron-fetch`};return t&&(n[`copilot-vision-request`]=`true`),n},w=`https://api.github.com`,Oe=e=>({...b(),authorization:`token ${e.githubToken}`,"editor-version":`vscode/${e.vsCodeVersion}`,"editor-plugin-version":Te,"user-agent":Ee,"x-github-api-version":De,"x-vscode-user-agent-library-version":`electron-fetch`}),T=`https://github.com`,E=`Iv1.b507a08c87ecfe98`,ke=[`read:user`].join(` `);var D=class extends Error{response;constructor(e,t){super(e),this.response=t}};async function O(e,t){if(n.error(`Error occurred:`,t),t instanceof D){let r=await t.response.text(),i;try{i=JSON.parse(r)}catch{i=r}return n.error(`HTTP error:`,i),e.json({error:{message:r,type:`error`}},t.response.status)}return e.json({error:{message:t.message,type:`error`}},500)}const Ae=async()=>{let e=await fetch(`${w}/copilot_internal/v2/token`,{headers:Oe(y)});if(!e.ok)throw new D(`Failed to get Copilot token`,e);return await e.json()};async function je(){let e=await fetch(`${T}/login/device/code`,{method:`POST`,headers:b(),body:JSON.stringify({client_id:E,scope:ke})});if(!e.ok)throw new D(`Failed to get device code`,e);return await e.json()}async function Me(){let e=await fetch(`${w}/user`,{headers:{authorization:`token ${y.githubToken}`,...b()}});if(!e.ok)throw new D(`Failed to get GitHub user`,e);return await e.json()}const Ne=async()=>{let e=await fetch(`${S(y)}/models`,{headers:C(y)});if(!e.ok)throw new D(`Failed to get models`,e);return await e.json()},Pe=`1.104.3`;async function Fe(){let e=new AbortController,t=setTimeout(()=>{e.abort()},5e3);try{let t=(await(await fetch(`https://aur.archlinux.org/cgit/aur.git/plain/PKGBUILD?h=visual-studio-code-bin`,{signal:e.signal})).text()).match(/pkgver=([0-9.]+)/);return t?t[1]:Pe}catch{return Pe}finally{clearTimeout(t)}}await Fe();const k=e=>new Promise(t=>{setTimeout(t,e)}),Ie=e=>e==null;async function A(){y.models=await Ne()}const Le=async()=>{let e=await Fe();y.vsCodeVersion=e,n.info(`Using VSCode version: ${e}`)};async function Re(e){let t=(e.interval+1)*1e3;for(n.debug(`Polling access token with interval of ${t}ms`);;){let r=await fetch(`${T}/login/oauth/access_token`,{method:`POST`,headers:b(),body:JSON.stringify({client_id:E,device_code:e.device_code,grant_type:`urn:ietf:params:oauth:grant-type:device_code`})});if(!r.ok){await k(t),n.error(`Failed to poll access token:`,await r.text());continue}let i=await r.json();n.debug(`Polling access token response:`,i);let{access_token:a}=i;if(a)return a;await k(t)}}const ze=()=>r.readFile(_.GITHUB_TOKEN_PATH,`utf8`),Be=e=>r.writeFile(_.GITHUB_TOKEN_PATH,e),Ve=e=>new Promise(t=>{setTimeout(t,e)}),j=async(e=3,t=1e3)=>{let r=null;for(let i=0;i<e;i++)try{return await Ae()}catch(a){r=a;let o=t*2**i;n.warn(`Token refresh attempt ${i+1}/${e} failed, retrying in ${o}ms:`,r.message),i<e-1&&await Ve(o)}throw r||Error(`Failed to refresh Copilot token`)},M=async()=>{try{n.debug(`Force refreshing Copilot token due to 401 response`);let{token:e}=await j();y.copilotToken=e,n.debug(`Copilot token force refreshed successfully`)}catch(e){n.error(`Failed to force refresh Copilot token:`,e)}},He=async()=>{let{token:e,refresh_in:t}=await Ae();y.copilotToken=e,n.debug(`GitHub Copilot Token fetched successfully!`),y.showToken&&n.info(`Copilot token:`,e);let r=(t-60)*1e3;setInterval(async()=>{try{n.debug(`Refreshing Copilot token`);let{token:e}=await j();y.copilotToken=e,n.debug(`Copilot token refreshed successfully`),y.showToken&&n.info(`Refreshed Copilot token:`,e)}catch(e){n.error(`Failed to refresh Copilot token, will retry on next interval:`,e)}},r)};async function N(e){try{let t=await ze();if(t&&!e?.force){y.githubToken=t,y.showToken&&n.info(`GitHub token:`,t),await P();return}n.info(`Not logged in, getting new access token`);let r=await je();n.debug(`Device code response:`,r),n.info(`Please enter the code "${r.user_code}" in ${r.verification_uri}`);let i=await Re(r);await Be(i),y.githubToken=i,y.showToken&&n.info(`GitHub token:`,i),await P()}catch(e){throw e instanceof D?(n.error(`Failed to get GitHub token:`,await e.response.json()),e):(n.error(`Failed to get GitHub token:`,e),e)}}async function P(){let e=await Me();y.githubLogin=e.login,n.info(`Logged in as ${e.login}`)}async function Ue(e){e.verbose&&(n.level=5,n.info(`Verbose logging enabled`)),y.showToken=e.showToken,await v(),await N({force:!0}),n.success(`GitHub token written to`,_.GITHUB_TOKEN_PATH)}const We=e({meta:{name:`auth`,description:`Run GitHub auth flow without running the server`},args:{verbose:{alias:`v`,type:`boolean`,default:!1,description:`Enable verbose logging`},"show-token":{type:`boolean`,default:!1,description:`Show GitHub token on auth`}},run({args:e}){return Ue({verbose:e.verbose,showToken:e[`show-token`]})}}),F=async()=>{let e=await fetch(`${w}/copilot_internal/user`,{headers:Oe(y)});if(!e.ok)throw new D(`Failed to get Copilot usage`,e);return await e.json()},Ge=e({meta:{name:`check-usage`,description:`Show current GitHub Copilot usage/quota information`},async run(){await v(),await N();try{let e=await F(),t=e.quota_snapshots.premium_interactions,r=t.entitlement,i=r-t.remaining,a=r>0?i/r*100:0,o=t.percent_remaining;function s(e,t){if(!t)return`${e}: N/A`;let n=t.entitlement,r=n-t.remaining,i=n>0?r/n*100:0,a=t.percent_remaining;return`${e}: ${r}/${n} used (${i.toFixed(1)}% used, ${a.toFixed(1)}% remaining)`}let c=`Premium: ${i}/${r} used (${a.toFixed(1)}% used, ${o.toFixed(1)}% remaining)`,l=s(`Chat`,e.quota_snapshots.chat),u=s(`Completions`,e.quota_snapshots.completions);n.box(`Copilot Usage (plan: ${e.copilot_plan})\nQuota resets: ${e.quota_reset_date}\n\nQuotas:\n ${c}\n ${l}\n ${u}`)}catch(e){n.error(`Failed to fetch Copilot usage:`,e),process.exit(1)}}});async function I(e){try{let t=`${e}.bak`;await i(e,t),n.info(`Backup saved: ${t}`)}catch{}}const L={"4.8":`claude-opus-4.8`,"4.7":`claude-opus-4.7-1m-internal`,"4.6":`claude-opus-4.6-1m`};async function Ke(e,t){let r=L[t];r||(n.error(`Unknown Claude model version: ${t}. Supported: ${Object.keys(L).join(`, `)}`),process.exit(1));let i=d(l(),`.claude`),c=d(i,`settings.json`);await a(i,{recursive:!0});let u={};try{let e=await o(c,`utf-8`);u=JSON.parse(e)}catch(e){e.code!==`ENOENT`&&(n.error(`Failed to parse ${c}. Please fix it manually.`),process.exit(1))}let ee=typeof u.env==`object`&&u.env!==null?u.env:{},f={...u,env:{...ee,ANTHROPIC_BASE_URL:`http://localhost:${e}`,ANTHROPIC_AUTH_TOKEN:`Powered by xc copilot`,ANTHROPIC_DEFAULT_OPUS_MODEL:r,CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS:`1`},model:`opus[1m]`};await I(c),await s(c,JSON.stringify(f,null,2)+` | ||
| `,`utf-8`),n.success(`Claude Code configured: ${c}`)}function R(e,t,n){let r=RegExp(`^${t}\\s*=.*$`,`m`),i=`${t} = ${JSON.stringify(n)}`;if(r.test(e))return e.replace(r,i);let a=e.match(/^\[/m);return a?.index===void 0?e.trimEnd()+` | ||
@@ -8,3 +8,3 @@ `+i+` | ||
| `+a}async function Je(e){let t=d(l(),`.codex`),r=d(t,`config.toml`);await a(t,{recursive:!0});let i=``;try{i=await o(r,`utf-8`)}catch(e){e.code!==`ENOENT`&&(n.error(`Failed to read ${r}. Please fix it manually.`),process.exit(1))}i=R(i,`model`,`gpt-5.5`),i=R(i,`model_provider`,`copilot-api`),i=qe(i,`model_providers.copilot-api`,`name = "copilot-api"\nbase_url = "http://localhost:${e}/v1"\nwire_api = "responses"`),await I(r),await s(r,i,`utf-8`),n.success(`Codex CLI configured: ${r}`)}const Ye=e({meta:{name:`config`,description:`Configure external AI tools (Claude Code, Codex CLI) to use Copilot API`},args:{claude:{alias:`c`,type:`boolean`,default:!1,description:`Configure Claude Code (~/.claude/settings.json)`},codex:{alias:`x`,type:`boolean`,default:!1,description:`Configure Codex CLI (~/.codex/config.toml)`},"claude-model":{alias:`m`,type:`string`,default:`4.7`,description:`Claude Opus model version (4.7 or 4.6)`},port:{alias:`p`,type:`string`,default:`4141`,description:`Port the Copilot API server listens on`}},async run({args:e}){!e.claude&&!e.codex&&(n.error(`Specify at least one: --claude or --codex`),process.exit(1));let t=Number.parseInt(e.port,10);e.claude&&await Ke(t,e[`claude-model`]),e.codex&&await Je(t)}});async function Xe(){try{let e=new URL(`../package.json`,import.meta.url).pathname;return JSON.parse(await r.readFile(e)).version}catch{return`unknown`}}function Ze(){let e=typeof Bun<`u`;return{name:e?`bun`:`node`,version:e?Bun.version:process.version.slice(1),platform:c.platform(),arch:c.arch()}}async function Qe(){try{return(await r.stat(_.GITHUB_TOKEN_PATH)).isFile()?(await r.readFile(_.GITHUB_TOKEN_PATH,`utf8`)).trim().length>0:!1}catch{return!1}}async function $e(){let[e,t]=await Promise.all([Xe(),Qe()]);return{version:e,runtime:Ze(),paths:{APP_DIR:_.APP_DIR,GITHUB_TOKEN_PATH:_.GITHUB_TOKEN_PATH},tokenExists:t}}function et(e){n.info(`xc-copilot-api debug | ||
| `+a}async function Je(e){let t=d(l(),`.codex`),r=d(t,`config.toml`);await a(t,{recursive:!0});let i=``;try{i=await o(r,`utf-8`)}catch(e){e.code!==`ENOENT`&&(n.error(`Failed to read ${r}. Please fix it manually.`),process.exit(1))}i=R(i,`model`,`gpt-5.5`),i=R(i,`model_provider`,`copilot-api`),i=qe(i,`model_providers.copilot-api`,`name = "copilot-api"\nbase_url = "http://localhost:${e}/v1"\nwire_api = "responses"`),await I(r),await s(r,i,`utf-8`),n.success(`Codex CLI configured: ${r}`)}const Ye=e({meta:{name:`config`,description:`Configure external AI tools (Claude Code, Codex CLI) to use Copilot API. Configures both by default; use --claude or --codex to target one.`},args:{claude:{alias:`c`,type:`boolean`,default:!1,description:`Configure Claude Code (~/.claude/settings.json)`},codex:{alias:`x`,type:`boolean`,default:!1,description:`Configure Codex CLI (~/.codex/config.toml)`},"claude-model":{alias:`m`,type:`string`,default:`4.8`,description:`Claude Opus model version (4.8, 4.7, or 4.6)`},port:{alias:`p`,type:`string`,default:`4141`,description:`Port the Copilot API server listens on`}},async run({args:e}){let t=Number.parseInt(e.port,10),n=!e.claude&&!e.codex;(n||e.claude)&&await Ke(t,e[`claude-model`]),(n||e.codex)&&await Je(t)}});async function Xe(){try{let e=new URL(`../package.json`,import.meta.url).pathname;return JSON.parse(await r.readFile(e)).version}catch{return`unknown`}}function Ze(){let e=typeof Bun<`u`;return{name:e?`bun`:`node`,version:e?Bun.version:process.version.slice(1),platform:c.platform(),arch:c.arch()}}async function Qe(){try{return(await r.stat(_.GITHUB_TOKEN_PATH)).isFile()?(await r.readFile(_.GITHUB_TOKEN_PATH,`utf8`)).trim().length>0:!1}catch{return!1}}async function $e(){let[e,t]=await Promise.all([Xe(),Qe()]);return{version:e,runtime:Ze(),paths:{APP_DIR:_.APP_DIR,GITHUB_TOKEN_PATH:_.GITHUB_TOKEN_PATH},tokenExists:t}}function et(e){n.info(`xc-copilot-api debug | ||
@@ -681,4 +681,4 @@ Version: ${e.version} | ||
| `);let t=[];for(let n of e)switch(n.type){case`text`:t.push({type:`text`,text:n.text});break;case`thinking`:t.push({type:`text`,text:n.thinking});break;case`image`:t.push({type:`image_url`,image_url:{url:`data:${n.source.media_type};base64,${n.source.data}`}});break}return t}function Ut(e){if(e)return e.map(e=>({type:`function`,function:{name:e.name,description:e.description,parameters:e.input_schema}}))}function Wt(e){if(e)switch(e.type){case`auto`:return`auto`;case`any`:return`required`;case`tool`:return e.name?{type:`function`,function:{name:e.name}}:void 0;case`none`:return`none`;default:return}}function Gt(e){let t=[],n=[],r=null;r=e.choices[0]?.finish_reason??r;for(let i of e.choices){let e=Kt(i.message.content),a=qt(i.message.tool_calls);t.push(...e),n.push(...a),(i.finish_reason===`tool_calls`||r===`stop`)&&(r=i.finish_reason)}return{id:e.id,type:`message`,role:`assistant`,model:e.model,content:[...t,...n],stop_reason:It(r),stop_sequence:null,usage:{input_tokens:(e.usage?.prompt_tokens??0)-(e.usage?.prompt_tokens_details?.cached_tokens??0),output_tokens:e.usage?.completion_tokens??0,...e.usage?.prompt_tokens_details?.cached_tokens!==void 0&&{cache_read_input_tokens:e.usage.prompt_tokens_details.cached_tokens}}}}function Kt(e){return typeof e==`string`?[{type:`text`,text:e}]:Array.isArray(e)?e.filter(e=>e.type===`text`).map(e=>({type:`text`,text:e.text})):[]}function qt(e){return e?e.map(e=>({type:`tool_use`,id:e.id,name:e.function.name,input:JSON.parse(e.function.arguments)})):[]}async function Jt(e){try{let t=await e.req.text();if(n.debug(`Anthropic count_tokens payload:`,t.slice(0,1e3)),Nt(t)){let n=await Mt(t,e.req.raw.headers,`/v1/messages/count_tokens`);return new Response(n.body,{status:n.status,headers:Pt(n.headers)})}let r=e.req.header(`anthropic-beta`),i=JSON.parse(t),a=Lt(i),o=y.models?.data.find(e=>e.id===i.model);if(!o)return n.warn(`Model not found, returning default token count`),e.json({input_tokens:1});let s=await gt(a,o);if(i.tools&&i.tools.length>0){let e=!1;r?.startsWith(`claude-code`)&&(e=i.tools.some(e=>e.name.startsWith(`mcp__`))),e||(i.model.startsWith(`claude`)?s.input+=346:i.model.startsWith(`grok`)&&(s.input+=480))}let c=s.input+s.output;return i.model.startsWith(`claude`)?c=Math.round(c*1.15):i.model.startsWith(`grok`)&&(c=Math.round(c*1.03)),n.info(`Token count:`,c),e.json({input_tokens:c})}catch(t){return n.error(`Error counting tokens:`,t),e.json({input_tokens:1})}}function Yt(e){return e.contentBlockOpen?Object.values(e.toolCalls).some(t=>t.anthropicBlockIndex===e.contentBlockIndex):!1}function Xt(e,t){let n=[];if(e.choices.length===0)return n;let r=e.choices[0],{delta:i}=r;if(t.messageStartSent||=(n.push({type:`message_start`,message:{id:e.id,type:`message`,role:`assistant`,content:[],model:e.model,stop_reason:null,stop_sequence:null,usage:{input_tokens:(e.usage?.prompt_tokens??0)-(e.usage?.prompt_tokens_details?.cached_tokens??0),output_tokens:0,...e.usage?.prompt_tokens_details?.cached_tokens!==void 0&&{cache_read_input_tokens:e.usage.prompt_tokens_details.cached_tokens}}}}),!0),i.content&&(Yt(t)&&(n.push({type:`content_block_stop`,index:t.contentBlockIndex}),t.contentBlockIndex++,t.contentBlockOpen=!1),t.contentBlockOpen||=(n.push({type:`content_block_start`,index:t.contentBlockIndex,content_block:{type:`text`,text:``}}),!0),n.push({type:`content_block_delta`,index:t.contentBlockIndex,delta:{type:`text_delta`,text:i.content}})),i.tool_calls)for(let e of i.tool_calls){if(e.id&&e.function?.name){t.contentBlockOpen&&=(n.push({type:`content_block_stop`,index:t.contentBlockIndex}),t.contentBlockIndex++,!1);let r=t.contentBlockIndex;t.toolCalls[e.index]={id:e.id,name:e.function.name,anthropicBlockIndex:r},n.push({type:`content_block_start`,index:r,content_block:{type:`tool_use`,id:e.id,name:e.function.name,input:{}}}),t.contentBlockOpen=!0}if(e.function?.arguments){let r=t.toolCalls[e.index];r&&n.push({type:`content_block_delta`,index:r.anthropicBlockIndex,delta:{type:`input_json_delta`,partial_json:e.function.arguments}})}}return r.finish_reason&&(t.contentBlockOpen&&=(n.push({type:`content_block_stop`,index:t.contentBlockIndex}),!1),n.push({type:`message_delta`,delta:{stop_reason:It(r.finish_reason),stop_sequence:null},usage:{input_tokens:(e.usage?.prompt_tokens??0)-(e.usage?.prompt_tokens_details?.cached_tokens??0),output_tokens:e.usage?.completion_tokens??0,...e.usage?.prompt_tokens_details?.cached_tokens!==void 0&&{cache_read_input_tokens:e.usage.prompt_tokens_details.cached_tokens}}},{type:`message_stop`})),n}async function Zt(e){await H(y);let t=await e.req.text();if(n.debug(`Anthropic request payload:`,t.slice(0,1e3)),Nt(t)){y.manualApprove&&await V();let n=await Mt(t,e.req.raw.headers);return new Response(n.body,{status:n.status,headers:Pt(n.headers)})}let r=JSON.parse(t);n.debug(`Anthropic request payload:`,JSON.stringify(r));let i=Lt(r);n.debug(`Translated OpenAI request payload:`,JSON.stringify(i)),y.manualApprove&&await V();let a=await K(i);if(Qt(a)){n.debug(`Non-streaming response from Copilot:`,JSON.stringify(a).slice(-400));let t=Gt(a);return n.debug(`Translated Anthropic response:`,JSON.stringify(t)),e.json(t)}return n.debug(`Streaming response from Copilot`),m(e,async e=>{let t={messageStartSent:!1,contentBlockIndex:0,contentBlockOpen:!1,toolCalls:{}};for await(let r of a){if(n.debug(`Copilot raw stream event:`,JSON.stringify(r)),r.data===`[DONE]`)break;if(!r.data)continue;let i=JSON.parse(r.data),a=Xt(i,t);for(let t of a)n.debug(`Translated Anthropic event:`,JSON.stringify(t)),await e.writeSSE({event:t.type,data:JSON.stringify(t)})}})}const Qt=e=>Object.hasOwn(e,`choices`),X=new p;X.post(`/`,async e=>{try{return await Zt(e)}catch(t){return await O(e,t)}}),X.post(`/count_tokens`,async e=>{try{return await Jt(e)}catch(t){return await O(e,t)}});const Z=new p;Z.get(`/`,async e=>{try{y.models||await A();let t=y.models?.data.map(e=>({id:e.id,object:`model`,type:`model`,created:0,created_at:new Date(0).toISOString(),owned_by:e.vendor,display_name:e.name}));return e.json({object:`list`,data:t,has_more:!1})}catch(t){return await O(e,t)}});const $t=[`content-type`,`cache-control`,`x-request-id`];function en(e){return tn(e)?.model?.startsWith(`gpt`)??!1}function tn(e){try{return JSON.parse(e)}catch{return}}const nn=async(e,t)=>{let n=rn(e);return Ct({path:`/responses`,body:n,requestHeaders:t,initiator:`user`,errorMessage:`Failed to create responses`,throwOnError:!0})};function rn(e){let t=tn(e);if(!t?.tools||!Array.isArray(t.tools))return e;let n=new Set([`image_generation`]),r=t.tools.filter(e=>!n.has(e.type??``));return r.length===t.tools.length?e:(t.tools=r,JSON.stringify(t))}function an(e){return Tt(e,$t)}async function on(e){await H(y);let t=await e.req.text();if(!en(t))return e.json({error:{message:`Responses API is only enabled for GPT models.`,type:`invalid_request_error`}},400);y.manualApprove&&await V();let n=await nn(t,e.req.raw.headers);return new Response(n.body,{status:n.status,headers:an(n.headers)})}const Q=new p;Q.post(`/`,async e=>{try{return await on(e)}catch(t){return await O(e,t)}});const sn=new p;sn.get(`/`,e=>{try{return e.json({token:y.copilotToken})}catch(t){return B(`Error fetching token:`,t),e.json({error:`Failed to fetch token`,token:null},500)}});const cn=new p;cn.get(`/`,async e=>{try{let t=await F();return e.json(t)}catch(t){return B(`Error fetching Copilot usage:`,t),e.json({error:`Failed to fetch Copilot usage`},500)}});const $=new p;$.use(at()),$.use(ae()),$.route(`/`,xt),$.route(`/chat/completions`,q),$.route(`/models`,Z),$.route(`/embeddings`,J),$.route(`/responses`,Q),$.route(`/usage`,cn),$.route(`/token`,sn),$.route(`/v1/chat/completions`,q),$.route(`/v1/models`,Z),$.route(`/v1/embeddings`,J),$.route(`/v1/responses`,Q),$.route(`/v1/messages`,X);async function ln(e){e.proxyEnv&&it(),e.verbose&&(n.level=5,n.info(`Verbose logging enabled`)),y.accountType=e.accountType,e.accountType!==`individual`&&n.info(`Using ${e.accountType} plan GitHub account`),y.manualApprove=e.manual,y.rateLimitSeconds=e.rateLimit,y.rateLimitWait=e.rateLimitWait,y.showToken=e.showToken,await v(),await Le(),e.githubToken?(y.githubToken=e.githubToken,n.info(`Using provided GitHub token`)):await N(),await He(),await A(),n.info(`Available models: \n${y.models?.data.map(e=>`- ${e.id}`).join(` | ||
| `);let t=[];for(let n of e)switch(n.type){case`text`:t.push({type:`text`,text:n.text});break;case`thinking`:t.push({type:`text`,text:n.thinking});break;case`image`:t.push({type:`image_url`,image_url:{url:`data:${n.source.media_type};base64,${n.source.data}`}});break}return t}function Ut(e){if(e)return e.map(e=>({type:`function`,function:{name:e.name,description:e.description,parameters:e.input_schema}}))}function Wt(e){if(e)switch(e.type){case`auto`:return`auto`;case`any`:return`required`;case`tool`:return e.name?{type:`function`,function:{name:e.name}}:void 0;case`none`:return`none`;default:return}}function Gt(e){let t=[],n=[],r=null;r=e.choices[0]?.finish_reason??r;for(let i of e.choices){let e=Kt(i.message.content),a=qt(i.message.tool_calls);t.push(...e),n.push(...a),(i.finish_reason===`tool_calls`||r===`stop`)&&(r=i.finish_reason)}return{id:e.id,type:`message`,role:`assistant`,model:e.model,content:[...t,...n],stop_reason:It(r),stop_sequence:null,usage:{input_tokens:(e.usage?.prompt_tokens??0)-(e.usage?.prompt_tokens_details?.cached_tokens??0),output_tokens:e.usage?.completion_tokens??0,...e.usage?.prompt_tokens_details?.cached_tokens!==void 0&&{cache_read_input_tokens:e.usage.prompt_tokens_details.cached_tokens}}}}function Kt(e){return typeof e==`string`?[{type:`text`,text:e}]:Array.isArray(e)?e.filter(e=>e.type===`text`).map(e=>({type:`text`,text:e.text})):[]}function qt(e){return e?e.map(e=>({type:`tool_use`,id:e.id,name:e.function.name,input:JSON.parse(e.function.arguments)})):[]}async function Jt(e){try{let t=await e.req.text();if(n.debug(`Anthropic count_tokens payload:`,t.slice(0,1e3)),Nt(t)){let n=await Mt(t,e.req.raw.headers,`/v1/messages/count_tokens`);return new Response(n.body,{status:n.status,headers:Pt(n.headers)})}let r=e.req.header(`anthropic-beta`),i=JSON.parse(t),a=Lt(i),o=y.models?.data.find(e=>e.id===i.model);if(!o)return n.warn(`Model not found, returning default token count`),e.json({input_tokens:1});let s=await gt(a,o);if(i.tools&&i.tools.length>0){let e=!1;r?.startsWith(`claude-code`)&&(e=i.tools.some(e=>e.name.startsWith(`mcp__`))),e||(i.model.startsWith(`claude`)?s.input+=346:i.model.startsWith(`grok`)&&(s.input+=480))}let c=s.input+s.output;return i.model.startsWith(`claude`)?c=Math.round(c*1.15):i.model.startsWith(`grok`)&&(c=Math.round(c*1.03)),n.info(`Token count:`,c),e.json({input_tokens:c})}catch(t){return n.error(`Error counting tokens:`,t),e.json({input_tokens:1})}}function Yt(e){return e.contentBlockOpen?Object.values(e.toolCalls).some(t=>t.anthropicBlockIndex===e.contentBlockIndex):!1}function Xt(e,t){let n=[];if(e.choices.length===0)return n;let r=e.choices[0],{delta:i}=r;if(t.messageStartSent||=(n.push({type:`message_start`,message:{id:e.id,type:`message`,role:`assistant`,content:[],model:e.model,stop_reason:null,stop_sequence:null,usage:{input_tokens:(e.usage?.prompt_tokens??0)-(e.usage?.prompt_tokens_details?.cached_tokens??0),output_tokens:0,...e.usage?.prompt_tokens_details?.cached_tokens!==void 0&&{cache_read_input_tokens:e.usage.prompt_tokens_details.cached_tokens}}}}),!0),i.content&&(Yt(t)&&(n.push({type:`content_block_stop`,index:t.contentBlockIndex}),t.contentBlockIndex++,t.contentBlockOpen=!1),t.contentBlockOpen||=(n.push({type:`content_block_start`,index:t.contentBlockIndex,content_block:{type:`text`,text:``}}),!0),n.push({type:`content_block_delta`,index:t.contentBlockIndex,delta:{type:`text_delta`,text:i.content}})),i.tool_calls)for(let e of i.tool_calls){if(e.id&&e.function?.name){t.contentBlockOpen&&=(n.push({type:`content_block_stop`,index:t.contentBlockIndex}),t.contentBlockIndex++,!1);let r=t.contentBlockIndex;t.toolCalls[e.index]={id:e.id,name:e.function.name,anthropicBlockIndex:r},n.push({type:`content_block_start`,index:r,content_block:{type:`tool_use`,id:e.id,name:e.function.name,input:{}}}),t.contentBlockOpen=!0}if(e.function?.arguments){let r=t.toolCalls[e.index];r&&n.push({type:`content_block_delta`,index:r.anthropicBlockIndex,delta:{type:`input_json_delta`,partial_json:e.function.arguments}})}}return r.finish_reason&&(t.contentBlockOpen&&=(n.push({type:`content_block_stop`,index:t.contentBlockIndex}),!1),n.push({type:`message_delta`,delta:{stop_reason:It(r.finish_reason),stop_sequence:null},usage:{input_tokens:(e.usage?.prompt_tokens??0)-(e.usage?.prompt_tokens_details?.cached_tokens??0),output_tokens:e.usage?.completion_tokens??0,...e.usage?.prompt_tokens_details?.cached_tokens!==void 0&&{cache_read_input_tokens:e.usage.prompt_tokens_details.cached_tokens}}},{type:`message_stop`})),n}async function Zt(e){await H(y);let t=await e.req.text();if(n.debug(`Anthropic request payload:`,t.slice(0,1e3)),Nt(t)){y.manualApprove&&await V();let n=await Mt(t,e.req.raw.headers);return new Response(n.body,{status:n.status,headers:Pt(n.headers)})}let r=JSON.parse(t);n.debug(`Anthropic request payload:`,JSON.stringify(r));let i=Lt(r);n.debug(`Translated OpenAI request payload:`,JSON.stringify(i)),y.manualApprove&&await V();let a=await K(i);if(Qt(a)){n.debug(`Non-streaming response from Copilot:`,JSON.stringify(a).slice(-400));let t=Gt(a);return n.debug(`Translated Anthropic response:`,JSON.stringify(t)),e.json(t)}return n.debug(`Streaming response from Copilot`),m(e,async e=>{let t={messageStartSent:!1,contentBlockIndex:0,contentBlockOpen:!1,toolCalls:{}};for await(let r of a){if(n.debug(`Copilot raw stream event:`,JSON.stringify(r)),r.data===`[DONE]`)break;if(!r.data)continue;let i=JSON.parse(r.data),a=Xt(i,t);for(let t of a)n.debug(`Translated Anthropic event:`,JSON.stringify(t)),await e.writeSSE({event:t.type,data:JSON.stringify(t)})}})}const Qt=e=>Object.hasOwn(e,`choices`),X=new p;X.post(`/`,async e=>{try{return await Zt(e)}catch(t){return await O(e,t)}}),X.post(`/count_tokens`,async e=>{try{return await Jt(e)}catch(t){return await O(e,t)}});const Z=new p;Z.get(`/`,async e=>{try{try{await A()}catch(e){if(!y.models)throw e;n.warn(`Failed to refresh models, serving cached copy`,e)}let t=y.models?.data.map(e=>({id:e.id,object:`model`,type:`model`,created:0,created_at:new Date(0).toISOString(),owned_by:e.vendor,display_name:e.name}));return e.json({object:`list`,data:t,has_more:!1})}catch(t){return await O(e,t)}});const $t=[`content-type`,`cache-control`,`x-request-id`];function en(e){return tn(e)?.model?.startsWith(`gpt`)??!1}function tn(e){try{return JSON.parse(e)}catch{return}}const nn=async(e,t)=>{let n=rn(e);return Ct({path:`/responses`,body:n,requestHeaders:t,initiator:`user`,errorMessage:`Failed to create responses`,throwOnError:!0})};function rn(e){let t=tn(e);if(!t?.tools||!Array.isArray(t.tools))return e;let n=new Set([`image_generation`]),r=t.tools.filter(e=>!n.has(e.type??``));return r.length===t.tools.length?e:(t.tools=r,JSON.stringify(t))}function an(e){return Tt(e,$t)}async function on(e){await H(y);let t=await e.req.text();if(!en(t))return e.json({error:{message:`Responses API is only enabled for GPT models.`,type:`invalid_request_error`}},400);y.manualApprove&&await V();let n=await nn(t,e.req.raw.headers);return new Response(n.body,{status:n.status,headers:an(n.headers)})}const Q=new p;Q.post(`/`,async e=>{try{return await on(e)}catch(t){return await O(e,t)}});const sn=new p;sn.get(`/`,e=>{try{return e.json({token:y.copilotToken})}catch(t){return B(`Error fetching token:`,t),e.json({error:`Failed to fetch token`,token:null},500)}});const cn=new p;cn.get(`/`,async e=>{try{let t=await F();return e.json(t)}catch(t){return B(`Error fetching Copilot usage:`,t),e.json({error:`Failed to fetch Copilot usage`},500)}});const $=new p;$.use(at()),$.use(ae()),$.route(`/`,xt),$.route(`/chat/completions`,q),$.route(`/models`,Z),$.route(`/embeddings`,J),$.route(`/responses`,Q),$.route(`/usage`,cn),$.route(`/token`,sn),$.route(`/v1/chat/completions`,q),$.route(`/v1/models`,Z),$.route(`/v1/embeddings`,J),$.route(`/v1/responses`,Q),$.route(`/v1/messages`,X);async function ln(e){e.proxyEnv&&it(),e.verbose&&(n.level=5,n.info(`Verbose logging enabled`)),y.accountType=e.accountType,e.accountType!==`individual`&&n.info(`Using ${e.accountType} plan GitHub account`),y.manualApprove=e.manual,y.rateLimitSeconds=e.rateLimit,y.rateLimitWait=e.rateLimitWait,y.showToken=e.showToken,await v(),await Le(),e.githubToken?(y.githubToken=e.githubToken,n.info(`Using provided GitHub token`)):await N(),await He(),await A(),n.info(`Available models: \n${y.models?.data.map(e=>`- ${e.id}`).join(` | ||
| `)}`);let t=`http://localhost:${e.port}`;n.box(`🌐 Usage Viewer: https://billxc.github.io/copilot-api?endpoint=${t}/usage`),f({fetch:$.fetch,port:e.port,idleTimeout:255})}const un=e({meta:{name:`start`,description:`Start the Copilot API server`},args:{port:{alias:`p`,type:`string`,default:`4141`,description:`Port to listen on`},verbose:{alias:`v`,type:`boolean`,default:!1,description:`Enable verbose logging`},"account-type":{alias:`a`,type:`string`,default:`individual`,description:`Account type to use (individual, business, enterprise)`},manual:{type:`boolean`,default:!1,description:`Enable manual request approval`},"rate-limit":{alias:`r`,type:`string`,description:`Rate limit in seconds between requests`},wait:{alias:`w`,type:`boolean`,default:!1,description:`Wait instead of error when rate limit is hit. Has no effect if rate limit is not set`},"github-token":{alias:`g`,type:`string`,description:"Provide GitHub token directly (must be generated using the `auth` subcommand)"},"show-token":{type:`boolean`,default:!1,description:`Show GitHub and Copilot tokens on fetch and refresh`},"proxy-env":{type:`boolean`,default:!1,description:`Initialize proxy from environment variables`}},run({args:e}){let t=e[`rate-limit`],n=t===void 0?void 0:Number.parseInt(t,10);return ln({port:Number.parseInt(e.port,10),verbose:e.verbose,accountType:e[`account-type`],manual:e.manual,rateLimit:n,rateLimitWait:e.wait,githubToken:e[`github-token`],showToken:e[`show-token`],proxyEnv:e[`proxy-env`]})}}),dn=e({meta:{name:`xc-copilot-api`,version:h.version,description:`A wrapper around GitHub Copilot API to make it OpenAI compatible, making it usable for other tools.`},args:{version:{type:`boolean`,alias:`V`,description:`Show version number`}},run({args:e}){e.version&&(console.log(h.version),process.exit(0))},subCommands:{auth:We,start:un,config:Ye,"check-usage":Ge,debug:rt}});await t(dn);export{}; | ||
| //# sourceMappingURL=main.js.map |
+1
-1
| { | ||
| "name": "xc-copilot-api", | ||
| "version": "1.2.5", | ||
| "version": "1.2.6", | ||
| "description": "Turn GitHub Copilot into OpenAI/Anthropic API compatible server. Usable with Claude Code and Codex", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
Sorry, the diff of this file is too big to display
234200
0.26%