copilot-api-node20 0.11.1 → 0.12.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.
- package/README.md +1 -0
- package/dist/get-user-CSS558OK.js +1 -0
- package/dist/get-user-CkQLlbpH.js +1 -0
- package/dist/main.js +18 -1
- package/package.json +18 -10
- package/dist/get-user-BJ4s6iMX.js +0 -1
- package/dist/get-user-BT-kLu95.js +0 -1
package/README.md
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import e from"consola";import t from"node:fs/promises";import n from"node:os";import r from"node:path";import i from"node:process";import{createHash as a,randomBytes as o,randomUUID as s}from"node:crypto";const c=r.join(n.homedir(),`.local`,`share`,`\u0063\u006f\u0070\u0069\u006c\u006f\u0074-api`),l=r.join(c,`\u0067\u0069\u0074\u0068\u0075\u0062_token`),u=r.join(c,`machine_id`),d=r.join(c,`session_id`),f={APP_DIR:c,GITHUB_TOKEN_PATH:l,MACHINE_ID_PATH:u,SESSION_ID_PATH:d};async function p(){await t.mkdir(f.APP_DIR,{recursive:!0}),await m(f.GITHUB_TOKEN_PATH),await m(f.SESSION_ID_PATH)}async function m(e){try{await t.access(e,t.constants.W_OK)}catch{await t.writeFile(e,``),await t.chmod(e,384)}}const h={accountType:`individual`,manualApprove:!1,rateLimitWait:!1,showToken:!1,connectivity:{enabled:!0,probeEndpoints:[`https://api.\u0067\u0069\u0074\u0068\u0075\u0062.com`,`https://www.google.com`,`https://1.1.1.1`],fastProbeInterval:5e3,slowProbeInterval:6e4,timeoutMs:5e3,jitterMaxMs:1e3,connectionPooling:!0,dnsCache:!0}};let g;const _={byModel:new Map};let v;function y(){if(_.byModel.size!==0){for(let[e,t]of _.byModel)S(`usage_stats`,{model:e},{requests:t.requests,inputTokens:t.inputTokens,outputTokens:t.outputTokens});_.byModel.clear()}}function b(e,t,n){if(!g)return;let r=_.byModel.get(e);r?(r.requests++,r.inputTokens+=t,r.outputTokens+=n):_.byModel.set(e,{requests:1,inputTokens:t,outputTokens:n})}async function x(e){i.env.OTEL_SERVICE_NAME=`\u0063\u006f\u0070\u0069\u006c\u006f\u0074-api`,i.env.OTEL_RESOURCE_ATTRIBUTES=[`service.version=${e.version}`,`service.instance.id=${e.machineId??n.hostname()}`].join(`,`);let t=await import(`applicationinsights`);t.default.setup(e.connectionString).setAutoCollectRequests(!1).setAutoCollectPerformance(!1,!1).setAutoCollectExceptions(!1).setAutoCollectDependencies(!1).setAutoCollectConsole(!1),g=t.default.defaultClient,g.commonProperties={accountType:e.accountType,runtime:e.runtime.name,runtimeVersion:e.runtime.version,userId:e.userId,os:`${e.runtime.platform} ${e.runtime.arch}`},t.default.start(),v&&clearInterval(v),v=setInterval(y,3e5),v.unref()}function S(e,t,n){g?.trackEvent({name:e,properties:t,measurements:n})}function C(e,t,n){g?.trackException({exception:e,properties:t,measurements:n})}async function w(){g&&(v&&clearInterval(v),y(),await g.flush())}const T=()=>({"content-type":`application/json`,accept:`application/json`}),E=`0.39.2026030604`,D=`\u0063\u006f\u0070\u0069\u006c\u006f\u0074-chat/${E}`,O=`\u0047\u0069\u0074\u0048\u0075\u0062\u0043\u006f\u0070\u0069\u006c\u006f\u0074Chat/${E}`,k=e=>{let t=a(`sha256`);return t.update(process.platform),t.update(process.arch),t.update(process.env.USER||process.env.USERNAME||`anonymous`),t.update(n.hostname()),t.update(e),t.update(Date.now().toString()),t.update(o(16)),t.digest(`hex`)},A=e=>{let t=e.replaceAll(/[^\w.-]/g,`_`).trim();if(t.length===0||t===`.`||t===`..`||/^[_.]+$/.test(t))throw Error(`Invalid \u0047\u0069\u0074\u0048\u0075\u0062 username: cannot be empty or consist only of special characters after sanitization`);return`${f.MACHINE_ID_PATH}_${t}`},j=async e=>{let n=A(e);try{let e=await t.readFile(n,`utf8`);if(e.trim())return e.trim()}catch{}let r=k(e);return await t.writeFile(n,r),await t.chmod(n,384),r},M=async()=>{try{let e=await t.readFile(f.SESSION_ID_PATH,`utf8`);if(e.trim())return e.trim()}catch{}let e=s();return await t.writeFile(f.SESSION_ID_PATH,e),await t.chmod(f.SESSION_ID_PATH,384),e},N=async(e,t)=>{e.machineId||=await j(t),e.sessionId||=await M()},P=e=>e.accountType===`individual`?`https://api.\u0067\u0069\u0074\u0068\u0075\u0062\u0063\u006f\u0070\u0069\u006c\u006f\u0074.com`:`https://api.${e.accountType}.\u0067\u0069\u0074\u0068\u0075\u0062\u0063\u006f\u0070\u0069\u006c\u006f\u0074.com`,F=(e,t=!1)=>{if(!e.machineId||!e.sessionId)throw Error(`\u0056\u0053\u0043\u006f\u0064\u0065 identifiers not initialized. Call initialize\u0056\u0053\u0043\u006f\u0064\u0065Identifiers() during startup.`);let n=s(),r={Authorization:`Bearer ${e.\u0063\u006f\u0070\u0069\u006c\u006f\u0074Token}`,"Content-Type":`application/json`,accept:`*/*`,"accept-encoding":`br, gzip, deflate`,"accept-language":`*`,"sec-fetch-mode":`cors`,"\u0043\u006f\u0070\u0069\u006c\u006f\u0074-Integration-Id":`\u0076\u0073\u0063\u006f\u0064\u0065-chat`,"Editor-Version":`\u0076\u0073\u0063\u006f\u0064\u0065/${e.\u0076\u0073\u0043\u006f\u0064\u0065Version}`,"Editor-Plugin-Version":D,"User-Agent":O,"\u0056\u0053\u0063\u006f\u0064\u0065-MachineId":e.machineId,"\u0056\u0053\u0063\u006f\u0064\u0065-SessionId":e.sessionId,"\u004f\u0070\u0065\u006e\u0041\u0049-Intent":`conversation-agent`,"X-Interaction-Type":`conversation-agent`,"X-Agent-Task-Id":n,"X-\u0056\u0053\u0043\u006f\u0064\u0065-User-Agent-Library-Version":`node-fetch`,"X-\u0047\u0069\u0074\u0048\u0075\u0062-Api-Version":`2025-05-01`,"X-Interaction-Id":s(),"X-Request-Id":n};return t&&(r[`\u0063\u006f\u0070\u0069\u006c\u006f\u0074-vision-request`]=`true`),r},I=`https://api.\u0067\u0069\u0074\u0068\u0075\u0062.com`,L=e=>({...T(),authorization:`token ${e.\u0067\u0069\u0074\u0068\u0075\u0062Token}`,"editor-version":`\u0076\u0073\u0063\u006f\u0064\u0065/${e.\u0076\u0073\u0043\u006f\u0064\u0065Version}`,"editor-plugin-version":D,"user-agent":O,"x-\u0067\u0069\u0074\u0068\u0075\u0062-api-version":`2025-04-01`,"x-\u0076\u0073\u0063\u006f\u0064\u0065-user-agent-library-version":`node-fetch`}),R=`https://\u0067\u0069\u0074\u0068\u0075\u0062.com`,z=`\u0030\u0031\u0061\u0062\u0038\u0061\u0063\u0039\u0034\u0030\u0030\u0063\u0034\u0065\u0034\u0032\u0039\u0062\u0032\u0033`,B=[`user:email`].join(` `),V=e=>e>=1e5||e>=1e4?`${Math.round(e/1e3)}K`:e>=1e3?`${(e/1e3).toFixed(1)}K`:e.toString(),H=(e,t)=>e.padEnd(t),U=(e,t)=>{if(!h.models)return``;let n=h.models.data.find(e=>e.id===t);if(!n)return``;let r=n.capabilities.limits?.max_context_window_tokens;if(!r)return``;let i=(e/r*100).toFixed(1);return` (${i}%)`},W=e=>{let t=[];if(e.model){let n=H(e.model,18);t.push(n)}if(e.tokenUsage){let n=e.tokenUsage,r=(n.inputTokens||0)+(n.outputTokens||0),i=e.model?U(r,e.model):``,a=V(n.inputTokens||0).padStart(5),o=V(n.outputTokens||0).padStart(5),s=`↑${a} │ ↓${o}`,c=H(s,18),l=V(r),u=i?`${l}${i.padStart(15-l.length)}`:l.padEnd(15);t.push(`Tokens: ${c} | Context: ${u}`)}else if(e.model){let e=H(`N/A`,18),n=`N/A`.padEnd(15);t.push(`Tokens: ${e} | Context: ${n}`)}if(e.copilotDuration){let n=H(`${Math.round(e.\u0063\u006f\u0070\u0069\u006c\u006f\u0074Duration)}ms`,8);t.push(`API: ${n}`)}return t.length>0?` | ${t.join(` | `)}`:``},G={completionCallbacks:new Map,registerCompletion(e,t,n){this.completionCallbacks.set(e,{context:t,startTime:n,requestId:e})},executeCompletion(e){let t=this.completionCallbacks.get(e);t&&(this.logCompletion(t),this.completionCallbacks.delete(e))},logCompletion(t){let{context:n,startTime:r}=t,i=Date.now(),a=i-r,o=n.get(`requestData`),s=H(n.req.method,4),c=H(n.req.path,21),l=H(n.res.status.toString(),3),u=H(`${a}ms`,8),d=` --> ${s}${c}${l} ${u}`;o&&(d+=W(o)),e.info(d),o?.model&&o.tokenUsage&&b(o.model,o.tokenUsage.inputTokens??0,o.tokenUsage.outputTokens??0)},logRateLimit(t,n){let{context:r,startTime:i}=t,a=Date.now(),o=a-i,s=n.headers.get(`x-ratelimit-exceeded`)||``,c=s.split(`:`)[1]||`unknown`,l=n.headers.get(`retry-after`)||n.headers.get(`x-ratelimit-user-retry-after`)||`?`,u=H(r.req.method,4),d=H(r.req.path,21),f=H(`429`,3),p=H(`${o}ms`,8),m=`⚠ --> ${u}${d}${f} ${p}`;m+=` | Rate limited (${l}s retry) | ${c}`;let h=r.get(`requestData`);if(h?.copilotDuration){let e=H(`${Math.round(h.\u0063\u006f\u0070\u0069\u006c\u006f\u0074Duration)}ms`,8);m+=` | API: ${e}`}e.info(m),S(`rate_limit_upstream`,{model:h?.model??`unknown`,path:r.req.path,rateLimitType:c,retryAfter:l},{durationMs:o})},cleanup(){let e=1e3,t=Date.now()-300*1e3;for(let[e,n]of this.completionCallbacks)n.startTime<t&&this.completionCallbacks.delete(e);if(this.completionCallbacks.size>e){let t=Array.from(this.completionCallbacks.entries()).sort(([,e],[,t])=>e.startTime-t.startTime),n=t.slice(0,t.length-e);for(let[e]of n)this.completionCallbacks.delete(e)}}};setInterval(()=>G.cleanup(),60*1e3);var K=class extends Error{response;constructor(e,t){super(e),this.response=t}};async function q(t,n){if(n instanceof K&&n.response.status===429){let e=t.get(`requestId`),r=G.completionCallbacks.get(e);r&&(G.logRateLimit(r,n.response),G.completionCallbacks.delete(e));let i=await n.response.text(),a;try{a=JSON.parse(i)}catch{a={error:{message:i,type:`error`}}}return t.json(a,429)}if(e.error(`Error occurred:`,n),n instanceof K){let r=await n.response.text(),i;try{i=JSON.parse(r)}catch{i=r}return e.error(`HTTP error:`,i),C(n,{statusCode:String(n.response.status),path:t.req.path,errorType:`HTTPError`}),t.json({error:{message:r,type:`error`}},n.response.status)}let r=n instanceof Error?n:Error(String(n));return C(r,{path:t.req.path,errorType:r.name}),t.json({error:{message:r.message,type:`error`}},500)}async function J(){let e=new AbortController,t=h.timeoutMs??12e4,n=setTimeout(()=>{e.abort()},t);try{let t=await fetch(`${I}/user`,{headers:{authorization:`token ${h.\u0067\u0069\u0074\u0068\u0075\u0062Token}`,...T()},signal:e.signal});if(!t.ok)throw new K(`Failed to get \u0047\u0069\u0074\u0048\u0075\u0062 user`,t);return await t.json()}finally{clearTimeout(n)}}export{G as _c1,I as _g1,B as _g4,R as _g2,z as _g3,K as HTTPError,f as PATHS,P as _s1,F as _s2,p as ensurePaths,w as _t1,q as _c2,J as _s4,L as _s3,x as _t2,N as _s5,T as _c3,h as state,S as _t3,C as _t4};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_s4 as e}from"./get-user-CSS558OK.js";export{e as _s4};
|
package/dist/main.js
CHANGED
|
@@ -1,2 +1,19 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{CompletionLogger as A,GITHUB_API_BASE_URL as J,GITHUB_APP_SCOPES as fe,GITHUB_BASE_URL as W,GITHUB_CLIENT_ID as K,HTTPError as w,PATHS as b,copilotBaseUrl as q,copilotHeaders as N,ensurePaths as H,forwardError as O,getGitHubUser as he,githubHeaders as V,initializeVSCodeIdentifiers as ge,standardHeaders as z,state as s}from"./get-user-BJ4s6iMX.js";import{defineCommand as x,runMain as ye}from"citty";import a from"consola";import $ from"node:fs/promises";import Q from"node:os";import we from"clipboardy";import g 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 _}from"hono";import{cors as ve}from"hono/cors";import{streamSSE as X}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){a.debug("Network monitoring disabled");return}a.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(){a.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=>{a.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,a.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&&a.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&&(a.warn("Network lost"),this.dispatchEvent(new CustomEvent("offline"))))}handleConnectivityError(e){this.lastErrorType=e.name,this.lastErrorMessage=e.message,a.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,Y=async()=>{let e=new AbortController,t=s.timeoutMs??12e4,o=setTimeout(()=>{e.abort()},t);try{let n=await fetch(`${J}/\u0063\u006f\u0070\u0069\u006c\u006f\u0074_internal/v2/token`,{headers:V(s),signal:e.signal});if(!n.ok)throw new w("\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 $e(){let e=new AbortController,t=s.timeoutMs??12e4,o=setTimeout(()=>{e.abort()},t);try{let n=await fetch(`${W}/login/device/code`,{method:"POST",headers:z(),body:JSON.stringify({client_id:K,scope:fe}),signal:e.signal});if(!n.ok)throw new w("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(`${q(s)}/models`,{headers:N(s),signal:e.signal});if(!n.ok)throw new w("Failed to get models",n);return await n.json()}finally{clearTimeout(o)}};function Z(){return"1.105.0-insider"}Z();const E=e=>new Promise(t=>{setTimeout(t,e)}),Ie=e=>e==null;async function ee(){let e=await Se();s.models=e}const Ae=()=>{let e=Z();s.vsCodeVersion=e,a.info(`Using VSCode version:${e}`)};async function Oe(e){let t=(e.interval+1)*1e3;for(a.debug(`Polling access token with interval of ${t}ms`);;){let o=new AbortController,n=s.timeoutMs??12e4,r=setTimeout(()=>{o.abort()},n);try{let i=await fetch(`${W}/login/oauth/access_token`,{method:"POST",headers:z(),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),a.error("Failed to poll access token:",await i.text());continue}let l=await i.json();a.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"){a.error("Access token polling timed out"),await E(t);continue}throw i}finally{clearTimeout(r)}}}let F,D=!1,P,j;function Ee(){a.debug("Cleaning up token management"),F&&=(clearInterval(F),void 0),P&&=(C.off("online",P),void 0),j&&=(C.off("offline",j),void 0)}const Pe=()=>$.readFile(b.GITHUB_TOKEN_PATH,"utf8"),je=e=>$.writeFile(b.GITHUB_TOKEN_PATH,e),qe=async()=>{let{token:e,refresh_in:t}=await Y();s.copilotToken=e,a.debug("GitHub Copilot Token fetched successfully!"),s.showToken&&a.info("Copilot token:",e);let o=(t-60)*1e3,n=async(r=5,i=1e3,l="scheduled")=>{if(D){a.debug("Service refresh already in progress,skipping");return}D=!0;try{for(let u=1;u<=r;u++)try{a.debug(`Refreshing Copilot token (${l},attempt ${u}/${r})`);let{token:c}=await Y();s.copilotToken=c,a.debug("Copilot token refreshed successfully"),s.showToken&&a.info("Refreshed Copilot token:",c);return}catch(c){let d=u===r;if(a.error(`Failed to refresh Copilot token (attempt ${u}/${r}):`,c),d){a.error("All token refresh attempts failed. Service may be unavailable until next scheduled refresh.");return}let m=i*2**(u-1);a.debug(`Retrying token refresh in ${m}ms...`),await new Promise(p=>setTimeout(p,m))}}finally{D=!1}};F=setInterval(()=>{n(5,1e3,"scheduled").catch(r=>{a.error("Unexpected error in scheduled token refresh:",r)})},o),C.start(),P=()=>{a.debug("Network status restored,attempting immediate token refresh"),n(3,500,"network-restored").catch(r=>{a.error("Unexpected error in network-restored token refresh:",r)})},j=()=>{a.debug("Network status lost")},C.on("online",P),C.on("offline",j)};async function M(e){try{let t=await Pe();if(t&&!e?.force){s.githubToken=t,s.showToken&&a.info("GitHub token:",t),await te();return}a.info("Authentication required");let o=await $e();a.debug("Device code response:",o),a.info(`Please enter the code "${o.user_code}" in ${o.verification_uri}`);let n=await Oe(o);await je(n),s.githubToken=n,s.showToken&&a.info("GitHub token:",n),await te()}catch(t){throw t instanceof w?(a.error("Failed to get GitHub token:",await t.response.json()),t):(a.error("Failed to get GitHub token:",t),t)}}async function te(){let e=await he();a.info(`Logged in as ${e.login}`)}async function Ne(e){e.verbose&&(a.level=5,a.info("Verbose logging enabled")),s.showToken=e.showToken,await H(),await M({force:!0}),a.success("GitHub token written to",b.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 Ne({verbose:e.verbose,showToken:e["show-token"]})}}),ne=async()=>{let e=new AbortController,t=s.timeoutMs??12e4,o=setTimeout(()=>{e.abort()},t);try{let n=await fetch(`${J}/\u0063\u006f\u0070\u0069\u006c\u006f\u0074_internal/user`,{headers:V(s),signal:e.signal});if(!n.ok)throw new w("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 H(),await M();try{let u=function(p,f){if(!f)return`${p}:N/A`;let k=f.entitlement,I=k-f.remaining,y=k>0?I/k*100:0,me=f.percent_remaining;return`${p}:${I}/${k} used (${y.toFixed(1)}% used,${me.toFixed(1)}% remaining)`};var e=u;let t=await ne(),o=t.quota_snapshots.premium_interactions,n=o.entitlement,r=n-o.remaining,i=n>0?r/n*100:0,l=o.percent_remaining,c=`Premium:${r}/${n} used (${i.toFixed(1)}% used,${l.toFixed(1)}% remaining)`,d=u("Chat",t.quota_snapshots.chat),m=u("Completions",t.quota_snapshots.completions);a.box(`Copilot Usage (plan:${t.copilot_plan})Quota resets:${t.quota_reset_date}Quotas:${c} ${d} ${m}`)}catch(t){a.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 $.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:Q.platform(),arch:Q.arch()}}async function Ue(){try{return(await $.stat(b.GITHUB_TOKEN_PATH)).isFile()?(await $.readFile(b.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:b.APP_DIR,GITHUB_TOKEN_PATH:b.GITHUB_TOKEN_PATH},tokenExists:t}}function Ge(e){a.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}=g;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),r;switch(o){case"powershell":r=n.map(([i,l])=>`$env:${i} =${l}`).join(";");break;case"cmd":r=n.map(([i,l])=>`set ${i}=${l}`).join(" & ");break;case"fish":r=n.map(([i,l])=>`set -gx ${i} ${l}`).join(";");break;default:{let i=n.map(([l,u])=>`${l}=${u}`).join(" ");r=n.length>0?`export ${i}`:"";break}}return r&&t?`${r}${o==="cmd"?" & ":" && "}${t}`:r||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),A.registerCompletion(n,e,o),await t(),e.get("requestData")?.tokenUsage&&A.executeCompletion(n)}}const oe=async()=>{if(!await a.prompt("Accept incoming request?",{type:"confirm"}))throw new w("Request rejected",Response.json({message:"Request rejected"},{status:403}))},ie={input:3e-6,output:15e-6};function v(e){let t=e.prompt_tokens||0,o=e.completion_tokens||0,n=e.total_tokens||t+o,r=t*ie.input+o*ie.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}}const Qe=[{pattern:/haiku/i,family:"haiku"},{pattern:/sonnet[.-]?4[.-]6/i,family:"sonnet-4.6"},{pattern:/(sonnet-4[.-]5|[.-]?3[.-]5[.-]?sonnet|[.-]?3[.-]7[.-]?sonnet)/i,family:"sonnet-4.5"},{pattern:/sonnet-4(?![.-]5|[.-]6|[.-]1)/i,family:"sonnet-4"},{pattern:/opus[.-]?4[.-]6/i,family:"opus-4.6"},{pattern:/opus[.-]?4[.-]5/i,family:"opus-4.5"},{pattern:/opus/i,family:"opus"}],Xe={haiku:"claude-haiku-4.5","sonnet-4.6":"claude-sonnet-4.6","sonnet-4.5":"claude-sonnet-4.5","sonnet-4":"claude-sonnet-4","opus-4.6":"claude-opus-4.6","opus-4.5":"claude-opus-4.5",opus:"claude-opus-4.5"};function Ye(e){return e.startsWith("anthropic/")?e.slice(10):e}function Ze(e){let t=e.lastIndexOf("["),o=e.lastIndexOf("]");return t!==-1&&o===e.length-1&&o>t?[e.slice(0,t),e.slice(t+1,o)]:[e,null]}function et(e){for(let t of Qe)if(t.pattern.test(e))return t.family;return null}function tt(e,t,o=null){let n=Xe[e];if(!n)return null;if(o){let r=`${n}-${o}`;if(t.includes(r))return r}if(t.includes(n))return n;if(e==="sonnet-4.5"){let r=["claude-3.5-sonnet"];for(let i of r){let l=o?`${i}-${o}`:i;if(t.includes(l))return l}}return null}function nt(e,t){let o=Ye(e),[n,r]=Ze(o);if(t.includes(o))return o;if(r){let c=`${n}-${r}`,d=c.replaceAll(/(\d)-(\d)\b/g,"$1.$2");if(t.includes(d))return d}let i=et(n);if(!i)return null;let l=n.replace(/-\d{8}(?::.*)?$/,""),u=r?`-${r}`:"";for(let c of t){let d=c.replace(/-\d{8}(?::.*)?$/,""),m=`${l}${u}`.toLowerCase().replaceAll(/(\d)-(\d)\b/g,"$1.$2");if(d.toLowerCase().replaceAll(/(\d)-(\d)\b/g,"$1.$2")===m)return c}return tt(i,t,r)}var T=class extends Error{statusCode;constructor(e,t=400){super(e),this.name="ModelValidationError",this.statusCode=t}};function U(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=nt(e,t);if(!o)throw new T(`Invalid model:'${e}'. Available models:${t.join(",")}`);return o}async function re(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 a.warn(`Rate limit exceeded. Need to wait ${n} more seconds.`),new w("Rate limit exceeded",Response.json({message:"Rate limit exceeded"},{status:429}));let r=n*1e3;a.warn(`Rate limit reached. Waiting ${n} seconds before proceeding...`),await E(r),e.lastRequestTimestamp=t,a.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 r=1;r<n.length;r++){let i=n[r],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 B(e){if(typeof e=="string")return ot(e);if(Array.isArray(e))return e.map(o=>B(o));if(e&&typeof e=="object"){let t={};for(let[o,n]of Object.entries(e))t[o]=B(n);return t}return e}const ae=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=B(e),o=t.messages.some(c=>typeof c.content!="string"&&c.content?.some(d=>d.type==="image_url")),n=t.messages.some(c=>["assistant","tool"].includes(c.role)),r={...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:d,body:m}=await Te(`${q(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:i.signal,headersTimeout:l,bodyTimeout:l*3}),p=new Response(m,{status:c,headers:d});if(!p.ok)throw new w("Failed to create chat completions",p);return t.stream?Ce(p):await p.json()}finally{clearTimeout(u)}};function it(e){let t=U(e.model);return t===e.model?e:(a.debug(`Normalized model from '${e.model}' to '${t}'`),{...e,model:t})}async function rt(e){await re(s);let t=await e.req.json();a.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 oe(),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},a.debug("Set max_tokens to:",JSON.stringify(t.max_tokens))}let o=performance.now(),n=await ae(t),r=performance.now()-o;if(at(n)){let i=e.get("requestData")||{};return n.usage&&(i.tokenUsage=v(n.usage)),i.copilotDuration=r,e.set("requestData",i),a.debug("Response data:",JSON.stringify(n)),e.json(n)}return X(e,async i=>{let l=null;for await(let c of n){let d=c;if(c.data&&c.data!=="[DONE]")try{let m=JSON.parse(c.data);if(m.usage){l=m.usage;let p=e.get("requestData")||{};p.tokenUsage=v(l),p.copilotDuration=r,e.set("requestData",p)}if(m.usage?.prompt_tokens_details?.cached_tokens!==void 0){let p={...m,usage:{...m.usage,prompt_tokens_details:void 0}};d={...c,data:JSON.stringify(p)}}}catch{}await i.writeSSE(d)}if(l){let c=e.get("requestData")||{};c.tokenUsage||(c.tokenUsage=v(l),c.copilotDuration=r,e.set("requestData",c))}let u=e.get("requestId");u&&A.executeCompletion(u)})}const at=e=>Object.hasOwn(e,"choices"),G=new _;G.post("/",async e=>{try{return await rt(e)}catch(t){return await O(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 r=await fetch(`${q(s)}/embeddings`,{method:"POST",headers:N(s),body:JSON.stringify(e),signal:t.signal});if(!r.ok)throw new w("Failed to create embeddings",r);return await r.json()}finally{clearTimeout(n)}},R=new _;R.post("/",async e=>{try{let t=await e.req.json();try{U(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),r=performance.now()-o,i=e.get("requestData")||{};return i.tokenUsage=v(n.usage),i.copilotDuration=r,e.set("requestData",i),e.json(n)}catch(t){return await O(e,t)}});function se(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(r=>r.role==="user"?dt(r):pt(r));return[...o,...n]}function le(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:le(e)}];{let t=e.map(o=>o.text).join(``);return[{role:"system",content:le(t)}]}}function dt(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:S(r.content)});n.length>0&&t.push({role:"user",content:S(n)})}else t.push({role:"user",content:S(e.content)});return t}function pt(e){if(!Array.isArray(e.content))return[{role:"assistant",content:S(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"),r=[...o.map(i=>i.text),...n.map(i=>i.thinking)].join(``);return t.length>0?[{role:"assistant",content:r||null,tool_calls:t.map(i=>({id:i.id,type:"function",function:{name:i.name,arguments:JSON.stringify(i.input)}}))}]:[{role:"assistant",content:S(e.content)}]}function S(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 r of e.choices){let i=gt(r.message.content),l=yt(r.message.tool_calls);t.push(...i),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:se(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: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&&(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:r.content}})),r.tool_calls)for(let i of r.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:se(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=U(t.model);return o===t.model?t:(a.debug(`Model mapping:'${t.model}' \u2192 '${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 re(s);let t=await e.req.json();a.debug("API request payload:",JSON.stringify(t));let o=e.req.header("anthropic-beta")??"";if(/context-1m/i.test(o)){let c=t.model;t={...t,model:`${t.model}-1m`},a.debug(`Detected context-1m beta flag,rewriting model:'${c}' \u2192 '${t.model}'`)}let n=bt(e,t);if(!n)return;t=n;let r=lt(t);a.debug("Processed API request payload:",JSON.stringify(r)),e.set("requestData",{model:r.model});let i=performance.now();s.manualApprove&&await oe();let l=await ae(r),u=performance.now()-i;if(vt(l)){let c=e.get("requestData")||{};l.usage&&(c.tokenUsage=v(l.usage)),c.copilotDuration=u,e.set("requestData",c),a.debug("Non-streaming response from Copilot:",JSON.stringify(l).slice(-400));let d=ht(l);return a.debug("Processed API response:",JSON.stringify(d)),e.json(d)}return a.debug("Streaming response from service"),X(e,async c=>{let d=null,m={messageStartSent:!1,contentBlockIndex:0,contentBlockOpen:!1,toolCalls:{}};for await(let f of l){if(a.debug("Copilot raw stream event:",JSON.stringify(f)),f.data==="[DONE]")break;if(!f.data)continue;let k=JSON.parse(f.data);if(k.usage){d=k.usage;let y=e.get("requestData")||{};y.tokenUsage=v(d),y.copilotDuration=u,e.set("requestData",y)}let I=kt(k,m);for(let y of I)a.debug("Processed API event:",JSON.stringify(y)),await c.writeSSE({event:y.type,data:JSON.stringify(y)})}if(d){let f=e.get("requestData")||{};f.tokenUsage||(f.tokenUsage=v(d),f.copilotDuration=u,e.set("requestData",f))}let p=e.get("requestId");p&&A.executeCompletion(p)})}const vt=e=>Object.hasOwn(e,"choices"),ce=new _;ce.post("/",async e=>{try{return await _t(e)}catch(t){return await O(e,t)}});const L=new _;L.get("/",async e=>{try{s.models||await ee();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 O(e,t)}});const ue=new _;ue.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 de=new _;de.get("/",async e=>{try{let t=await ne();return e.json(t)}catch(t){return console.error("Error fetching Copilot usage:",t),e.json({error:"Failed to fetch Copilot usage"},500)}});const h=new _;h.use(ze()),h.use(ve()),h.get("/",e=>e.text("Server running")),h.route("/chat/completions",G),h.route("\u002f\u006d\u006f\u0064\u0065\u006c\u0073",L),h.route("\u002f\u0065\u006d\u0062\u0065\u0064\u0064\u0069\u006e\u0067\u0073",R),h.route("/usage",de),h.route("/token",ue),h.route("\u002f\u0076\u0031\u002f\u0063\u0068\u0061\u0074\u002f\u0063\u006f\u006d\u0070\u006c\u0065\u0074\u0069\u006f\u006e\u0073",G),h.route("\u002f\u0076\u0031\u002f\u006d\u006f\u0064\u0065\u006c\u0073",L),h.route("\u002f\u0076\u0031\u002f\u0065\u006d\u0062\u0065\u0064\u0064\u0069\u006e\u0067\u0073",R),h.route("\u002f\u0076\u0031\u002f\u006d\u0065\u0073\u0073\u0061\u0067\u0065\u0073",ce),h.post("/v1/messages/count_tokens",e=>e.json({input_tokens:1}));const pe=[];function Ct(){let e=async()=>{a.info("Gracefully shutting down...");for(let t of pe)try{await t()}catch(o){a.error("Error during cleanup:",o)}a.info("Shutdown complete"),g.exit(0)};g.on("SIGINT",e),g.on("SIGTERM",e),g.on("uncaughtException",t=>{a.error("Uncaught exception:",t),e().finally(()=>g.exit(1))}),g.on("unhandledRejection",(t,o)=>{a.error("Unhandled promise rejection at:",o,"reason:",t),e().finally(()=>g.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)||(a.error(`Invalid model:${e.model}`),a.info(`Available models:${i.join(``)}`),g.exit(1)),i.includes(e.smallModel)||(a.error(`Invalid small model:${e.smallModel}`),a.info(`Available models:${i.join(``)}`),g.exit(1)),o=e.model,n=e.smallModel,a.info(`Using model:${o}`),a.info(`Using small model:${n}`)}else e.model||e.smallModel?(a.error("Both --model and --small-model must be specified when using command-line model selection"),g.exit(1)):(o=await a.prompt("Select a model to use with Claude Code",{type:"select",options:s.models.data.map(i=>i.id)}),n=await a.prompt("Select a small model to use with Claude Code",{type:"select",options:s.models.data.map(i=>i.id)}));let r=Ke({ANTHROPIC_BASE_URL:t,ANTHROPIC_AUTH_TOKEN:"dummy",ANTHROPIC_MODEL:o,ANTHROPIC_SMALL_FAST_MODEL:n},"claude");try{we.writeSync(r),a.success("Copied Claude Code command to clipboard!")}catch{a.warn("Failed to copy to clipboard. Here is the Claude Code command:"),a.log(r)}}async function xt(e){Ct(),pe.push(()=>{a.debug("Cleaning up connectivity monitor"),C.stop()},()=>{a.debug("Cleaning up token management"),Ee()}),e.verbose&&(a.level=5,a.info("Verbose logging enabled")),s.accountType=e.accountType,e.accountType!=="individual"&&a.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 H(),Ae(),e.githubToken?(s.githubToken=e.githubToken,a.info("Using provided auth token")):await M();try{let{getGitHubUser:o}=await import("./get-user-BT-kLu95.js"),n=await o();await ge(s,n.login)}catch(o){a.error("Failed to get GitHub user info for machine ID generation:",o),a.error("Cannot proceed without GitHub user information"),g.exit(1)}await qe(),await ee(),a.info("Available services:");for(let o of s.models?.data??[]){let n=o.capabilities.limits?.max_context_window_tokens,r=n?` (${n.toLocaleString()} tokens)`:"";a.info(`- ${o.id}${r}`)}let t=`http://localhost:${e.port}`;await Tt(e,t),a.box(`\u{1F310} Usage Viewer:https://ericc-ch.\u0067\u0069\u0074\u0068\u0075\u0062.io/copilot-api?endpoint=${t}/usage`),ke({fetch:h.fetch,port:e.port})}const $t=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,r=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:r,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:He,start:$t,"check-usage":Fe,debug:Je}});await ye(St);
|
|
2
|
+
import{_c1 as e,_g1 as t,_g4 as n,_g2 as r,_g3 as i,HTTPError as a,PATHS as o,_s1 as s,_s2 as c,ensurePaths as l,_t1 as u,_c2 as d,_s4 as ee,_s3 as f,_t2 as te,_s5 as ne,_c3 as p,state as m,_t3 as h,_t4 as re}from"./get-user-CSS558OK.js";import{defineCommand as g,runMain as ie}from"citty";import _ from"consola";import v from"node:fs/promises";import y from"node:os";import b from"node:process";import ae from"clipboardy";import{serve as oe}from"srvx";import se from"tiny-invariant";import{execSync as ce}from"node:child_process";import{Hono as x}from"hono";import{cors as le}from"hono/cors";import{streamSSE as S}from"hono/streaming";import{events as ue}from"fetch-event-stream";import{request as de}from"undici";var fe=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(!m.connectivity.enabled){_.debug(`Connectivity monitoring disabled`);return}_.info(`Starting connectivity monitor`,{probeEndpoints:m.connectivity.probeEndpoints,fastInterval:m.connectivity.fastProbeInterval}),this.scheduleNextCheck();let e=()=>{this.stop(),process.exit(0)};process.on(`SIGINT`,e),process.on(`SIGTERM`,e)}stop(){_.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?m.connectivity.slowProbeInterval:m.connectivity.fastProbeInterval,t=Math.random()*m.connectivity.jitterMaxMs,n=e+t;this.checkInterval=setTimeout(()=>{this.performConnectivityCheck().catch(e=>{_.error(`Connectivity check failed:`,e)})},n)}async performConnectivityCheck(){this.abortController=new AbortController;let e=setTimeout(()=>this.abortController?.abort(),m.connectivity.timeoutMs);try{let e=!1;for(let t of m.connectivity.probeEndpoints)try{let n=await fetch(t,{method:`HEAD`,signal:this.abortController.signal,headers:{"User-Agent":`\u0063\u006f\u0070\u0069\u006c\u006f\u0074-api-connectivity-monitor/1.0`,...m.connectivity.dnsCache&&{"Cache-Control":`max-age=300`}}});if(n.ok){e=!0,this.lastSuccessfulEndpoint=t;break}}catch(e){this.endpointFailureStats[t]=(this.endpointFailureStats[t]||0)+1,_.debug(`Probe failed for ${t}:`,e)}this.updateConnectivityState(e)}catch(e){this.handleConnectivityError(e)}finally{clearTimeout(e),this.scheduleNextCheck()}}updateConnectivityState(e){let t=this.isOnline;if(this.isOnline=e,this.lastChecked=new Date().toISOString(),e){let e=this.consecutiveFailures;this.consecutiveFailures>0&&_.info(`Connectivity restored after ${this.consecutiveFailures} failures`),this.consecutiveFailures=0,this.lastErrorType=void 0,this.lastErrorMessage=void 0,t||(this.dispatchEvent(new CustomEvent(`online`)),h(`connectivity_change`,{status:`online`},{consecutiveFailures:e}))}else this.consecutiveFailures++,t&&(_.warn(`Connectivity lost`),this.dispatchEvent(new CustomEvent(`offline`)),h(`connectivity_change`,{status:`offline`},{consecutiveFailures:this.consecutiveFailures}))}handleConnectivityError(e){this.lastErrorType=e.name,this.lastErrorMessage=e.message,_.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?m.connectivity.slowProbeInterval:m.connectivity.fastProbeInterval,t=new Date(Date.now()+e+Math.random()*m.connectivity.jitterMaxMs).toISOString();return{currentInterval:e,nextCheckEstimate:t,lastSuccessfulEndpoint:this.lastSuccessfulEndpoint,endpointFailureStats:{...this.endpointFailureStats},jitterEnabled:m.connectivity.jitterMaxMs>0,connectionPooling:m.connectivity.connectionPooling,dnsCache:m.connectivity.dnsCache}}};const C=new fe,w=async()=>{let e=new AbortController,n=m.timeoutMs??12e4,r=setTimeout(()=>{e.abort()},n);try{let n=await fetch(`${t}/\u0063\u006f\u0070\u0069\u006c\u006f\u0074_internal/v2/token`,{headers:f(m),signal:e.signal});if(!n.ok)throw new a(`Failed to get Service token`,n);return await n.json()}finally{clearTimeout(r)}};async function pe(){let e=new AbortController,t=m.timeoutMs??12e4,o=setTimeout(()=>{e.abort()},t);try{let t=await fetch(`${r}/login/device/code`,{method:`POST`,headers:p(),body:JSON.stringify({client_id:i,scope:n}),signal:e.signal});if(!t.ok)throw new a(`Failed to get device code`,t);return await t.json()}finally{clearTimeout(o)}}const me=async()=>{let e=new AbortController,t=m.timeoutMs??12e4,n=setTimeout(()=>{e.abort()},t);try{let t=await fetch(`${s(m)}/models`,{headers:c(m),signal:e.signal});if(!t.ok)throw new a(`Failed to get models`,t);return await t.json()}finally{clearTimeout(n)}};function T(){return`1.111.0-insider`}T();const E=e=>new Promise(t=>{setTimeout(t,e)}),he=e=>e==null;async function ge(){let e=await me();m.models=e}const _e=()=>{let e=T();m.vsCodeVersion=e,_.info(`Using client version: ${e}`)};async function ve(e){let t=(e.interval+1)*1e3;for(_.debug(`Polling access token with interval of ${t}ms`);;){let n=new AbortController,a=m.timeoutMs??12e4,o=setTimeout(()=>{n.abort()},a);try{let a=await fetch(`${r}/login/oauth/access_token`,{method:`POST`,headers:p(),body:JSON.stringify({client_id:i,device_code:e.device_code,grant_type:`urn:ietf:params:oauth:grant-type:device_code`}),signal:n.signal});if(!a.ok){await E(t),_.error(`Failed to poll access token:`,await a.text());continue}let o=await a.json();_.debug(`Polling access token response:`,o);let{access_token:s}=o;if(s)return s;await E(t)}catch(e){if(e instanceof Error&&e.name===`AbortError`){_.error(`Access token polling timed out`),await E(t);continue}throw e}finally{clearTimeout(o)}}}let D,O=!1,k,A;function ye(){_.debug(`Cleaning up token management`),D&&=(clearInterval(D),void 0),k&&=(C.off(`online`,k),void 0),A&&=(C.off(`offline`,A),void 0)}const be=()=>v.readFile(o.GITHUB_TOKEN_PATH,`utf8`),xe=e=>v.writeFile(o.GITHUB_TOKEN_PATH,e),Se=async()=>{let{token:e,refresh_in:t}=await w();m.copilotToken=e,_.debug(`Service token fetched successfully!`),m.showToken&&_.info(`Service token:`,e);let n=(t-60)*1e3,r=async(e=5,t=1e3,n=`scheduled`)=>{if(O){_.debug(`Refresh already in progress, skipping`);return}O=!0;try{for(let r=1;r<=e;r++)try{_.debug(`Refreshing Service token (${n}, attempt ${r}/${e})`);let{token:t}=await w();m.copilotToken=t,_.debug(`Service token refreshed successfully`),m.showToken&&_.info(`Refreshed Service token:`,t),h(`token_refresh`,{reason:n},{attempt:r});return}catch(i){let a=r===e;if(_.error(`Failed to refresh Service token (attempt ${r}/${e}):`,i),a){_.error(`All refresh attempts failed. May be unavailable until next scheduled refresh.`);let t=i instanceof Error?i:Error(String(i));re(t,{reason:n,event:`token_refresh_failed`},{attempt:r,maxRetries:e});return}let o=t*2**(r-1);_.debug(`Retrying token refresh in ${o}ms...`),await new Promise(e=>setTimeout(e,o))}}finally{O=!1}};D=setInterval(()=>{r(5,1e3,`scheduled`).catch(e=>{_.error(`Unexpected error in scheduled token refresh:`,e)})},n),C.start(),k=()=>{_.debug(`Network connectivity restored, attempting immediate token refresh`),r(3,500,`network-restored`).catch(e=>{_.error(`Unexpected error in network-restored token refresh:`,e)})},A=()=>{_.debug(`Network connectivity lost`)},C.on(`online`,k),C.on(`offline`,A)};async function j(e){try{let t=await be();if(t&&!e?.force){m.githubToken=t,m.showToken&&_.info(`Auth token:`,t),await M();return}_.info(`Authentication required`);let n=await pe();_.debug(`Device code response:`,n),_.info(`Please enter the code "${n.user_code}" in ${n.verification_uri}`);let r=await ve(n);await xe(r),m.githubToken=r,m.showToken&&_.info(`Auth token:`,r),await M()}catch(e){throw e instanceof a?(_.error(`Failed to get Auth token:`,await e.response.json()),e):(_.error(`Failed to get Auth token:`,e),e)}}async function M(){let e=await ee();_.info(`Authenticated as ${e.login}`)}async function Ce(e){e.verbose&&(_.level=5,_.info(`Verbose logging enabled`)),m.showToken=e.showToken,await l(),await j({force:!0}),_.success(`Auth token written to`,o.GITHUB_TOKEN_PATH)}const we=g({meta:{name:`auth`,description:`Run authentication flow`},args:{verbose:{alias:`v`,type:`boolean`,default:!1,description:`Enable verbose logging`},"show-token":{type:`boolean`,default:!1,description:`Show token on auth`}},run({args:e}){return Ce({verbose:e.verbose,showToken:e[`show-token`]})}}),N=async()=>{let e=new AbortController,n=m.timeoutMs??12e4,r=setTimeout(()=>{e.abort()},n);try{let n=await fetch(`${t}/\u0063\u006f\u0070\u0069\u006c\u006f\u0074_internal/user`,{headers:f(m),signal:e.signal});if(!n.ok)throw new a(`Failed to get usage`,n);return await n.json()}finally{clearTimeout(r)}},Te=g({meta:{name:`check-usage`,description:`Show current usage/quota information`},async run(){await l(),await j();try{let e=await N(),t=e.quota_snapshots.premium_interactions,n=t.entitlement,r=n-t.remaining,i=n>0?r/n*100:0,a=t.percent_remaining;function o(e,t){if(!t)return`${e}: N/A`;let n=t.entitlement,r=n-t.remaining,i=n>0?r/n*100:0,a=t.percent_remaining;return`${e}: ${r}/${n} used (${i.toFixed(1)}% used, ${a.toFixed(1)}% remaining)`}let s=`Premium: ${r}/${n} used (${i.toFixed(1)}% used, ${a.toFixed(1)}% remaining)`,c=o(`Chat`,e.quota_snapshots.chat),l=o(`Completions`,e.quota_snapshots.completions);_.box(`Usage (plan: ${e.\u0063\u006f\u0070\u0069\u006c\u006f\u0074_plan})\nQuota resets: ${e.quota_reset_date}\n\nQuotas:\n ${s}\n ${c}\n ${l}`)}catch(e){_.error(`Failed to fetch usage:`,e),process.exit(1)}}});async function P(){try{let e=new URL(`../package.json`,import.meta.url).pathname,t=await v.readFile(e),n=JSON.parse(t.toString());return n.version}catch{return`unknown`}}function F(){let e=typeof Bun<`u`;return{name:e?`bun`:`node`,version:e?Bun.version:process.version.slice(1),platform:y.platform(),arch:y.arch()}}async function Ee(){try{let e=await v.stat(o.GITHUB_TOKEN_PATH);if(!e.isFile())return!1;let t=await v.readFile(o.GITHUB_TOKEN_PATH,`utf8`);return t.trim().length>0}catch{return!1}}async function De(){let[e,t]=await Promise.all([P(),Ee()]);return{version:e,runtime:F(),paths:{APP_DIR:o.APP_DIR,GITHUB_TOKEN_PATH:o.GITHUB_TOKEN_PATH},tokenExists:t}}function Oe(e){_.info(`service debug
|
|
3
|
+
|
|
4
|
+
Version: ${e.version}
|
|
5
|
+
Runtime: ${e.runtime.name} ${e.runtime.version} (${e.runtime.platform} ${e.runtime.arch})
|
|
6
|
+
|
|
7
|
+
Paths:
|
|
8
|
+
- APP_DIR: ${e.paths.APP_DIR}
|
|
9
|
+
- \u0047\u0049\u0054\u0048\u0055\u0042_TOKEN_PATH: ${e.paths.\u0047\u0049\u0054\u0048\u0055\u0042_TOKEN_PATH}
|
|
10
|
+
|
|
11
|
+
Token exists: ${e.tokenExists?`Yes`:`No`}`)}function ke(e){console.log(JSON.stringify(e,null,2))}async function Ae(e){let t=await De();e.json?ke(t):Oe(t)}const je=g({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 Ae({json:e.json})}});function Me(){let{platform:e,ppid:t,env:n}=b;if(e===`win32`){try{let e=`wmic process get ParentProcessId,Name | findstr "${t}"`,n=ce(e,{stdio:`pipe`}).toString();if(n.toLowerCase().includes(`powershell.exe`))return`powershell`}catch{return`cmd`}return`cmd`}else{let e=n.SHELL;if(e){if(e.endsWith(`zsh`))return`zsh`;if(e.endsWith(`fish`))return`fish`;if(e.endsWith(`bash`))return`bash`}return`sh`}}function Ne(e,t=``){let n=Me(),r=Object.entries(e).filter(([,e])=>e!==void 0),i;switch(n){case`powershell`:i=r.map(([e,t])=>`$env:${e} = ${t}`).join(`; `);break;case`cmd`:i=r.map(([e,t])=>`set ${e}=${t}`).join(` & `);break;case`fish`:i=r.map(([e,t])=>`set -gx ${e} ${t}`).join(`; `);break;default:{let e=r.map(([e,t])=>`${e}=${t}`).join(` `);i=r.length>0?`export ${e}`:``;break}}if(i&&t){let e=n===`cmd`?` & `:` && `;return`${i}${e}${t}`}return i||t}function Pe(){return`req_${Date.now()}_${Math.random().toString(36).slice(2,11)}`}function Fe(){return async(t,n)=>{let r=Date.now(),i=Pe();t.set(`requestId`,i),t.header(`x-request-id`,i),e.registerCompletion(i,t,r),await n();let a=t.get(`requestData`);a?.tokenUsage&&e.executeCompletion(i)}}const I=async()=>{let e=await _.prompt(`Accept incoming request?`,{type:`confirm`});if(!e)throw new a(`Request rejected`,Response.json({message:`Request rejected`},{status:403}))},L={input:3e-6,output:15e-6};function R(e){let t=e.prompt_tokens||0,n=e.completion_tokens||0,r=e.total_tokens||t+n,i=t*L.input+n*L.output;return{inputTokens:t,outputTokens:n,totalTokens:r,estimatedCost:i,cachedTokens:e.prompt_tokens_details?.cached_tokens,acceptedPredictionTokens:e.completion_tokens_details?.accepted_prediction_tokens,rejectedPredictionTokens:e.completion_tokens_details?.rejected_prediction_tokens}}const Ie=[{pattern:/haiku/i,family:`haiku`},{pattern:/sonnet[.-]?4[.-]6/i,family:`sonnet-4.6`},{pattern:/(sonnet-4[.-]5|[.-]?3[.-]5[.-]?sonnet|[.-]?3[.-]7[.-]?sonnet)/i,family:`sonnet-4.5`},{pattern:/sonnet-4(?![.-]5|[.-]6|[.-]1)/i,family:`sonnet-4`},{pattern:/opus[.-]?4[.-]6/i,family:`opus-4.6`},{pattern:/opus[.-]?4[.-]5/i,family:`opus-4.5`},{pattern:/opus/i,family:`opus`}],Le={haiku:`\u0063\u006c\u0061\u0075\u0064\u0065-haiku-4.5`,"sonnet-4.6":`\u0063\u006c\u0061\u0075\u0064\u0065-sonnet-4.6`,"sonnet-4.5":`\u0063\u006c\u0061\u0075\u0064\u0065-sonnet-4.5`,"sonnet-4":`\u0063\u006c\u0061\u0075\u0064\u0065-sonnet-4`,"opus-4.6":`\u0063\u006c\u0061\u0075\u0064\u0065-opus-4.6`,"opus-4.5":`\u0063\u006c\u0061\u0075\u0064\u0065-opus-4.5`,opus:`\u0063\u006c\u0061\u0075\u0064\u0065-opus-4.5`};function Re(e){return e.startsWith(`\u0061\u006e\u0074\u0068\u0072\u006f\u0070\u0069\u0063/`)?e.slice(10):e}function ze(e){let t=e.lastIndexOf(`[`),n=e.lastIndexOf(`]`);return t!==-1&&n===e.length-1&&n>t?[e.slice(0,t),e.slice(t+1,n)]:[e,null]}function Be(e){for(let t of Ie)if(t.pattern.test(e))return t.family;return null}function Ve(e,t,n=null){let r=Le[e];if(!r)return null;if(n){let e=`${r}-${n}`;if(t.includes(e))return e}if(t.includes(r))return r;if(e===`sonnet-4.5`){let e=[`\u0063\u006c\u0061\u0075\u0064\u0065-3.5-sonnet`];for(let r of e){let e=n?`${r}-${n}`:r;if(t.includes(e))return e}}return null}function He(e,t){let n=Re(e),[r,i]=ze(n);if(t.includes(n))return n;if(i){let e=`${r}-${i}`,n=e.replaceAll(/(\d)-(\d)\b/g,`$1.$2`);if(t.includes(n))return n}let a=Be(r);if(!a)return null;let o=r.replace(/-\d{8}(?::.*)?$/,``),s=i?`-${i}`:``;for(let e of t){let t=e.replace(/-\d{8}(?::.*)?$/,``),n=`${o}${s}`.toLowerCase().replaceAll(/(\d)-(\d)\b/g,`$1.$2`),r=t.toLowerCase().replaceAll(/(\d)-(\d)\b/g,`$1.$2`);if(r===n)return e}return Ve(a,t,i)}var z=class extends Error{statusCode;constructor(e,t=400){super(e),this.name=`ModelValidationError`,this.statusCode=t}};function B(e){if(!e||typeof e!=`string`)throw new z(`Model name is required and must be a string`);if(!m.models?.data)throw new z(`Models not available. Please try again later.`,503);let t=m.models.data.map(e=>e.id),n=He(e,t);if(!n)throw h(`model_validation_error`,{requestedModel:e}),new z(`Invalid model: '${e}'. Available services: ${t.join(`, `)}`);return n}async function V(e){if(e.rateLimitSeconds===void 0)return;let t=Date.now();if(!e.lastRequestTimestamp){e.lastRequestTimestamp=t;return}let n=(t-e.lastRequestTimestamp)/1e3;if(n>e.rateLimitSeconds){e.lastRequestTimestamp=t;return}let r=Math.ceil(e.rateLimitSeconds-n);if(!e.rateLimitWait)throw _.warn(`Rate limit exceeded. Need to wait ${r} more seconds.`),h(`rate_limit_triggered`,{action:`rejected`},{waitTimeSeconds:r}),new a(`Rate limit exceeded`,Response.json({message:`Rate limit exceeded`},{status:429}));let i=r*1e3;_.warn(`Rate limit reached. Waiting ${r} seconds before proceeding...`),h(`rate_limit_triggered`,{action:`waited`},{waitTimeSeconds:r}),await E(i),e.lastRequestTimestamp=t,_.info(`Rate limit wait completed, proceeding with request`)}function Ue(e){let t=e,n=String.fromCodePoint(27),r=t.split(n);if(r.length>1){t=r[0];for(let e=1;e<r.length;e++){let i=r[e],a=i.match(/^\[[0-9;]*[a-z]/i);t+=a?i.slice(a[0].length):n+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 H(e){if(typeof e==`string`)return Ue(e);if(Array.isArray(e)){let t=e.map(e=>H(e));return t}if(e&&typeof e==`object`){let t={};for(let[n,r]of Object.entries(e))t[n]=H(r);return t}return e}const U=async e=>{if(!m.copilotToken)throw Error(`Service token not found`);let t=H(e),n=t.messages.some(e=>typeof e.content!=`string`&&e.content?.some(e=>e.type===`image_url`)),r=t.messages.some(e=>[`assistant`,`tool`].includes(e.role)),i={...c(m,n),"X-Initiator":r?`agent`:`user`},o=new AbortController,l=m.timeoutMs??12e4,u=setTimeout(()=>{o.abort()},l);try{let{statusCode:e,headers:n,body:r}=await de(`${s(m)}/chat/completions`,{method:`POST`,headers:i,body:JSON.stringify(t),signal:o.signal,headersTimeout:l,bodyTimeout:l*3}),c=new Response(r,{status:e,headers:n});if(!c.ok)throw new a(`Failed to create chat completions`,c);return t.stream?ue(c):await c.json()}finally{clearTimeout(u)}};function We(e){let t=B(e.model);return t===e.model?e:(_.debug(`Normalized model from '${e.model}' to '${t}'`),{...e,model:t})}async function Ge(t){await V(m);let n=await t.req.json();_.debug(`Request payload:`,JSON.stringify(n).slice(-400));try{n=We(n)}catch(e){if(e instanceof z)return t.json({error:{message:e.message,type:`invalid_request_error`,code:`invalid_model`}},e.statusCode);throw e}if(t.set(`requestData`,{model:n.model}),m.manualApprove&&await I(),he(n.max_tokens)){let e=m.models?.data.find(e=>e.id===n.model);n={...n,max_tokens:e?.capabilities.limits?.max_output_tokens},_.debug(`Set max_tokens to:`,JSON.stringify(n.max_tokens))}let r=performance.now(),i=await U(n),a=performance.now()-r;if(Ke(i)){let e=t.get(`requestData`)||{};return i.usage&&(e.tokenUsage=R(i.usage)),e.copilotDuration=a,t.set(`requestData`,e),_.debug(`Non-streaming response:`,JSON.stringify(i)),t.json(i)}return S(t,async n=>{let r=null;for await(let e of i){let i=e;if(e.data&&e.data!==`[DONE]`)try{let n=JSON.parse(e.data);if(n.usage){r=n.usage;let e=t.get(`requestData`)||{};e.tokenUsage=R(r),e.copilotDuration=a,t.set(`requestData`,e)}if(n.usage?.prompt_tokens_details?.cached_tokens!==void 0){let t={...n,usage:{...n.usage,prompt_tokens_details:void 0}};i={...e,data:JSON.stringify(t)}}}catch{}await n.writeSSE(i)}if(r){let e=t.get(`requestData`)||{};e.tokenUsage||(e.tokenUsage=R(r),e.copilotDuration=a,t.set(`requestData`,e))}let o=t.get(`requestId`);o&&e.executeCompletion(o)})}const Ke=e=>Object.hasOwn(e,`choices`),W=new x;W.post(`/`,async e=>{try{return await Ge(e)}catch(t){return await d(e,t)}});const qe=async e=>{if(!m.copilotToken)throw Error(`Service token not found`);let t=new AbortController,n=m.timeoutMs??12e4,r=setTimeout(()=>{t.abort()},n);try{let n=await fetch(`${s(m)}/embeddings`,{method:`POST`,headers:c(m),body:JSON.stringify(e),signal:t.signal});if(!n.ok)throw new a(`Failed to create embeddings`,n);return await n.json()}finally{clearTimeout(r)}},G=new x;G.post(`/`,async e=>{try{let t=await e.req.json();try{B(t.model)}catch(t){if(t instanceof z)return e.json({error:{message:t.message,type:`invalid_request_error`,code:`invalid_model`}},t.statusCode);throw t}e.set(`requestData`,{model:t.model});let n=performance.now(),r=await qe(t),i=performance.now()-n,a=e.get(`requestData`)||{};return a.tokenUsage=R(r.usage),a.copilotDuration=i,e.set(`requestData`,a),e.json(r)}catch(t){return await d(e,t)}});function K(e){if(e===null)return null;let t={stop:`end_turn`,length:`max_tokens`,tool_calls:`tool_use`,content_filter:`end_turn`};return t[e]}function Je(e){return{model:Ye(e.model),messages:Xe(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:et(e.tools),tool_choice:tt(e.tool_choice)}}function Ye(e){return e}function Xe(e,t){let n=Ze(t),r=e.flatMap(e=>e.role===`user`?Qe(e):$e(e));return[...n,...r]}function q(e){return e.startsWith(`x-\u0061\u006e\u0074\u0068\u0072\u006f\u0070\u0069\u0063-billing-header`)?e.replace(/^x-anthropic-billing-header:[^\n]*\n+/,``):e}function Ze(e){if(!e)return[];if(typeof e==`string`)return[{role:`system`,content:q(e)}];{let t=e.map(e=>e.text).join(`
|
|
12
|
+
|
|
13
|
+
`);return[{role:`system`,content:q(t)}]}}function Qe(e){let t=[];if(Array.isArray(e.content)){let n=e.content.filter(e=>e.type===`tool_result`),r=e.content.filter(e=>e.type!==`tool_result`);for(let e of n)t.push({role:`tool`,tool_call_id:e.tool_use_id,content:J(e.content)});r.length>0&&t.push({role:`user`,content:J(r)})}else t.push({role:`user`,content:J(e.content)});return t}function $e(e){if(!Array.isArray(e.content))return[{role:`assistant`,content:J(e.content)}];let t=e.content.filter(e=>e.type===`tool_use`),n=e.content.filter(e=>e.type===`text`),r=e.content.filter(e=>e.type===`thinking`),i=[...n.map(e=>e.text),...r.map(e=>e.thinking)].join(`
|
|
14
|
+
|
|
15
|
+
`);return t.length>0?[{role:`assistant`,content:i||null,tool_calls:t.map(e=>({id:e.id,type:`function`,function:{name:e.name,arguments:JSON.stringify(e.input)}}))}]:[{role:`assistant`,content:J(e.content)}]}function J(e){if(typeof e==`string`)return e;if(!Array.isArray(e))return null;let t=e.some(e=>e.type===`image`);if(!t)return e.filter(e=>e.type===`text`||e.type===`thinking`).map(e=>e.type===`text`?e.text:e.thinking).join(`
|
|
16
|
+
|
|
17
|
+
`);let n=[];for(let t of e)switch(t.type){case`text`:n.push({type:`text`,text:t.text});break;case`thinking`:n.push({type:`text`,text:t.thinking});break;case`image`:n.push({type:`image_url`,image_url:{url:`data:${t.source.media_type};base64,${t.source.data}`}});break}return n}function et(e){if(e)return e.map(e=>({type:`function`,function:{name:e.name,description:e.description,parameters:e.input_schema}}))}function tt(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 nt(e){let t=[],n=[],r=null;r=e.choices[0]?.finish_reason??r;for(let i of e.choices){let e=rt(i.message.content),a=it(i.message.tool_calls);t.push(...e),n.push(...a),(i.finish_reason===`tool_calls`||r===`stop`)&&(r=i.finish_reason)}return{id:e.id,type:`message`,role:`assistant`,model:e.model,content:[...t,...n],stop_reason:K(r),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(e=>e.type===`text`).map(e=>({type:`text`,text:e.text})):[]}function it(e){return e?e.map(e=>({type:`tool_use`,id:e.id,name:e.function.name,input:JSON.parse(e.function.arguments)})):[]}function at(e){return e.contentBlockOpen?Object.values(e.toolCalls).some(t=>t.anthropicBlockIndex===e.contentBlockIndex):!1}function ot(e,t){let n=[];if(e.choices.length===0)return n;let r=e.choices[0],{delta:i}=r;if(t.messageStartSent||=(n.push({type:`message_start`,message:{id:e.id,type:`message`,role:`assistant`,content:[],model:e.model,stop_reason:null,stop_sequence:null,usage:{input_tokens:e.usage?.prompt_tokens??0,output_tokens:0}}}),!0),i.content&&(at(t)&&(n.push({type:`content_block_stop`,index:t.contentBlockIndex}),t.contentBlockIndex++,t.contentBlockOpen=!1),t.contentBlockOpen||=(n.push({type:`content_block_start`,index:t.contentBlockIndex,content_block:{type:`text`,text:``}}),!0),n.push({type:`content_block_delta`,index:t.contentBlockIndex,delta:{type:`text_delta`,text:i.content}})),i.tool_calls)for(let e of i.tool_calls){if(e.id&&e.function?.name){t.contentBlockOpen&&=(n.push({type:`content_block_stop`,index:t.contentBlockIndex}),t.contentBlockIndex++,!1);let r=t.contentBlockIndex;t.toolCalls[e.index]={id:e.id,name:e.function.name,anthropicBlockIndex:r},n.push({type:`content_block_start`,index:r,content_block:{type:`tool_use`,id:e.id,name:e.function.name,input:{}}}),t.contentBlockOpen=!0}if(e.function?.arguments){let r=t.toolCalls[e.index];r&&n.push({type:`content_block_delta`,index:r.anthropicBlockIndex,delta:{type:`input_json_delta`,partial_json:e.function.arguments}})}}return r.finish_reason&&(t.contentBlockOpen&&=(n.push({type:`content_block_stop`,index:t.contentBlockIndex}),!1),n.push({type:`message_delta`,delta:{stop_reason:K(r.finish_reason),stop_sequence:null},usage:{input_tokens:e.usage?.prompt_tokens??0,output_tokens:e.usage?.completion_tokens??0}},{type:`message_stop`})),n}function st(e,t){try{let e=B(t.model);return e===t.model?t:(_.debug(`Model mapping: '${t.model}' → '${e}'`),{...t,model:e})}catch(t){if(t instanceof z)return e.json({type:`error`,error:{type:`invalid_request_error`,message:t.message}},t.statusCode),null;throw t}}async function ct(t){await V(m);let n=await t.req.json();_.debug(`\u0041\u006e\u0074\u0068\u0072\u006f\u0070\u0069\u0063 request payload:`,JSON.stringify(n));let r=t.req.header(`\u0061\u006e\u0074\u0068\u0072\u006f\u0070\u0069\u0063-beta`)??``;if(/context-1m/i.test(r)){let e=n.model;n={...n,model:`${n.model}-1m`},_.debug(`Detected context-1m beta flag, rewriting model: '${e}' → '${n.model}'`)}let i=st(t,n);if(!i)return;n=i;let a=Je(n);_.debug(`Translated \u004f\u0070\u0065\u006e\u0041\u0049 request payload:`,JSON.stringify(a)),t.set(`requestData`,{model:a.model});let o=performance.now();m.manualApprove&&await I();let s=await U(a),c=performance.now()-o;if(lt(s)){let e=t.get(`requestData`)||{};s.usage&&(e.tokenUsage=R(s.usage)),e.copilotDuration=c,t.set(`requestData`,e),_.debug(`Non-streaming response:`,JSON.stringify(s).slice(-400));let n=nt(s);return _.debug(`Translated \u0041\u006e\u0074\u0068\u0072\u006f\u0070\u0069\u0063 response:`,JSON.stringify(n)),t.json(n)}return _.debug(`Streaming response from service`),S(t,async n=>{let r=null,i={messageStartSent:!1,contentBlockIndex:0,contentBlockOpen:!1,toolCalls:{}};for await(let e of s){if(_.debug(`Raw stream event:`,JSON.stringify(e)),e.data===`[DONE]`)break;if(!e.data)continue;let a=JSON.parse(e.data);if(a.usage){r=a.usage;let e=t.get(`requestData`)||{};e.tokenUsage=R(r),e.copilotDuration=c,t.set(`requestData`,e)}let o=ot(a,i);for(let e of o)_.debug(`Translated \u0041\u006e\u0074\u0068\u0072\u006f\u0070\u0069\u0063 event:`,JSON.stringify(e)),await n.writeSSE({event:e.type,data:JSON.stringify(e)})}if(r){let e=t.get(`requestData`)||{};e.tokenUsage||(e.tokenUsage=R(r),e.copilotDuration=c,t.set(`requestData`,e))}let a=t.get(`requestId`);a&&e.executeCompletion(a)})}const lt=e=>Object.hasOwn(e,`choices`),Y=new x;Y.post(`/`,async e=>{try{return await ct(e)}catch(t){return await d(e,t)}});const X=new x;X.get(`/`,async e=>{try{m.models||await ge();let t=m.models?.data.map(e=>({id:e.id,object:`model`,type:`model`,created:0,created_at:new Date(0).toISOString(),owned_by:e.vendor,display_name:e.name,context_length:e.capabilities.limits?.max_context_window_tokens}));return e.json({object:`list`,data:t,has_more:!1})}catch(t){return await d(e,t)}});const Z=new x;Z.get(`/`,e=>{try{return e.json({token:m.copilotToken})}catch(t){return console.error(`Error fetching token:`,t),e.json({error:`Failed to fetch token`,token:null},500)}});const Q=new x;Q.get(`/`,async e=>{try{let t=await N();return e.json(t)}catch(t){return console.error(`Error fetching usage:`,t),e.json({error:`Failed to fetch usage`},500)}});const $=new x;$.use(Fe()),$.use(le()),$.get(`/`,e=>e.text(`Server running`)),$.route(`/chat/completions`,W),$.route(`/models`,X),$.route(`/embeddings`,G),$.route(`/usage`,Q),$.route(`/token`,Z),$.route(`/v1/chat/completions`,W),$.route(`/v1/models`,X),$.route(`/v1/embeddings`,G),$.route(`/v1/messages`,Y),$.post(`/v1/messages/count_tokens`,e=>e.json({input_tokens:1}));const ut=[],dt=Date.now();function ft(){let e=async(e,t=0)=>{_.info(`Gracefully shutting down...`),h(`server_shutdown`,{reason:e},{uptimeSeconds:(Date.now()-dt)/1e3});for(let e of ut)try{await e()}catch(e){_.error(`Error during cleanup:`,e)}await u(),_.info(`Shutdown complete`),b.exit(t)};b.on(`SIGINT`,()=>e(`SIGINT`)),b.on(`SIGTERM`,()=>e(`SIGTERM`)),b.on(`uncaughtException`,t=>{_.error(`Uncaught exception:`,t),e(`uncaughtException`,1)}),b.on(`unhandledRejection`,(t,n)=>{_.error(`Unhandled promise rejection at:`,n,`reason:`,t),e(`unhandledRejection`,1)})}async function pt(e,t){let n=b.env.APPLICATIONINSIGHTS_CONNECTION_STRING||`InstrumentationKey=8ffe3e28-3e27-4f6b-9454-011eaeeacd85;IngestionEndpoint=https://northeurope-2.in.applicationinsights.azure.com/;LiveEndpoint=https://northeurope.livediagnostics.monitor.azure.com/;ApplicationId=16380e14-d2f7-4eea-ba03-80995b2815bb`,r=await P(),i=F();try{await te({connectionString:n,version:r,runtime:i,accountType:e.accountType,machineId:m.machineId,userId:t})}catch(e){_.debug(`Failed to initialize \u0074\u0065\u006c\u0065\u006d\u0065\u0074\u0072\u0079:`,e);return}if(h(`server_started`,{version:r,platform:i.platform,arch:i.arch,accountType:e.accountType,claudeCode:String(e.claudeCode),verbose:String(e.verbose)},{port:e.port,modelsCount:m.models?.data.length??0,rateLimitSeconds:e.rateLimit??0,timeoutMs:e.timeout??12e4}),m.models?.data){let e=m.models.data.map(e=>({id:e.id,vendor:e.vendor,family:e.capabilities.family,contextWindow:e.capabilities.limits?.max_context_window_tokens??0,maxOutputTokens:e.capabilities.limits?.max_output_tokens??0,toolCalls:e.capabilities.supports.tool_calls??!1})),t=JSON.stringify(e);if(t.length<=8192)h(`models_available`,{models:t},{modelsCount:e.length});else for(let t of e)h(`models_available`,{modelId:t.id,vendor:t.vendor,family:t.family,toolCalls:String(t.toolCalls)},{contextWindow:t.contextWindow,maxOutputTokens:t.maxOutputTokens,modelsCount:e.length})}}async function mt(e,t){if(!e.claudeCode)return;se(m.models,`Models should be loaded by now`);let n,r;if(e.model&&e.smallModel){let t=m.models.data.map(e=>e.id);t.includes(e.model)||(_.error(`Invalid model: ${e.model}`),_.info(`Available services: \n${t.join(`
|
|
18
|
+
`)}`),b.exit(1)),t.includes(e.smallModel)||(_.error(`Invalid small model: ${e.smallModel}`),_.info(`Available services: \n${t.join(`
|
|
19
|
+
`)}`),b.exit(1)),n=e.model,r=e.smallModel,_.info(`Using service: ${n}`),_.info(`Using small model: ${r}`)}else e.model||e.smallModel?(_.error(`Both --model and --small-model must be specified for model selection`),b.exit(1)):(n=await _.prompt(`Select a model to use`,{type:`select`,options:m.models.data.map(e=>e.id)}),r=await _.prompt(`Select a small model to use`,{type:`select`,options:m.models.data.map(e=>e.id)}));let i=Ne({ANTHROPIC_BASE_URL:t,ANTHROPIC_AUTH_TOKEN:`dummy`,ANTHROPIC_MODEL:n,ANTHROPIC_SMALL_FAST_MODEL:r},`\u0063\u006c\u0061\u0075\u0064\u0065`);try{ae.writeSync(i),_.success(`Copied command to clipboard!`)}catch{_.warn(`Failed to copy to clipboard. Here is the command:`),_.log(i)}}async function ht(e){ft(),ut.push(()=>{_.debug(`Cleaning up connectivity monitor`),C.stop()},()=>{_.debug(`Cleaning up token management`),ye()}),e.verbose&&(_.level=5,_.info(`Verbose logging enabled`)),m.accountType=e.accountType,e.accountType!==`individual`&&_.info(`Using ${e.accountType} plan account`),m.manualApprove=e.manual,m.rateLimitSeconds=e.rateLimit,m.rateLimitWait=e.rateLimitWait,m.showToken=e.showToken,m.timeoutMs=e.timeout,m.connectivity.enabled=!e.disableConnectivityMonitoring,await l(),_e(),e.githubToken?(m.githubToken=e.githubToken,_.info(`Using provided Auth token`)):await j();let t;try{let{_s4:e}=await import(`./get-user-CkQLlbpH.js`);t=await e(),await ne(m,t.login)}catch(e){_.error(`Failed to get user info for machine ID generation:`,e),_.error(`Cannot proceed without user information`),b.exit(1)}await Se(),await ge(),await pt(e,t.login),_.info(`Available services:`);for(let e of m.models?.data??[]){let t=e.capabilities.limits?.max_context_window_tokens,n=t?` (${t.toLocaleString()} tokens)`:``;_.info(`- ${e.id}${n}`)}let n=`http://localhost:${e.port}`;await mt(e,n),_.box(`🌐 Usage Viewer: https://ericc-ch.\u0067\u0069\u0074\u0068\u0075\u0062.io/\u0063\u006f\u0070\u0069\u006c\u006f\u0074-api?endpoint=${n}/usage`),oe({fetch:$.fetch,port:e.port})}const gt=g({meta:{name:`start`,description:`Start the 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 (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-token":{alias:`g`,type:`string`,description:"Provide auth token directly (must be generated using the `auth` subcommand)"},"\u0063\u006c\u0061\u0075\u0064\u0065-code":{alias:`c`,type:`boolean`,default:!1,description:`Generate a command to launch with API config`},model:{alias:`m`,type:`string`,description:`Model to use (requires --\u0063\u006c\u0061\u0075\u0064\u0065-code)`},"small-model":{alias:`s`,type:`string`,description:`Small/fast model to use (requires --\u0063\u006c\u0061\u0075\u0064\u0065-code)`},"show-token":{type:`boolean`,default:!1,description:`Show 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 monitoring for token refresh`}},run({args:e}){let t=e[`rate-limit`],n=t===void 0?void 0:Number.parseInt(t,10),r=e.timeout,i=r===void 0?12e4:Number.parseInt(r,10);return ht({port:Number.parseInt(e.port,10),verbose:e.verbose,accountType:e[`account-type`],manual:e.manual,rateLimit:n,rateLimitWait:e.wait,githubToken:e[`\u0067\u0069\u0074\u0068\u0075\u0062-token`],claudeCode:e[`\u0063\u006c\u0061\u0075\u0064\u0065-code`],model:e.model,smallModel:e[`small-model`],showToken:e[`show-token`],timeout:i,disableConnectivityMonitoring:e[`disable-connectivity-monitoring`]})}}),_t=g({meta:{name:`\u0063\u006f\u0070\u0069\u006c\u006f\u0074-api`,description:`API proxy server for tool integration.`},subCommands:{auth:we,start:gt,"check-usage":Te,debug:je}});await ie(_t);export{};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "copilot-api-node20",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.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",
|
|
@@ -24,16 +24,14 @@
|
|
|
24
24
|
"dist"
|
|
25
25
|
],
|
|
26
26
|
"scripts": {
|
|
27
|
-
"build": "tsdown && node
|
|
28
|
-
"build:no-
|
|
29
|
-
"build:no-string-obfuscation": "tsdown",
|
|
27
|
+
"build": "tsdown && node obfuscate-dist.js",
|
|
28
|
+
"build:no-obfuscation": "tsdown",
|
|
30
29
|
"build:readable": "tsdown --no-minify",
|
|
31
30
|
"dev": "bun run --watch ./src/main.ts",
|
|
32
31
|
"knip": "knip-bun",
|
|
33
32
|
"lint": "eslint . --cache",
|
|
34
33
|
"prepack": "npm run build",
|
|
35
34
|
"prepare": "simple-git-hooks",
|
|
36
|
-
"release": "bumpp && bun publish --access public",
|
|
37
35
|
"start": "NODE_ENV=production bun run ./src/main.ts",
|
|
38
36
|
"test": "bun test",
|
|
39
37
|
"test:coverage": "bun test --coverage",
|
|
@@ -47,29 +45,39 @@
|
|
|
47
45
|
"*": "bun run lint --fix"
|
|
48
46
|
},
|
|
49
47
|
"overrides": {
|
|
50
|
-
"
|
|
48
|
+
"@typescript-eslint/eslint-plugin": "^8.56.0",
|
|
49
|
+
"@typescript-eslint/parser": "^8.56.0",
|
|
50
|
+
"@typescript-eslint/typescript-estree": "^8.56.0",
|
|
51
|
+
"@typescript-eslint/utils": "^8.56.0",
|
|
52
|
+
"minimatch": "^10.2.4",
|
|
53
|
+
"typescript-eslint": "^8.56.0"
|
|
51
54
|
},
|
|
52
55
|
"dependencies": {
|
|
56
|
+
"applicationinsights": "^3.14.0",
|
|
53
57
|
"citty": "^0.1.6",
|
|
54
58
|
"clipboardy": "^4.0.0",
|
|
55
59
|
"consola": "^3.4.2",
|
|
56
60
|
"fetch-event-stream": "^0.1.5",
|
|
57
|
-
"hono": "^4.12.
|
|
61
|
+
"hono": "^4.12.5",
|
|
58
62
|
"srvx": "^0.6.0",
|
|
59
63
|
"tiny-invariant": "^1.3.3",
|
|
60
64
|
"undici": "^7.16.0"
|
|
61
65
|
},
|
|
62
66
|
"devDependencies": {
|
|
63
67
|
"@echristian/eslint-config": "^0.0.54",
|
|
68
|
+
"@semantic-release/changelog": "^6.0.3",
|
|
69
|
+
"@semantic-release/commit-analyzer": "^13.0.1",
|
|
70
|
+
"@semantic-release/git": "^10.0.1",
|
|
71
|
+
"@semantic-release/github": "^12.0.6",
|
|
72
|
+
"@semantic-release/npm": "^13.1.5",
|
|
73
|
+
"@semantic-release/release-notes-generator": "^14.1.0",
|
|
64
74
|
"@types/bun": "^1.2.21",
|
|
65
|
-
"bumpp": "^10.2.3",
|
|
66
75
|
"bun": "^1.3.9",
|
|
67
|
-
"esbuild": "^0.25.10",
|
|
68
76
|
"eslint": "^10.0.2",
|
|
69
|
-
"javascript-obfuscator": "^0.6.2",
|
|
70
77
|
"knip": "^5.63.0",
|
|
71
78
|
"lint-staged": "^16.1.5",
|
|
72
79
|
"prettier-plugin-packagejson": "^2.5.19",
|
|
80
|
+
"semantic-release": "^25.0.3",
|
|
73
81
|
"simple-git-hooks": "^2.13.1",
|
|
74
82
|
"terser": "^5.44.0",
|
|
75
83
|
"tsdown": "^0.14.2",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import e from"consola";import t from"node:fs/promises";import n from"node:os";import r from"node:path";import{createHash as i,randomBytes as a,randomUUID as o}from"node:crypto";const s=r.join(n.homedir(),`.local`,`share`,`copilot-api`),c=r.join(s,`github_token`),l=r.join(s,`machine_id`),u=r.join(s,`session_id`),d={APP_DIR:s,GITHUB_TOKEN_PATH:c,MACHINE_ID_PATH:l,SESSION_ID_PATH:u};async function f(){await t.mkdir(d.APP_DIR,{recursive:!0}),await p(d.GITHUB_TOKEN_PATH),await p(d.SESSION_ID_PATH)}async function p(e){try{await t.access(e,t.constants.W_OK)}catch{await t.writeFile(e,``),await t.chmod(e,384)}}const m={accountType:`individual`,manualApprove:!1,rateLimitWait:!1,showToken:!1,connectivity:{enabled:!0,probeEndpoints:[`https://api.github.com`,`https://www.google.com`,`https://1.1.1.1`],fastProbeInterval:5e3,slowProbeInterval:6e4,timeoutMs:5e3,jitterMaxMs:1e3,connectionPooling:!0,dnsCache:!0}},h=()=>({"content-type":`application/json`,accept:`application/json`}),g=`0.32.2025100203`,_=`copilot-chat/${g}`,v=`GitHubCopilotChat/${g}`,y=`2025-08-20`,b=e=>{let t=i(`sha256`);return t.update(process.platform),t.update(process.arch),t.update(process.env.USER||process.env.USERNAME||`anonymous`),t.update(n.hostname()),t.update(e),t.update(Date.now().toString()),t.update(a(16)),t.digest(`hex`)},x=e=>{let t=e.replaceAll(/[^\w.-]/g,`_`).trim();if(t.length===0||t===`.`||t===`..`||/^[_.]+$/.test(t))throw Error(`Invalid GitHub username: cannot be empty or consist only of special characters after sanitization`);return`${d.MACHINE_ID_PATH}_${t}`},S=async e=>{let n=x(e);try{let e=await t.readFile(n,`utf8`);if(e.trim())return e.trim()}catch{}let r=b(e);return await t.writeFile(n,r),await t.chmod(n,384),r},C=async()=>{try{let e=await t.readFile(d.SESSION_ID_PATH,`utf8`);if(e.trim())return e.trim()}catch{}let e=o();return await t.writeFile(d.SESSION_ID_PATH,e),await t.chmod(d.SESSION_ID_PATH,384),e},w=async(e,t)=>{e.machineId||=await S(t),e.sessionId||=await C()},T=e=>e.accountType===`individual`?`https://api.githubcopilot.com`:`https://api.${e.accountType}.githubcopilot.com`,E=(e,t=!1)=>{if(!e.machineId||!e.sessionId)throw Error(`VSCode identifiers not initialized. Call initializeVSCodeIdentifiers() during startup.`);let n={Authorization:`Bearer ${e.copilotToken}`,"Content-Type":`application/json`,accept:`*/*`,"accept-encoding":`br, gzip, deflate`,"accept-language":`*`,"sec-fetch-mode":`cors`,"Copilot-Integration-Id":`vscode-chat`,"Editor-Version":`vscode/${e.vsCodeVersion}`,"Editor-Plugin-Version":_,"User-Agent":v,"VScode-MachineId":e.machineId,"VScode-SessionId":e.sessionId,"OpenAI-Intent":`conversation-agent`,"X-Interaction-Type":`conversation-agent`,"X-VSCode-User-Agent-Library-Version":`node-fetch`,"X-GitHub-Api-Version":y,"X-Interaction-Id":o(),"X-Request-Id":o(),"openai-intent":`conversation-agent`,"x-interaction-type":`conversation-agent`};return t&&(n[`copilot-vision-request`]=`true`),n},D=`https://api.github.com`,O=e=>({...h(),authorization:`token ${e.githubToken}`,"editor-version":`vscode/${e.vsCodeVersion}`,"editor-plugin-version":_,"user-agent":v,"x-github-api-version":y,"x-vscode-user-agent-library-version":`node-fetch`}),k=`https://github.com`,A=`01ab8ac9400c4e429b23`,j=[`user:email`].join(` `),M=e=>e>=1e5||e>=1e4?`${Math.round(e/1e3)}K`:e>=1e3?`${(e/1e3).toFixed(1)}K`:e.toString(),N=(e,t)=>e.padEnd(t),P=(e,t)=>{if(!m.models)return``;let n=m.models.data.find(e=>e.id===t);if(!n)return``;let r=n.capabilities.limits.max_context_window_tokens;if(!r)return``;let i=(e/r*100).toFixed(1);return` (${i}%)`},F=e=>{let t=[];if(e.model){let n=N(e.model,18);t.push(n)}if(e.tokenUsage){let n=e.tokenUsage,r=(n.inputTokens||0)+(n.outputTokens||0),i=e.model?P(r,e.model):``,a=M(n.inputTokens||0).padStart(5),o=M(n.outputTokens||0).padStart(5),s=`↑${a} │ ↓${o}`,c=N(s,18),l=M(r),u=i?`${l}${i.padStart(15-l.length)}`:l.padEnd(15);t.push(`Tokens: ${c} | Context: ${u}`)}else if(e.model){let e=N(`N/A`,18),n=`N/A`.padEnd(15);t.push(`Tokens: ${e} | Context: ${n}`)}if(e.copilotDuration){let n=N(`${Math.round(e.copilotDuration)}ms`,8);t.push(`API: ${n}`)}return t.length>0?` | ${t.join(` | `)}`:``},I={completionCallbacks:new Map,registerCompletion(e,t,n){this.completionCallbacks.set(e,{context:t,startTime:n,requestId:e})},executeCompletion(e){let t=this.completionCallbacks.get(e);t&&(this.logCompletion(t),this.completionCallbacks.delete(e))},logCompletion(t){let{context:n,startTime:r}=t,i=Date.now(),a=i-r,o=n.get(`requestData`),s=N(n.req.method,4),c=N(n.req.path,21),l=N(n.res.status.toString(),3),u=N(`${a}ms`,8),d=` --> ${s}${c}${l} ${u}`;o&&(d+=F(o)),e.info(d)},logRateLimit(t,n){let{context:r,startTime:i}=t,a=Date.now(),o=a-i,s=n.headers.get(`x-ratelimit-exceeded`)||``,c=s.split(`:`)[1]||`unknown`,l=n.headers.get(`retry-after`)||n.headers.get(`x-ratelimit-user-retry-after`)||`?`,u=N(r.req.method,4),d=N(r.req.path,21),f=N(`429`,3),p=N(`${o}ms`,8),m=`⚠ --> ${u}${d}${f} ${p}`;m+=` | Rate limited (${l}s retry) | ${c}`;let h=r.get(`requestData`);if(h?.copilotDuration){let e=N(`${Math.round(h.copilotDuration)}ms`,8);m+=` | API: ${e}`}e.info(m)},cleanup(){let e=1e3,t=Date.now()-300*1e3;for(let[e,n]of this.completionCallbacks)n.startTime<t&&this.completionCallbacks.delete(e);if(this.completionCallbacks.size>e){let t=Array.from(this.completionCallbacks.entries()).sort(([,e],[,t])=>e.startTime-t.startTime),n=t.slice(0,t.length-e);for(let[e]of n)this.completionCallbacks.delete(e)}}};setInterval(()=>I.cleanup(),60*1e3);var L=class extends Error{response;constructor(e,t){super(e),this.response=t}};async function R(t,n){if(n instanceof L&&n.response.status===429){let e=t.get(`requestId`),r=I.completionCallbacks.get(e);r&&(I.logRateLimit(r,n.response),I.completionCallbacks.delete(e));let i=await n.response.text(),a;try{a=JSON.parse(i)}catch{a={error:{message:i,type:`error`}}}return t.json(a,429)}if(e.error(`Error occurred:`,n),n instanceof L){let r=await n.response.text(),i;try{i=JSON.parse(r)}catch{i=r}return e.error(`HTTP error:`,i),t.json({error:{message:r,type:`error`}},n.response.status)}return t.json({error:{message:n.message,type:`error`}},500)}async function z(){let e=new AbortController,t=m.timeoutMs??12e4,n=setTimeout(()=>{e.abort()},t);try{let t=await fetch(`${D}/user`,{headers:{authorization:`token ${m.githubToken}`,...h()},signal:e.signal});if(!t.ok)throw new L(`Failed to get GitHub user`,t);return await t.json()}finally{clearTimeout(n)}}export{I as CompletionLogger,D as GITHUB_API_BASE_URL,j as GITHUB_APP_SCOPES,k as GITHUB_BASE_URL,A as GITHUB_CLIENT_ID,L as HTTPError,d as PATHS,T as copilotBaseUrl,E as copilotHeaders,f as ensurePaths,R as forwardError,z as getGitHubUser,O as githubHeaders,w as initializeVSCodeIdentifiers,h as standardHeaders,m as state};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{getGitHubUser as e}from"./get-user-BJ4s6iMX.js";export{e as getGitHubUser};
|