copilot-api-node20 0.8.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/main.js +1 -1
  2. 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 me,GITHUB_BASE_URL as J,GITHUB_CLIENT_ID as K,HTTPError as y,PATHS as k,copilotBaseUrl as j,copilotHeaders as N,ensurePaths as q,forwardError as A,getGitHubUser as fe,githubHeaders as W,initializeVSCodeIdentifiers as he,standardHeaders as V,state as s}from"./get-user-BJ4s6iMX.js";import{defineCommand as x,runMain as ge}from"citty";import r from"consola";import S from"node:fs/promises";import z from"node:os";import ye from"clipboardy";import h from"node:process";import{serve as we}from"srvx";import ke from"tiny-invariant";import{execSync as be}from"node:child_process";import{Hono as b}from"hono";import{cors as _e}from"hono/cors";import{streamSSE as Q}from"hono/streaming";import{events as ve}from"fetch-event-stream";import{request as Ce}from"undici";var Te=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 Te,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:W(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 xe(){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:K,scope:me}),signal:e.signal});if(!n.ok)throw new y("Failed to get device code",n);return await n.json()}finally{clearTimeout(o)}}const Se=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)}),$e=e=>e==null;async function Z(){let e=await Se();s.models=e}const Ie=()=>{let e=Y();s.vsCodeVersion=e,r.info(`Using VSCode version:${e}`)};async function Ae(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:K,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 Ee(){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 Oe=()=>S.readFile(k.GITHUB_TOKEN_PATH,"utf8"),Pe=e=>S.writeFile(k.GITHUB_TOKEN_PATH,e),je=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 Oe();if(t&&!e?.force){s.githubToken=t,s.showToken&&r.info("GitHub token:",t),await ee();return}r.info("Authentication required");let o=await xe();r.debug("Device code response:",o),r.info(`Please enter the code "${o.user_code}" in ${o.verification_uri}`);let n=await Ae(o);await Pe(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 fe();r.info(`Logged in as ${e.login}`)}async function Ne(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 qe=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 Ne({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:W(s),signal:e.signal});if(!n.ok)throw new y("Failed to get Copilot usage",n);return await n.json()}finally{clearTimeout(o)}},He=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,de=v>0?g/v*100:0,pe=w.percent_remaining;return`${d}:${g}/${v} used (${de.toFixed(1)}% used,${pe.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 Fe(){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 De(){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 Me(){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 Ue(){let[e,t]=await Promise.all([Fe(),Me()]);return{version:e,runtime:De(),paths:{APP_DIR:k.APP_DIR,GITHUB_TOKEN_PATH:k.GITHUB_TOKEN_PATH},tokenExists:t}}function Be(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 Ge(e){console.log(JSON.stringify(e,null,2))}async function Re(e){let t=await Ue();e.json?Ge(t):Be(t)}const Le=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 Re({json:e.json})}});function Je(){let{platform:e,ppid:t,env:o}=h;if(e==="win32"){try{let n=`wmic process get ParentProcessId,Name | findstr "${t}"`;if(be(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=Je(),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 We(){return`req_${Date.now()}_${Math.random().toString(36).slice(2,11)}`}function Ve(){return async(e,t)=>{let o=Date.now(),n=We();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 ze=[{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"}],Qe={haiku:"claude-haiku-4.5","sonnet-4.5":"claude-sonnet-4.5","sonnet-4":"claude-sonnet-4",opus:"claude-opus-41"};function Xe(e){return e.startsWith("anthropic/")?e.slice(10):e}function Ye(e){for(let t of ze)if(t.pattern.test(e))return t.family;return null}function Ze(e,t){let o=Qe[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 et(e,t){let o=Xe(e);if(t.includes(o))return o;let n=Ye(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 Ze(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=et(e,t);if(!o)throw new T(`Invalid model:'${e}'. Available models:${t.join(",")}`);return o}function tt(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 nt(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 nt(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 Ce(`${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?ve(d):await d.json()}finally{clearTimeout(u)}};function ot(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 it(e){await ie(s);let t=await e.req.json();r.debug("Request data:",JSON.stringify(t).slice(-400));try{t=ot(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(),$e(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(rt(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 rt=e=>Object.hasOwn(e,"choices"),B=new b;B.post("/",async e=>{try{return await it(e)}catch(t){return await A(e,t)}});const at=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{tt(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 at(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 st(e){return{model:e.model,messages:lt(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:pt(e.tools),tool_choice:mt(e.tool_choice)}}function Gt(e){return e}function lt(e,t){let o=ct(t),n=e.flatMap(a=>a.role==="user"?ut(a):dt(a));return[...o,...n]}function ct(e){return e?typeof e=="string"?[{role:"system",content:e}]:[{role:"system",content:e.map(o=>o.text).join(``)}]:[]}function ut(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 dt(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 pt(e){if(e)return e.map(t=>({type:"function",function:{name:t.name,description:t.description,parameters:t.input_schema}}))}function mt(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 ft(e){let t=[],o=[],n=null;n=e.choices[0]?.finish_reason??n;for(let a of e.choices){let i=ht(a.message.content),l=gt(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 ht(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 gt(e){return e?e.map(t=>({type:"tool_use",id:t.id,name:t.function.name,input:JSON.parse(t.function.arguments)})):[]}function yt(e){return e.contentBlockOpen?Object.values(e.toolCalls).some(t=>t.anthropicBlockIndex===e.contentBlockIndex):!1}function wt(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&&(yt(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 kt(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 bt(e){await ie(s);let t=await e.req.json();r.debug("API request payload:",JSON.stringify(t));let o=kt(e,t);if(!o)return;t=o;let n=st(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(_t(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=ft(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=wt(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 _t=e=>Object.hasOwn(e,"choices"),se=new b;se.post("/",async e=>{try{return await bt(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 le=new b;le.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 ce=new b;ce.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(Ve()),m.use(_e()),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",ce),m.route("/token",le),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",se),m.post("/v1/messages/count_tokens",e=>e.json({input_tokens:1}));const ue=[];function vt(){let e=async()=>{r.info("Gracefully shutting down...");for(let t of ue)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 Ct(e,t){if(!e.claudeCode)return;ke(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{ye.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 Tt(e){vt(),ue.push(()=>{r.debug("Cleaning up connectivity monitor"),C.stop()},()=>{r.debug("Cleaning up token management"),Ee()}),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(),Ie(),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 he(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 je(),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 Ct(e,t),r.box(`\u{1F310} Usage Viewer:https://ericc-ch.\u0067\u0069\u0074\u0068\u0075\u0062.io/copilot-api?endpoint=${t}/usage`),we({fetch:m.fetch,port:e.port})}const xt=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 Tt({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"]})}}),St=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:qe,start:xt,"check-usage":He,debug:Le}});await ge(St);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "copilot-api-node20",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
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": "^4.1.1",
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",