copilot-api-node20 0.8.0 → 0.9.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.
- package/dist/main.js +1 -1
- package/package.json +2 -2
package/dist/main.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{CompletionLogger as S,GITHUB_API_BASE_URL as G,GITHUB_APP_SCOPES as de,GITHUB_BASE_URL as R,GITHUB_CLIENT_ID as L,HTTPError as y,PATHS as w,copilotBaseUrl as E,copilotHeaders as P,ensurePaths as j,forwardError as I,getGitHubUser as pe,githubHeaders as J,initializeVSCodeIdentifiers as me,standardHeaders as W,state as s}from"./get-user-BJ4s6iMX.js";import{defineCommand as T,runMain as fe}from"citty";import i from"consola";import C from"node:fs/promises";import K from"node:os";import he from"clipboardy";import g from"node:process";import{serve as ge}from"srvx";import ye from"tiny-invariant";import{execSync as we}from"node:child_process";import{Hono as k}from"hono";import{cors as ke}from"hono/cors";import{streamSSE as V}from"hono/streaming";import{events as be}from"fetch-event-stream";import{request as _e}from"undici";var ve=class extends EventTarget{isOnline=!0;lastChecked=new Date().toISOString();consecutiveFailures=0;lastErrorType;lastErrorMessage;lastSuccessfulEndpoint;endpointFailureStats={};checkInterval;abortController;on(e,t){return this.addEventListener(e,t),this}off(e,t){return this.removeEventListener(e,t),this}start(){if(!s.connectivity.enabled){i.debug("Network monitoring disabled");return}i.info("Starting network monitor",{probeEndpoints:s.connectivity.probeEndpoints,fastInterval:s.connectivity.fastProbeInterval}),this.scheduleNextCheck();let e=()=>{this.stop(),process.exit(0)};process.on("SIGINT",e),process.on("SIGTERM",e)}stop(){i.debug("Stopping connectivity monitor"),this.checkInterval&&=(clearTimeout(this.checkInterval),void 0),this.abortController&&=(this.abortController.abort(),void 0)}scheduleNextCheck(){this.checkInterval&&clearTimeout(this.checkInterval);let e=this.isOnline?s.connectivity.slowProbeInterval:s.connectivity.fastProbeInterval,t=Math.random()*s.connectivity.jitterMaxMs,o=e+t;this.checkInterval=setTimeout(()=>{this.performConnectivityCheck().catch(n=>{i.error("Connectivity check failed:",n)})},o)}async performConnectivityCheck(){this.abortController=new AbortController;let e=setTimeout(()=>this.abortController?.abort(),s.connectivity.timeoutMs);try{let t=!1;for(let o of s.connectivity.probeEndpoints)try{if((await fetch(o,{method:"HEAD",signal:this.abortController.signal,headers:{"\u0055\u0073\u0065\u0072\u002d\u0041\u0067\u0065\u006e\u0074":"service-api-connectivity-monitor/1.0",...s.connectivity.dnsCache&&{"Cache-Control":"max-age=300"}}})).ok){t=!0,this.lastSuccessfulEndpoint=o;break}}catch(n){this.endpointFailureStats[o]=(this.endpointFailureStats[o]||0)+1,i.debug(`Probe failed for ${o}:`,n)}this.updateConnectivityState(t)}catch(t){this.handleConnectivityError(t)}finally{clearTimeout(e),this.scheduleNextCheck()}}updateConnectivityState(e){let t=this.isOnline;this.isOnline=e,this.lastChecked=new Date().toISOString(),e?(this.consecutiveFailures>0&&i.info(`Connectivity restored after ${this.consecutiveFailures} failures`),this.consecutiveFailures=0,this.lastErrorType=void 0,this.lastErrorMessage=void 0,t||this.dispatchEvent(new CustomEvent("online"))):(this.consecutiveFailures++,t&&(i.warn("Network lost"),this.dispatchEvent(new CustomEvent("offline"))))}handleConnectivityError(e){this.lastErrorType=e.name,this.lastErrorMessage=e.message,i.error("Connectivity check failed:",e),this.updateConnectivityState(!1)}getConnectivityStats(){return{isOnline:this.isOnline,lastChecked:this.lastChecked,consecutiveFailures:this.consecutiveFailures,lastErrorType:this.lastErrorType,lastErrorMessage:this.lastErrorMessage}}getPerformanceStats(){let e=this.isOnline?s.connectivity.slowProbeInterval:s.connectivity.fastProbeInterval,t=new Date(Date.now()+e+Math.random()*s.connectivity.jitterMaxMs).toISOString();return{currentInterval:e,nextCheckEstimate:t,lastSuccessfulEndpoint:this.lastSuccessfulEndpoint,endpointFailureStats:{...this.endpointFailureStats},jitterEnabled:s.connectivity.jitterMaxMs>0,connectionPooling:s.connectivity.connectionPooling,dnsCache:s.connectivity.dnsCache}}};const v=new ve,z=async()=>{let e=new AbortController,t=s.timeoutMs??12e4,o=setTimeout(()=>{e.abort()},t);try{let n=await fetch(`${G}/\u0063\u006f\u0070\u0069\u006c\u006f\u0074_internal/v2/token`,{headers:J(s),signal:e.signal});if(!n.ok)throw new y("\u0046\u0061\u0069\u006c\u0065\u0064\u0020\u0074\u006f\u0020\u0067\u0065\u0074\u0020\u0043\u006f\u0070\u0069\u006c\u006f\u0074\u0020\u0074\u006f\u006b\u0065\u006e",n);return await n.json()}finally{clearTimeout(o)}};async function Te(){let e=new AbortController,t=s.timeoutMs??12e4,o=setTimeout(()=>{e.abort()},t);try{let n=await fetch(`${R}/login/device/code`,{method:"POST",headers:W(),body:JSON.stringify({client_id:L,scope:de}),signal:e.signal});if(!n.ok)throw new y("Failed to get device code",n);return await n.json()}finally{clearTimeout(o)}}const Ce=async()=>{let e=new AbortController,t=s.timeoutMs??12e4,o=setTimeout(()=>{e.abort()},t);try{let n=await fetch(`${E(s)}/models`,{headers:P(s),signal:e.signal});if(!n.ok)throw new y("Failed to get models",n);return await n.json()}finally{clearTimeout(o)}};function Q(){return"1.105.0-insider"}Q();const A=e=>new Promise(t=>{setTimeout(t,e)}),xe=e=>e==null;async function X(){let e=await Ce();s.models=e}const Se=()=>{let e=Q();s.vsCodeVersion=e,i.info(`Using VSCode version:${e}`)};async function Ie(e){let t=(e.interval+1)*1e3;for(i.debug(`Polling access token with interval of ${t}ms`);;){let o=new AbortController,n=s.timeoutMs??12e4,r=setTimeout(()=>{o.abort()},n);try{let a=await fetch(`${R}/login/oauth/access_token`,{method:"POST",headers:W(),body:JSON.stringify({client_id:L,device_code:e.device_code,grant_type:"urn:ietf:params:oauth:grant-type:device_code"}),signal:o.signal});if(!a.ok){await A(t),i.error("Failed to poll access token:",await a.text());continue}let l=await a.json();i.debug("Polling access token response:",l);let{access_token:c}=l;if(c)return c;await A(t)}catch(a){if(a instanceof Error&&a.name==="AbortError"){i.error("Access token polling timed out"),await A(t);continue}throw a}finally{clearTimeout(r)}}}let N,H=!1,$,O;function Ae(){i.debug("Cleaning up token management"),N&&=(clearInterval(N),void 0),$&&=(v.off("online",$),void 0),O&&=(v.off("offline",O),void 0)}const $e=()=>C.readFile(w.GITHUB_TOKEN_PATH,"utf8"),Oe=e=>C.writeFile(w.GITHUB_TOKEN_PATH,e),Ee=async()=>{let{token:e,refresh_in:t}=await z();s.copilotToken=e,i.debug("GitHub Copilot Token fetched successfully!"),s.showToken&&i.info("Copilot token:",e);let o=(t-60)*1e3,n=async(r=5,a=1e3,l="scheduled")=>{if(H){i.debug("Service refresh already in progress,skipping");return}H=!0;try{for(let c=1;c<=r;c++)try{i.debug(`Refreshing Copilot token (${l},attempt ${c}/${r})`);let{token:u}=await z();s.copilotToken=u,i.debug("Copilot token refreshed successfully"),s.showToken&&i.info("Refreshed Copilot token:",u);return}catch(u){let f=c===r;if(i.error(`Failed to refresh Copilot token (attempt ${c}/${r}):`,u),f){i.error("All token refresh attempts failed. Service may be unavailable until next scheduled refresh.");return}let d=a*2**(c-1);i.debug(`Retrying token refresh in ${d}ms...`),await new Promise(p=>setTimeout(p,d))}}finally{H=!1}};N=setInterval(()=>{n(5,1e3,"scheduled").catch(r=>{i.error("Unexpected error in scheduled token refresh:",r)})},o),v.start(),$=()=>{i.debug("Network status restored,attempting immediate token refresh"),n(3,500,"network-restored").catch(r=>{i.error("Unexpected error in network-restored token refresh:",r)})},O=()=>{i.debug("Network status lost")},v.on("online",$),v.on("offline",O)};async function q(e){try{let t=await $e();if(t&&!e?.force){s.githubToken=t,s.showToken&&i.info("GitHub token:",t),await Y();return}i.info("Authentication required");let o=await Te();i.debug("Device code response:",o),i.info(`Please enter the code "${o.user_code}" in ${o.verification_uri}`);let n=await Ie(o);await Oe(n),s.githubToken=n,s.showToken&&i.info("GitHub token:",n),await Y()}catch(t){throw t instanceof y?(i.error("Failed to get GitHub token:",await t.response.json()),t):(i.error("Failed to get GitHub token:",t),t)}}async function Y(){let e=await pe();i.info(`Logged in as ${e.login}`)}async function Pe(e){e.verbose&&(i.level=5,i.info("Verbose logging enabled")),s.showToken=e.showToken,await j(),await q({force:!0}),i.success("GitHub token written to",w.GITHUB_TOKEN_PATH)}const je=T({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 Pe({verbose:e.verbose,showToken:e["show-token"]})}}),Z=async()=>{let e=new AbortController,t=s.timeoutMs??12e4,o=setTimeout(()=>{e.abort()},t);try{let n=await fetch(`${G}/\u0063\u006f\u0070\u0069\u006c\u006f\u0074_internal/user`,{headers:J(s),signal:e.signal});if(!n.ok)throw new y("Failed to get Copilot usage",n);return await n.json()}finally{clearTimeout(o)}},Ne=T({meta:{name:"check-usage",description:"Show current GitHub Copilot usage/quota information"},async run(){await j(),await q();try{let c=function(p,_){if(!_)return`${p}:N/A`;let h=_.entitlement,M=h-_.remaining,ce=h>0?M/h*100:0,ue=_.percent_remaining;return`${p}:${M}/${h} used (${ce.toFixed(1)}% used,${ue.toFixed(1)}% remaining)`};var e=c;let t=await Z(),o=t.quota_snapshots.premium_interactions,n=o.entitlement,r=n-o.remaining,a=n>0?r/n*100:0,l=o.percent_remaining,u=`Premium:${r}/${n} used (${a.toFixed(1)}% used,${l.toFixed(1)}% remaining)`,f=c("Chat",t.quota_snapshots.chat),d=c("Completions",t.quota_snapshots.completions);i.box(`Copilot Usage (plan:${t.copilot_plan})Quota resets:${t.quota_reset_date}Quotas:${u} ${f} ${d}`)}catch(t){i.error("Failed to fetch Copilot usage:",t),process.exit(1)}}});async function He(){try{let e=new URL("../package.json",import.meta.url).pathname,t=await C.readFile(e);return JSON.parse(t.toString()).version}catch{return"unknown"}}function qe(){let e=typeof Bun<"u";return{name:e?"bun":"node",version:e?Bun.version:process.version.slice(1),platform:K.platform(),arch:K.arch()}}async function Fe(){try{return(await C.stat(w.GITHUB_TOKEN_PATH)).isFile()?(await C.readFile(w.GITHUB_TOKEN_PATH,"utf8")).trim().length>0:!1}catch{return!1}}async function De(){let[e,t]=await Promise.all([He(),Fe()]);return{version:e,runtime:qe(),paths:{APP_DIR:w.APP_DIR,GITHUB_TOKEN_PATH:w.GITHUB_TOKEN_PATH},tokenExists:t}}function Ue(e){i.info(`copilot-api debugVersion:${e.version}Runtime:${e.runtime.name} ${e.runtime.version} (${e.runtime.platform} ${e.runtime.arch})Paths:- APP_DIR:${e.paths.APP_DIR}- GITHUB_TOKEN_PATH:${e.paths.GITHUB_TOKEN_PATH}Token exists:${e.tokenExists?"Yes":"No"}`)}function Be(e){console.log(JSON.stringify(e,null,2))}async function Me(e){let t=await De();e.json?Be(t):Ue(t)}const Ge=T({meta:{name:"debug",description:"Print debug information about the application"},args:{json:{type:"boolean",default:!1,description:"Output debug information as JSON"}},run({args:e}){return Me({json:e.json})}});function Re(){let{platform:e,ppid:t,env:o}=g;if(e==="win32"){try{let n=`wmic process get ParentProcessId,Name | findstr "${t}"`;if(we(n,{stdio:"pipe"}).toString().toLowerCase().includes("powershell.exe"))return"powershell"}catch{return"cmd"}return"cmd"}else{let n=o.SHELL;if(n){if(n.endsWith("zsh"))return"zsh";if(n.endsWith("fish"))return"fish";if(n.endsWith("bash"))return"bash"}return"sh"}}function Le(e,t=""){let o=Re(),n=Object.entries(e).filter(([,a])=>a!==void 0),r;switch(o){case"powershell":r=n.map(([a,l])=>`$env:${a} =${l}`).join(";");break;case"cmd":r=n.map(([a,l])=>`set ${a}=${l}`).join(" & ");break;case"fish":r=n.map(([a,l])=>`set -gx ${a} ${l}`).join(";");break;default:{let a=n.map(([l,c])=>`${l}=${c}`).join(" ");r=n.length>0?`export ${a}`:"";break}}return r&&t?`${r}${o==="cmd"?" & ":" && "}${t}`:r||t}function Je(){return`req_${Date.now()}_${Math.random().toString(36).slice(2,11)}`}function We(){return async(e,t)=>{let o=Date.now(),n=Je();e.set("requestId",n),e.header("x-request-id",n),S.registerCompletion(n,e,o),await t(),e.get("requestData")?.tokenUsage&&S.executeCompletion(n)}}const ee=async()=>{if(!await i.prompt("Accept incoming request?",{type:"confirm"}))throw new y("Request rejected",Response.json({message:"Request rejected"},{status:403}))},te={input:3e-6,output:15e-6};function b(e){let t=e.prompt_tokens||0,o=e.completion_tokens||0,n=e.total_tokens||t+o,r=t*te.input+o*te.output;return{inputTokens:t,outputTokens:o,totalTokens:n,estimatedCost:r,cachedTokens:e.prompt_tokens_details?.cached_tokens,acceptedPredictionTokens:e.completion_tokens_details?.accepted_prediction_tokens,rejectedPredictionTokens:e.completion_tokens_details?.rejected_prediction_tokens}}async function ne(e){if(e.rateLimitSeconds===void 0)return;let t=Date.now();if(!e.lastRequestTimestamp){e.lastRequestTimestamp=t;return}let o=(t-e.lastRequestTimestamp)/1e3;if(o>e.rateLimitSeconds){e.lastRequestTimestamp=t;return}let n=Math.ceil(e.rateLimitSeconds-o);if(!e.rateLimitWait)throw i.warn(`Rate limit exceeded. Need to wait ${n} more seconds.`),new y("Rate limit exceeded",Response.json({message:"Rate limit exceeded"},{status:429}));let r=n*1e3;i.warn(`Rate limit reached. Waiting ${n} seconds before proceeding...`),await A(r),e.lastRequestTimestamp=t,i.info("Rate limit wait completed,proceeding with request")}function Ke(e){let t=e,o=String.fromCodePoint(27),n=t.split(o);if(n.length>1){t=n[0];for(let r=1;r<n.length;r++){let a=n[r],l=a.match(/^\[[0-9;]*[a-z]/i);t+=l?a.slice(l[0].length):o+a}}return t.replaceAll(/[\u200B-\u200D\uFEFF]/g,"").replaceAll(/[\u2060-\u2064]/g,"").replaceAll(/[\u206A-\u206F]/g,"").replaceAll(/[\u180E\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]/g,"").replaceAll(/[\uFFF0-\uFFFF]/g,"").replaceAll(/[\x00-\x08\v\f\x0E-\x1F]/g,"")}function F(e){if(typeof e=="string")return Ke(e);if(Array.isArray(e))return e.map(o=>F(o));if(e&&typeof e=="object"){let t={};for(let[o,n]of Object.entries(e))t[o]=F(n);return t}return e}const oe=async e=>{if(!s.copilotToken)throw Error("\u0043\u006f\u0070\u0069\u006c\u006f\u0074\u0020\u0074\u006f\u006b\u0065\u006e\u0020\u006e\u006f\u0074\u0020\u0066\u006f\u0075\u006e\u0064");let t=F(e),o=t.messages.some(u=>typeof u.content!="string"&&u.content?.some(f=>f.type==="image_url")),n=t.messages.some(u=>["assistant","tool"].includes(u.role)),r={...P(s,o),"X-Initiator":n?"agent":"user"},a=new AbortController,l=s.timeoutMs??12e4,c=setTimeout(()=>{a.abort()},l);try{let{statusCode:u,headers:f,body:d}=await _e(`${E(s)}/\u0063\u0068\u0061\u0074\u002f\u0063\u006f\u006d\u0070\u006c\u0065\u0074\u0069\u006f\u006e\u0073`,{method:"POST",headers:r,body:JSON.stringify(t),signal:a.signal,headersTimeout:l,bodyTimeout:l*3}),p=new Response(d,{status:u,headers:f});if(!p.ok)throw new y("Failed to create chat completions",p);return t.stream?be(p):await p.json()}finally{clearTimeout(c)}};async function Ve(e){await ne(s);let t=await e.req.json();if(i.debug("Request data:",JSON.stringify(t).slice(-400)),e.set("requestData",{model:t.model}),s.manualApprove&&await ee(),xe(t.max_tokens)){let a=s.models?.data.find(l=>l.id===t.model);t={...t,max_tokens:a?.capabilities.limits.max_output_tokens},i.debug("Set max_tokens to:",JSON.stringify(t.max_tokens))}let o=performance.now(),n=await oe(t),r=performance.now()-o;if(ze(n)){let a=e.get("requestData")||{};return n.usage&&(a.tokenUsage=b(n.usage)),a.copilotDuration=r,e.set("requestData",a),i.debug("Response data:",JSON.stringify(n)),e.json(n)}return V(e,async a=>{let l=null;for await(let u of n){let f=u;if(u.data&&u.data!=="[DONE]")try{let d=JSON.parse(u.data);if(d.usage){l=d.usage;let p=e.get("requestData")||{};p.tokenUsage=b(l),p.copilotDuration=r,e.set("requestData",p)}if(d.usage?.prompt_tokens_details?.cached_tokens!==void 0){let p={...d,usage:{...d.usage,prompt_tokens_details:void 0}};f={...u,data:JSON.stringify(p)}}}catch{}await a.writeSSE(f)}if(l){let u=e.get("requestData")||{};u.tokenUsage||(u.tokenUsage=b(l),u.copilotDuration=r,e.set("requestData",u))}let c=e.get("requestId");c&&S.executeCompletion(c)})}const ze=e=>Object.hasOwn(e,"choices"),D=new k;D.post("/",async e=>{try{return await Ve(e)}catch(t){return await I(e,t)}});const Qe=async e=>{if(!s.copilotToken)throw Error("\u0043\u006f\u0070\u0069\u006c\u006f\u0074\u0020\u0074\u006f\u006b\u0065\u006e\u0020\u006e\u006f\u0074\u0020\u0066\u006f\u0075\u006e\u0064");let t=new AbortController,o=s.timeoutMs??12e4,n=setTimeout(()=>{t.abort()},o);try{let r=await fetch(`${E(s)}/embeddings`,{method:"POST",headers:P(s),body:JSON.stringify(e),signal:t.signal});if(!r.ok)throw new y("Failed to create embeddings",r);return await r.json()}finally{clearTimeout(n)}},U=new k;U.post("/",async e=>{try{let t=await e.req.json();e.set("requestData",{model:t.model});let o=performance.now(),n=await Qe(t),r=performance.now()-o,a=e.get("requestData")||{};return a.tokenUsage=b(n.usage),a.copilotDuration=r,e.set("requestData",a),e.json(n)}catch(t){return await I(e,t)}});function ie(e){return e===null?null:{stop:"end_turn",length:"max_tokens",tool_calls:"tool_use",content_filter:"end_turn"}[e]}function Xe(e){return{model:Ye(e.model),messages:Ze(e.messages,e.system),max_tokens:e.max_tokens,stop:e.stop_sequences,stream:e.stream,temperature:e.temperature,top_p:e.top_p,user:e.metadata?.user_id,tools:ot(e.tools),tool_choice:it(e.tool_choice)}}function Ye(e){return e.startsWith("claude-sonnet-4-")?e.replace(/^claude-sonnet-4-.*/,"claude-sonnet-4"):e.startsWith("claude-opus-")?e.replace(/^claude-opus-4-.*/,"claude-opus-4"):e}function Ze(e,t){let o=et(t),n=e.flatMap(r=>r.role==="user"?tt(r):nt(r));return[...o,...n]}function et(e){return e?typeof e=="string"?[{role:"system",content:e}]:[{role:"system",content:e.map(o=>o.text).join(``)}]:[]}function tt(e){let t=[];if(Array.isArray(e.content)){let o=e.content.filter(r=>r.type==="tool_result"),n=e.content.filter(r=>r.type!=="tool_result");for(let r of o)t.push({role:"tool",tool_call_id:r.tool_use_id,content:x(r.content)});n.length>0&&t.push({role:"user",content:x(n)})}else t.push({role:"user",content:x(e.content)});return t}function nt(e){if(!Array.isArray(e.content))return[{role:"assistant",content:x(e.content)}];let t=e.content.filter(a=>a.type==="tool_use"),o=e.content.filter(a=>a.type==="text"),n=e.content.filter(a=>a.type==="thinking"),r=[...o.map(a=>a.text),...n.map(a=>a.thinking)].join(``);return t.length>0?[{role:"assistant",content:r||null,tool_calls:t.map(a=>({id:a.id,type:"function",function:{name:a.name,arguments:JSON.stringify(a.input)}}))}]:[{role:"assistant",content:x(e.content)}]}function x(e){if(typeof e=="string")return e;if(!Array.isArray(e))return null;if(!e.some(n=>n.type==="image"))return e.filter(n=>n.type==="text"||n.type==="thinking").map(n=>n.type==="text"?n.text:n.thinking).join(``);let o=[];for(let n of e)switch(n.type){case"text":o.push({type:"text",text:n.text});break;case"thinking":o.push({type:"text",text:n.thinking});break;case"image":o.push({type:"image_url",image_url:{url:`data:${n.source.media_type};base64,${n.source.data}`}});break}return o}function ot(e){if(e)return e.map(t=>({type:"function",function:{name:t.name,description:t.description,parameters:t.input_schema}}))}function it(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 at(e){let t=[],o=[],n=null;n=e.choices[0]?.finish_reason??n;for(let r of e.choices){let a=rt(r.message.content),l=st(r.message.tool_calls);t.push(...a),o.push(...l),(r.finish_reason==="tool_calls"||n==="stop")&&(n=r.finish_reason)}return{id:e.id,type:"message",role:"assistant",model:e.model,content:[...t,...o],stop_reason:ie(n),stop_sequence:null,usage:{input_tokens:e.usage?.prompt_tokens??0,output_tokens:e.usage?.completion_tokens??0}}}function rt(e){return typeof e=="string"?[{type:"text",text:e}]:Array.isArray(e)?e.filter(t=>t.type==="text").map(t=>({type:"text",text:t.text})):[]}function st(e){return e?e.map(t=>({type:"tool_use",id:t.id,name:t.function.name,input:JSON.parse(t.function.arguments)})):[]}function lt(e){return e.contentBlockOpen?Object.values(e.toolCalls).some(t=>t.anthropicBlockIndex===e.contentBlockIndex):!1}function ct(e,t){let o=[];if(e.choices.length===0)return o;let n=e.choices[0],{delta:r}=n;if(t.messageStartSent||=(o.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,output_tokens:0}}}),!0),r.content&&(lt(t)&&(o.push({type:"content_block_stop",index:t.contentBlockIndex}),t.contentBlockIndex++,t.contentBlockOpen=!1),t.contentBlockOpen||=(o.push({type:"content_block_start",index:t.contentBlockIndex,content_block:{type:"text",text:""}}),!0),o.push({type:"content_block_delta",index:t.contentBlockIndex,delta:{type:"text_delta",text:r.content}})),r.tool_calls)for(let a of r.tool_calls){if(a.id&&a.function?.name){t.contentBlockOpen&&=(o.push({type:"content_block_stop",index:t.contentBlockIndex}),t.contentBlockIndex++,!1);let l=t.contentBlockIndex;t.toolCalls[a.index]={id:a.id,name:a.function.name,anthropicBlockIndex:l},o.push({type:"content_block_start",index:l,content_block:{type:"tool_use",id:a.id,name:a.function.name,input:{}}}),t.contentBlockOpen=!0}if(a.function?.arguments){let l=t.toolCalls[a.index];l&&o.push({type:"content_block_delta",index:l.anthropicBlockIndex,delta:{type:"input_json_delta",partial_json:a.function.arguments}})}}return n.finish_reason&&(t.contentBlockOpen&&=(o.push({type:"content_block_stop",index:t.contentBlockIndex}),!1),o.push({type:"message_delta",delta:{stop_reason:ie(n.finish_reason),stop_sequence:null},usage:{input_tokens:e.usage?.prompt_tokens??0,output_tokens:e.usage?.completion_tokens??0}},{type:"message_stop"})),o}async function ut(e){await ne(s);let t=await e.req.json();i.debug("API request payload:",JSON.stringify(t));let o=Xe(t);i.debug("Processed API request payload:",JSON.stringify(o)),e.set("requestData",{model:o.model});let n=performance.now();s.manualApprove&&await ee();let r=await oe(o),a=performance.now()-n;if(dt(r)){let l=e.get("requestData")||{};r.usage&&(l.tokenUsage=b(r.usage)),l.copilotDuration=a,e.set("requestData",l),i.debug("Non-streaming response from Copilot:",JSON.stringify(r).slice(-400));let c=at(r);return i.debug("Processed API response:",JSON.stringify(c)),e.json(c)}return i.debug("Streaming response from service"),V(e,async l=>{let c=null,u={messageStartSent:!1,contentBlockIndex:0,contentBlockOpen:!1,toolCalls:{}};for await(let d of r){if(i.debug("Copilot raw stream event:",JSON.stringify(d)),d.data==="[DONE]")break;if(!d.data)continue;let p=JSON.parse(d.data);if(p.usage){c=p.usage;let h=e.get("requestData")||{};h.tokenUsage=b(c),h.copilotDuration=a,e.set("requestData",h)}let _=ct(p,u);for(let h of _)i.debug("Processed API event:",JSON.stringify(h)),await l.writeSSE({event:h.type,data:JSON.stringify(h)})}if(c){let d=e.get("requestData")||{};d.tokenUsage||(d.tokenUsage=b(c),d.copilotDuration=a,e.set("requestData",d))}let f=e.get("requestId");f&&S.executeCompletion(f)})}const dt=e=>Object.hasOwn(e,"choices"),ae=new k;ae.post("/",async e=>{try{return await ut(e)}catch(t){return await I(e,t)}});const B=new k;B.get("/",async e=>{try{s.models||await X();let t=s.models?.data.map(o=>({id:o.id,object:"model",type:"model",created:0,created_at:new Date(0).toISOString(),owned_by:o.vendor,display_name:o.name,context_length:o.capabilities.limits?.max_context_window_tokens}));return e.json({object:"list",data:t,has_more:!1})}catch(t){return await I(e,t)}});const re=new k;re.get("/",e=>{try{return e.json({token:s.copilotToken})}catch(t){return console.error("Error fetching token:",t),e.json({error:"Failed to fetch token",token:null},500)}});const se=new k;se.get("/",async e=>{try{let t=await Z();return e.json(t)}catch(t){return console.error("Error fetching Copilot usage:",t),e.json({error:"Failed to fetch Copilot usage"},500)}});const m=new k;m.use(We()),m.use(ke()),m.get("/",e=>e.text("Server running")),m.route("/chat/completions",D),m.route("\u002f\u006d\u006f\u0064\u0065\u006c\u0073",B),m.route("\u002f\u0065\u006d\u0062\u0065\u0064\u0064\u0069\u006e\u0067\u0073",U),m.route("/usage",se),m.route("/token",re),m.route("\u002f\u0076\u0031\u002f\u0063\u0068\u0061\u0074\u002f\u0063\u006f\u006d\u0070\u006c\u0065\u0074\u0069\u006f\u006e\u0073",D),m.route("\u002f\u0076\u0031\u002f\u006d\u006f\u0064\u0065\u006c\u0073",B),m.route("\u002f\u0076\u0031\u002f\u0065\u006d\u0062\u0065\u0064\u0064\u0069\u006e\u0067\u0073",U),m.route("\u002f\u0076\u0031\u002f\u006d\u0065\u0073\u0073\u0061\u0067\u0065\u0073",ae),m.post("/v1/messages/count_tokens",e=>e.json({input_tokens:1}));const le=[];function pt(){let e=async()=>{i.info("Gracefully shutting down...");for(let t of le)try{await t()}catch(o){i.error("Error during cleanup:",o)}i.info("Shutdown complete"),g.exit(0)};g.on("SIGINT",e),g.on("SIGTERM",e),g.on("uncaughtException",t=>{i.error("Uncaught exception:",t),e().finally(()=>g.exit(1))}),g.on("unhandledRejection",(t,o)=>{i.error("Unhandled promise rejection at:",o,"reason:",t),e().finally(()=>g.exit(1))})}async function mt(e,t){if(!e.claudeCode)return;ye(s.models,"Models should be loaded by now");let o,n;if(e.model&&e.smallModel){let a=s.models.data.map(l=>l.id);a.includes(e.model)||(i.error(`Invalid model:${e.model}`),i.info(`Available models:${a.join(``)}`),g.exit(1)),a.includes(e.smallModel)||(i.error(`Invalid small model:${e.smallModel}`),i.info(`Available models:${a.join(``)}`),g.exit(1)),o=e.model,n=e.smallModel,i.info(`Using model:${o}`),i.info(`Using small model:${n}`)}else e.model||e.smallModel?(i.error("Both --model and --small-model must be specified when using command-line model selection"),g.exit(1)):(o=await i.prompt("Select a model to use with Claude Code",{type:"select",options:s.models.data.map(a=>a.id)}),n=await i.prompt("Select a small model to use with Claude Code",{type:"select",options:s.models.data.map(a=>a.id)}));let r=Le({ANTHROPIC_BASE_URL:t,ANTHROPIC_AUTH_TOKEN:"dummy",ANTHROPIC_MODEL:o,ANTHROPIC_SMALL_FAST_MODEL:n},"claude");try{he.writeSync(r),i.success("Copied Claude Code command to clipboard!")}catch{i.warn("Failed to copy to clipboard. Here is the Claude Code command:"),i.log(r)}}async function ft(e){pt(),le.push(()=>{i.debug("Cleaning up connectivity monitor"),v.stop()},()=>{i.debug("Cleaning up token management"),Ae()}),e.verbose&&(i.level=5,i.info("Verbose logging enabled")),s.accountType=e.accountType,e.accountType!=="individual"&&i.info(`Using ${e.accountType} plan GitHub account`),s.manualApprove=e.manual,s.rateLimitSeconds=e.rateLimit,s.rateLimitWait=e.rateLimitWait,s.showToken=e.showToken,s.timeoutMs=e.timeout,s.connectivity.enabled=!e.disableConnectivityMonitoring,await j(),Se(),e.githubToken?(s.githubToken=e.githubToken,i.info("Using provided auth token")):await q();try{let{getGitHubUser:o}=await import("./get-user-BT-kLu95.js"),n=await o();await me(s,n.login)}catch(o){i.error("Failed to get GitHub user info for machine ID generation:",o),i.error("Cannot proceed without GitHub user information"),g.exit(1)}await Ee(),await X(),i.info("Available services:");for(let o of s.models?.data??[]){let n=o.capabilities.limits?.max_context_window_tokens,r=n?` (${n.toLocaleString()} tokens)`:"";i.info(`- ${o.id}${r}`)}let t=`http://localhost:${e.port}`;await mt(e,t),i.box(`\u{1F310} Usage Viewer:https://ericc-ch.\u0067\u0069\u0074\u0068\u0075\u0062.io/copilot-api?endpoint=${t}/usage`),ge({fetch:m.fetch,port:e.port})}const ht=T({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"},"\u0067\u0069\u0074\u0068\u0075\u0062\u002d\u0074\u006f\u006b\u0065\u006e":{alias:"g",type:"string",description:"Provide GitHub token directly (must be generated using the `auth` subcommand)"},"claude-code":{alias:"c",type:"boolean",default:!1,description:"Generate a command to launch Claude Code with Copilot API config"},model:{alias:"m",type:"string",description:"Model to use with Claude Code (requires --claude-code)"},"small-model":{alias:"s",type:"string",description:"Small/fast model to use with Claude Code (requires --claude-code)"},"show-token":{type:"boolean",default:!1,description:"Show GitHub and Copilot tokens on fetch and refresh"},timeout:{alias:"t",type:"string",description:"API timeout in milliseconds (default:120000)"},"disable-connectivity-monitoring":{type:"boolean",default:!1,description:"Disable automatic network connectivity monitoring for token refresh"}},run({args:e}){let t=e["rate-limit"],o=t===void 0?void 0:Number.parseInt(t,10),n=e.timeout,r=n===void 0?12e4:Number.parseInt(n,10);return ft({port:Number.parseInt(e.port,10),verbose:e.verbose,accountType:e["account-type"],manual:e.manual,rateLimit:o,rateLimitWait:e.wait,githubToken:e["\u0067\u0069\u0074\u0068\u0075\u0062\u002d\u0074\u006f\u006b\u0065\u006e"],claudeCode:e["claude-code"],model:e.model,smallModel:e["small-model"],showToken:e["show-token"],timeout:r,disableConnectivityMonitoring:e["disable-connectivity-monitoring"]})}}),gt=T({meta:{name:"\u0063\u006f\u0070\u0069\u006c\u006f\u0074\u002d\u0061\u0070\u0069",description:"A wrapper around GitHub Copilot API to make it OpenAI compatible,making it usable for other tools."},subCommands:{auth:je,start:ht,"check-usage":Ne,debug:Ge}});await fe(gt);
|
|
2
|
+
import{CompletionLogger as I,GITHUB_API_BASE_URL as L,GITHUB_APP_SCOPES as fe,GITHUB_BASE_URL as J,GITHUB_CLIENT_ID as W,HTTPError as y,PATHS as k,copilotBaseUrl as j,copilotHeaders as N,ensurePaths as q,forwardError as A,getGitHubUser as he,githubHeaders as K,initializeVSCodeIdentifiers as ge,standardHeaders as V,state as s}from"./get-user-BJ4s6iMX.js";import{defineCommand as x,runMain as ye}from"citty";import r from"consola";import S from"node:fs/promises";import z from"node:os";import we from"clipboardy";import h from"node:process";import{serve as ke}from"srvx";import be from"tiny-invariant";import{execSync as _e}from"node:child_process";import{Hono as b}from"hono";import{cors as ve}from"hono/cors";import{streamSSE as Q}from"hono/streaming";import{events as Ce}from"fetch-event-stream";import{request as Te}from"undici";var xe=class extends EventTarget{isOnline=!0;lastChecked=new Date().toISOString();consecutiveFailures=0;lastErrorType;lastErrorMessage;lastSuccessfulEndpoint;endpointFailureStats={};checkInterval;abortController;on(e,t){return this.addEventListener(e,t),this}off(e,t){return this.removeEventListener(e,t),this}start(){if(!s.connectivity.enabled){r.debug("Network monitoring disabled");return}r.info("Starting network monitor",{probeEndpoints:s.connectivity.probeEndpoints,fastInterval:s.connectivity.fastProbeInterval}),this.scheduleNextCheck();let e=()=>{this.stop(),process.exit(0)};process.on("SIGINT",e),process.on("SIGTERM",e)}stop(){r.debug("Stopping connectivity monitor"),this.checkInterval&&=(clearTimeout(this.checkInterval),void 0),this.abortController&&=(this.abortController.abort(),void 0)}scheduleNextCheck(){this.checkInterval&&clearTimeout(this.checkInterval);let e=this.isOnline?s.connectivity.slowProbeInterval:s.connectivity.fastProbeInterval,t=Math.random()*s.connectivity.jitterMaxMs,o=e+t;this.checkInterval=setTimeout(()=>{this.performConnectivityCheck().catch(n=>{r.error("Connectivity check failed:",n)})},o)}async performConnectivityCheck(){this.abortController=new AbortController;let e=setTimeout(()=>this.abortController?.abort(),s.connectivity.timeoutMs);try{let t=!1;for(let o of s.connectivity.probeEndpoints)try{if((await fetch(o,{method:"HEAD",signal:this.abortController.signal,headers:{"\u0055\u0073\u0065\u0072\u002d\u0041\u0067\u0065\u006e\u0074":"service-api-connectivity-monitor/1.0",...s.connectivity.dnsCache&&{"Cache-Control":"max-age=300"}}})).ok){t=!0,this.lastSuccessfulEndpoint=o;break}}catch(n){this.endpointFailureStats[o]=(this.endpointFailureStats[o]||0)+1,r.debug(`Probe failed for ${o}:`,n)}this.updateConnectivityState(t)}catch(t){this.handleConnectivityError(t)}finally{clearTimeout(e),this.scheduleNextCheck()}}updateConnectivityState(e){let t=this.isOnline;this.isOnline=e,this.lastChecked=new Date().toISOString(),e?(this.consecutiveFailures>0&&r.info(`Connectivity restored after ${this.consecutiveFailures} failures`),this.consecutiveFailures=0,this.lastErrorType=void 0,this.lastErrorMessage=void 0,t||this.dispatchEvent(new CustomEvent("online"))):(this.consecutiveFailures++,t&&(r.warn("Network lost"),this.dispatchEvent(new CustomEvent("offline"))))}handleConnectivityError(e){this.lastErrorType=e.name,this.lastErrorMessage=e.message,r.error("Connectivity check failed:",e),this.updateConnectivityState(!1)}getConnectivityStats(){return{isOnline:this.isOnline,lastChecked:this.lastChecked,consecutiveFailures:this.consecutiveFailures,lastErrorType:this.lastErrorType,lastErrorMessage:this.lastErrorMessage}}getPerformanceStats(){let e=this.isOnline?s.connectivity.slowProbeInterval:s.connectivity.fastProbeInterval,t=new Date(Date.now()+e+Math.random()*s.connectivity.jitterMaxMs).toISOString();return{currentInterval:e,nextCheckEstimate:t,lastSuccessfulEndpoint:this.lastSuccessfulEndpoint,endpointFailureStats:{...this.endpointFailureStats},jitterEnabled:s.connectivity.jitterMaxMs>0,connectionPooling:s.connectivity.connectionPooling,dnsCache:s.connectivity.dnsCache}}};const C=new xe,X=async()=>{let e=new AbortController,t=s.timeoutMs??12e4,o=setTimeout(()=>{e.abort()},t);try{let n=await fetch(`${L}/\u0063\u006f\u0070\u0069\u006c\u006f\u0074_internal/v2/token`,{headers:K(s),signal:e.signal});if(!n.ok)throw new y("\u0046\u0061\u0069\u006c\u0065\u0064\u0020\u0074\u006f\u0020\u0067\u0065\u0074\u0020\u0043\u006f\u0070\u0069\u006c\u006f\u0074\u0020\u0074\u006f\u006b\u0065\u006e",n);return await n.json()}finally{clearTimeout(o)}};async function Se(){let e=new AbortController,t=s.timeoutMs??12e4,o=setTimeout(()=>{e.abort()},t);try{let n=await fetch(`${J}/login/device/code`,{method:"POST",headers:V(),body:JSON.stringify({client_id:W,scope:fe}),signal:e.signal});if(!n.ok)throw new y("Failed to get device code",n);return await n.json()}finally{clearTimeout(o)}}const $e=async()=>{let e=new AbortController,t=s.timeoutMs??12e4,o=setTimeout(()=>{e.abort()},t);try{let n=await fetch(`${j(s)}/models`,{headers:N(s),signal:e.signal});if(!n.ok)throw new y("Failed to get models",n);return await n.json()}finally{clearTimeout(o)}};function Y(){return"1.105.0-insider"}Y();const E=e=>new Promise(t=>{setTimeout(t,e)}),Ie=e=>e==null;async function Z(){let e=await $e();s.models=e}const Ae=()=>{let e=Y();s.vsCodeVersion=e,r.info(`Using VSCode version:${e}`)};async function Ee(e){let t=(e.interval+1)*1e3;for(r.debug(`Polling access token with interval of ${t}ms`);;){let o=new AbortController,n=s.timeoutMs??12e4,a=setTimeout(()=>{o.abort()},n);try{let i=await fetch(`${J}/login/oauth/access_token`,{method:"POST",headers:V(),body:JSON.stringify({client_id:W,device_code:e.device_code,grant_type:"urn:ietf:params:oauth:grant-type:device_code"}),signal:o.signal});if(!i.ok){await E(t),r.error("Failed to poll access token:",await i.text());continue}let l=await i.json();r.debug("Polling access token response:",l);let{access_token:u}=l;if(u)return u;await E(t)}catch(i){if(i instanceof Error&&i.name==="AbortError"){r.error("Access token polling timed out"),await E(t);continue}throw i}finally{clearTimeout(a)}}}let H,F=!1,O,P;function Oe(){r.debug("Cleaning up token management"),H&&=(clearInterval(H),void 0),O&&=(C.off("online",O),void 0),P&&=(C.off("offline",P),void 0)}const Pe=()=>S.readFile(k.GITHUB_TOKEN_PATH,"utf8"),je=e=>S.writeFile(k.GITHUB_TOKEN_PATH,e),Ne=async()=>{let{token:e,refresh_in:t}=await X();s.copilotToken=e,r.debug("GitHub Copilot Token fetched successfully!"),s.showToken&&r.info("Copilot token:",e);let o=(t-60)*1e3,n=async(a=5,i=1e3,l="scheduled")=>{if(F){r.debug("Service refresh already in progress,skipping");return}F=!0;try{for(let u=1;u<=a;u++)try{r.debug(`Refreshing Copilot token (${l},attempt ${u}/${a})`);let{token:c}=await X();s.copilotToken=c,r.debug("Copilot token refreshed successfully"),s.showToken&&r.info("Refreshed Copilot token:",c);return}catch(c){let f=u===a;if(r.error(`Failed to refresh Copilot token (attempt ${u}/${a}):`,c),f){r.error("All token refresh attempts failed. Service may be unavailable until next scheduled refresh.");return}let p=i*2**(u-1);r.debug(`Retrying token refresh in ${p}ms...`),await new Promise(d=>setTimeout(d,p))}}finally{F=!1}};H=setInterval(()=>{n(5,1e3,"scheduled").catch(a=>{r.error("Unexpected error in scheduled token refresh:",a)})},o),C.start(),O=()=>{r.debug("Network status restored,attempting immediate token refresh"),n(3,500,"network-restored").catch(a=>{r.error("Unexpected error in network-restored token refresh:",a)})},P=()=>{r.debug("Network status lost")},C.on("online",O),C.on("offline",P)};async function D(e){try{let t=await Pe();if(t&&!e?.force){s.githubToken=t,s.showToken&&r.info("GitHub token:",t),await ee();return}r.info("Authentication required");let o=await Se();r.debug("Device code response:",o),r.info(`Please enter the code "${o.user_code}" in ${o.verification_uri}`);let n=await Ee(o);await je(n),s.githubToken=n,s.showToken&&r.info("GitHub token:",n),await ee()}catch(t){throw t instanceof y?(r.error("Failed to get GitHub token:",await t.response.json()),t):(r.error("Failed to get GitHub token:",t),t)}}async function ee(){let e=await he();r.info(`Logged in as ${e.login}`)}async function qe(e){e.verbose&&(r.level=5,r.info("Verbose logging enabled")),s.showToken=e.showToken,await q(),await D({force:!0}),r.success("GitHub token written to",k.GITHUB_TOKEN_PATH)}const He=x({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 qe({verbose:e.verbose,showToken:e["show-token"]})}}),te=async()=>{let e=new AbortController,t=s.timeoutMs??12e4,o=setTimeout(()=>{e.abort()},t);try{let n=await fetch(`${L}/\u0063\u006f\u0070\u0069\u006c\u006f\u0074_internal/user`,{headers:K(s),signal:e.signal});if(!n.ok)throw new y("Failed to get Copilot usage",n);return await n.json()}finally{clearTimeout(o)}},Fe=x({meta:{name:"check-usage",description:"Show current GitHub Copilot usage/quota information"},async run(){await q(),await D();try{let u=function(d,w){if(!w)return`${d}:N/A`;let v=w.entitlement,g=v-w.remaining,pe=v>0?g/v*100:0,me=w.percent_remaining;return`${d}:${g}/${v} used (${pe.toFixed(1)}% used,${me.toFixed(1)}% remaining)`};var e=u;let t=await te(),o=t.quota_snapshots.premium_interactions,n=o.entitlement,a=n-o.remaining,i=n>0?a/n*100:0,l=o.percent_remaining,c=`Premium:${a}/${n} used (${i.toFixed(1)}% used,${l.toFixed(1)}% remaining)`,f=u("Chat",t.quota_snapshots.chat),p=u("Completions",t.quota_snapshots.completions);r.box(`Copilot Usage (plan:${t.copilot_plan})Quota resets:${t.quota_reset_date}Quotas:${c} ${f} ${p}`)}catch(t){r.error("Failed to fetch Copilot usage:",t),process.exit(1)}}});async function De(){try{let e=new URL("../package.json",import.meta.url).pathname,t=await S.readFile(e);return JSON.parse(t.toString()).version}catch{return"unknown"}}function Me(){let e=typeof Bun<"u";return{name:e?"bun":"node",version:e?Bun.version:process.version.slice(1),platform:z.platform(),arch:z.arch()}}async function Ue(){try{return(await S.stat(k.GITHUB_TOKEN_PATH)).isFile()?(await S.readFile(k.GITHUB_TOKEN_PATH,"utf8")).trim().length>0:!1}catch{return!1}}async function Be(){let[e,t]=await Promise.all([De(),Ue()]);return{version:e,runtime:Me(),paths:{APP_DIR:k.APP_DIR,GITHUB_TOKEN_PATH:k.GITHUB_TOKEN_PATH},tokenExists:t}}function Ge(e){r.info(`copilot-api debugVersion:${e.version}Runtime:${e.runtime.name} ${e.runtime.version} (${e.runtime.platform} ${e.runtime.arch})Paths:- APP_DIR:${e.paths.APP_DIR}- GITHUB_TOKEN_PATH:${e.paths.GITHUB_TOKEN_PATH}Token exists:${e.tokenExists?"Yes":"No"}`)}function Re(e){console.log(JSON.stringify(e,null,2))}async function Le(e){let t=await Be();e.json?Re(t):Ge(t)}const Je=x({meta:{name:"debug",description:"Print debug information about the application"},args:{json:{type:"boolean",default:!1,description:"Output debug information as JSON"}},run({args:e}){return Le({json:e.json})}});function We(){let{platform:e,ppid:t,env:o}=h;if(e==="win32"){try{let n=`wmic process get ParentProcessId,Name | findstr "${t}"`;if(_e(n,{stdio:"pipe"}).toString().toLowerCase().includes("powershell.exe"))return"powershell"}catch{return"cmd"}return"cmd"}else{let n=o.SHELL;if(n){if(n.endsWith("zsh"))return"zsh";if(n.endsWith("fish"))return"fish";if(n.endsWith("bash"))return"bash"}return"sh"}}function Ke(e,t=""){let o=We(),n=Object.entries(e).filter(([,i])=>i!==void 0),a;switch(o){case"powershell":a=n.map(([i,l])=>`$env:${i} =${l}`).join(";");break;case"cmd":a=n.map(([i,l])=>`set ${i}=${l}`).join(" & ");break;case"fish":a=n.map(([i,l])=>`set -gx ${i} ${l}`).join(";");break;default:{let i=n.map(([l,u])=>`${l}=${u}`).join(" ");a=n.length>0?`export ${i}`:"";break}}return a&&t?`${a}${o==="cmd"?" & ":" && "}${t}`:a||t}function Ve(){return`req_${Date.now()}_${Math.random().toString(36).slice(2,11)}`}function ze(){return async(e,t)=>{let o=Date.now(),n=Ve();e.set("requestId",n),e.header("x-request-id",n),I.registerCompletion(n,e,o),await t(),e.get("requestData")?.tokenUsage&&I.executeCompletion(n)}}const ne=async()=>{if(!await r.prompt("Accept incoming request?",{type:"confirm"}))throw new y("Request rejected",Response.json({message:"Request rejected"},{status:403}))},oe={input:3e-6,output:15e-6};function _(e){let t=e.prompt_tokens||0,o=e.completion_tokens||0,n=e.total_tokens||t+o,a=t*oe.input+o*oe.output;return{inputTokens:t,outputTokens:o,totalTokens:n,estimatedCost:a,cachedTokens:e.prompt_tokens_details?.cached_tokens,acceptedPredictionTokens:e.completion_tokens_details?.accepted_prediction_tokens,rejectedPredictionTokens:e.completion_tokens_details?.rejected_prediction_tokens}}const Qe=[{pattern:/haiku/i,family:"haiku"},{pattern:/(sonnet-4[.-]5|[.-]?3[.-]5[.-]?sonnet|[.-]?3[.-]7[.-]?sonnet)/i,family:"sonnet-4.5"},{pattern:/sonnet-4(?![.-]5|[.-]1)/i,family:"sonnet-4"},{pattern:/opus/i,family:"opus"}],Xe={haiku:"claude-haiku-4.5","sonnet-4.5":"claude-sonnet-4.5","sonnet-4":"claude-sonnet-4",opus:"claude-opus-41"};function Ye(e){return e.startsWith("anthropic/")?e.slice(10):e}function Ze(e){for(let t of Qe)if(t.pattern.test(e))return t.family;return null}function et(e,t){let o=Xe[e];if(!o)return null;if(t.includes(o))return o;if(e==="sonnet-4.5"){let n=["claude-3.5-sonnet"];for(let a of n)if(t.includes(a))return a}return null}function tt(e,t){let o=Ye(e);if(t.includes(o))return o;let n=Ze(o);if(!n)return null;let a=o.replace(/-\d{8}(?::.*)?$/,"");for(let i of t){let l=i.replace(/-\d{8}(?::.*)?$/,""),u=a.toLowerCase().replaceAll(/(\d)-(\d)/g,"$1.$2");if(l.toLowerCase().replaceAll(/(\d)-(\d)/g,"$1.$2")===u)return i}return et(n,t)}var T=class extends Error{statusCode;constructor(e,t=400){super(e),this.name="ModelValidationError",this.statusCode=t}};function M(e){if(!e||typeof e!="string")throw new T("Model name is required and must be a string");if(!s.models?.data)throw new T("Models not available. Please try again later.",503);let t=s.models.data.map(n=>n.id),o=tt(e,t);if(!o)throw new T(`Invalid model:'${e}'. Available models:${t.join(",")}`);return o}function nt(e){M(e)}async function ie(e){if(e.rateLimitSeconds===void 0)return;let t=Date.now();if(!e.lastRequestTimestamp){e.lastRequestTimestamp=t;return}let o=(t-e.lastRequestTimestamp)/1e3;if(o>e.rateLimitSeconds){e.lastRequestTimestamp=t;return}let n=Math.ceil(e.rateLimitSeconds-o);if(!e.rateLimitWait)throw r.warn(`Rate limit exceeded. Need to wait ${n} more seconds.`),new y("Rate limit exceeded",Response.json({message:"Rate limit exceeded"},{status:429}));let a=n*1e3;r.warn(`Rate limit reached. Waiting ${n} seconds before proceeding...`),await E(a),e.lastRequestTimestamp=t,r.info("Rate limit wait completed,proceeding with request")}function ot(e){let t=e,o=String.fromCodePoint(27),n=t.split(o);if(n.length>1){t=n[0];for(let a=1;a<n.length;a++){let i=n[a],l=i.match(/^\[[0-9;]*[a-z]/i);t+=l?i.slice(l[0].length):o+i}}return t.replaceAll(/[\u200B-\u200D\uFEFF]/g,"").replaceAll(/[\u2060-\u2064]/g,"").replaceAll(/[\u206A-\u206F]/g,"").replaceAll(/[\u180E\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]/g,"").replaceAll(/[\uFFF0-\uFFFF]/g,"").replaceAll(/[\x00-\x08\v\f\x0E-\x1F]/g,"")}function U(e){if(typeof e=="string")return ot(e);if(Array.isArray(e))return e.map(o=>U(o));if(e&&typeof e=="object"){let t={};for(let[o,n]of Object.entries(e))t[o]=U(n);return t}return e}const re=async e=>{if(!s.copilotToken)throw Error("\u0043\u006f\u0070\u0069\u006c\u006f\u0074\u0020\u0074\u006f\u006b\u0065\u006e\u0020\u006e\u006f\u0074\u0020\u0066\u006f\u0075\u006e\u0064");let t=U(e),o=t.messages.some(c=>typeof c.content!="string"&&c.content?.some(f=>f.type==="image_url")),n=t.messages.some(c=>["assistant","tool"].includes(c.role)),a={...N(s,o),"X-Initiator":n?"agent":"user"},i=new AbortController,l=s.timeoutMs??12e4,u=setTimeout(()=>{i.abort()},l);try{let{statusCode:c,headers:f,body:p}=await Te(`${j(s)}/\u0063\u0068\u0061\u0074\u002f\u0063\u006f\u006d\u0070\u006c\u0065\u0074\u0069\u006f\u006e\u0073`,{method:"POST",headers:a,body:JSON.stringify(t),signal:i.signal,headersTimeout:l,bodyTimeout:l*3}),d=new Response(p,{status:c,headers:f});if(!d.ok)throw new y("Failed to create chat completions",d);return t.stream?Ce(d):await d.json()}finally{clearTimeout(u)}};function it(e){let t=M(e.model);return t===e.model?e:(r.debug(`Normalized model from '${e.model}' to '${t}'`),{...e,model:t})}async function rt(e){await ie(s);let t=await e.req.json();r.debug("Request data:",JSON.stringify(t).slice(-400));try{t=it(t)}catch(i){if(i instanceof T)return e.json({error:{message:i.message,type:"invalid_request_error",code:"invalid_model"}},i.statusCode);throw i}if(e.set("requestData",{model:t.model}),s.manualApprove&&await ne(),Ie(t.max_tokens)){let i=s.models?.data.find(l=>l.id===t.model);t={...t,max_tokens:i?.capabilities.limits.max_output_tokens},r.debug("Set max_tokens to:",JSON.stringify(t.max_tokens))}let o=performance.now(),n=await re(t),a=performance.now()-o;if(at(n)){let i=e.get("requestData")||{};return n.usage&&(i.tokenUsage=_(n.usage)),i.copilotDuration=a,e.set("requestData",i),r.debug("Response data:",JSON.stringify(n)),e.json(n)}return Q(e,async i=>{let l=null;for await(let c of n){let f=c;if(c.data&&c.data!=="[DONE]")try{let p=JSON.parse(c.data);if(p.usage){l=p.usage;let d=e.get("requestData")||{};d.tokenUsage=_(l),d.copilotDuration=a,e.set("requestData",d)}if(p.usage?.prompt_tokens_details?.cached_tokens!==void 0){let d={...p,usage:{...p.usage,prompt_tokens_details:void 0}};f={...c,data:JSON.stringify(d)}}}catch{}await i.writeSSE(f)}if(l){let c=e.get("requestData")||{};c.tokenUsage||(c.tokenUsage=_(l),c.copilotDuration=a,e.set("requestData",c))}let u=e.get("requestId");u&&I.executeCompletion(u)})}const at=e=>Object.hasOwn(e,"choices"),B=new b;B.post("/",async e=>{try{return await rt(e)}catch(t){return await A(e,t)}});const st=async e=>{if(!s.copilotToken)throw Error("\u0043\u006f\u0070\u0069\u006c\u006f\u0074\u0020\u0074\u006f\u006b\u0065\u006e\u0020\u006e\u006f\u0074\u0020\u0066\u006f\u0075\u006e\u0064");let t=new AbortController,o=s.timeoutMs??12e4,n=setTimeout(()=>{t.abort()},o);try{let a=await fetch(`${j(s)}/embeddings`,{method:"POST",headers:N(s),body:JSON.stringify(e),signal:t.signal});if(!a.ok)throw new y("Failed to create embeddings",a);return await a.json()}finally{clearTimeout(n)}},G=new b;G.post("/",async e=>{try{let t=await e.req.json();try{nt(t.model)}catch(l){if(l instanceof T)return e.json({error:{message:l.message,type:"invalid_request_error",code:"invalid_model"}},l.statusCode);throw l}e.set("requestData",{model:t.model});let o=performance.now(),n=await st(t),a=performance.now()-o,i=e.get("requestData")||{};return i.tokenUsage=_(n.usage),i.copilotDuration=a,e.set("requestData",i),e.json(n)}catch(t){return await A(e,t)}});function ae(e){return e===null?null:{stop:"end_turn",length:"max_tokens",tool_calls:"tool_use",content_filter:"end_turn"}[e]}function lt(e){return{model:e.model,messages:ct(e.messages,e.system),max_tokens:e.max_tokens,stop:e.stop_sequences,stream:e.stream,temperature:e.temperature,top_p:e.top_p,user:e.metadata?.user_id,tools:mt(e.tools),tool_choice:ft(e.tool_choice)}}function Rt(e){return e}function ct(e,t){let o=ut(t),n=e.flatMap(a=>a.role==="user"?dt(a):pt(a));return[...o,...n]}function se(e){return e.startsWith("x-anthropic-billing-header")?e.replace(/^x-anthropic-billing-header:[^\n]*\n+/,""):e}function ut(e){if(!e)return[];if(typeof e=="string")return[{role:"system",content:se(e)}];{let t=e.map(o=>o.text).join(``);return[{role:"system",content:se(t)}]}}function dt(e){let t=[];if(Array.isArray(e.content)){let o=e.content.filter(a=>a.type==="tool_result"),n=e.content.filter(a=>a.type!=="tool_result");for(let a of o)t.push({role:"tool",tool_call_id:a.tool_use_id,content:$(a.content)});n.length>0&&t.push({role:"user",content:$(n)})}else t.push({role:"user",content:$(e.content)});return t}function pt(e){if(!Array.isArray(e.content))return[{role:"assistant",content:$(e.content)}];let t=e.content.filter(i=>i.type==="tool_use"),o=e.content.filter(i=>i.type==="text"),n=e.content.filter(i=>i.type==="thinking"),a=[...o.map(i=>i.text),...n.map(i=>i.thinking)].join(``);return t.length>0?[{role:"assistant",content:a||null,tool_calls:t.map(i=>({id:i.id,type:"function",function:{name:i.name,arguments:JSON.stringify(i.input)}}))}]:[{role:"assistant",content:$(e.content)}]}function $(e){if(typeof e=="string")return e;if(!Array.isArray(e))return null;if(!e.some(n=>n.type==="image"))return e.filter(n=>n.type==="text"||n.type==="thinking").map(n=>n.type==="text"?n.text:n.thinking).join(``);let o=[];for(let n of e)switch(n.type){case"text":o.push({type:"text",text:n.text});break;case"thinking":o.push({type:"text",text:n.thinking});break;case"image":o.push({type:"image_url",image_url:{url:`data:${n.source.media_type};base64,${n.source.data}`}});break}return o}function mt(e){if(e)return e.map(t=>({type:"function",function:{name:t.name,description:t.description,parameters:t.input_schema}}))}function ft(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 ht(e){let t=[],o=[],n=null;n=e.choices[0]?.finish_reason??n;for(let a of e.choices){let i=gt(a.message.content),l=yt(a.message.tool_calls);t.push(...i),o.push(...l),(a.finish_reason==="tool_calls"||n==="stop")&&(n=a.finish_reason)}return{id:e.id,type:"message",role:"assistant",model:e.model,content:[...t,...o],stop_reason:ae(n),stop_sequence:null,usage:{input_tokens:e.usage?.prompt_tokens??0,output_tokens:e.usage?.completion_tokens??0}}}function gt(e){return typeof e=="string"?[{type:"text",text:e}]:Array.isArray(e)?e.filter(t=>t.type==="text").map(t=>({type:"text",text:t.text})):[]}function yt(e){return e?e.map(t=>({type:"tool_use",id:t.id,name:t.function.name,input:JSON.parse(t.function.arguments)})):[]}function wt(e){return e.contentBlockOpen?Object.values(e.toolCalls).some(t=>t.anthropicBlockIndex===e.contentBlockIndex):!1}function kt(e,t){let o=[];if(e.choices.length===0)return o;let n=e.choices[0],{delta:a}=n;if(t.messageStartSent||=(o.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,output_tokens:0}}}),!0),a.content&&(wt(t)&&(o.push({type:"content_block_stop",index:t.contentBlockIndex}),t.contentBlockIndex++,t.contentBlockOpen=!1),t.contentBlockOpen||=(o.push({type:"content_block_start",index:t.contentBlockIndex,content_block:{type:"text",text:""}}),!0),o.push({type:"content_block_delta",index:t.contentBlockIndex,delta:{type:"text_delta",text:a.content}})),a.tool_calls)for(let i of a.tool_calls){if(i.id&&i.function?.name){t.contentBlockOpen&&=(o.push({type:"content_block_stop",index:t.contentBlockIndex}),t.contentBlockIndex++,!1);let l=t.contentBlockIndex;t.toolCalls[i.index]={id:i.id,name:i.function.name,anthropicBlockIndex:l},o.push({type:"content_block_start",index:l,content_block:{type:"tool_use",id:i.id,name:i.function.name,input:{}}}),t.contentBlockOpen=!0}if(i.function?.arguments){let l=t.toolCalls[i.index];l&&o.push({type:"content_block_delta",index:l.anthropicBlockIndex,delta:{type:"input_json_delta",partial_json:i.function.arguments}})}}return n.finish_reason&&(t.contentBlockOpen&&=(o.push({type:"content_block_stop",index:t.contentBlockIndex}),!1),o.push({type:"message_delta",delta:{stop_reason:ae(n.finish_reason),stop_sequence:null},usage:{input_tokens:e.usage?.prompt_tokens??0,output_tokens:e.usage?.completion_tokens??0}},{type:"message_stop"})),o}function bt(e,t){try{let o=M(t.model);return o===t.model?t:(r.debug(`Normalized model from '${t.model}' to '${o}'`),{...t,model:o})}catch(o){if(o instanceof T)return e.json({type:"error",error:{type:"invalid_request_error",message:o.message}},o.statusCode),null;throw o}}async function _t(e){await ie(s);let t=await e.req.json();r.debug("API request payload:",JSON.stringify(t));let o=bt(e,t);if(!o)return;t=o;let n=lt(t);r.debug("Processed API request payload:",JSON.stringify(n)),e.set("requestData",{model:n.model});let a=performance.now();s.manualApprove&&await ne();let i=await re(n),l=performance.now()-a;if(vt(i)){let u=e.get("requestData")||{};i.usage&&(u.tokenUsage=_(i.usage)),u.copilotDuration=l,e.set("requestData",u),r.debug("Non-streaming response from Copilot:",JSON.stringify(i).slice(-400));let c=ht(i);return r.debug("Processed API response:",JSON.stringify(c)),e.json(c)}return r.debug("Streaming response from service"),Q(e,async u=>{let c=null,f={messageStartSent:!1,contentBlockIndex:0,contentBlockOpen:!1,toolCalls:{}};for await(let d of i){if(r.debug("Copilot raw stream event:",JSON.stringify(d)),d.data==="[DONE]")break;if(!d.data)continue;let w=JSON.parse(d.data);if(w.usage){c=w.usage;let g=e.get("requestData")||{};g.tokenUsage=_(c),g.copilotDuration=l,e.set("requestData",g)}let v=kt(w,f);for(let g of v)r.debug("Processed API event:",JSON.stringify(g)),await u.writeSSE({event:g.type,data:JSON.stringify(g)})}if(c){let d=e.get("requestData")||{};d.tokenUsage||(d.tokenUsage=_(c),d.copilotDuration=l,e.set("requestData",d))}let p=e.get("requestId");p&&I.executeCompletion(p)})}const vt=e=>Object.hasOwn(e,"choices"),le=new b;le.post("/",async e=>{try{return await _t(e)}catch(t){return await A(e,t)}});const R=new b;R.get("/",async e=>{try{s.models||await Z();let t=s.models?.data.map(o=>({id:o.id,object:"model",type:"model",created:0,created_at:new Date(0).toISOString(),owned_by:o.vendor,display_name:o.name,context_length:o.capabilities.limits?.max_context_window_tokens}));return e.json({object:"list",data:t,has_more:!1})}catch(t){return await A(e,t)}});const ce=new b;ce.get("/",e=>{try{return e.json({token:s.copilotToken})}catch(t){return console.error("Error fetching token:",t),e.json({error:"Failed to fetch token",token:null},500)}});const ue=new b;ue.get("/",async e=>{try{let t=await te();return e.json(t)}catch(t){return console.error("Error fetching Copilot usage:",t),e.json({error:"Failed to fetch Copilot usage"},500)}});const m=new b;m.use(ze()),m.use(ve()),m.get("/",e=>e.text("Server running")),m.route("/chat/completions",B),m.route("\u002f\u006d\u006f\u0064\u0065\u006c\u0073",R),m.route("\u002f\u0065\u006d\u0062\u0065\u0064\u0064\u0069\u006e\u0067\u0073",G),m.route("/usage",ue),m.route("/token",ce),m.route("\u002f\u0076\u0031\u002f\u0063\u0068\u0061\u0074\u002f\u0063\u006f\u006d\u0070\u006c\u0065\u0074\u0069\u006f\u006e\u0073",B),m.route("\u002f\u0076\u0031\u002f\u006d\u006f\u0064\u0065\u006c\u0073",R),m.route("\u002f\u0076\u0031\u002f\u0065\u006d\u0062\u0065\u0064\u0064\u0069\u006e\u0067\u0073",G),m.route("\u002f\u0076\u0031\u002f\u006d\u0065\u0073\u0073\u0061\u0067\u0065\u0073",le),m.post("/v1/messages/count_tokens",e=>e.json({input_tokens:1}));const de=[];function Ct(){let e=async()=>{r.info("Gracefully shutting down...");for(let t of de)try{await t()}catch(o){r.error("Error during cleanup:",o)}r.info("Shutdown complete"),h.exit(0)};h.on("SIGINT",e),h.on("SIGTERM",e),h.on("uncaughtException",t=>{r.error("Uncaught exception:",t),e().finally(()=>h.exit(1))}),h.on("unhandledRejection",(t,o)=>{r.error("Unhandled promise rejection at:",o,"reason:",t),e().finally(()=>h.exit(1))})}async function Tt(e,t){if(!e.claudeCode)return;be(s.models,"Models should be loaded by now");let o,n;if(e.model&&e.smallModel){let i=s.models.data.map(l=>l.id);i.includes(e.model)||(r.error(`Invalid model:${e.model}`),r.info(`Available models:${i.join(``)}`),h.exit(1)),i.includes(e.smallModel)||(r.error(`Invalid small model:${e.smallModel}`),r.info(`Available models:${i.join(``)}`),h.exit(1)),o=e.model,n=e.smallModel,r.info(`Using model:${o}`),r.info(`Using small model:${n}`)}else e.model||e.smallModel?(r.error("Both --model and --small-model must be specified when using command-line model selection"),h.exit(1)):(o=await r.prompt("Select a model to use with Claude Code",{type:"select",options:s.models.data.map(i=>i.id)}),n=await r.prompt("Select a small model to use with Claude Code",{type:"select",options:s.models.data.map(i=>i.id)}));let a=Ke({ANTHROPIC_BASE_URL:t,ANTHROPIC_AUTH_TOKEN:"dummy",ANTHROPIC_MODEL:o,ANTHROPIC_SMALL_FAST_MODEL:n},"claude");try{we.writeSync(a),r.success("Copied Claude Code command to clipboard!")}catch{r.warn("Failed to copy to clipboard. Here is the Claude Code command:"),r.log(a)}}async function xt(e){Ct(),de.push(()=>{r.debug("Cleaning up connectivity monitor"),C.stop()},()=>{r.debug("Cleaning up token management"),Oe()}),e.verbose&&(r.level=5,r.info("Verbose logging enabled")),s.accountType=e.accountType,e.accountType!=="individual"&&r.info(`Using ${e.accountType} plan GitHub account`),s.manualApprove=e.manual,s.rateLimitSeconds=e.rateLimit,s.rateLimitWait=e.rateLimitWait,s.showToken=e.showToken,s.timeoutMs=e.timeout,s.connectivity.enabled=!e.disableConnectivityMonitoring,await q(),Ae(),e.githubToken?(s.githubToken=e.githubToken,r.info("Using provided auth token")):await D();try{let{getGitHubUser:o}=await import("./get-user-BT-kLu95.js"),n=await o();await ge(s,n.login)}catch(o){r.error("Failed to get GitHub user info for machine ID generation:",o),r.error("Cannot proceed without GitHub user information"),h.exit(1)}await Ne(),await Z(),r.info("Available services:");for(let o of s.models?.data??[]){let n=o.capabilities.limits?.max_context_window_tokens,a=n?` (${n.toLocaleString()} tokens)`:"";r.info(`- ${o.id}${a}`)}let t=`http://localhost:${e.port}`;await Tt(e,t),r.box(`\u{1F310} Usage Viewer:https://ericc-ch.\u0067\u0069\u0074\u0068\u0075\u0062.io/copilot-api?endpoint=${t}/usage`),ke({fetch:m.fetch,port:e.port})}const St=x({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"},"\u0067\u0069\u0074\u0068\u0075\u0062\u002d\u0074\u006f\u006b\u0065\u006e":{alias:"g",type:"string",description:"Provide GitHub token directly (must be generated using the `auth` subcommand)"},"claude-code":{alias:"c",type:"boolean",default:!1,description:"Generate a command to launch Claude Code with Copilot API config"},model:{alias:"m",type:"string",description:"Model to use with Claude Code (requires --claude-code)"},"small-model":{alias:"s",type:"string",description:"Small/fast model to use with Claude Code (requires --claude-code)"},"show-token":{type:"boolean",default:!1,description:"Show GitHub and Copilot tokens on fetch and refresh"},timeout:{alias:"t",type:"string",description:"API timeout in milliseconds (default:120000)"},"disable-connectivity-monitoring":{type:"boolean",default:!1,description:"Disable automatic network connectivity monitoring for token refresh"}},run({args:e}){let t=e["rate-limit"],o=t===void 0?void 0:Number.parseInt(t,10),n=e.timeout,a=n===void 0?12e4:Number.parseInt(n,10);return xt({port:Number.parseInt(e.port,10),verbose:e.verbose,accountType:e["account-type"],manual:e.manual,rateLimit:o,rateLimitWait:e.wait,githubToken:e["\u0067\u0069\u0074\u0068\u0075\u0062\u002d\u0074\u006f\u006b\u0065\u006e"],claudeCode:e["claude-code"],model:e.model,smallModel:e["small-model"],showToken:e["show-token"],timeout:a,disableConnectivityMonitoring:e["disable-connectivity-monitoring"]})}}),$t=x({meta:{name:"\u0063\u006f\u0070\u0069\u006c\u006f\u0074\u002d\u0061\u0070\u0069",description:"A wrapper around GitHub Copilot API to make it OpenAI compatible,making it usable for other tools."},subCommands:{auth:He,start:St,"check-usage":Fe,debug:Je}});await ye($t);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "copilot-api-node20",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.1",
|
|
4
4
|
"description": "Turn GitHub Copilot into OpenAI/Anthropic API compatible server. Usable with Claude Code! (Node v20+ fork)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"proxy",
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
"bumpp": "^10.2.3",
|
|
63
63
|
"esbuild": "^0.25.10",
|
|
64
64
|
"eslint": "^9.34.0",
|
|
65
|
-
"javascript-obfuscator": "^
|
|
65
|
+
"javascript-obfuscator": "^0.6.2",
|
|
66
66
|
"knip": "^5.63.0",
|
|
67
67
|
"lint-staged": "^16.1.5",
|
|
68
68
|
"prettier-plugin-packagejson": "^2.5.19",
|