@simonesiega/codex-limits 0.1.6 → 1.0.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.
@@ -0,0 +1,5 @@
1
+ import{joinSession as x1}from"@github/copilot-sdk/extension";function FQ(Q){let Z=[];if(Q.windows.fiveHour)Z.push(TQ("5-hour",Q.windows.fiveHour));if(Q.windows.weekly)Z.push(TQ("Weekly",Q.windows.weekly));if(Z.length===0)Z.push(["Usage limits Unavailable"]);if(Z.push(TZ(Q)),Q.warnings.length>0)Z.push(["Warnings",...Q.warnings.map(($)=>`- ${$}`)]);return Z.map(($)=>$.join(`
2
+ `)).join(`
3
+
4
+ `)}function TQ(Q,Z){let $=Z.remainingPercent;return[`${Q} ${FZ($)}`,`Remaining ${$===null?"Unknown":`${Math.round($)}% remaining`}`,PZ($),`Reset ${Z.resetsIn?`in ${Z.resetsIn}`:"unknown"}`]}function PZ(Q){let Z=Q===null?0:Math.min(Math.max(Q,0),100),$=Math.round(Z/100*22);return`[${"=".repeat($)}${" ".repeat(22-$)}] ${Math.round(Z)}%`}function TZ(Q){let Z=Q.coupons?.available,G=[`Reset credits ${Z===null||Z===void 0?"Unknown":`${Z} ${Z===1?"credit":"credits"} available`}`],J=Q.coupons?.nextExpirationIn,z=Q.coupons?.nextExpirationDate,K=J&&z?`${J} (${z})`:J??z;if(K!==null&&K!==void 0)G.push(`Next expires ${K}`);return G}function FZ(Q){if(Q===null)return"Unknown";if(Q>=50)return"Healthy";if(Q>=15)return"Low";return"Critical"}function AQ(Q){return FQ(Q)}import{constants as AZ}from"node:fs";import{access as bZ,stat as IZ}from"node:fs/promises";import{homedir as kZ}from"node:os";import{join as I,normalize as s}from"node:path";function U(Q,Z){let $=Q[Z]?.trim();return $?$:null}function A(Q){return Q??process.env}var bQ="CODEX_LIMITS_HOME";function LZ(Q={}){let Z=A(Q.env),$=Q.homeDirectory??U(Z,"HOME")??U(Z,"USERPROFILE")??kZ(),G=Q.appData??U(Z,"APPDATA"),J=Q.localAppData??U(Z,"LOCALAPPDATA"),z=[];if(D(z,U(Z,bQ),"env"),D(z,U(Z,"CODEX_HOME"),"env"),$)D(z,I($,".codex"),"default"),D(z,I($,".config","codex"),"default"),D(z,I($,"Library","Application Support","Codex"),"default"),D(z,I($,"Library","Application Support","Parall","Codex",".codex"),"default");return D(z,G?I(G,"Codex"):null,"default"),D(z,J?I(J,"Codex"):null,"default"),RZ(z)}async function v(Q={}){let Z=A(Q.env),$=U(Z,bQ),G=await Promise.all(LZ(Q).map(async(J)=>({...J,exists:await _Z(J.path)})));return{overrideHome:$?s($):null,candidates:G,foundHome:G.find((J)=>J.exists)?.path??null}}function D(Q,Z,$){if(Z)Q.push({path:s(Z),source:$})}async function _Z(Q){try{if(!(await IZ(Q)).isDirectory())return!1;return await bZ(Q,AZ.R_OK),!0}catch{return!1}}function RZ(Q){let Z=new Set,$=[];for(let G of Q){let J=s(G.path),z=process.platform==="win32"?J.toLowerCase():J;if(!Z.has(z))Z.add(z),$.push({path:J,source:G.source})}return $}import{constants as a}from"node:fs";import{lstat as h,open as cZ,opendir as pZ,realpath as fQ}from"node:fs/promises";import{join as SQ}from"node:path";var yZ=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],fZ=["January","February","March","April","May","June","July","August","September","October","November","December"];function L(Q,Z={}){let $=Z.includeSeconds??!1,G=Math.max(Math.floor(Q/1000),0),J=Math.floor(G/86400);G%=86400;let z=Math.floor(G/3600);G%=3600;let K=Math.floor(G/60),j=G%60,X=[];if(J>0)X.push(`${J}d`);if(z>0)X.push(`${z}h`);if(K>0)X.push(`${K}m`);if($&&j>0)X.push(`${j}s`);return X.length>0?X.join(" "):$?`${j}s`:"0m"}function P(Q){if(typeof Q==="number"&&Number.isFinite(Q)){let Z=Q<10000000000?Q*1000:Q,$=new Date(Z);return Number.isNaN($.getTime())?null:$}if(typeof Q==="string"&&Q.trim().length>0){let Z=Q.trim(),$=Number(Z);if(Number.isFinite($))return P($);let G=new Date(Z);return Number.isNaN(G.getTime())?null:G}return null}function IQ(Q){return`${yZ[Q.getDay()]} ${Q.getDate()} ${fZ[Q.getMonth()]} ${Q.getFullYear()}`}import{isAbsolute as vZ,relative as LQ,resolve as kQ,sep as mZ}from"node:path";var SZ=/(?:chatgpt[-_]?account[-_]?id|access[-_]?token|refresh[-_]?token|id[-_]?token|session[-_]?token|api[-_]?key|account[-_]?id|authorization|cookie|client[-_]?secret|password|credential|secret|token)/,EZ=/[\u0000-\u001f\u007f-\u009f]/g,wZ=new RegExp(`["']?${SZ.source}["']?\\s*[:=]\\s*(?:"(?:\\\\.|[^"\\\\])*"|'(?:\\\\.|[^'\\\\])*'|[^,\\r\\n}\\]&]+)`,"gi"),gZ=[wZ,/Bearer\s+[A-Za-z0-9._~+/=-]+/gi,/\beyJ[A-Za-z0-9_-]{5,}\.[A-Za-z0-9_-]{5,}(?:\.[A-Za-z0-9_-]{5,})?\b/g,/sk-[A-Za-z0-9_-]{10,}/g,/\b[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}\b/gi,/[A-Za-z0-9_-]{32,}/g];function _(Q){let Z=Q;for(let $ of gZ)Z=Z.replace($,"[redacted]");return Z.replace(EZ,"?")}function t(Q){return Q.map(_)}function _Q(Q,Z){let $=LQ(kQ(Q),kQ(Z));return $===""||!RQ($)}function R(Q,Z){let $=LQ(Q,Z);return $&&!RQ($)?hZ($):"."}function hZ(Q){let Z=_(Q);return Z.length<=240?Z:`${Z.slice(0,239)}…`}function RQ(Q){return Q===".."||Q.startsWith(`..${mZ}`)||vZ(Q)}function W(Q){return typeof Q==="object"&&Q!==null&&!Array.isArray(Q)}function N(Q,Z){let $=Q[Z];return typeof $==="string"&&$.trim()?$.trim():null}var uZ=8,e=20,m=1000,lZ=512,dZ=1000,GQ=25000000,rZ=1e6,iZ=/^rollout-.*\.jsonl$/i;async function EQ(Q){let Z=SQ(Q,"sessions"),$=[];if(await G0(Z))return $.push("Skipped the symbolic-link Codex sessions directory."),{homePath:Q,sessionsRoot:Z,files:[],latestSnapshot:null,warnings:$};let G=await oZ(Z,$),J=[],z=null;for(let K of G.slice(0,e)){let j=R(Q,K.path);if(K.size>GQ){$.push("Skipped a local Codex session file because it is too large to inspect safely."),J.push(ZQ(K.path,j,K.modifiedAtMs,!1,"too-large"));continue}try{let X=await tZ(Q,K);if(J.push(ZQ(K.path,j,K.modifiedAtMs,X.snapshot!==null,null)),X.skippedOversizedLine)$.push("Skipped an oversized JSONL line in a local Codex session file.");if(X.snapshot&&(!z||eZ(X.snapshot,z)))z=X.snapshot}catch(X){let Y=X instanceof c;$.push(Y?"Skipped a local Codex session file because it grew too large to inspect safely.":"Could not inspect a local Codex session file safely."),J.push(ZQ(K.path,j,K.modifiedAtMs,!1,Y?"too-large":"read-error"))}}if(G.length>e)$.push(`Skipped ${G.length-e} older session files to keep inspection small.`);if(G.length>0&&!z)$.push("No token-count rate-limit snapshot was found in local Codex session logs.");return{homePath:Q,sessionsRoot:Z,files:J,latestSnapshot:z,warnings:$}}async function oZ(Q,Z){let $={directories:0,files:[],hitLimit:!1,skippedSymlink:!1};if(await wQ(Q,0,$,Z),$.hitLimit)Z.push("Stopped session discovery after reaching a safe inspection limit.");if($.skippedSymlink)Z.push("Skipped symbolic links while inspecting Codex sessions.");let G;try{G=await fQ(Q)}catch{return[]}let J=[];for(let z of $.files){let K=await nZ(G,z,Z);if(K)J.push(K)}return J.sort((z,K)=>K.modifiedAtMs-z.modifiedAtMs||z.path.localeCompare(K.path))}async function nZ(Q,Z,$){try{let[G,J]=await Promise.all([h(Z),fQ(Z)]);if(!G.isFile()||!_Q(Q,J))return $.push("Could not inspect a local Codex session file safely."),null;return{path:Z,modifiedAtMs:G.mtimeMs,size:G.size,dev:G.dev,ino:G.ino}}catch{return $.push("Could not inspect a local Codex session file safely."),null}}async function wQ(Q,Z,$,G){if(Z>uZ||$.files.length>=m){$.hitLimit||=$.files.length>=m;return}if($.directories>=lZ){$.hitLimit=!0;return}$.directories+=1;let J;try{J=await sZ(Q,$)}catch{if(Z>0)G.push("Could not inspect part of the local Codex sessions directory safely.");return}for(let z of J){if($.files.length>=m){$.hitLimit=!0;return}let K=SQ(Q,z.name);if(z.isSymbolicLink()){$.skippedSymlink=!0;continue}if(z.isDirectory()){await wQ(K,Z+1,$,G);continue}if(z.isFile()&&iZ.test(z.name)){if($.files.push(K),$.files.length>=m){$.hitLimit=!0;return}}}}async function sZ(Q,Z){let $=await pZ(Q),G=[];for await(let J of $){if(G.length>=dZ){Z.hitLimit=!0;break}G.push(J)}return G.sort((J,z)=>z.name.localeCompare(J.name))}async function tZ(Q,Z){let $=Z.path,G=R(Q,$),J=await aZ(Z),z=null,K=null,j="",X=0,Y=0,H=!1,M=!1;for await(let x of J){let O=String(x);if(Y+=Buffer.byteLength(O,"utf8"),Y>GQ)throw new c;let T=0;while(T<O.length){let F=O.indexOf(`
5
+ `,T),g=F===-1?O.length:F,PQ=O.slice(T,g);if(!H){let C=Buffer.byteLength(PQ,"utf8");if(X+C>rZ)j="",X=0,H=!0,M=!0;else j+=PQ,X+=C}if(F===-1)break;if(!H){let C=yQ(j.endsWith("\r")?j.slice(0,-1):j);if(C.threadId)z=C.threadId;if(C.rateLimits)K={sessionFile:$,relativePath:G,threadId:z,eventTimestamp:C.timestamp,rateLimits:C.rateLimits}}j="",X=0,H=!1,T=F+1}}if(!H&&j.length>0){let x=yQ(j.endsWith("\r")?j.slice(0,-1):j);if(x.threadId)z=x.threadId;if(x.rateLimits)K={sessionFile:$,relativePath:G,threadId:z,eventTimestamp:x.timestamp,rateLimits:x.rateLimits}}return{snapshot:K,skippedOversizedLine:M}}async function aZ(Q){let Z;try{let $=await h(Q.path);if(!$.isFile()||!QQ($,Q))throw new $Q;let G=a.O_NOFOLLOW,J=typeof G==="number"?a.O_RDONLY|G:a.O_RDONLY;Z=await cZ(Q.path,J);let[z,K]=await Promise.all([Z.stat(),h(Q.path)]);if(!z.isFile()||!K.isFile()||!QQ(z,Q)||!QQ(z,K))throw new $Q;if(z.size>GQ)throw new c;return Z.createReadStream({encoding:"utf8",highWaterMark:65536})}catch($){throw await Z?.close().catch(()=>{return}),$}}function QQ(Q,Z){return Q.dev===Z.dev&&Q.ino===Z.ino}function eZ(Q,Z){let $=P(Q.eventTimestamp)?.getTime()??null,G=P(Z.eventTimestamp)?.getTime()??null;if($===null)return!1;return G===null||$>G}function yQ(Q){let Z=Q0(Q);if(!Z)return{threadId:null,timestamp:null,rateLimits:null};return{threadId:Z0(Z),timestamp:N(Z,"timestamp"),rateLimits:$0(Z)}}function Q0(Q){let Z=Q.trim();if(!Z)return null;try{let $=JSON.parse(Z);return W($)?$:null}catch{return null}}function Z0(Q){if(Q.type!=="session_meta"||!W(Q.payload))return null;return N(Q.payload,"id")}function $0(Q){if(Q.type!=="event_msg"||!W(Q.payload))return null;if(Q.payload.type!=="token_count"||!W(Q.payload.rate_limits))return null;return Q.payload.rate_limits}function ZQ(Q,Z,$,G,J){return{path:Q,relativePath:Z,modifiedAtMs:$,hasSnapshot:G,error:J}}async function G0(Q){try{return(await h(Q)).isSymbolicLink()}catch{return!1}}class c extends Error{}class $Q extends Error{}import{opendir as z0}from"node:fs/promises";import{extname as K0,join as j0}from"node:path";import{constants as JQ}from"node:fs";import{lstat as gQ,open as J0}from"node:fs/promises";class q extends Error{code;constructor(Q){super(Q);this.name="BoundedFileError",this.code=Q}}async function p(Q,Z){let $;try{let G=await gQ(Q);if(!G.isFile())throw new q("not-file");let J=JQ.O_NOFOLLOW,z=typeof J==="number"?JQ.O_RDONLY|J:JQ.O_RDONLY;$=await J0(Q,z);let K=await $.stat(),j=await gQ(Q);if(!K.isFile()||!j.isFile()||!vQ(G,K)||!vQ(K,j))throw new q("not-file");if(K.size>Z)throw new q("too-large");let X=Buffer.allocUnsafe(Z+1),Y=0;while(Y<=Z){let H=await $.read(X,Y,Z+1-Y,null);if(H.bytesRead===0)break;Y+=H.bytesRead}if(Y>Z)throw new q("too-large");return X.subarray(0,Y).toString("utf8")}catch(G){if(G instanceof q)throw G;if(mQ(G)&&G.code==="ENOENT")throw new q("not-found");if(mQ(G)&&G.code==="ELOOP")throw new q("not-file");throw new q("read-error")}finally{await $?.close().catch(()=>{return})}}function vQ(Q,Z){return Q.dev===Z.dev&&Q.ino===Z.ino}function mQ(Q){return Q instanceof Error&&"code"in Q}var X0=2,zQ=25,KQ=100,Y0=64,H0=500,W0=1e6,V0=/(?:auth|token|cookie|session|secret|credential|api[-_]?key|keychain)/i;async function hQ(Q){let Z={directories:0,files:[],hitDirectoryLimit:!1,hitEntryLimit:!1,hitFileLimit:!1,skippedSensitive:!1,skippedSymlink:!1,warnings:[]};if(await cQ(Q,0,Z),Z.hitDirectoryLimit||Z.hitEntryLimit||Z.hitFileLimit)Z.warnings.push("Stopped local state discovery after reaching a safe inspection limit.");if(Z.skippedSensitive)Z.warnings.push("Skipped a sensitive-looking local file.");if(Z.skippedSymlink)Z.warnings.push("Skipped symbolic links while inspecting local Codex state.");let $=Z.files.sort((J,z)=>J.localeCompare(z)),G=[];for(let J of $.slice(0,zQ)){let z=R(Q,J);try{let K=await p(J,W0),j=q0(K,Z.warnings);G.push({path:J,relativePath:z,json:j.value,error:j.error})}catch(K){Z.warnings.push(K instanceof q&&K.code==="too-large"?"Skipped a local Codex state file because it is too large to inspect safely.":"Could not read a local Codex state file safely.")}}if($.length>zQ)Z.warnings.push(`Skipped ${$.length-zQ} extra files to keep inspection small.`);return{homePath:Q,files:G,warnings:Z.warnings}}async function cQ(Q,Z,$){if(Z>X0||$.files.length>=KQ){$.hitFileLimit||=$.files.length>=KQ;return}if($.directories>=Y0){$.hitDirectoryLimit=!0;return}$.directories+=1;let G=await M0(Q,$);for(let J of G){if($.files.length>=KQ){$.hitFileLimit=!0;return}if(V0.test(J.name)){$.skippedSensitive=!0;continue}let z=j0(Q,J.name);if(J.isSymbolicLink())$.skippedSymlink=!0;else if(J.isDirectory())await cQ(z,Z+1,$);else if(J.isFile()&&K0(J.name).toLowerCase()===".json")$.files.push(z)}}async function M0(Q,Z){try{let $=await z0(Q),G=[];for await(let J of $){if(G.length>=H0){Z.hitEntryLimit=!0;break}G.push(J)}return G.sort((J,z)=>J.name.localeCompare(z.name))}catch{return Z.warnings.push("Could not inspect part of the local Codex state directory safely."),[]}}function q0(Q,Z){try{return{value:JSON.parse(Q),error:null}}catch{return Z.push("Could not parse JSON in a local Codex state file."),{value:null,error:"invalid-json"}}}import{join as U0,normalize as N0}from"node:path";function B(Q,Z,$){return{code:Q,source:Z,severity:"warning",message:$}}function k(Q){return Q.map((Z)=>_(Z.message))}var B0=1e6;async function u(Q={}){let Z=A(Q.env),$=U(Z,"CODEX_LIMITS_ACCESS_TOKEN"),G=U(Z,"CODEX_LIMITS_ACCOUNT_ID");if($&&G)return{credentials:{accessToken:$,accountId:G},status:"configured",diagnostics:[]};if($||G)return{credentials:null,status:"partial",diagnostics:[B("auth.environment.partial","authentication","Codex authentication environment variables are incomplete.")]};let J=await x0(Q);return J?O0(J):{credentials:null,status:"missing",diagnostics:[]}}async function x0(Q){if(Q.authFile)return N0(Q.authFile);let Z=await v(Q);return Z.foundHome?U0(Z.foundHome,"auth.json"):null}async function O0(Q){let Z;try{Z=await p(Q,B0)}catch($){if($ instanceof q&&$.code==="not-found")return{credentials:null,status:"missing",diagnostics:[]};let G=$ instanceof q&&$.code==="too-large";return{credentials:null,status:"unreadable",diagnostics:[B(G?"auth.file.too-large":"auth.file.unreadable","authentication",G?"Codex auth.json is too large to inspect safely.":"Codex auth.json could not be read safely.")]}}try{let $=JSON.parse(Z);if(!W($))return jQ();let G=W($.tokens)?$.tokens:$,J=N(G,"access_token"),z=N(G,"account_id");return J&&z?{credentials:{accessToken:J,accountId:z},status:"configured",diagnostics:[]}:jQ()}catch{return jQ()}}function jQ(){return{credentials:null,status:"malformed",diagnostics:[B("auth.file.malformed","authentication","Codex auth.json is malformed or does not contain required credentials.")]}}var C0=/[\u0000-\u0020\u007f-\u009f]/;function XQ(Q){return Q.length>0&&Q.length<=512&&!C0.test(Q)}import{request as D0}from"node:http";import{request as P0}from"node:https";var T0=new Set(["127.0.0.1","::1","[::1]","localhost"]);function f(Q){try{let Z=new URL(Q);return Z.username="",Z.password="",Z.search="",Z.hash="",Z.href}catch{return"[invalid endpoint]"}}async function uQ(Q){let Z=F0(Q.endpoint);if(!Z.ok)return Z;if(Q.signal?.aborted)return V("aborted");let $=Q.fetch??globalThis.fetch;if(!$)return pQ(Z.url,Q);let G=await A0(Z.url,Q,$);if(G.ok||G.code==="aborted"||!k0(G,Q.fallbackOnHttpError??!1))return G;let J=await pQ(Z.url,Q);if(J.ok||J.code==="http-error"||J.code==="invalid-json"||J.code==="response-too-large")return J;return G}function l(Q){let Z={...Q,method:"GET"};return delete Z.body,uQ(Z)}function F0(Q){let Z;try{Z=new URL(Q)}catch{return V("invalid-url")}if(Z.username||Z.password)return V("invalid-url");if(Z.protocol==="https:")return{ok:!0,url:Z};if(Z.protocol==="http:"&&T0.has(Z.hostname.toLowerCase()))return{ok:!0,url:Z};return V("unsupported-protocol")}async function A0(Q,Z,$){let G=dQ(Z.timeoutMs,Z.signal);try{let J=await $(Q.href,{method:Z.method??"GET",headers:Z.headers,redirect:"error",signal:G.signal,...Z.body===void 0?{}:{body:Z.body}});if(!J.ok)return await lQ(J),V("http-error",WQ(J.status));let z=await b0(J,Z.maxResponseBytes);return{ok:!0,status:WQ(J.status)??200,payload:z,transport:"fetch"}}catch(J){if(J instanceof y)return V("response-too-large");if(J instanceof d)return V("invalid-json");if(Z.signal?.aborted)return V("aborted");if(G.didTimeout())return V("timeout");return V("network-error")}finally{G.dispose()}}async function b0(Q,Z){let $=Number(Q.headers?.get("content-length"));if(Number.isFinite($)&&$>Z)throw await lQ(Q),new y;if(Q.body){let G=Q.body.getReader(),J=[],z=0;while(!0){let j=await G.read();if(j.done)break;if(!j.value)continue;if(z+=j.value.byteLength,z>Z)throw await G.cancel?.(),new y;J.push(j.value)}let K=Buffer.concat(J.map((j)=>Buffer.from(j)),z).toString("utf8");return HQ(K)}if(Q.text){let G=await Q.text();if(Buffer.byteLength(G,"utf8")>Z)throw new y;return HQ(G)}throw new d}async function lQ(Q){if(!Q.body)return;try{await Q.body.getReader().cancel?.()}catch{}}function pQ(Q,Z){return new Promise(($)=>{let G=dQ(Z.timeoutMs,Z.signal),J=!1,z=null,K=(X)=>{if(J)return;J=!0,G.dispose(),$(X)},j=()=>{z?.destroy(),K(V(Z.signal?.aborted?"aborted":"timeout"))};G.signal.addEventListener("abort",j,{once:!0});try{z=(Q.protocol==="http:"?D0:P0)(Q,{method:Z.method??"GET",headers:Z.headers,signal:G.signal},(Y)=>I0(Y,Z.maxResponseBytes,K)),z.on("error",()=>{if(Z.signal?.aborted)K(V("aborted"));else if(G.didTimeout())K(V("timeout"));else K(V("network-error"))}),z.end(Z.body)}catch{K(V("network-error"))}})}function I0(Q,Z,$){let G=WQ(Q.statusCode);if(G===null||G<200||G>=300){$(V("http-error",G)),YQ(Q);return}let J=Number(Q.headers["content-length"]);if(Number.isFinite(J)&&J>Z){$(V("response-too-large")),YQ(Q);return}let z=[],K=0;Q.on("data",(j)=>{let X=Buffer.isBuffer(j)?j:Buffer.from(j);if(K+=X.length,K>Z){$(V("response-too-large")),YQ(Q);return}z.push(X)}),Q.on("end",()=>{try{let j=HQ(Buffer.concat(z,K).toString("utf8"));$({ok:!0,status:G,payload:j,transport:"node"})}catch{$(V("invalid-json"))}}),Q.on("error",()=>$(V("network-error")))}function YQ(Q){Q.destroy(),Q.socket.destroy()}function dQ(Q,Z){let $=new AbortController,G=!1,J=Number.isFinite(Q)&&Q>0?Math.min(Math.floor(Q),2147483647):1,z=setTimeout(()=>{G=!0,$.abort()},J),K=()=>$.abort();if(Z?.addEventListener("abort",K,{once:!0}),Z?.aborted)K();return{signal:$.signal,didTimeout:()=>G,dispose:()=>{clearTimeout(z),Z?.removeEventListener("abort",K)}}}function k0(Q,Z){return Q.code==="network-error"||Q.code==="timeout"||Q.code==="invalid-json"||Z&&Q.code==="http-error"}function HQ(Q){try{return JSON.parse(Q)}catch{throw new d}}function WQ(Q){return typeof Q==="number"&&Number.isInteger(Q)&&Q>=0?Q:null}function V(Q,Z=null){return{ok:!1,code:Q,status:Z}}class y extends Error{}class d extends Error{}function r(Q,Z){switch(Q.code){case"aborted":return B("network.request.aborted","network",`${Z} lookup was cancelled.`);case"http-error":return B("network.response.http","network",Q.status===null?`${Z} endpoint returned an invalid HTTP status.`:`${Z} endpoint returned HTTP ${Q.status}.`);case"invalid-json":return B("network.response.invalid-json","network",`${Z} endpoint returned malformed JSON.`);case"invalid-url":return B("network.endpoint.invalid","network",`${Z} endpoint URL is invalid.`);case"response-too-large":return B("network.response.too-large","network",`${Z} endpoint response was too large.`);case"timeout":return B("network.request.timeout","network",`${Z} lookup timed out.`);case"unsupported-protocol":return B("network.endpoint.protocol","network",`${Z} endpoint must use HTTPS or loopback HTTP.`);case"network-error":return B("network.request.failed","network",`${Z} lookup failed.`)}}var nQ=["credits","reset_credits","items"],sQ=["available_count","availableCount","available"],tQ=["total_earned_count","earned_this_period","earnedThisPeriod","totalEarnedCount"],L0=64,_0=/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.(\d+))?(?:Z|[+-](\d{2}):(\d{2}))$/i;function aQ(Q,Z,$){if(!W(Q)||!R0(Q))return S(Z,["Live reset coupon endpoint returned an unexpected payload."]);let G=E0(Q,nQ);if(G.malformed)return S(Z,["Live reset coupon endpoint returned an unexpected payload."]);let J=G.value,z=J.map((H,M)=>y0(H,M+1,$)).filter((H)=>H!==null).sort(S0).map((H,M)=>({...H,index:M+1})),K=z.find((H)=>H.status?.toLowerCase()==="available")??z[0]??null,j=oQ(Q,sQ),X=oQ(Q,tQ),Y=[];if(J.length!==z.length)Y.push("Live reset coupon endpoint ignored malformed coupon entries.");if(j.malformed||X.malformed)Y.push("Live reset coupon endpoint ignored malformed summary fields.");return{status:Y.length>0?"partial":"available",available:j.value,earnedThisPeriod:X.value,nextExpirationDate:K?.expirationDate??null,nextExpirationIn:K?.expiresIn??null,items:z,warnings:Y,source:{live:!0,label:"live Codex reset-credit endpoint",endpoint:Z}}}function S(Q,Z=[]){return{status:"unavailable",available:null,earnedThisPeriod:null,nextExpirationDate:null,nextExpirationIn:null,items:[],warnings:Z,source:{live:!1,label:"live Codex reset-credit endpoint",endpoint:Q}}}function R0(Q){return[...nQ,...sQ,...tQ].some((Z)=>(Z in Q))}function y0(Q,Z,$){if(!W(Q))return null;let G=Q.id,J=typeof G==="string"&&XQ(G)?G:null,z=Q.reset_type??Q.resetType,K=typeof z==="string"&&/^[a-z][a-z0-9_-]{0,63}$/i.test(z)?z:null,j="expires_at"in Q||"expiresAt"in Q,X="granted_at"in Q||"grantedAt"in Q,Y=N(Q,"expires_at")??N(Q,"expiresAt"),H=N(Q,"granted_at")??N(Q,"grantedAt"),M=rQ(Y),x=rQ(H),O=N(Q,"status"),T=O&&/^[a-z][a-z0-9_-]{0,63}$/i.test(O)?O:null,F=x?H:null,g=M?Y:null;if("id"in Q&&!J||X&&!x||j&&!M||!T&&!F&&!g)return null;return{id:J,resetType:K,index:Z,status:T,grantedAt:F,expiresAt:g,expirationDate:M?IQ(M):null,expiresIn:M?L(M.getTime()-$.getTime()):null}}function rQ(Q){if(!Q||Q.length>L0)return null;let Z=_0.exec(Q);if(!Z)return null;let $=Number(Z[1]),G=Number(Z[2]),J=Number(Z[3]),z=Number(Z[4]),K=Number(Z[5]),j=Number(Z[6]),X=Z[8]===void 0?0:Number(Z[8]),Y=Z[9]===void 0?0:Number(Z[9]);if(G<1||G>12||J<1||J>f0($,G)||z>23||K>59||j>59||X>23||Y>59)return null;let H=new Date(Q);return Number.isNaN(H.getTime())?null:H}function f0(Q,Z){if(Z===2)return Q%4===0&&(Q%100!==0||Q%400===0)?29:28;return Z===4||Z===6||Z===9||Z===11?30:31}function S0(Q,Z){return iQ(Q.expiresAt)-iQ(Z.expiresAt)}function iQ(Q){return P(Q)?.getTime()??Number.POSITIVE_INFINITY}function E0(Q,Z){let $=!1;for(let G of Z){if(!(G in Q))continue;$=!0;let J=Q[G];if(Array.isArray(J))return{value:J,malformed:!1}}return{value:[],malformed:$}}function oQ(Q,Z){let $=!1;for(let G of Z){if(!(G in Q))continue;$=!0;let J=Q[G];if(typeof J==="number"&&Number.isInteger(J)&&J>=0)return{value:J,malformed:!1}}return{value:null,malformed:$}}var VQ="https://chatgpt.com/backend-api/wham/rate-limit-reset-credits",F2=`${VQ}/consume`,w0=1e4,g0=1e6;async function QZ(Q={}){let Z=Q.endpoint??VQ,$=f(Z),G=await u(Q);if(!G.credentials){let z=k(G.diagnostics);return v0($,z.length>0?z:["Live reset coupons require a readable Codex auth.json file or CODEX_LIMITS_ACCESS_TOKEN and CODEX_LIMITS_ACCOUNT_ID."])}let J=m0(Z,G.credentials,Q);try{let z=await(Q.transport??l)(J);return z.ok?aQ(z.payload,$,Q.now??new Date):eQ($,z)}catch{return eQ($,{ok:!1,code:"network-error",status:null})}}function v0(Q=VQ,Z=[]){return S(f(Q),Z)}function eQ(Q,Z){return S(Q,k([r(Z,"Live reset coupon")]))}function m0(Q,Z,$){return{endpoint:Q,headers:h0(Z),timeoutMs:$.timeoutMs??w0,maxResponseBytes:g0,...$.fetch?{fetch:$.fetch}:{},...$.signal?{signal:$.signal}:{}}}function h0(Q){return{Authorization:`Bearer ${Q.accessToken}`,"ChatGPT-Account-ID":Q.accountId,"OpenAI-Beta":"codex-1",originator:"Codex Desktop",Accept:"application/json"}}var zZ=5,UQ="5-hour usage limit",NQ="Weekly usage limit",BQ=["fiveHour","five_hour","fiveHourWindow","five_hour_window","primary","primaryWindow","primary_window","main","mainWindow"],xQ=["weekly","week","weeklyWindow","weekly_window","secondary","secondaryWindow","secondary_window","backup","backupWindow"],c0=["used_percent","usedPercent","used","usage","percentUsed","usagePercent","usagePercentage","percent"],p0=["remaining_percent","remainingPercent","remaining","percentRemaining","availablePercent","available_percentage"],u0=["resets_at","resetsAt","resetAt","resetTime","reset_at","reset","ends_at","endsAt","windowEnd"],l0=["resetsIn","resetIn","resets_in","reset_in","timeUntilReset"],d0=["limit_window_seconds","limitWindowSeconds","window_seconds","windowSeconds","window_length_seconds","windowLengthSeconds"],r0=["window_minutes","windowMinutes","window_length_minutes","windowLengthMinutes"],i0=18000,o0=604800,n0=/^(?:(\d+)d)?(?:\s*(\d+)h)?(?:\s*(\d+)m)?(?:\s*(\d+)s)?$/i;function KZ(Q,Z=new Date){let $=Q.latestSnapshot;if(!$)return DQ(Q.warnings);return n(OQ($.rateLimits,Z),Q.warnings)}function OQ(Q,Z=new Date){return WZ(i(Q,BQ),i(Q,xQ),Z)}function jZ(Q){return i(Q,BQ)!==null||i(Q,xQ)!==null}function E(Q){let Z=JZ(b(Q,d0,!1)),$=JZ(b(Q,r0,!1)),G=Z??($===null?null:$*60);if(G===i0)return"fiveHour";if(G===o0)return"weekly";return null}function XZ(Q,Z){return{...Q,source:Z}}function CQ(Q,Z,$=[]){return{...n(Q,$),source:Z}}function YZ(Q,Z=new Date){let $={fiveHour:null,weekly:null};for(let G of Q.files){if(!G.json)continue;let J=s0(G.json,Z);$=VZ($,J.windows)}return n($,Q.warnings)}function DQ(Q=[]){return{status:"unavailable",windows:{fiveHour:null,weekly:null},warnings:Q}}function HZ(Q,Z){let $=VZ(Q.windows,Z.windows);return n($,[...Q.warnings,...Z.warnings])}function s0(Q,Z){if(!W(Q))return{windows:{fiveHour:null,weekly:null}};let $=qQ(Q,BQ),G=qQ(Q,xQ);if($||G)return{windows:WZ($,G,Z)};let J=E(Q)??"fiveHour",z=MQ(Q,J==="weekly"?NQ:UQ,Z);return{windows:{fiveHour:J==="fiveHour"?z:null,weekly:J==="weekly"?z:null}}}function WZ(Q,Z,$){let G=[];if(Q)G.push({fallbackKind:"fiveHour",value:Q});if(Z)G.push({fallbackKind:"weekly",value:Z});return{fiveHour:MQ(ZZ(G,"fiveHour"),UQ,$),weekly:MQ(ZZ(G,"weekly"),NQ,$)}}function MQ(Q,Z,$){if(!Q)return null;let G=GZ(b(Q,c0,!0)),J=GZ(b(Q,p0,!0)),z=G??(J===null?null:o(100-J)),K=J??(G===null?null:o(100-G)),j=b(Q,u0,!0),X=P(j),Y=X?X.toISOString():null,H=X?L(X.getTime()-$.getTime()):e0(b(Q,l0,!0)),M={label:Z,remainingPercent:K,usedPercent:z,resetsAt:Y,resetsIn:H};return MZ(M)?M:null}function n(Q,Z){return{status:t0(Q),windows:Q,warnings:Z}}function t0(Q){let Z=[Q.fiveHour,Q.weekly].filter(($)=>MZ($));if(Z.length===0)return"unavailable";return Z.every(a0)?"available":"partial"}function ZZ(Q,Z){let $=Q.find((G)=>E(G.value)===Z);if($)return $.value;return Q.find((G)=>G.fallbackKind===Z&&E(G.value)===null)?.value??null}function VZ(Q,Z){return{fiveHour:$Z(Q.fiveHour,Z.fiveHour,UQ),weekly:$Z(Q.weekly,Z.weekly,NQ)}}function $Z(Q,Z,$){if(!Q&&!Z)return null;return{label:$,remainingPercent:Q?.remainingPercent??Z?.remainingPercent??null,usedPercent:Q?.usedPercent??Z?.usedPercent??null,resetsAt:Q?.resetsAt??Z?.resetsAt??null,resetsIn:Q?.resetsIn??Z?.resetsIn??null}}function MZ(Q){return Q!==null&&(Q.remainingPercent!==null||Q.usedPercent!==null||Q.resetsAt!==null||Q.resetsIn!==null)}function a0(Q){return Q!==null&&Q.remainingPercent!==null&&Q.usedPercent!==null&&(Q.resetsAt!==null||Q.resetsIn!==null)}function qQ(Q,Z,$=0){if($>zZ)return null;for(let G of Z){let J=Q[G];if(W(J))return J}for(let G of Object.values(Q)){if(!W(G))continue;let J=qQ(G,Z,$+1);if(J)return J}return null}function i(Q,Z){for(let $ of Z){let G=Q[$];if(W(G))return G}return null}function b(Q,Z,$,G=0){if(G>zZ)return;for(let J of Z)if(J in Q)return Q[J];if(!$)return;for(let J of Object.values(Q)){if(!W(J))continue;let z=b(J,Z,$,G+1);if(z!==void 0)return z}return}function GZ(Q){if(typeof Q==="number"&&Number.isFinite(Q))return o(Q);if(typeof Q==="string"&&Q.trim().length>0){let Z=Q.trim(),$=Z.endsWith("%")?Z.slice(0,-1):Z,G=Number($);return Number.isFinite(G)?o(G):null}return null}function o(Q){return Math.round(Math.min(Math.max(Q,0),100)*10)/10}function JZ(Q){if(typeof Q==="number"&&Number.isFinite(Q))return Q;if(typeof Q==="string"&&Q.trim().length>0){let Z=Number(Q);return Number.isFinite(Z)?Z:null}return null}function e0(Q){let Z=Q1(Q);if(!Z||Z.length>100)return null;let G=n0.exec(Z)?.slice(1);if(!G||G.every((K)=>K===void 0))return null;let J=[86400,3600,60,1],z=0;for(let[K,j]of G.entries()){if(j===void 0)continue;let X=Number(j),Y=X*J[K];if(!Number.isSafeInteger(X)||!Number.isSafeInteger(Y))return null;if(z+=Y,!Number.isSafeInteger(z))return null}return z<=Math.floor(Number.MAX_SAFE_INTEGER/1000)?L(z*1000):null}function Q1(Q){if(typeof Q==="string"&&Q.trim().length>0)return Q.trim();return null}var Z1=5,$1=1000,G1={kind:"unavailable",label:"Unavailable"};function UZ(Q,Z,$){let G=J1(Q)??z1(Q);if(!G)return w(["Live usage endpoint returned an unexpected payload."]);let J=CQ(OQ(G,$),{kind:"api",label:"API",endpoint:Z});if(J.status==="unavailable")return w(["Live usage endpoint returned an unexpected payload."]);if(J.status==="partial")return{...J,warnings:["Live usage endpoint returned incomplete usage data."]};return J}function w(Q){return CQ({fiveHour:null,weekly:null},G1,Q)}function J1(Q){return NZ(Q,(Z)=>{if(!W(Z))return null;let $=Z.rate_limits??Z.rateLimits??Z.rate_limit??Z.rateLimit;if(W($))return $;return jZ(Z)?Z:null})}function z1(Q){return NZ(Q,(Z)=>{if(!Array.isArray(Z))return null;let $=Z.find((J)=>qZ(J,"fiveHour")),G=Z.find((J)=>qZ(J,"weekly"));return $||G?{fiveHour:$,weekly:G}:null})}function NZ(Q,Z){let $=[{value:Q,depth:0}],G=new WeakSet;for(let J=0;J<$.length;J+=1){let z=$[J];if(!z)break;let K=Z(z.value);if(K)return K;if(z.depth>=Z1||typeof z.value!=="object"||!z.value)continue;if(G.has(z.value))continue;G.add(z.value);let j=Array.isArray(z.value)?z.value:W(z.value)?Object.values(z.value):[];for(let X of j){if($.length>=$1)break;$.push({value:X,depth:z.depth+1})}}return null}function qZ(Q,Z){if(!W(Q))return!1;let $=E(Q);if($)return $===Z;let G=String(Q.type??Q.kind??Q.name??Q.label??Q.window??"").toLowerCase();return Z==="fiveHour"?G.includes("primary")||G.includes("5-hour")||G.includes("five"):G.includes("secondary")||G.includes("weekly")||G.includes("week")}var K1="https://chatgpt.com/backend-api/codex/usage",j1=1e4,X1=1e6;async function BZ(Q={}){return(await Y1(Q)).usage}async function Y1(Q={}){let Z=W1(Q),$=f(Z),G=await u(Q);if(!G.credentials){let K=k(G.diagnostics);return{usage:w(K.length>0?K:["Live usage requires Codex authentication."]),authenticationFound:!1,endpointStatus:"not-checked"}}let J={endpoint:Z,headers:H1(G.credentials),timeoutMs:Q.timeoutMs??j1,maxResponseBytes:X1,fallbackOnHttpError:!0,...Q.fetch?{fetch:Q.fetch}:{},...Q.signal?{signal:Q.signal}:{}},z;try{z=await(Q.transport??l)(J)}catch{z={ok:!1,code:"network-error",status:null}}return{usage:z.ok?UZ(z.payload,$,Q.now??new Date):M1(z),authenticationFound:!0,endpointStatus:V1(z)}}function H1(Q){return{Authorization:`Bearer ${Q.accessToken}`,"ChatGPT-Account-ID":Q.accountId,"OpenAI-Beta":"codex-1",originator:"Codex Desktop",Accept:"application/json","User-Agent":"Codex Desktop",Referer:"https://chatgpt.com/codex/cloud/settings/analytics",Origin:"https://chatgpt.com"}}function W1(Q){let Z=A(Q.env);return Q.usageEndpoint??U(Z,"CODEX_LIMITS_USAGE_ENDPOINT")??K1}function V1(Q){if(Q.ok)return"reachable";switch(Q.code){case"http-error":case"invalid-json":case"response-too-large":return"reachable";case"aborted":return"not-checked";case"invalid-url":case"network-error":case"timeout":case"unsupported-protocol":return"unreachable"}}function M1(Q){return w(k([r(Q,"Live usage")]))}var q1={kind:"local",label:"Local"};async function xZ(Q={}){let Z=Q.includeCoupons===!1?Promise.resolve(null):QZ(Q),[$,G]=await Promise.all([U1(Q),Z]),J=G?{...G,warnings:t(G.warnings)}:null;return{windows:$.windows,usageSource:$.source,coupons:J,warnings:t([...$.warnings,...J?.warnings??[]])}}async function U1(Q={}){let Z=await BZ(Q);if(Z.status!=="unavailable")return Z;let $=XZ(await B1(Q),q1);return N1(Z,$)}function N1(Q,Z){if(Q.status!=="unavailable")return Q;if(Z.status!=="unavailable")return Z;return{...Z,warnings:[...Q.warnings,...Z.warnings]}}async function B1(Q={}){let Z=Q.now??new Date,$=await v(Q);if(!$.foundHome)return DQ(["No readable local Codex home directory was found."]);let[G,J]=await Promise.all([EQ($.foundHome),hQ($.foundHome)]);return HZ(KZ(G,Z),YZ(J,Z))}var O1="Could not load Codex limits.",OZ="Could not display Codex limits.",s2="codex-limits-copilot-extension-v1";async function DZ(Q={}){let Z=Q.getLimits??xZ,$=Q.joinSession??((J)=>x1(J)),G;G=await $({commands:[{name:"codex-limits",description:"Check Codex limits, resets, and credits",handler:async()=>{let J;try{J=AQ(await Z())}catch{await CZ(G,O1,{level:"error"});return}await CZ(G,J)}}]})}async function CZ(Q,Z,$){if(!Q)throw Error(OZ);try{await Q.log(Z,$)}catch{throw Error(OZ)}}try{await DZ()}catch{process.exitCode=1}var a2=DZ;export{DZ as startCopilotExtension,a2 as default,s2 as COPILOT_EXTENSION_MARKER};
@@ -0,0 +1,5 @@
1
+ function AQ(Q){let Z=[];if(Q.windows.fiveHour)Z.push(FQ("5-hour",Q.windows.fiveHour));if(Q.windows.weekly)Z.push(FQ("Weekly",Q.windows.weekly));if(Z.length===0)Z.push(["Usage limits Unavailable"]);if(Z.push(AZ(Q)),Q.warnings.length>0)Z.push(["Warnings",...Q.warnings.map(($)=>`- ${$}`)]);return Z.map(($)=>$.join(`
2
+ `)).join(`
3
+
4
+ `)}function FQ(Q,Z){let $=Z.remainingPercent;return[`${Q} ${bZ($)}`,`Remaining ${$===null?"Unknown":`${Math.round($)}% remaining`}`,FZ($),`Reset ${Z.resetsIn?`in ${Z.resetsIn}`:"unknown"}`]}function FZ(Q){let Z=Q===null?0:Math.min(Math.max(Q,0),100),$=Math.round(Z/100*22);return`[${"=".repeat($)}${" ".repeat(22-$)}] ${Math.round(Z)}%`}function AZ(Q){let Z=Q.coupons?.available,G=[`Reset credits ${Z===null||Z===void 0?"Unknown":`${Z} ${Z===1?"credit":"credits"} available`}`],J=Q.coupons?.nextExpirationIn,z=Q.coupons?.nextExpirationDate,j=J&&z?`${J} (${z})`:J??z;if(j!==null&&j!==void 0)G.push(`Next expires ${j}`);return G}function bZ(Q){if(Q===null)return"Unknown";if(Q>=50)return"Healthy";if(Q>=15)return"Low";return"Critical"}function bQ(Q){return AQ(Q)}import{constants as kZ}from"node:fs";import{access as IZ,stat as LZ}from"node:fs/promises";import{homedir as _Z}from"node:os";import{join as k,normalize as s}from"node:path";function U(Q,Z){let $=Q[Z]?.trim();return $?$:null}function A(Q){return Q??process.env}var kQ="CODEX_LIMITS_HOME";function RZ(Q={}){let Z=A(Q.env),$=Q.homeDirectory??U(Z,"HOME")??U(Z,"USERPROFILE")??_Z(),G=Q.appData??U(Z,"APPDATA"),J=Q.localAppData??U(Z,"LOCALAPPDATA"),z=[];if(D(z,U(Z,kQ),"env"),D(z,U(Z,"CODEX_HOME"),"env"),$)D(z,k($,".codex"),"default"),D(z,k($,".config","codex"),"default"),D(z,k($,"Library","Application Support","Codex"),"default"),D(z,k($,"Library","Application Support","Parall","Codex",".codex"),"default");return D(z,G?k(G,"Codex"):null,"default"),D(z,J?k(J,"Codex"):null,"default"),fZ(z)}async function v(Q={}){let Z=A(Q.env),$=U(Z,kQ),G=await Promise.all(RZ(Q).map(async(J)=>({...J,exists:await yZ(J.path)})));return{overrideHome:$?s($):null,candidates:G,foundHome:G.find((J)=>J.exists)?.path??null}}function D(Q,Z,$){if(Z)Q.push({path:s(Z),source:$})}async function yZ(Q){try{if(!(await LZ(Q)).isDirectory())return!1;return await IZ(Q,kZ.R_OK),!0}catch{return!1}}function fZ(Q){let Z=new Set,$=[];for(let G of Q){let J=s(G.path),z=process.platform==="win32"?J.toLowerCase():J;if(!Z.has(z))Z.add(z),$.push({path:J,source:G.source})}return $}import{constants as a}from"node:fs";import{lstat as h,open as uZ,opendir as lZ,realpath as SQ}from"node:fs/promises";import{join as EQ}from"node:path";var SZ=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],EZ=["January","February","March","April","May","June","July","August","September","October","November","December"];function L(Q,Z={}){let $=Z.includeSeconds??!1,G=Math.max(Math.floor(Q/1000),0),J=Math.floor(G/86400);G%=86400;let z=Math.floor(G/3600);G%=3600;let j=Math.floor(G/60),K=G%60,X=[];if(J>0)X.push(`${J}d`);if(z>0)X.push(`${z}h`);if(j>0)X.push(`${j}m`);if($&&K>0)X.push(`${K}s`);return X.length>0?X.join(" "):$?`${K}s`:"0m"}function P(Q){if(typeof Q==="number"&&Number.isFinite(Q)){let Z=Q<10000000000?Q*1000:Q,$=new Date(Z);return Number.isNaN($.getTime())?null:$}if(typeof Q==="string"&&Q.trim().length>0){let Z=Q.trim(),$=Number(Z);if(Number.isFinite($))return P($);let G=new Date(Z);return Number.isNaN(G.getTime())?null:G}return null}function IQ(Q){return`${SZ[Q.getDay()]} ${Q.getDate()} ${EZ[Q.getMonth()]} ${Q.getFullYear()}`}import{isAbsolute as hZ,relative as _Q,resolve as LQ,sep as cZ}from"node:path";var wZ=/(?:chatgpt[-_]?account[-_]?id|access[-_]?token|refresh[-_]?token|id[-_]?token|session[-_]?token|api[-_]?key|account[-_]?id|authorization|cookie|client[-_]?secret|password|credential|secret|token)/,gZ=/[\u0000-\u001f\u007f-\u009f]/g,vZ=new RegExp(`["']?${wZ.source}["']?\\s*[:=]\\s*(?:"(?:\\\\.|[^"\\\\])*"|'(?:\\\\.|[^'\\\\])*'|[^,\\r\\n}\\]&]+)`,"gi"),mZ=[vZ,/Bearer\s+[A-Za-z0-9._~+/=-]+/gi,/\beyJ[A-Za-z0-9_-]{5,}\.[A-Za-z0-9_-]{5,}(?:\.[A-Za-z0-9_-]{5,})?\b/g,/sk-[A-Za-z0-9_-]{10,}/g,/\b[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}\b/gi,/[A-Za-z0-9_-]{32,}/g];function _(Q){let Z=Q;for(let $ of mZ)Z=Z.replace($,"[redacted]");return Z.replace(gZ,"?")}function t(Q){return Q.map(_)}function RQ(Q,Z){let $=_Q(LQ(Q),LQ(Z));return $===""||!yQ($)}function R(Q,Z){let $=_Q(Q,Z);return $&&!yQ($)?pZ($):"."}function pZ(Q){let Z=_(Q);return Z.length<=240?Z:`${Z.slice(0,239)}…`}function yQ(Q){return Q===".."||Q.startsWith(`..${cZ}`)||hZ(Q)}function W(Q){return typeof Q==="object"&&Q!==null&&!Array.isArray(Q)}function B(Q,Z){let $=Q[Z];return typeof $==="string"&&$.trim()?$.trim():null}var dZ=8,e=20,m=1000,rZ=512,iZ=1000,GQ=25000000,oZ=1e6,nZ=/^rollout-.*\.jsonl$/i;async function wQ(Q){let Z=EQ(Q,"sessions"),$=[];if(await z0(Z))return $.push("Skipped the symbolic-link Codex sessions directory."),{homePath:Q,sessionsRoot:Z,files:[],latestSnapshot:null,warnings:$};let G=await sZ(Z,$),J=[],z=null;for(let j of G.slice(0,e)){let K=R(Q,j.path);if(j.size>GQ){$.push("Skipped a local Codex session file because it is too large to inspect safely."),J.push(ZQ(j.path,K,j.modifiedAtMs,!1,"too-large"));continue}try{let X=await eZ(Q,j);if(J.push(ZQ(j.path,K,j.modifiedAtMs,X.snapshot!==null,null)),X.skippedOversizedLine)$.push("Skipped an oversized JSONL line in a local Codex session file.");if(X.snapshot&&(!z||Z0(X.snapshot,z)))z=X.snapshot}catch(X){let Y=X instanceof c;$.push(Y?"Skipped a local Codex session file because it grew too large to inspect safely.":"Could not inspect a local Codex session file safely."),J.push(ZQ(j.path,K,j.modifiedAtMs,!1,Y?"too-large":"read-error"))}}if(G.length>e)$.push(`Skipped ${G.length-e} older session files to keep inspection small.`);if(G.length>0&&!z)$.push("No token-count rate-limit snapshot was found in local Codex session logs.");return{homePath:Q,sessionsRoot:Z,files:J,latestSnapshot:z,warnings:$}}async function sZ(Q,Z){let $={directories:0,files:[],hitLimit:!1,skippedSymlink:!1};if(await gQ(Q,0,$,Z),$.hitLimit)Z.push("Stopped session discovery after reaching a safe inspection limit.");if($.skippedSymlink)Z.push("Skipped symbolic links while inspecting Codex sessions.");let G;try{G=await SQ(Q)}catch{return[]}let J=[];for(let z of $.files){let j=await tZ(G,z,Z);if(j)J.push(j)}return J.sort((z,j)=>j.modifiedAtMs-z.modifiedAtMs||z.path.localeCompare(j.path))}async function tZ(Q,Z,$){try{let[G,J]=await Promise.all([h(Z),SQ(Z)]);if(!G.isFile()||!RQ(Q,J))return $.push("Could not inspect a local Codex session file safely."),null;return{path:Z,modifiedAtMs:G.mtimeMs,size:G.size,dev:G.dev,ino:G.ino}}catch{return $.push("Could not inspect a local Codex session file safely."),null}}async function gQ(Q,Z,$,G){if(Z>dZ||$.files.length>=m){$.hitLimit||=$.files.length>=m;return}if($.directories>=rZ){$.hitLimit=!0;return}$.directories+=1;let J;try{J=await aZ(Q,$)}catch{if(Z>0)G.push("Could not inspect part of the local Codex sessions directory safely.");return}for(let z of J){if($.files.length>=m){$.hitLimit=!0;return}let j=EQ(Q,z.name);if(z.isSymbolicLink()){$.skippedSymlink=!0;continue}if(z.isDirectory()){await gQ(j,Z+1,$,G);continue}if(z.isFile()&&nZ.test(z.name)){if($.files.push(j),$.files.length>=m){$.hitLimit=!0;return}}}}async function aZ(Q,Z){let $=await lZ(Q),G=[];for await(let J of $){if(G.length>=iZ){Z.hitLimit=!0;break}G.push(J)}return G.sort((J,z)=>z.name.localeCompare(J.name))}async function eZ(Q,Z){let $=Z.path,G=R(Q,$),J=await Q0(Z),z=null,j=null,K="",X=0,Y=0,H=!1,M=!1;for await(let x of J){let O=String(x);if(Y+=Buffer.byteLength(O,"utf8"),Y>GQ)throw new c;let T=0;while(T<O.length){let F=O.indexOf(`
5
+ `,T),g=F===-1?O.length:F,TQ=O.slice(T,g);if(!H){let C=Buffer.byteLength(TQ,"utf8");if(X+C>oZ)K="",X=0,H=!0,M=!0;else K+=TQ,X+=C}if(F===-1)break;if(!H){let C=fQ(K.endsWith("\r")?K.slice(0,-1):K);if(C.threadId)z=C.threadId;if(C.rateLimits)j={sessionFile:$,relativePath:G,threadId:z,eventTimestamp:C.timestamp,rateLimits:C.rateLimits}}K="",X=0,H=!1,T=F+1}}if(!H&&K.length>0){let x=fQ(K.endsWith("\r")?K.slice(0,-1):K);if(x.threadId)z=x.threadId;if(x.rateLimits)j={sessionFile:$,relativePath:G,threadId:z,eventTimestamp:x.timestamp,rateLimits:x.rateLimits}}return{snapshot:j,skippedOversizedLine:M}}async function Q0(Q){let Z;try{let $=await h(Q.path);if(!$.isFile()||!QQ($,Q))throw new $Q;let G=a.O_NOFOLLOW,J=typeof G==="number"?a.O_RDONLY|G:a.O_RDONLY;Z=await uZ(Q.path,J);let[z,j]=await Promise.all([Z.stat(),h(Q.path)]);if(!z.isFile()||!j.isFile()||!QQ(z,Q)||!QQ(z,j))throw new $Q;if(z.size>GQ)throw new c;return Z.createReadStream({encoding:"utf8",highWaterMark:65536})}catch($){throw await Z?.close().catch(()=>{return}),$}}function QQ(Q,Z){return Q.dev===Z.dev&&Q.ino===Z.ino}function Z0(Q,Z){let $=P(Q.eventTimestamp)?.getTime()??null,G=P(Z.eventTimestamp)?.getTime()??null;if($===null)return!1;return G===null||$>G}function fQ(Q){let Z=$0(Q);if(!Z)return{threadId:null,timestamp:null,rateLimits:null};return{threadId:G0(Z),timestamp:B(Z,"timestamp"),rateLimits:J0(Z)}}function $0(Q){let Z=Q.trim();if(!Z)return null;try{let $=JSON.parse(Z);return W($)?$:null}catch{return null}}function G0(Q){if(Q.type!=="session_meta"||!W(Q.payload))return null;return B(Q.payload,"id")}function J0(Q){if(Q.type!=="event_msg"||!W(Q.payload))return null;if(Q.payload.type!=="token_count"||!W(Q.payload.rate_limits))return null;return Q.payload.rate_limits}function ZQ(Q,Z,$,G,J){return{path:Q,relativePath:Z,modifiedAtMs:$,hasSnapshot:G,error:J}}async function z0(Q){try{return(await h(Q)).isSymbolicLink()}catch{return!1}}class c extends Error{}class $Q extends Error{}import{opendir as K0}from"node:fs/promises";import{extname as X0,join as Y0}from"node:path";import{constants as JQ}from"node:fs";import{lstat as vQ,open as j0}from"node:fs/promises";class q extends Error{code;constructor(Q){super(Q);this.name="BoundedFileError",this.code=Q}}async function p(Q,Z){let $;try{let G=await vQ(Q);if(!G.isFile())throw new q("not-file");let J=JQ.O_NOFOLLOW,z=typeof J==="number"?JQ.O_RDONLY|J:JQ.O_RDONLY;$=await j0(Q,z);let j=await $.stat(),K=await vQ(Q);if(!j.isFile()||!K.isFile()||!mQ(G,j)||!mQ(j,K))throw new q("not-file");if(j.size>Z)throw new q("too-large");let X=Buffer.allocUnsafe(Z+1),Y=0;while(Y<=Z){let H=await $.read(X,Y,Z+1-Y,null);if(H.bytesRead===0)break;Y+=H.bytesRead}if(Y>Z)throw new q("too-large");return X.subarray(0,Y).toString("utf8")}catch(G){if(G instanceof q)throw G;if(hQ(G)&&G.code==="ENOENT")throw new q("not-found");if(hQ(G)&&G.code==="ELOOP")throw new q("not-file");throw new q("read-error")}finally{await $?.close().catch(()=>{return})}}function mQ(Q,Z){return Q.dev===Z.dev&&Q.ino===Z.ino}function hQ(Q){return Q instanceof Error&&"code"in Q}var H0=2,zQ=25,jQ=100,W0=64,V0=500,M0=1e6,q0=/(?:auth|token|cookie|session|secret|credential|api[-_]?key|keychain)/i;async function cQ(Q){let Z={directories:0,files:[],hitDirectoryLimit:!1,hitEntryLimit:!1,hitFileLimit:!1,skippedSensitive:!1,skippedSymlink:!1,warnings:[]};if(await pQ(Q,0,Z),Z.hitDirectoryLimit||Z.hitEntryLimit||Z.hitFileLimit)Z.warnings.push("Stopped local state discovery after reaching a safe inspection limit.");if(Z.skippedSensitive)Z.warnings.push("Skipped a sensitive-looking local file.");if(Z.skippedSymlink)Z.warnings.push("Skipped symbolic links while inspecting local Codex state.");let $=Z.files.sort((J,z)=>J.localeCompare(z)),G=[];for(let J of $.slice(0,zQ)){let z=R(Q,J);try{let j=await p(J,M0),K=B0(j,Z.warnings);G.push({path:J,relativePath:z,json:K.value,error:K.error})}catch(j){Z.warnings.push(j instanceof q&&j.code==="too-large"?"Skipped a local Codex state file because it is too large to inspect safely.":"Could not read a local Codex state file safely.")}}if($.length>zQ)Z.warnings.push(`Skipped ${$.length-zQ} extra files to keep inspection small.`);return{homePath:Q,files:G,warnings:Z.warnings}}async function pQ(Q,Z,$){if(Z>H0||$.files.length>=jQ){$.hitFileLimit||=$.files.length>=jQ;return}if($.directories>=W0){$.hitDirectoryLimit=!0;return}$.directories+=1;let G=await U0(Q,$);for(let J of G){if($.files.length>=jQ){$.hitFileLimit=!0;return}if(q0.test(J.name)){$.skippedSensitive=!0;continue}let z=Y0(Q,J.name);if(J.isSymbolicLink())$.skippedSymlink=!0;else if(J.isDirectory())await pQ(z,Z+1,$);else if(J.isFile()&&X0(J.name).toLowerCase()===".json")$.files.push(z)}}async function U0(Q,Z){try{let $=await K0(Q),G=[];for await(let J of $){if(G.length>=V0){Z.hitEntryLimit=!0;break}G.push(J)}return G.sort((J,z)=>J.name.localeCompare(z.name))}catch{return Z.warnings.push("Could not inspect part of the local Codex state directory safely."),[]}}function B0(Q,Z){try{return{value:JSON.parse(Q),error:null}}catch{return Z.push("Could not parse JSON in a local Codex state file."),{value:null,error:"invalid-json"}}}import{join as N0,normalize as x0}from"node:path";function N(Q,Z,$){return{code:Q,source:Z,severity:"warning",message:$}}function I(Q){return Q.map((Z)=>_(Z.message))}var O0=1e6;async function u(Q={}){let Z=A(Q.env),$=U(Z,"CODEX_LIMITS_ACCESS_TOKEN"),G=U(Z,"CODEX_LIMITS_ACCOUNT_ID");if($&&G)return{credentials:{accessToken:$,accountId:G},status:"configured",diagnostics:[]};if($||G)return{credentials:null,status:"partial",diagnostics:[N("auth.environment.partial","authentication","Codex authentication environment variables are incomplete.")]};let J=await C0(Q);return J?D0(J):{credentials:null,status:"missing",diagnostics:[]}}async function C0(Q){if(Q.authFile)return x0(Q.authFile);let Z=await v(Q);return Z.foundHome?N0(Z.foundHome,"auth.json"):null}async function D0(Q){let Z;try{Z=await p(Q,O0)}catch($){if($ instanceof q&&$.code==="not-found")return{credentials:null,status:"missing",diagnostics:[]};let G=$ instanceof q&&$.code==="too-large";return{credentials:null,status:"unreadable",diagnostics:[N(G?"auth.file.too-large":"auth.file.unreadable","authentication",G?"Codex auth.json is too large to inspect safely.":"Codex auth.json could not be read safely.")]}}try{let $=JSON.parse(Z);if(!W($))return KQ();let G=W($.tokens)?$.tokens:$,J=B(G,"access_token"),z=B(G,"account_id");return J&&z?{credentials:{accessToken:J,accountId:z},status:"configured",diagnostics:[]}:KQ()}catch{return KQ()}}function KQ(){return{credentials:null,status:"malformed",diagnostics:[N("auth.file.malformed","authentication","Codex auth.json is malformed or does not contain required credentials.")]}}var P0=/[\u0000-\u0020\u007f-\u009f]/;function XQ(Q){return Q.length>0&&Q.length<=512&&!P0.test(Q)}import{request as T0}from"node:http";import{request as F0}from"node:https";var A0=new Set(["127.0.0.1","::1","[::1]","localhost"]);function f(Q){try{let Z=new URL(Q);return Z.username="",Z.password="",Z.search="",Z.hash="",Z.href}catch{return"[invalid endpoint]"}}async function lQ(Q){let Z=b0(Q.endpoint);if(!Z.ok)return Z;if(Q.signal?.aborted)return V("aborted");let $=Q.fetch??globalThis.fetch;if(!$)return uQ(Z.url,Q);let G=await k0(Z.url,Q,$);if(G.ok||G.code==="aborted"||!_0(G,Q.fallbackOnHttpError??!1))return G;let J=await uQ(Z.url,Q);if(J.ok||J.code==="http-error"||J.code==="invalid-json"||J.code==="response-too-large")return J;return G}function l(Q){let Z={...Q,method:"GET"};return delete Z.body,lQ(Z)}function b0(Q){let Z;try{Z=new URL(Q)}catch{return V("invalid-url")}if(Z.username||Z.password)return V("invalid-url");if(Z.protocol==="https:")return{ok:!0,url:Z};if(Z.protocol==="http:"&&A0.has(Z.hostname.toLowerCase()))return{ok:!0,url:Z};return V("unsupported-protocol")}async function k0(Q,Z,$){let G=rQ(Z.timeoutMs,Z.signal);try{let J=await $(Q.href,{method:Z.method??"GET",headers:Z.headers,redirect:"error",signal:G.signal,...Z.body===void 0?{}:{body:Z.body}});if(!J.ok)return await dQ(J),V("http-error",WQ(J.status));let z=await I0(J,Z.maxResponseBytes);return{ok:!0,status:WQ(J.status)??200,payload:z,transport:"fetch"}}catch(J){if(J instanceof y)return V("response-too-large");if(J instanceof d)return V("invalid-json");if(Z.signal?.aborted)return V("aborted");if(G.didTimeout())return V("timeout");return V("network-error")}finally{G.dispose()}}async function I0(Q,Z){let $=Number(Q.headers?.get("content-length"));if(Number.isFinite($)&&$>Z)throw await dQ(Q),new y;if(Q.body){let G=Q.body.getReader(),J=[],z=0;while(!0){let K=await G.read();if(K.done)break;if(!K.value)continue;if(z+=K.value.byteLength,z>Z)throw await G.cancel?.(),new y;J.push(K.value)}let j=Buffer.concat(J.map((K)=>Buffer.from(K)),z).toString("utf8");return HQ(j)}if(Q.text){let G=await Q.text();if(Buffer.byteLength(G,"utf8")>Z)throw new y;return HQ(G)}throw new d}async function dQ(Q){if(!Q.body)return;try{await Q.body.getReader().cancel?.()}catch{}}function uQ(Q,Z){return new Promise(($)=>{let G=rQ(Z.timeoutMs,Z.signal),J=!1,z=null,j=(X)=>{if(J)return;J=!0,G.dispose(),$(X)},K=()=>{z?.destroy(),j(V(Z.signal?.aborted?"aborted":"timeout"))};G.signal.addEventListener("abort",K,{once:!0});try{z=(Q.protocol==="http:"?T0:F0)(Q,{method:Z.method??"GET",headers:Z.headers,signal:G.signal},(Y)=>L0(Y,Z.maxResponseBytes,j)),z.on("error",()=>{if(Z.signal?.aborted)j(V("aborted"));else if(G.didTimeout())j(V("timeout"));else j(V("network-error"))}),z.end(Z.body)}catch{j(V("network-error"))}})}function L0(Q,Z,$){let G=WQ(Q.statusCode);if(G===null||G<200||G>=300){$(V("http-error",G)),YQ(Q);return}let J=Number(Q.headers["content-length"]);if(Number.isFinite(J)&&J>Z){$(V("response-too-large")),YQ(Q);return}let z=[],j=0;Q.on("data",(K)=>{let X=Buffer.isBuffer(K)?K:Buffer.from(K);if(j+=X.length,j>Z){$(V("response-too-large")),YQ(Q);return}z.push(X)}),Q.on("end",()=>{try{let K=HQ(Buffer.concat(z,j).toString("utf8"));$({ok:!0,status:G,payload:K,transport:"node"})}catch{$(V("invalid-json"))}}),Q.on("error",()=>$(V("network-error")))}function YQ(Q){Q.destroy(),Q.socket.destroy()}function rQ(Q,Z){let $=new AbortController,G=!1,J=Number.isFinite(Q)&&Q>0?Math.min(Math.floor(Q),2147483647):1,z=setTimeout(()=>{G=!0,$.abort()},J),j=()=>$.abort();if(Z?.addEventListener("abort",j,{once:!0}),Z?.aborted)j();return{signal:$.signal,didTimeout:()=>G,dispose:()=>{clearTimeout(z),Z?.removeEventListener("abort",j)}}}function _0(Q,Z){return Q.code==="network-error"||Q.code==="timeout"||Q.code==="invalid-json"||Z&&Q.code==="http-error"}function HQ(Q){try{return JSON.parse(Q)}catch{throw new d}}function WQ(Q){return typeof Q==="number"&&Number.isInteger(Q)&&Q>=0?Q:null}function V(Q,Z=null){return{ok:!1,code:Q,status:Z}}class y extends Error{}class d extends Error{}function r(Q,Z){switch(Q.code){case"aborted":return N("network.request.aborted","network",`${Z} lookup was cancelled.`);case"http-error":return N("network.response.http","network",Q.status===null?`${Z} endpoint returned an invalid HTTP status.`:`${Z} endpoint returned HTTP ${Q.status}.`);case"invalid-json":return N("network.response.invalid-json","network",`${Z} endpoint returned malformed JSON.`);case"invalid-url":return N("network.endpoint.invalid","network",`${Z} endpoint URL is invalid.`);case"response-too-large":return N("network.response.too-large","network",`${Z} endpoint response was too large.`);case"timeout":return N("network.request.timeout","network",`${Z} lookup timed out.`);case"unsupported-protocol":return N("network.endpoint.protocol","network",`${Z} endpoint must use HTTPS or loopback HTTP.`);case"network-error":return N("network.request.failed","network",`${Z} lookup failed.`)}}var sQ=["credits","reset_credits","items"],tQ=["available_count","availableCount","available"],aQ=["total_earned_count","earned_this_period","earnedThisPeriod","totalEarnedCount"],R0=64,y0=/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.(\d+))?(?:Z|[+-](\d{2}):(\d{2}))$/i;function eQ(Q,Z,$){if(!W(Q)||!f0(Q))return S(Z,["Live reset coupon endpoint returned an unexpected payload."]);let G=g0(Q,sQ);if(G.malformed)return S(Z,["Live reset coupon endpoint returned an unexpected payload."]);let J=G.value,z=J.map((H,M)=>S0(H,M+1,$)).filter((H)=>H!==null).sort(w0).map((H,M)=>({...H,index:M+1})),j=z.find((H)=>H.status?.toLowerCase()==="available")??z[0]??null,K=nQ(Q,tQ),X=nQ(Q,aQ),Y=[];if(J.length!==z.length)Y.push("Live reset coupon endpoint ignored malformed coupon entries.");if(K.malformed||X.malformed)Y.push("Live reset coupon endpoint ignored malformed summary fields.");return{status:Y.length>0?"partial":"available",available:K.value,earnedThisPeriod:X.value,nextExpirationDate:j?.expirationDate??null,nextExpirationIn:j?.expiresIn??null,items:z,warnings:Y,source:{live:!0,label:"live Codex reset-credit endpoint",endpoint:Z}}}function S(Q,Z=[]){return{status:"unavailable",available:null,earnedThisPeriod:null,nextExpirationDate:null,nextExpirationIn:null,items:[],warnings:Z,source:{live:!1,label:"live Codex reset-credit endpoint",endpoint:Q}}}function f0(Q){return[...sQ,...tQ,...aQ].some((Z)=>(Z in Q))}function S0(Q,Z,$){if(!W(Q))return null;let G=Q.id,J=typeof G==="string"&&XQ(G)?G:null,z=Q.reset_type??Q.resetType,j=typeof z==="string"&&/^[a-z][a-z0-9_-]{0,63}$/i.test(z)?z:null,K="expires_at"in Q||"expiresAt"in Q,X="granted_at"in Q||"grantedAt"in Q,Y=B(Q,"expires_at")??B(Q,"expiresAt"),H=B(Q,"granted_at")??B(Q,"grantedAt"),M=iQ(Y),x=iQ(H),O=B(Q,"status"),T=O&&/^[a-z][a-z0-9_-]{0,63}$/i.test(O)?O:null,F=x?H:null,g=M?Y:null;if("id"in Q&&!J||X&&!x||K&&!M||!T&&!F&&!g)return null;return{id:J,resetType:j,index:Z,status:T,grantedAt:F,expiresAt:g,expirationDate:M?IQ(M):null,expiresIn:M?L(M.getTime()-$.getTime()):null}}function iQ(Q){if(!Q||Q.length>R0)return null;let Z=y0.exec(Q);if(!Z)return null;let $=Number(Z[1]),G=Number(Z[2]),J=Number(Z[3]),z=Number(Z[4]),j=Number(Z[5]),K=Number(Z[6]),X=Z[8]===void 0?0:Number(Z[8]),Y=Z[9]===void 0?0:Number(Z[9]);if(G<1||G>12||J<1||J>E0($,G)||z>23||j>59||K>59||X>23||Y>59)return null;let H=new Date(Q);return Number.isNaN(H.getTime())?null:H}function E0(Q,Z){if(Z===2)return Q%4===0&&(Q%100!==0||Q%400===0)?29:28;return Z===4||Z===6||Z===9||Z===11?30:31}function w0(Q,Z){return oQ(Q.expiresAt)-oQ(Z.expiresAt)}function oQ(Q){return P(Q)?.getTime()??Number.POSITIVE_INFINITY}function g0(Q,Z){let $=!1;for(let G of Z){if(!(G in Q))continue;$=!0;let J=Q[G];if(Array.isArray(J))return{value:J,malformed:!1}}return{value:[],malformed:$}}function nQ(Q,Z){let $=!1;for(let G of Z){if(!(G in Q))continue;$=!0;let J=Q[G];if(typeof J==="number"&&Number.isInteger(J)&&J>=0)return{value:J,malformed:!1}}return{value:null,malformed:$}}var VQ="https://chatgpt.com/backend-api/wham/rate-limit-reset-credits",I2=`${VQ}/consume`,v0=1e4,m0=1e6;async function ZZ(Q={}){let Z=Q.endpoint??VQ,$=f(Z),G=await u(Q);if(!G.credentials){let z=I(G.diagnostics);return h0($,z.length>0?z:["Live reset coupons require a readable Codex auth.json file or CODEX_LIMITS_ACCESS_TOKEN and CODEX_LIMITS_ACCOUNT_ID."])}let J=c0(Z,G.credentials,Q);try{let z=await(Q.transport??l)(J);return z.ok?eQ(z.payload,$,Q.now??new Date):QZ($,z)}catch{return QZ($,{ok:!1,code:"network-error",status:null})}}function h0(Q=VQ,Z=[]){return S(f(Q),Z)}function QZ(Q,Z){return S(Q,I([r(Z,"Live reset coupon")]))}function c0(Q,Z,$){return{endpoint:Q,headers:p0(Z),timeoutMs:$.timeoutMs??v0,maxResponseBytes:m0,...$.fetch?{fetch:$.fetch}:{},...$.signal?{signal:$.signal}:{}}}function p0(Q){return{Authorization:`Bearer ${Q.accessToken}`,"ChatGPT-Account-ID":Q.accountId,"OpenAI-Beta":"codex-1",originator:"Codex Desktop",Accept:"application/json"}}var jZ=5,UQ="5-hour usage limit",BQ="Weekly usage limit",NQ=["fiveHour","five_hour","fiveHourWindow","five_hour_window","primary","primaryWindow","primary_window","main","mainWindow"],xQ=["weekly","week","weeklyWindow","weekly_window","secondary","secondaryWindow","secondary_window","backup","backupWindow"],u0=["used_percent","usedPercent","used","usage","percentUsed","usagePercent","usagePercentage","percent"],l0=["remaining_percent","remainingPercent","remaining","percentRemaining","availablePercent","available_percentage"],d0=["resets_at","resetsAt","resetAt","resetTime","reset_at","reset","ends_at","endsAt","windowEnd"],r0=["resetsIn","resetIn","resets_in","reset_in","timeUntilReset"],i0=["limit_window_seconds","limitWindowSeconds","window_seconds","windowSeconds","window_length_seconds","windowLengthSeconds"],o0=["window_minutes","windowMinutes","window_length_minutes","windowLengthMinutes"],n0=18000,s0=604800,t0=/^(?:(\d+)d)?(?:\s*(\d+)h)?(?:\s*(\d+)m)?(?:\s*(\d+)s)?$/i;function KZ(Q,Z=new Date){let $=Q.latestSnapshot;if(!$)return DQ(Q.warnings);return n(OQ($.rateLimits,Z),Q.warnings)}function OQ(Q,Z=new Date){return VZ(i(Q,NQ),i(Q,xQ),Z)}function XZ(Q){return i(Q,NQ)!==null||i(Q,xQ)!==null}function E(Q){let Z=zZ(b(Q,i0,!1)),$=zZ(b(Q,o0,!1)),G=Z??($===null?null:$*60);if(G===n0)return"fiveHour";if(G===s0)return"weekly";return null}function YZ(Q,Z){return{...Q,source:Z}}function CQ(Q,Z,$=[]){return{...n(Q,$),source:Z}}function HZ(Q,Z=new Date){let $={fiveHour:null,weekly:null};for(let G of Q.files){if(!G.json)continue;let J=a0(G.json,Z);$=MZ($,J.windows)}return n($,Q.warnings)}function DQ(Q=[]){return{status:"unavailable",windows:{fiveHour:null,weekly:null},warnings:Q}}function WZ(Q,Z){let $=MZ(Q.windows,Z.windows);return n($,[...Q.warnings,...Z.warnings])}function a0(Q,Z){if(!W(Q))return{windows:{fiveHour:null,weekly:null}};let $=qQ(Q,NQ),G=qQ(Q,xQ);if($||G)return{windows:VZ($,G,Z)};let J=E(Q)??"fiveHour",z=MQ(Q,J==="weekly"?BQ:UQ,Z);return{windows:{fiveHour:J==="fiveHour"?z:null,weekly:J==="weekly"?z:null}}}function VZ(Q,Z,$){let G=[];if(Q)G.push({fallbackKind:"fiveHour",value:Q});if(Z)G.push({fallbackKind:"weekly",value:Z});return{fiveHour:MQ($Z(G,"fiveHour"),UQ,$),weekly:MQ($Z(G,"weekly"),BQ,$)}}function MQ(Q,Z,$){if(!Q)return null;let G=JZ(b(Q,u0,!0)),J=JZ(b(Q,l0,!0)),z=G??(J===null?null:o(100-J)),j=J??(G===null?null:o(100-G)),K=b(Q,d0,!0),X=P(K),Y=X?X.toISOString():null,H=X?L(X.getTime()-$.getTime()):Z1(b(Q,r0,!0)),M={label:Z,remainingPercent:j,usedPercent:z,resetsAt:Y,resetsIn:H};return qZ(M)?M:null}function n(Q,Z){return{status:e0(Q),windows:Q,warnings:Z}}function e0(Q){let Z=[Q.fiveHour,Q.weekly].filter(($)=>qZ($));if(Z.length===0)return"unavailable";return Z.every(Q1)?"available":"partial"}function $Z(Q,Z){let $=Q.find((G)=>E(G.value)===Z);if($)return $.value;return Q.find((G)=>G.fallbackKind===Z&&E(G.value)===null)?.value??null}function MZ(Q,Z){return{fiveHour:GZ(Q.fiveHour,Z.fiveHour,UQ),weekly:GZ(Q.weekly,Z.weekly,BQ)}}function GZ(Q,Z,$){if(!Q&&!Z)return null;return{label:$,remainingPercent:Q?.remainingPercent??Z?.remainingPercent??null,usedPercent:Q?.usedPercent??Z?.usedPercent??null,resetsAt:Q?.resetsAt??Z?.resetsAt??null,resetsIn:Q?.resetsIn??Z?.resetsIn??null}}function qZ(Q){return Q!==null&&(Q.remainingPercent!==null||Q.usedPercent!==null||Q.resetsAt!==null||Q.resetsIn!==null)}function Q1(Q){return Q!==null&&Q.remainingPercent!==null&&Q.usedPercent!==null&&(Q.resetsAt!==null||Q.resetsIn!==null)}function qQ(Q,Z,$=0){if($>jZ)return null;for(let G of Z){let J=Q[G];if(W(J))return J}for(let G of Object.values(Q)){if(!W(G))continue;let J=qQ(G,Z,$+1);if(J)return J}return null}function i(Q,Z){for(let $ of Z){let G=Q[$];if(W(G))return G}return null}function b(Q,Z,$,G=0){if(G>jZ)return;for(let J of Z)if(J in Q)return Q[J];if(!$)return;for(let J of Object.values(Q)){if(!W(J))continue;let z=b(J,Z,$,G+1);if(z!==void 0)return z}return}function JZ(Q){if(typeof Q==="number"&&Number.isFinite(Q))return o(Q);if(typeof Q==="string"&&Q.trim().length>0){let Z=Q.trim(),$=Z.endsWith("%")?Z.slice(0,-1):Z,G=Number($);return Number.isFinite(G)?o(G):null}return null}function o(Q){return Math.round(Math.min(Math.max(Q,0),100)*10)/10}function zZ(Q){if(typeof Q==="number"&&Number.isFinite(Q))return Q;if(typeof Q==="string"&&Q.trim().length>0){let Z=Number(Q);return Number.isFinite(Z)?Z:null}return null}function Z1(Q){let Z=$1(Q);if(!Z||Z.length>100)return null;let G=t0.exec(Z)?.slice(1);if(!G||G.every((j)=>j===void 0))return null;let J=[86400,3600,60,1],z=0;for(let[j,K]of G.entries()){if(K===void 0)continue;let X=Number(K),Y=X*J[j];if(!Number.isSafeInteger(X)||!Number.isSafeInteger(Y))return null;if(z+=Y,!Number.isSafeInteger(z))return null}return z<=Math.floor(Number.MAX_SAFE_INTEGER/1000)?L(z*1000):null}function $1(Q){if(typeof Q==="string"&&Q.trim().length>0)return Q.trim();return null}var G1=5,J1=1000,z1={kind:"unavailable",label:"Unavailable"};function BZ(Q,Z,$){let G=j1(Q)??K1(Q);if(!G)return w(["Live usage endpoint returned an unexpected payload."]);let J=CQ(OQ(G,$),{kind:"api",label:"API",endpoint:Z});if(J.status==="unavailable")return w(["Live usage endpoint returned an unexpected payload."]);if(J.status==="partial")return{...J,warnings:["Live usage endpoint returned incomplete usage data."]};return J}function w(Q){return CQ({fiveHour:null,weekly:null},z1,Q)}function j1(Q){return NZ(Q,(Z)=>{if(!W(Z))return null;let $=Z.rate_limits??Z.rateLimits??Z.rate_limit??Z.rateLimit;if(W($))return $;return XZ(Z)?Z:null})}function K1(Q){return NZ(Q,(Z)=>{if(!Array.isArray(Z))return null;let $=Z.find((J)=>UZ(J,"fiveHour")),G=Z.find((J)=>UZ(J,"weekly"));return $||G?{fiveHour:$,weekly:G}:null})}function NZ(Q,Z){let $=[{value:Q,depth:0}],G=new WeakSet;for(let J=0;J<$.length;J+=1){let z=$[J];if(!z)break;let j=Z(z.value);if(j)return j;if(z.depth>=G1||typeof z.value!=="object"||!z.value)continue;if(G.has(z.value))continue;G.add(z.value);let K=Array.isArray(z.value)?z.value:W(z.value)?Object.values(z.value):[];for(let X of K){if($.length>=J1)break;$.push({value:X,depth:z.depth+1})}}return null}function UZ(Q,Z){if(!W(Q))return!1;let $=E(Q);if($)return $===Z;let G=String(Q.type??Q.kind??Q.name??Q.label??Q.window??"").toLowerCase();return Z==="fiveHour"?G.includes("primary")||G.includes("5-hour")||G.includes("five"):G.includes("secondary")||G.includes("weekly")||G.includes("week")}var X1="https://chatgpt.com/backend-api/codex/usage",Y1=1e4,H1=1e6;async function xZ(Q={}){return(await W1(Q)).usage}async function W1(Q={}){let Z=M1(Q),$=f(Z),G=await u(Q);if(!G.credentials){let j=I(G.diagnostics);return{usage:w(j.length>0?j:["Live usage requires Codex authentication."]),authenticationFound:!1,endpointStatus:"not-checked"}}let J={endpoint:Z,headers:V1(G.credentials),timeoutMs:Q.timeoutMs??Y1,maxResponseBytes:H1,fallbackOnHttpError:!0,...Q.fetch?{fetch:Q.fetch}:{},...Q.signal?{signal:Q.signal}:{}},z;try{z=await(Q.transport??l)(J)}catch{z={ok:!1,code:"network-error",status:null}}return{usage:z.ok?BZ(z.payload,$,Q.now??new Date):U1(z),authenticationFound:!0,endpointStatus:q1(z)}}function V1(Q){return{Authorization:`Bearer ${Q.accessToken}`,"ChatGPT-Account-ID":Q.accountId,"OpenAI-Beta":"codex-1",originator:"Codex Desktop",Accept:"application/json","User-Agent":"Codex Desktop",Referer:"https://chatgpt.com/codex/cloud/settings/analytics",Origin:"https://chatgpt.com"}}function M1(Q){let Z=A(Q.env);return Q.usageEndpoint??U(Z,"CODEX_LIMITS_USAGE_ENDPOINT")??X1}function q1(Q){if(Q.ok)return"reachable";switch(Q.code){case"http-error":case"invalid-json":case"response-too-large":return"reachable";case"aborted":return"not-checked";case"invalid-url":case"network-error":case"timeout":case"unsupported-protocol":return"unreachable"}}function U1(Q){return w(I([r(Q,"Live usage")]))}var B1={kind:"local",label:"Local"};async function OZ(Q={}){let Z=Q.includeCoupons===!1?Promise.resolve(null):ZZ(Q),[$,G]=await Promise.all([N1(Q),Z]),J=G?{...G,warnings:t(G.warnings)}:null;return{windows:$.windows,usageSource:$.source,coupons:J,warnings:t([...$.warnings,...J?.warnings??[]])}}async function N1(Q={}){let Z=await xZ(Q);if(Z.status!=="unavailable")return Z;let $=YZ(await O1(Q),B1);return x1(Z,$)}function x1(Q,Z){if(Q.status!=="unavailable")return Q;if(Z.status!=="unavailable")return Z;return{...Z,warnings:[...Q.warnings,...Z.warnings]}}async function O1(Q={}){let Z=Q.now??new Date,$=await v(Q);if(!$.foundHome)return DQ(["No readable local Codex home directory was found."]);let[G,J]=await Promise.all([wQ($.foundHome),cQ($.foundHome)]);return WZ(KZ(G,Z),HZ(J,Z))}var PQ="Codex Limits",C1="Check Codex limits, resets, and credits.",CZ="Could not load Codex limits.";function D1(Q={}){let Z=new WeakSet,$=Q.getLimits??OZ,G=Q.nextFrame??(()=>new Promise((J)=>setTimeout(J,0)));return{id:"codex-limits",tui:async(J)=>{if(Z.has(J))return;let z=P1(J,$,G),j;try{let X=T1(J,z);j=typeof X==="function"?X:void 0}catch{throw Error("Could not register the codex-limits OpenCode command.")}let K=()=>{if(!Z.delete(J))return;try{j?.()}catch{}};Z.add(J);try{J.lifecycle.onDispose(K)}catch{throw K(),Error("Could not register the codex-limits OpenCode lifecycle.")}}}}function P1(Q,Z,$){let G=0;return{title:PQ,value:"codex-limits.show",description:C1,category:"Codex",slash:{name:"codex-limits"},onSelect:async(J)=>{let z=++G;J?.clear(),Q.ui.dialog.clear(),await $();let j=Q.ui.dialog,K=(X)=>j.replace(()=>Q.ui.DialogAlert({title:PQ,message:X}));j.setSize("large"),K("Loading Codex limits...");try{let X=await Z();if(z===G)K(bQ(X))}catch{if(z===G)Q.ui.toast({variant:"error",title:PQ,message:CZ}),K(CZ)}}}}function T1(Q,Z){let $=Q;if(typeof $.keymap?.registerLayer==="function")return $.keymap.registerLayer({commands:[{namespace:"palette",name:Z.value,title:Z.title,desc:Z.description,category:Z.category,slashName:Z.slash?.name,slashAliases:Z.slash?.aliases,run:()=>Z.onSelect?.()}],bindings:[]});if(typeof $.command?.register==="function")return $.command.register(()=>[Z]);throw Error("No supported OpenCode command API is available.")}var DZ=D1(),PZ=DZ,e2=DZ.tui;var TZ=PZ,J3=TZ,$3=TZ.tui;export{$3 as tui,J3 as default};
package/dist/pi.js CHANGED
@@ -1,5 +1,5 @@
1
- import{DynamicBorder as VZ}from"@earendil-works/pi-coding-agent";import{Container as G1,matchesKey as qQ,Text as WQ}from"@earendil-works/pi-tui";function UQ(Q){let Z=[];if(Q.windows.fiveHour)Z.push(NQ("5-hour",Q.windows.fiveHour));if(Q.windows.weekly)Z.push(NQ("Weekly",Q.windows.weekly));if(Z.length===0)Z.push(["Usage limits Unavailable"]);if(Z.push(UZ(Q)),Q.warnings.length>0)Z.push(["Warnings",...Q.warnings.map(($)=>`- ${$}`)]);return Z.map(($)=>$.join(`
1
+ import{DynamicBorder as DZ}from"@earendil-works/pi-coding-agent";import{Container as x1,matchesKey as TQ,Text as PQ}from"@earendil-works/pi-tui";function bQ(Q){let Z=[];if(Q.windows.fiveHour)Z.push(AQ("5-hour",Q.windows.fiveHour));if(Q.windows.weekly)Z.push(AQ("Weekly",Q.windows.weekly));if(Z.length===0)Z.push(["Usage limits Unavailable"]);if(Z.push(AZ(Q)),Q.warnings.length>0)Z.push(["Warnings",...Q.warnings.map(($)=>`- ${$}`)]);return Z.map(($)=>$.join(`
2
2
  `)).join(`
3
3
 
4
- `)}function NQ(Q,Z){let $=Z.remainingPercent;return[`${Q} ${BZ($)}`,`Remaining ${$===null?"Unknown":`${Math.round($)}% remaining`}`,NZ($),`Reset ${Z.resetsIn?`in ${Z.resetsIn}`:"unknown"}`]}function NZ(Q){let Z=Q===null?0:Math.min(Math.max(Q,0),100),$=Math.round(Z/100*22);return`[${"=".repeat($)}${" ".repeat(22-$)}] ${Math.round(Z)}%`}function UZ(Q){let Z=Q.coupons?.available,G=[`Reset credits ${Z===null||Z===void 0?"Unknown":`${Z} ${Z===1?"credit":"credits"} available`}`],J=Q.coupons?.nextExpirationIn,z=Q.coupons?.nextExpirationDate,j=J&&z?`${J} (${z})`:J??z;if(j!==null&&j!==void 0)G.push(`Next expires ${j}`);return G}function BZ(Q){if(Q===null)return"Unknown";if(Q>=50)return"Healthy";if(Q>=15)return"Low";return"Critical"}function BQ(Q){return UQ(Q)}import{constants as CZ}from"node:fs";import{access as OZ,stat as TZ}from"node:fs/promises";import{homedir as xZ}from"node:os";import{join as b,normalize as r}from"node:path";function N(Q,Z){let $=Q[Z]?.trim();return $?$:null}function D(Q){return Q??process.env}var CQ="CODEX_LIMITS_HOME";function DZ(Q={}){let Z=D(Q.env),$=Q.homeDirectory??N(Z,"HOME")??N(Z,"USERPROFILE")??xZ(),G=Q.appData??N(Z,"APPDATA"),J=Q.localAppData??N(Z,"LOCALAPPDATA"),z=[];if(x(z,N(Z,CQ),"env"),x(z,N(Z,"CODEX_HOME"),"env"),$)x(z,b($,".codex"),"default"),x(z,b($,".config","codex"),"default"),x(z,b($,"Library","Application Support","Codex"),"default"),x(z,b($,"Library","Application Support","Parall","Codex",".codex"),"default");return x(z,G?b(G,"Codex"):null,"default"),x(z,J?b(J,"Codex"):null,"default"),FZ(z)}async function E(Q={}){let Z=D(Q.env),$=N(Z,CQ),G=await Promise.all(DZ(Q).map(async(J)=>({...J,exists:await AZ(J.path)})));return{overrideHome:$?r($):null,candidates:G,foundHome:G.find((J)=>J.exists)?.path??null}}function x(Q,Z,$){if(Z)Q.push({path:r(Z),source:$})}async function AZ(Q){try{if(!(await TZ(Q)).isDirectory())return!1;return await OZ(Q,CZ.R_OK),!0}catch{return!1}}function FZ(Q){let Z=new Set,$=[];for(let G of Q){let J=r(G.path),z=process.platform==="win32"?J.toLowerCase():J;if(!Z.has(z))Z.add(z),$.push({path:J,source:G.source})}return $}import{createReadStream as yZ}from"node:fs";import{lstat as fZ,opendir as SZ,realpath as FQ,stat as EZ}from"node:fs/promises";import{join as IQ}from"node:path";import{isAbsolute as _Z,relative as TQ,resolve as OQ,sep as PZ}from"node:path";var IZ=/(?:chatgpt[-_]?account[-_]?id|access[-_]?token|refresh[-_]?token|id[-_]?token|session[-_]?token|api[-_]?key|account[-_]?id|authorization|cookie|client[-_]?secret|password|credential|secret|token)/,bZ=/[\u0000-\u001f\u007f-\u009f]/g,kZ=new RegExp(`["']?${IZ.source}["']?\\s*[:=]\\s*(?:"(?:\\\\.|[^"\\\\])*"|'(?:\\\\.|[^'\\\\])*'|[^,\\r\\n}\\]&]+)`,"gi"),LZ=[kZ,/Bearer\s+[A-Za-z0-9._~+/=-]+/gi,/\beyJ[A-Za-z0-9_-]{5,}\.[A-Za-z0-9_-]{5,}(?:\.[A-Za-z0-9_-]{5,})?\b/g,/sk-[A-Za-z0-9_-]{10,}/g,/\b[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}\b/gi,/[A-Za-z0-9_-]{32,}/g];function A(Q){let Z=Q;for(let $ of LZ)Z=Z.replace($,"[redacted]");return Z.replace(bZ,"?")}function o(Q){return Q.map(A)}function xQ(Q,Z){let $=TQ(OQ(Q),OQ(Z));return $===""||!DQ($)}function C(Q,Z){let $=TQ(Q,Z);return $&&!DQ($)?RZ($):"."}function RZ(Q){let Z=A(Q);return Z.length<=240?Z:`${Z.slice(0,239)}…`}function DQ(Q){return Q===".."||Q.startsWith(`..${PZ}`)||_Z(Q)}function H(Q){return typeof Q==="object"&&Q!==null&&!Array.isArray(Q)}function B(Q,Z){let $=Q[Z];return typeof $==="string"&&$.trim()?$.trim():null}var wZ=8,i=20,w=1000,mZ=512,vZ=1000,bQ=25000000,gZ=1e6,hZ=/^rollout-.*\.jsonl$/i;async function kQ(Q){let Z=IQ(Q,"sessions"),$=[];if(await iZ(Z))return $.push("Skipped the symbolic-link Codex sessions directory."),{homePath:Q,sessionsRoot:Z,files:[],latestSnapshot:null,warnings:$};let G=await pZ(Q,Z,$),J=[],z=null;for(let j of G.slice(0,i)){let X=C(Q,j.path);if(j.size>bQ){$.push(`Skipped ${X} because it is too large to inspect safely.`),J.push(n(j.path,X,j.modifiedAtMs,!1,"too-large"));continue}try{let K=await dZ(Q,j.path);if(J.push(n(j.path,X,j.modifiedAtMs,K.snapshot!==null,null)),K.skippedOversizedLine)$.push(`Skipped an oversized JSONL line in ${X}.`);if(K.snapshot&&!z)z=K.snapshot}catch(K){let Y=K instanceof s;$.push(Y?`Skipped ${X} because it grew too large to inspect safely.`:`Could not inspect ${X}.`),J.push(n(j.path,X,j.modifiedAtMs,!1,Y?"too-large":"read-error"))}if(z)break}if(G.length>i)$.push(`Skipped ${G.length-i} older session files to keep inspection small.`);if(G.length>0&&!z)$.push("No token-count rate-limit snapshot was found in local Codex session logs.");return{homePath:Q,sessionsRoot:Z,files:J,latestSnapshot:z,warnings:$}}async function pZ(Q,Z,$){let G={directories:0,files:[],hitLimit:!1,skippedSymlink:!1};if(await LQ(Z,0,G,$,Q),G.hitLimit)$.push("Stopped session discovery after reaching a safe inspection limit.");if(G.skippedSymlink)$.push("Skipped symbolic links while inspecting Codex sessions.");let J;try{J=await FQ(Z)}catch{return[]}let z=[];for(let j of G.files){let X=await cZ(Q,J,j,$);if(X)z.push(X)}return z.sort((j,X)=>X.modifiedAtMs-j.modifiedAtMs||j.path.localeCompare(X.path))}async function cZ(Q,Z,$,G){try{let[J,z]=await Promise.all([EZ($),FQ($)]);if(!J.isFile()||!xQ(Z,z))return G.push(`Could not inspect ${C(Q,$)}.`),null;return{path:$,modifiedAtMs:J.mtimeMs,size:J.size}}catch{return G.push(`Could not inspect ${C(Q,$)}.`),null}}async function LQ(Q,Z,$,G,J){if(Z>wZ||$.files.length>=w){$.hitLimit||=$.files.length>=w;return}if($.directories>=mZ){$.hitLimit=!0;return}$.directories+=1;let z;try{z=await uZ(Q,$)}catch{if(Z>0)G.push(`Could not inspect ${C(J,Q)}.`);return}for(let j of z){if($.files.length>=w){$.hitLimit=!0;return}let X=IQ(Q,j.name);if(j.isSymbolicLink()){$.skippedSymlink=!0;continue}if(j.isDirectory()){await LQ(X,Z+1,$,G,J);continue}if(j.isFile()&&hZ.test(j.name)){if($.files.push(X),$.files.length>=w){$.hitLimit=!0;return}}}}async function uZ(Q,Z){let $=await SZ(Q),G=[];for await(let J of $){if(G.length>=vZ){Z.hitLimit=!0;break}G.push(J)}return G.sort((J,z)=>z.name.localeCompare(J.name))}async function dZ(Q,Z){let $=C(Q,Z),G=yZ(Z,{encoding:"utf8",highWaterMark:65536}),J=null,z=null,j="",X=0,K=0,Y=!1,V=!1;for await(let M of G){let O=String(M);if(K+=Buffer.byteLength(O,"utf8"),K>bQ)throw new s;let f=0;while(f<O.length){let S=O.indexOf(`
5
- `,f),MZ=S===-1?O.length:S,MQ=O.slice(f,MZ);if(!Y){let T=Buffer.byteLength(MQ,"utf8");if(X+T>gZ)j="",X=0,Y=!0,V=!0;else j+=MQ,X+=T}if(S===-1)break;if(!Y){let T=AQ(j.endsWith("\r")?j.slice(0,-1):j);if(T.threadId)J=T.threadId;if(T.rateLimits)z={sessionFile:Z,relativePath:$,threadId:J,eventTimestamp:T.timestamp,rateLimits:T.rateLimits}}j="",X=0,Y=!1,f=S+1}}if(!Y&&j.length>0){let M=AQ(j.endsWith("\r")?j.slice(0,-1):j);if(M.threadId)J=M.threadId;if(M.rateLimits)z={sessionFile:Z,relativePath:$,threadId:J,eventTimestamp:M.timestamp,rateLimits:M.rateLimits}}return{snapshot:z,skippedOversizedLine:V}}function AQ(Q){let Z=lZ(Q);if(!Z)return{threadId:null,timestamp:null,rateLimits:null};return{threadId:rZ(Z),timestamp:B(Z,"timestamp"),rateLimits:oZ(Z)}}function lZ(Q){let Z=Q.trim();if(!Z)return null;try{let $=JSON.parse(Z);return H($)?$:null}catch{return null}}function rZ(Q){if(Q.type!=="session_meta"||!H(Q.payload))return null;return B(Q.payload,"id")}function oZ(Q){if(Q.type!=="event_msg"||!H(Q.payload))return null;if(Q.payload.type!=="token_count"||!H(Q.payload.rate_limits))return null;return Q.payload.rate_limits}function n(Q,Z,$,G,J){return{path:Q,relativePath:Z,modifiedAtMs:$,hasSnapshot:G,error:J}}async function iZ(Q){try{return(await fZ(Q)).isSymbolicLink()}catch{return!1}}class s extends Error{}import{opendir as sZ}from"node:fs/promises";import{extname as tZ,join as aZ}from"node:path";import{constants as t}from"node:fs";import{lstat as _Q,open as nZ}from"node:fs/promises";class W extends Error{code;constructor(Q){super(Q);this.name="BoundedFileError",this.code=Q}}async function m(Q,Z){let $;try{let G=await _Q(Q);if(!G.isFile())throw new W("not-file");let J=t.O_NOFOLLOW,z=typeof J==="number"?t.O_RDONLY|J:t.O_RDONLY;$=await nZ(Q,z);let j=await $.stat(),X=await _Q(Q);if(!j.isFile()||!X.isFile()||!PQ(G,j)||!PQ(j,X))throw new W("not-file");if(j.size>Z)throw new W("too-large");let K=Buffer.allocUnsafe(Z+1),Y=0;while(Y<=Z){let V=await $.read(K,Y,Z+1-Y,null);if(V.bytesRead===0)break;Y+=V.bytesRead}if(Y>Z)throw new W("too-large");return K.subarray(0,Y).toString("utf8")}catch(G){if(G instanceof W)throw G;if(RQ(G)&&G.code==="ENOENT")throw new W("not-found");if(RQ(G)&&G.code==="ELOOP")throw new W("not-file");throw new W("read-error")}finally{await $?.close().catch(()=>{return})}}function PQ(Q,Z){return Q.dev===Z.dev&&Q.ino===Z.ino}function RQ(Q){return Q instanceof Error&&"code"in Q}var eZ=2,a=25,e=100,Q0=64,Z0=500,$0=1e6,G0=/(?:auth|token|cookie|session|secret|credential|api[-_]?key|keychain)/i;async function yQ(Q){let Z={directories:0,files:[],hitDirectoryLimit:!1,hitEntryLimit:!1,hitFileLimit:!1,skippedSensitive:!1,skippedSymlink:!1,warnings:[]};if(await fQ(Q,Q,0,Z),Z.hitDirectoryLimit||Z.hitEntryLimit||Z.hitFileLimit)Z.warnings.push("Stopped local state discovery after reaching a safe inspection limit.");if(Z.skippedSensitive)Z.warnings.push("Skipped a sensitive-looking local file.");if(Z.skippedSymlink)Z.warnings.push("Skipped symbolic links while inspecting local Codex state.");let $=Z.files.sort((J,z)=>J.localeCompare(z)),G=[];for(let J of $.slice(0,a)){let z=C(Q,J);try{let j=await m(J,$0),X=z0(j,z,Z.warnings);G.push({path:J,relativePath:z,json:X.value,error:X.error})}catch(j){Z.warnings.push(j instanceof W&&j.code==="too-large"?`Skipped ${z} because it is too large to inspect safely.`:`Could not read ${z}.`)}}if($.length>a)Z.warnings.push(`Skipped ${$.length-a} extra files to keep inspection small.`);return{homePath:Q,files:G,warnings:Z.warnings}}async function fQ(Q,Z,$,G){if($>eZ||G.files.length>=e){G.hitFileLimit||=G.files.length>=e;return}if(G.directories>=Q0){G.hitDirectoryLimit=!0;return}G.directories+=1;let J=await J0(Q,Z,G);for(let z of J){if(G.files.length>=e){G.hitFileLimit=!0;return}if(G0.test(z.name)){G.skippedSensitive=!0;continue}let j=aZ(Z,z.name);if(z.isSymbolicLink())G.skippedSymlink=!0;else if(z.isDirectory())await fQ(Q,j,$+1,G);else if(z.isFile()&&tZ(z.name).toLowerCase()===".json")G.files.push(j)}}async function J0(Q,Z,$){try{let G=await sZ(Z),J=[];for await(let z of G){if(J.length>=Z0){$.hitEntryLimit=!0;break}J.push(z)}return J.sort((z,j)=>z.name.localeCompare(j.name))}catch{return $.warnings.push(`Could not inspect ${C(Q,Z)}.`),[]}}function z0(Q,Z,$){try{return{value:JSON.parse(Q),error:null}}catch{return $.push(`Could not parse JSON in ${Z}.`),{value:null,error:"invalid-json"}}}import{join as j0,normalize as X0}from"node:path";function U(Q,Z,$){return{code:Q,source:Z,severity:"warning",message:$}}function k(Q){return Q.map((Z)=>A(Z.message))}var K0=1e6;async function v(Q={}){let Z=D(Q.env),$=N(Z,"CODEX_LIMITS_ACCESS_TOKEN"),G=N(Z,"CODEX_LIMITS_ACCOUNT_ID");if($&&G)return{credentials:{accessToken:$,accountId:G},status:"configured",diagnostics:[]};if($||G)return{credentials:null,status:"partial",diagnostics:[U("auth.environment.partial","authentication","Codex authentication environment variables are incomplete.")]};let J=await Y0(Q);return J?H0(J):{credentials:null,status:"missing",diagnostics:[]}}async function Y0(Q){if(Q.authFile)return X0(Q.authFile);let Z=await E(Q);return Z.foundHome?j0(Z.foundHome,"auth.json"):null}async function H0(Q){let Z;try{Z=await m(Q,K0)}catch($){if($ instanceof W&&$.code==="not-found")return{credentials:null,status:"missing",diagnostics:[]};let G=$ instanceof W&&$.code==="too-large";return{credentials:null,status:"unreadable",diagnostics:[U(G?"auth.file.too-large":"auth.file.unreadable","authentication",G?"Codex auth.json is too large to inspect safely.":"Codex auth.json could not be read safely.")]}}try{let $=JSON.parse(Z);if(!H($))return QQ();let G=H($.tokens)?$.tokens:$,J=B(G,"access_token"),z=B(G,"account_id");return J&&z?{credentials:{accessToken:J,accountId:z},status:"configured",diagnostics:[]}:QQ()}catch{return QQ()}}function QQ(){return{credentials:null,status:"malformed",diagnostics:[U("auth.file.malformed","authentication","Codex auth.json is malformed or does not contain required credentials.")]}}import{request as V0}from"node:http";import{request as q0}from"node:https";var W0=new Set(["127.0.0.1","::1","[::1]","localhost"]);function _(Q){try{let Z=new URL(Q);return Z.username="",Z.password="",Z.search="",Z.hash="",Z.href}catch{return"[invalid endpoint]"}}async function g(Q){let Z=M0(Q.endpoint);if(!Z.ok)return Z;if(Q.signal?.aborted)return q("aborted");let $=Q.fetch??globalThis.fetch;if(!$)return SQ(Z.url,Q);let G=await N0(Z.url,Q,$);if(G.ok||G.code==="aborted"||!C0(G,Q.fallbackOnHttpError??!1))return G;let J=await SQ(Z.url,Q);if(J.ok||J.code==="http-error"||J.code==="invalid-json"||J.code==="response-too-large")return J;return G}function M0(Q){let Z;try{Z=new URL(Q)}catch{return q("invalid-url")}if(Z.username||Z.password)return q("invalid-url");if(Z.protocol==="https:")return{ok:!0,url:Z};if(Z.protocol==="http:"&&W0.has(Z.hostname.toLowerCase()))return{ok:!0,url:Z};return q("unsupported-protocol")}async function N0(Q,Z,$){let G=wQ(Z.timeoutMs,Z.signal);try{let J=await $(Q.href,{method:"GET",headers:Z.headers,redirect:"error",signal:G.signal});if(!J.ok)return await EQ(J),q("http-error",$Q(J.status));let z=await U0(J,Z.maxResponseBytes);return{ok:!0,status:$Q(J.status)??200,payload:z,transport:"fetch"}}catch(J){if(J instanceof L)return q("response-too-large");if(J instanceof h)return q("invalid-json");if(Z.signal?.aborted)return q("aborted");if(G.didTimeout())return q("timeout");return q("network-error")}finally{G.dispose()}}async function U0(Q,Z){let $=Number(Q.headers?.get("content-length"));if(Number.isFinite($)&&$>Z)throw await EQ(Q),new L;if(Q.body){let G=Q.body.getReader(),J=[],z=0;while(!0){let X=await G.read();if(X.done)break;if(!X.value)continue;if(z+=X.value.byteLength,z>Z)throw await G.cancel?.(),new L;J.push(X.value)}let j=Buffer.concat(J.map((X)=>Buffer.from(X)),z).toString("utf8");return ZQ(j)}if(Q.text){let G=await Q.text();if(Buffer.byteLength(G,"utf8")>Z)throw new L;return ZQ(G)}throw new h}async function EQ(Q){if(!Q.body)return;try{await Q.body.getReader().cancel?.()}catch{}}function SQ(Q,Z){return new Promise(($)=>{let G=wQ(Z.timeoutMs,Z.signal),J=!1,z=null,j=(K)=>{if(J)return;J=!0,G.dispose(),$(K)},X=()=>{z?.destroy(),j(q(Z.signal?.aborted?"aborted":"timeout"))};G.signal.addEventListener("abort",X,{once:!0});try{z=(Q.protocol==="http:"?V0:q0)(Q,{method:"GET",headers:Z.headers,signal:G.signal},(Y)=>B0(Y,Z.maxResponseBytes,j)),z.on("error",()=>{if(Z.signal?.aborted)j(q("aborted"));else if(G.didTimeout())j(q("timeout"));else j(q("network-error"))}),z.end()}catch{j(q("network-error"))}})}function B0(Q,Z,$){let G=$Q(Q.statusCode);if(G===null||G<200||G>=300){Q.resume(),$(q("http-error",G));return}let J=Number(Q.headers["content-length"]);if(Number.isFinite(J)&&J>Z){Q.destroy(),$(q("response-too-large"));return}let z=[],j=0;Q.on("data",(X)=>{let K=Buffer.isBuffer(X)?X:Buffer.from(X);if(j+=K.length,j>Z){Q.destroy(),$(q("response-too-large"));return}z.push(K)}),Q.on("end",()=>{try{let X=ZQ(Buffer.concat(z,j).toString("utf8"));$({ok:!0,status:G,payload:X,transport:"node"})}catch{$(q("invalid-json"))}}),Q.on("error",()=>$(q("network-error")))}function wQ(Q,Z){let $=new AbortController,G=!1,J=Number.isFinite(Q)&&Q>0?Math.min(Math.floor(Q),2147483647):1,z=setTimeout(()=>{G=!0,$.abort()},J),j=()=>$.abort();if(Z?.addEventListener("abort",j,{once:!0}),Z?.aborted)j();return{signal:$.signal,didTimeout:()=>G,dispose:()=>{clearTimeout(z),Z?.removeEventListener("abort",j)}}}function C0(Q,Z){return Q.code==="network-error"||Q.code==="timeout"||Q.code==="invalid-json"||Z&&Q.code==="http-error"}function ZQ(Q){try{return JSON.parse(Q)}catch{throw new h}}function $Q(Q){return typeof Q==="number"&&Number.isInteger(Q)&&Q>=0?Q:null}function q(Q,Z=null){return{ok:!1,code:Q,status:Z}}class L extends Error{}class h extends Error{}function p(Q,Z){switch(Q.code){case"aborted":return U("network.request.aborted","network",`${Z} lookup was cancelled.`);case"http-error":return U("network.response.http","network",Q.status===null?`${Z} endpoint returned an invalid HTTP status.`:`${Z} endpoint returned HTTP ${Q.status}.`);case"invalid-json":return U("network.response.invalid-json","network",`${Z} endpoint returned malformed JSON.`);case"invalid-url":return U("network.endpoint.invalid","network",`${Z} endpoint URL is invalid.`);case"response-too-large":return U("network.response.too-large","network",`${Z} endpoint response was too large.`);case"timeout":return U("network.request.timeout","network",`${Z} lookup timed out.`);case"unsupported-protocol":return U("network.endpoint.protocol","network",`${Z} endpoint must use HTTPS or loopback HTTP.`);case"network-error":return U("network.request.failed","network",`${Z} lookup failed.`)}}var O0=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],T0=["January","February","March","April","May","June","July","August","September","October","November","December"];function c(Q,Z={}){let $=Z.includeSeconds??!1,G=Math.max(Math.floor(Q/1000),0),J=Math.floor(G/86400);G%=86400;let z=Math.floor(G/3600);G%=3600;let j=Math.floor(G/60),X=G%60,K=[];if(J>0)K.push(`${J}d`);if(z>0)K.push(`${z}h`);if(j>0)K.push(`${j}m`);if($&&X>0)K.push(`${X}s`);return K.length>0?K.join(" "):$?`${X}s`:"0m"}function F(Q){if(typeof Q==="number"&&Number.isFinite(Q)){let Z=Q<10000000000?Q*1000:Q,$=new Date(Z);return Number.isNaN($.getTime())?null:$}if(typeof Q==="string"&&Q.trim().length>0){let Z=Q.trim(),$=Number(Z);if(Number.isFinite($))return F($);let G=new Date(Z);return Number.isNaN(G.getTime())?null:G}return null}function mQ(Q){return`${O0[Q.getDay()]} ${Q.getDate()} ${T0[Q.getMonth()]} ${Q.getFullYear()}`}var hQ=["credits","reset_credits","items"],pQ=["available_count","availableCount","available"],cQ=["total_earned_count","earned_this_period","earnedThisPeriod","totalEarnedCount"];function uQ(Q,Z,$){if(!H(Q)||!x0(Q))return P(Z,["Live reset coupon endpoint returned an unexpected payload."]);let G=F0(Q,hQ);if(G.malformed)return P(Z,["Live reset coupon endpoint returned an unexpected payload."]);let J=G.value,z=J.map((V,M)=>D0(V,M+1,$)).filter((V)=>V!==null).sort(A0).map((V,M)=>({...V,index:M+1})),j=z.find((V)=>V.status?.toLowerCase()==="available")??z[0]??null,X=gQ(Q,pQ),K=gQ(Q,cQ),Y=[];if(J.length!==z.length)Y.push("Live reset coupon endpoint ignored malformed coupon entries.");if(X.malformed||K.malformed)Y.push("Live reset coupon endpoint ignored malformed summary fields.");return{status:Y.length>0?"partial":"available",available:X.value,earnedThisPeriod:K.value,nextExpirationDate:j?.expirationDate??null,nextExpirationIn:j?.expiresIn??null,items:z,warnings:Y,source:{live:!0,label:"live Codex reset-credit endpoint",endpoint:Z}}}function P(Q,Z=[]){return{status:"unavailable",available:null,earnedThisPeriod:null,nextExpirationDate:null,nextExpirationIn:null,items:[],warnings:Z,source:{live:!1,label:"live Codex reset-credit endpoint",endpoint:Q}}}function x0(Q){return[...hQ,...pQ,...cQ].some((Z)=>(Z in Q))}function D0(Q,Z,$){if(!H(Q))return null;let G=B(Q,"expires_at")??B(Q,"expiresAt"),J=B(Q,"granted_at")??B(Q,"grantedAt"),z=F(G),j=F(J),X=B(Q,"status"),K=X&&/^[a-z][a-z0-9_-]{0,63}$/i.test(X)?X:null,Y=j?J:null,V=z?G:null;if(!K&&!Y&&!V)return null;return{index:Z,status:K,grantedAt:Y,expiresAt:V,expirationDate:z?mQ(z):null,expiresIn:z?c(z.getTime()-$.getTime()):null}}function A0(Q,Z){return vQ(Q.expiresAt)-vQ(Z.expiresAt)}function vQ(Q){return F(Q)?.getTime()??Number.POSITIVE_INFINITY}function F0(Q,Z){let $=!1;for(let G of Z){if(!(G in Q))continue;$=!0;let J=Q[G];if(Array.isArray(J))return{value:J,malformed:!1}}return{value:[],malformed:$}}function gQ(Q,Z){let $=!1;for(let G of Z){if(!(G in Q))continue;$=!0;let J=Q[G];if(typeof J==="number"&&Number.isInteger(J)&&J>=0)return{value:J,malformed:!1}}return{value:null,malformed:$}}var lQ="https://chatgpt.com/backend-api/wham/rate-limit-reset-credits",I0=1e4,b0=1e6;async function rQ(Q={}){let Z=Q.endpoint??lQ,$=_(Z),G=await v(Q);if(!G.credentials){let z=k(G.diagnostics);return k0($,z.length>0?z:["Live reset coupons require a readable Codex auth.json file or CODEX_LIMITS_ACCESS_TOKEN and CODEX_LIMITS_ACCOUNT_ID."])}let J={endpoint:Z,headers:{Authorization:`Bearer ${G.credentials.accessToken}`,"ChatGPT-Account-ID":G.credentials.accountId,"OpenAI-Beta":"codex-1",originator:"Codex Desktop",Accept:"application/json"},timeoutMs:Q.timeoutMs??I0,maxResponseBytes:b0,...Q.fetch?{fetch:Q.fetch}:{},...Q.signal?{signal:Q.signal}:{}};try{let z=await(Q.transport??g)(J);return z.ok?uQ(z.payload,$,Q.now??new Date):dQ($,z)}catch{return dQ($,{ok:!1,code:"network-error",status:null})}}function k0(Q=lQ,Z=[]){return P(_(Q),Z)}function dQ(Q,Z){return P(Q,k([p(Z,"Live reset coupon")]))}var tQ=5,zQ="5-hour usage limit",jQ="Weekly usage limit",XQ=["fiveHour","five_hour","fiveHourWindow","five_hour_window","primary","primaryWindow","primary_window","main","mainWindow"],KQ=["weekly","week","weeklyWindow","weekly_window","secondary","secondaryWindow","secondary_window","backup","backupWindow"],L0=["used_percent","usedPercent","used","usage","percentUsed","usagePercent","usagePercentage","percent"],_0=["remaining_percent","remainingPercent","remaining","percentRemaining","availablePercent","available_percentage"],P0=["resets_at","resetsAt","resetAt","resetTime","reset_at","reset","ends_at","endsAt","windowEnd"],R0=["resetsIn","resetIn","resets_in","reset_in","timeUntilReset"],y0=["limit_window_seconds","limitWindowSeconds","window_seconds","windowSeconds","window_length_seconds","windowLengthSeconds"],f0=["window_minutes","windowMinutes","window_length_minutes","windowLengthMinutes"],S0=18000,E0=604800;function aQ(Q,Z=new Date){let $=Q.latestSnapshot;if(!$)return VQ(Q.warnings);return l(YQ($.rateLimits,Z),Q.warnings)}function YQ(Q,Z=new Date){return GZ(u(Q,XQ),u(Q,KQ),Z)}function eQ(Q){return u(Q,XQ)!==null||u(Q,KQ)!==null}function R(Q){let Z=sQ(I(Q,y0,!1)),$=sQ(I(Q,f0,!1)),G=Z??($===null?null:$*60);if(G===S0)return"fiveHour";if(G===E0)return"weekly";return null}function QZ(Q,Z){return{...Q,source:Z}}function HQ(Q,Z,$=[]){return{...l(Q,$),source:Z}}function ZZ(Q,Z=new Date){let $={fiveHour:null,weekly:null};for(let G of Q.files){if(!G.json)continue;let J=w0(G.json,Z);$=JZ($,J.windows)}return l($,Q.warnings)}function VQ(Q=[]){return{status:"unavailable",windows:{fiveHour:null,weekly:null},warnings:Q}}function $Z(Q,Z){let $=JZ(Q.windows,Z.windows);return l($,[...Q.warnings,...Z.warnings])}function w0(Q,Z){if(!H(Q))return{windows:{fiveHour:null,weekly:null}};let $=JQ(Q,XQ),G=JQ(Q,KQ);if($||G)return{windows:GZ($,G,Z)};let J=R(Q)??"fiveHour",z=GQ(Q,J==="weekly"?jQ:zQ,Z);return{windows:{fiveHour:J==="fiveHour"?z:null,weekly:J==="weekly"?z:null}}}function GZ(Q,Z,$){let G=[];if(Q)G.push({fallbackKind:"fiveHour",value:Q});if(Z)G.push({fallbackKind:"weekly",value:Z});return{fiveHour:GQ(oQ(G,"fiveHour"),zQ,$),weekly:GQ(oQ(G,"weekly"),jQ,$)}}function GQ(Q,Z,$){if(!Q)return null;let G=nQ(I(Q,L0,!0)),J=nQ(I(Q,_0,!0)),z=G??(J===null?null:d(100-J)),j=J??(G===null?null:d(100-G)),X=I(Q,P0,!0),K=F(X),Y=K?K.toISOString():null,V=g0(I(Q,R0,!0)),M=K?c(K.getTime()-$.getTime()):V&&V.length<=100?A(V):null,O={label:Z,remainingPercent:j,usedPercent:z,resetsAt:Y,resetsIn:M};return zZ(O)?O:null}function l(Q,Z){return{status:m0(Q),windows:Q,warnings:Z}}function m0(Q){let Z=[Q.fiveHour,Q.weekly].filter(($)=>zZ($));if(Z.length===0)return"unavailable";return Z.every(v0)?"available":"partial"}function oQ(Q,Z){let $=Q.find((G)=>R(G.value)===Z);if($)return $.value;return Q.find((G)=>G.fallbackKind===Z&&R(G.value)===null)?.value??null}function JZ(Q,Z){return{fiveHour:iQ(Q.fiveHour,Z.fiveHour,zQ),weekly:iQ(Q.weekly,Z.weekly,jQ)}}function iQ(Q,Z,$){if(!Q&&!Z)return null;return{label:$,remainingPercent:Q?.remainingPercent??Z?.remainingPercent??null,usedPercent:Q?.usedPercent??Z?.usedPercent??null,resetsAt:Q?.resetsAt??Z?.resetsAt??null,resetsIn:Q?.resetsIn??Z?.resetsIn??null}}function zZ(Q){return Q!==null&&(Q.remainingPercent!==null||Q.usedPercent!==null||Q.resetsAt!==null||Q.resetsIn!==null)}function v0(Q){return Q!==null&&Q.remainingPercent!==null&&Q.usedPercent!==null&&(Q.resetsAt!==null||Q.resetsIn!==null)}function JQ(Q,Z,$=0){if($>tQ)return null;for(let G of Z){let J=Q[G];if(H(J))return J}for(let G of Object.values(Q)){if(!H(G))continue;let J=JQ(G,Z,$+1);if(J)return J}return null}function u(Q,Z){for(let $ of Z){let G=Q[$];if(H(G))return G}return null}function I(Q,Z,$,G=0){if(G>tQ)return;for(let J of Z)if(J in Q)return Q[J];if(!$)return;for(let J of Object.values(Q)){if(!H(J))continue;let z=I(J,Z,$,G+1);if(z!==void 0)return z}return}function nQ(Q){if(typeof Q==="number"&&Number.isFinite(Q))return d(Q);if(typeof Q==="string"&&Q.trim().length>0){let Z=Q.trim(),$=Z.endsWith("%")?Z.slice(0,-1):Z,G=Number($);return Number.isFinite(G)?d(G):null}return null}function d(Q){return Math.round(Math.min(Math.max(Q,0),100)*10)/10}function sQ(Q){if(typeof Q==="number"&&Number.isFinite(Q))return Q;if(typeof Q==="string"&&Q.trim().length>0){let Z=Number(Q);return Number.isFinite(Z)?Z:null}return null}function g0(Q){if(typeof Q==="string"&&Q.trim().length>0)return Q.trim();return null}var h0=5,p0=1000,c0={kind:"unavailable",label:"Unavailable"};function XZ(Q,Z,$){let G=u0(Q)??d0(Q);if(!G)return y(["Live usage endpoint returned an unexpected payload."]);let J=HQ(YQ(G,$),{kind:"api",label:"API",endpoint:Z});if(J.status==="unavailable")return y(["Live usage endpoint returned an unexpected payload."]);if(J.status==="partial")return{...J,warnings:["Live usage endpoint returned incomplete usage data."]};return J}function y(Q){return HQ({fiveHour:null,weekly:null},c0,Q)}function u0(Q){return KZ(Q,(Z)=>{if(!H(Z))return null;let $=Z.rate_limits??Z.rateLimits??Z.rate_limit??Z.rateLimit;if(H($))return $;return eQ(Z)?Z:null})}function d0(Q){return KZ(Q,(Z)=>{if(!Array.isArray(Z))return null;let $=Z.find((J)=>jZ(J,"fiveHour")),G=Z.find((J)=>jZ(J,"weekly"));return $||G?{fiveHour:$,weekly:G}:null})}function KZ(Q,Z){let $=[{value:Q,depth:0}],G=new WeakSet;for(let J=0;J<$.length;J+=1){let z=$[J];if(!z)break;let j=Z(z.value);if(j)return j;if(z.depth>=h0||typeof z.value!=="object"||!z.value)continue;if(G.has(z.value))continue;G.add(z.value);let X=Array.isArray(z.value)?z.value:H(z.value)?Object.values(z.value):[];for(let K of X){if($.length>=p0)break;$.push({value:K,depth:z.depth+1})}}return null}function jZ(Q,Z){if(!H(Q))return!1;let $=R(Q);if($)return $===Z;let G=String(Q.type??Q.kind??Q.name??Q.label??Q.window??"").toLowerCase();return Z==="fiveHour"?G.includes("primary")||G.includes("5-hour")||G.includes("five"):G.includes("secondary")||G.includes("weekly")||G.includes("week")}var l0="https://chatgpt.com/backend-api/codex/usage",r0=1e4,o0=1e6;async function YZ(Q={}){return(await i0(Q)).usage}async function i0(Q={}){let Z=s0(Q),$=_(Z),G=await v(Q);if(!G.credentials){let j=k(G.diagnostics);return{usage:y(j.length>0?j:["Live usage requires Codex authentication."]),authenticationFound:!1,endpointStatus:"not-checked"}}let J={endpoint:Z,headers:n0(G.credentials),timeoutMs:Q.timeoutMs??r0,maxResponseBytes:o0,fallbackOnHttpError:!0,...Q.fetch?{fetch:Q.fetch}:{},...Q.signal?{signal:Q.signal}:{}},z;try{z=await(Q.transport??g)(J)}catch{z={ok:!1,code:"network-error",status:null}}return{usage:z.ok?XZ(z.payload,$,Q.now??new Date):a0(z),authenticationFound:!0,endpointStatus:t0(z)}}function n0(Q){return{Authorization:`Bearer ${Q.accessToken}`,"ChatGPT-Account-ID":Q.accountId,"OpenAI-Beta":"codex-1",originator:"Codex Desktop",Accept:"application/json","User-Agent":"Codex Desktop",Referer:"https://chatgpt.com/codex/cloud/settings/analytics",Origin:"https://chatgpt.com"}}function s0(Q){let Z=D(Q.env);return Q.usageEndpoint??N(Z,"CODEX_LIMITS_USAGE_ENDPOINT")??l0}function t0(Q){if(Q.ok)return"reachable";switch(Q.code){case"http-error":case"invalid-json":case"response-too-large":return"reachable";case"aborted":return"not-checked";case"invalid-url":case"network-error":case"timeout":case"unsupported-protocol":return"unreachable"}}function a0(Q){return y(k([p(Q,"Live usage")]))}var e0={kind:"local",label:"Local"};async function HZ(Q={}){let Z=await Q1(Q),$=Q.includeCoupons===!1?null:await rQ(Q),G=$?{...$,warnings:o($.warnings)}:null;return{windows:Z.windows,usageSource:Z.source,coupons:G,warnings:o([...Z.warnings,...G?.warnings??[]])}}async function Q1(Q={}){let Z=await YZ(Q);if(Z.status!=="unavailable")return Z;let $=QZ(await $1(Q),e0);return Z1(Z,$)}function Z1(Q,Z){if(Q.status!=="unavailable")return Q;if(Z.status!=="unavailable")return Z;return{...Z,warnings:[...Q.warnings,...Z.warnings]}}async function $1(Q={}){let Z=Q.now??new Date,$=await E(Q);if(!$.foundHome)return VQ(["No readable local Codex home directory was found."]);let[G,J]=await Promise.all([kQ($.foundHome),yQ($.foundHome)]);return $Z(aQ(G,Z),ZZ(J,Z))}var J1="Codex Limits",qZ="Could not load Codex limits.",z1="Could not display Codex limits.";function j1(Q={}){let Z=Q.getLimits??HZ;return($)=>{$.registerCommand("codex-limits",{description:"Check Codex limits, resets, and credits",handler:async(G,J)=>{if(!J.hasUI||J.mode!=="tui")return;J.ui.setStatus("codex-limits","Loading Codex limits...");let z;try{z=BQ(await Z())}catch{z=qZ,J.ui.notify(qZ,"error")}finally{J.ui.setStatus("codex-limits",void 0)}try{await X1(z,J)}catch{J.ui.notify(z1,"error")}}})}}async function X1(Q,Z){await Z.ui.custom(($,G,J,z)=>{let j=WZ(Q,G);return{render:(X)=>j.render(X),invalidate:()=>{j=WZ(Q,G)},handleInput:(X)=>{if(qQ(X,"enter")||qQ(X,"escape")||qQ(X,"ctrl+c"))z(void 0)}}},{overlay:!0,overlayOptions:{width:56,minWidth:36,maxHeight:"90%",margin:1}})}function WZ(Q,Z){let $=new G1;return $.addChild(new VZ((G)=>Z.fg("accent",G))),$.addChild(new WQ(Z.fg("accent",Z.bold(J1)),1,0)),$.addChild(new WQ(Q,1,1)),$.addChild(new WQ(Z.fg("dim","Press Enter or Esc to close"),1,0)),$.addChild(new VZ((G)=>Z.fg("accent",G))),$}var K1=j1(),w2=K1;export{w2 as default,j1 as createPiPlugin};
4
+ `)}function AQ(Q,Z){let $=Z.remainingPercent;return[`${Q} ${bZ($)}`,`Remaining ${$===null?"Unknown":`${Math.round($)}% remaining`}`,FZ($),`Reset ${Z.resetsIn?`in ${Z.resetsIn}`:"unknown"}`]}function FZ(Q){let Z=Q===null?0:Math.min(Math.max(Q,0),100),$=Math.round(Z/100*22);return`[${"=".repeat($)}${" ".repeat(22-$)}] ${Math.round(Z)}%`}function AZ(Q){let Z=Q.coupons?.available,G=[`Reset credits ${Z===null||Z===void 0?"Unknown":`${Z} ${Z===1?"credit":"credits"} available`}`],J=Q.coupons?.nextExpirationIn,z=Q.coupons?.nextExpirationDate,j=J&&z?`${J} (${z})`:J??z;if(j!==null&&j!==void 0)G.push(`Next expires ${j}`);return G}function bZ(Q){if(Q===null)return"Unknown";if(Q>=50)return"Healthy";if(Q>=15)return"Low";return"Critical"}function IQ(Q){return bQ(Q)}import{constants as IZ}from"node:fs";import{access as kZ,stat as LZ}from"node:fs/promises";import{homedir as _Z}from"node:os";import{join as I,normalize as s}from"node:path";function U(Q,Z){let $=Q[Z]?.trim();return $?$:null}function A(Q){return Q??process.env}var kQ="CODEX_LIMITS_HOME";function RZ(Q={}){let Z=A(Q.env),$=Q.homeDirectory??U(Z,"HOME")??U(Z,"USERPROFILE")??_Z(),G=Q.appData??U(Z,"APPDATA"),J=Q.localAppData??U(Z,"LOCALAPPDATA"),z=[];if(D(z,U(Z,kQ),"env"),D(z,U(Z,"CODEX_HOME"),"env"),$)D(z,I($,".codex"),"default"),D(z,I($,".config","codex"),"default"),D(z,I($,"Library","Application Support","Codex"),"default"),D(z,I($,"Library","Application Support","Parall","Codex",".codex"),"default");return D(z,G?I(G,"Codex"):null,"default"),D(z,J?I(J,"Codex"):null,"default"),fZ(z)}async function g(Q={}){let Z=A(Q.env),$=U(Z,kQ),G=await Promise.all(RZ(Q).map(async(J)=>({...J,exists:await yZ(J.path)})));return{overrideHome:$?s($):null,candidates:G,foundHome:G.find((J)=>J.exists)?.path??null}}function D(Q,Z,$){if(Z)Q.push({path:s(Z),source:$})}async function yZ(Q){try{if(!(await LZ(Q)).isDirectory())return!1;return await kZ(Q,IZ.R_OK),!0}catch{return!1}}function fZ(Q){let Z=new Set,$=[];for(let G of Q){let J=s(G.path),z=process.platform==="win32"?J.toLowerCase():J;if(!Z.has(z))Z.add(z),$.push({path:J,source:G.source})}return $}import{constants as t}from"node:fs";import{lstat as h,open as uZ,opendir as lZ,realpath as EQ}from"node:fs/promises";import{join as wQ}from"node:path";var SZ=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],EZ=["January","February","March","April","May","June","July","August","September","October","November","December"];function L(Q,Z={}){let $=Z.includeSeconds??!1,G=Math.max(Math.floor(Q/1000),0),J=Math.floor(G/86400);G%=86400;let z=Math.floor(G/3600);G%=3600;let j=Math.floor(G/60),K=G%60,X=[];if(J>0)X.push(`${J}d`);if(z>0)X.push(`${z}h`);if(j>0)X.push(`${j}m`);if($&&K>0)X.push(`${K}s`);return X.length>0?X.join(" "):$?`${K}s`:"0m"}function T(Q){if(typeof Q==="number"&&Number.isFinite(Q)){let Z=Q<10000000000?Q*1000:Q,$=new Date(Z);return Number.isNaN($.getTime())?null:$}if(typeof Q==="string"&&Q.trim().length>0){let Z=Q.trim(),$=Number(Z);if(Number.isFinite($))return T($);let G=new Date(Z);return Number.isNaN(G.getTime())?null:G}return null}function LQ(Q){return`${SZ[Q.getDay()]} ${Q.getDate()} ${EZ[Q.getMonth()]} ${Q.getFullYear()}`}import{isAbsolute as hZ,relative as RQ,resolve as _Q,sep as cZ}from"node:path";var wZ=/(?:chatgpt[-_]?account[-_]?id|access[-_]?token|refresh[-_]?token|id[-_]?token|session[-_]?token|api[-_]?key|account[-_]?id|authorization|cookie|client[-_]?secret|password|credential|secret|token)/,vZ=/[\u0000-\u001f\u007f-\u009f]/g,gZ=new RegExp(`["']?${wZ.source}["']?\\s*[:=]\\s*(?:"(?:\\\\.|[^"\\\\])*"|'(?:\\\\.|[^'\\\\])*'|[^,\\r\\n}\\]&]+)`,"gi"),mZ=[gZ,/Bearer\s+[A-Za-z0-9._~+/=-]+/gi,/\beyJ[A-Za-z0-9_-]{5,}\.[A-Za-z0-9_-]{5,}(?:\.[A-Za-z0-9_-]{5,})?\b/g,/sk-[A-Za-z0-9_-]{10,}/g,/\b[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}\b/gi,/[A-Za-z0-9_-]{32,}/g];function _(Q){let Z=Q;for(let $ of mZ)Z=Z.replace($,"[redacted]");return Z.replace(vZ,"?")}function a(Q){return Q.map(_)}function yQ(Q,Z){let $=RQ(_Q(Q),_Q(Z));return $===""||!fQ($)}function R(Q,Z){let $=RQ(Q,Z);return $&&!fQ($)?pZ($):"."}function pZ(Q){let Z=_(Q);return Z.length<=240?Z:`${Z.slice(0,239)}…`}function fQ(Q){return Q===".."||Q.startsWith(`..${cZ}`)||hZ(Q)}function W(Q){return typeof Q==="object"&&Q!==null&&!Array.isArray(Q)}function N(Q,Z){let $=Q[Z];return typeof $==="string"&&$.trim()?$.trim():null}var dZ=8,e=20,m=1000,rZ=512,iZ=1000,GQ=25000000,oZ=1e6,nZ=/^rollout-.*\.jsonl$/i;async function vQ(Q){let Z=wQ(Q,"sessions"),$=[];if(await z0(Z))return $.push("Skipped the symbolic-link Codex sessions directory."),{homePath:Q,sessionsRoot:Z,files:[],latestSnapshot:null,warnings:$};let G=await sZ(Z,$),J=[],z=null;for(let j of G.slice(0,e)){let K=R(Q,j.path);if(j.size>GQ){$.push("Skipped a local Codex session file because it is too large to inspect safely."),J.push(ZQ(j.path,K,j.modifiedAtMs,!1,"too-large"));continue}try{let X=await eZ(Q,j);if(J.push(ZQ(j.path,K,j.modifiedAtMs,X.snapshot!==null,null)),X.skippedOversizedLine)$.push("Skipped an oversized JSONL line in a local Codex session file.");if(X.snapshot&&(!z||Z0(X.snapshot,z)))z=X.snapshot}catch(X){let Y=X instanceof c;$.push(Y?"Skipped a local Codex session file because it grew too large to inspect safely.":"Could not inspect a local Codex session file safely."),J.push(ZQ(j.path,K,j.modifiedAtMs,!1,Y?"too-large":"read-error"))}}if(G.length>e)$.push(`Skipped ${G.length-e} older session files to keep inspection small.`);if(G.length>0&&!z)$.push("No token-count rate-limit snapshot was found in local Codex session logs.");return{homePath:Q,sessionsRoot:Z,files:J,latestSnapshot:z,warnings:$}}async function sZ(Q,Z){let $={directories:0,files:[],hitLimit:!1,skippedSymlink:!1};if(await gQ(Q,0,$,Z),$.hitLimit)Z.push("Stopped session discovery after reaching a safe inspection limit.");if($.skippedSymlink)Z.push("Skipped symbolic links while inspecting Codex sessions.");let G;try{G=await EQ(Q)}catch{return[]}let J=[];for(let z of $.files){let j=await aZ(G,z,Z);if(j)J.push(j)}return J.sort((z,j)=>j.modifiedAtMs-z.modifiedAtMs||z.path.localeCompare(j.path))}async function aZ(Q,Z,$){try{let[G,J]=await Promise.all([h(Z),EQ(Z)]);if(!G.isFile()||!yQ(Q,J))return $.push("Could not inspect a local Codex session file safely."),null;return{path:Z,modifiedAtMs:G.mtimeMs,size:G.size,dev:G.dev,ino:G.ino}}catch{return $.push("Could not inspect a local Codex session file safely."),null}}async function gQ(Q,Z,$,G){if(Z>dZ||$.files.length>=m){$.hitLimit||=$.files.length>=m;return}if($.directories>=rZ){$.hitLimit=!0;return}$.directories+=1;let J;try{J=await tZ(Q,$)}catch{if(Z>0)G.push("Could not inspect part of the local Codex sessions directory safely.");return}for(let z of J){if($.files.length>=m){$.hitLimit=!0;return}let j=wQ(Q,z.name);if(z.isSymbolicLink()){$.skippedSymlink=!0;continue}if(z.isDirectory()){await gQ(j,Z+1,$,G);continue}if(z.isFile()&&nZ.test(z.name)){if($.files.push(j),$.files.length>=m){$.hitLimit=!0;return}}}}async function tZ(Q,Z){let $=await lZ(Q),G=[];for await(let J of $){if(G.length>=iZ){Z.hitLimit=!0;break}G.push(J)}return G.sort((J,z)=>z.name.localeCompare(J.name))}async function eZ(Q,Z){let $=Z.path,G=R(Q,$),J=await Q0(Z),z=null,j=null,K="",X=0,Y=0,H=!1,M=!1;for await(let O of J){let C=String(O);if(Y+=Buffer.byteLength(C,"utf8"),Y>GQ)throw new c;let P=0;while(P<C.length){let F=C.indexOf(`
5
+ `,P),v=F===-1?C.length:F,FQ=C.slice(P,v);if(!H){let x=Buffer.byteLength(FQ,"utf8");if(X+x>oZ)K="",X=0,H=!0,M=!0;else K+=FQ,X+=x}if(F===-1)break;if(!H){let x=SQ(K.endsWith("\r")?K.slice(0,-1):K);if(x.threadId)z=x.threadId;if(x.rateLimits)j={sessionFile:$,relativePath:G,threadId:z,eventTimestamp:x.timestamp,rateLimits:x.rateLimits}}K="",X=0,H=!1,P=F+1}}if(!H&&K.length>0){let O=SQ(K.endsWith("\r")?K.slice(0,-1):K);if(O.threadId)z=O.threadId;if(O.rateLimits)j={sessionFile:$,relativePath:G,threadId:z,eventTimestamp:O.timestamp,rateLimits:O.rateLimits}}return{snapshot:j,skippedOversizedLine:M}}async function Q0(Q){let Z;try{let $=await h(Q.path);if(!$.isFile()||!QQ($,Q))throw new $Q;let G=t.O_NOFOLLOW,J=typeof G==="number"?t.O_RDONLY|G:t.O_RDONLY;Z=await uZ(Q.path,J);let[z,j]=await Promise.all([Z.stat(),h(Q.path)]);if(!z.isFile()||!j.isFile()||!QQ(z,Q)||!QQ(z,j))throw new $Q;if(z.size>GQ)throw new c;return Z.createReadStream({encoding:"utf8",highWaterMark:65536})}catch($){throw await Z?.close().catch(()=>{return}),$}}function QQ(Q,Z){return Q.dev===Z.dev&&Q.ino===Z.ino}function Z0(Q,Z){let $=T(Q.eventTimestamp)?.getTime()??null,G=T(Z.eventTimestamp)?.getTime()??null;if($===null)return!1;return G===null||$>G}function SQ(Q){let Z=$0(Q);if(!Z)return{threadId:null,timestamp:null,rateLimits:null};return{threadId:G0(Z),timestamp:N(Z,"timestamp"),rateLimits:J0(Z)}}function $0(Q){let Z=Q.trim();if(!Z)return null;try{let $=JSON.parse(Z);return W($)?$:null}catch{return null}}function G0(Q){if(Q.type!=="session_meta"||!W(Q.payload))return null;return N(Q.payload,"id")}function J0(Q){if(Q.type!=="event_msg"||!W(Q.payload))return null;if(Q.payload.type!=="token_count"||!W(Q.payload.rate_limits))return null;return Q.payload.rate_limits}function ZQ(Q,Z,$,G,J){return{path:Q,relativePath:Z,modifiedAtMs:$,hasSnapshot:G,error:J}}async function z0(Q){try{return(await h(Q)).isSymbolicLink()}catch{return!1}}class c extends Error{}class $Q extends Error{}import{opendir as K0}from"node:fs/promises";import{extname as X0,join as Y0}from"node:path";import{constants as JQ}from"node:fs";import{lstat as mQ,open as j0}from"node:fs/promises";class q extends Error{code;constructor(Q){super(Q);this.name="BoundedFileError",this.code=Q}}async function p(Q,Z){let $;try{let G=await mQ(Q);if(!G.isFile())throw new q("not-file");let J=JQ.O_NOFOLLOW,z=typeof J==="number"?JQ.O_RDONLY|J:JQ.O_RDONLY;$=await j0(Q,z);let j=await $.stat(),K=await mQ(Q);if(!j.isFile()||!K.isFile()||!hQ(G,j)||!hQ(j,K))throw new q("not-file");if(j.size>Z)throw new q("too-large");let X=Buffer.allocUnsafe(Z+1),Y=0;while(Y<=Z){let H=await $.read(X,Y,Z+1-Y,null);if(H.bytesRead===0)break;Y+=H.bytesRead}if(Y>Z)throw new q("too-large");return X.subarray(0,Y).toString("utf8")}catch(G){if(G instanceof q)throw G;if(cQ(G)&&G.code==="ENOENT")throw new q("not-found");if(cQ(G)&&G.code==="ELOOP")throw new q("not-file");throw new q("read-error")}finally{await $?.close().catch(()=>{return})}}function hQ(Q,Z){return Q.dev===Z.dev&&Q.ino===Z.ino}function cQ(Q){return Q instanceof Error&&"code"in Q}var H0=2,zQ=25,jQ=100,W0=64,V0=500,M0=1e6,q0=/(?:auth|token|cookie|session|secret|credential|api[-_]?key|keychain)/i;async function pQ(Q){let Z={directories:0,files:[],hitDirectoryLimit:!1,hitEntryLimit:!1,hitFileLimit:!1,skippedSensitive:!1,skippedSymlink:!1,warnings:[]};if(await uQ(Q,0,Z),Z.hitDirectoryLimit||Z.hitEntryLimit||Z.hitFileLimit)Z.warnings.push("Stopped local state discovery after reaching a safe inspection limit.");if(Z.skippedSensitive)Z.warnings.push("Skipped a sensitive-looking local file.");if(Z.skippedSymlink)Z.warnings.push("Skipped symbolic links while inspecting local Codex state.");let $=Z.files.sort((J,z)=>J.localeCompare(z)),G=[];for(let J of $.slice(0,zQ)){let z=R(Q,J);try{let j=await p(J,M0),K=N0(j,Z.warnings);G.push({path:J,relativePath:z,json:K.value,error:K.error})}catch(j){Z.warnings.push(j instanceof q&&j.code==="too-large"?"Skipped a local Codex state file because it is too large to inspect safely.":"Could not read a local Codex state file safely.")}}if($.length>zQ)Z.warnings.push(`Skipped ${$.length-zQ} extra files to keep inspection small.`);return{homePath:Q,files:G,warnings:Z.warnings}}async function uQ(Q,Z,$){if(Z>H0||$.files.length>=jQ){$.hitFileLimit||=$.files.length>=jQ;return}if($.directories>=W0){$.hitDirectoryLimit=!0;return}$.directories+=1;let G=await U0(Q,$);for(let J of G){if($.files.length>=jQ){$.hitFileLimit=!0;return}if(q0.test(J.name)){$.skippedSensitive=!0;continue}let z=Y0(Q,J.name);if(J.isSymbolicLink())$.skippedSymlink=!0;else if(J.isDirectory())await uQ(z,Z+1,$);else if(J.isFile()&&X0(J.name).toLowerCase()===".json")$.files.push(z)}}async function U0(Q,Z){try{let $=await K0(Q),G=[];for await(let J of $){if(G.length>=V0){Z.hitEntryLimit=!0;break}G.push(J)}return G.sort((J,z)=>J.name.localeCompare(z.name))}catch{return Z.warnings.push("Could not inspect part of the local Codex state directory safely."),[]}}function N0(Q,Z){try{return{value:JSON.parse(Q),error:null}}catch{return Z.push("Could not parse JSON in a local Codex state file."),{value:null,error:"invalid-json"}}}import{join as B0,normalize as O0}from"node:path";function B(Q,Z,$){return{code:Q,source:Z,severity:"warning",message:$}}function k(Q){return Q.map((Z)=>_(Z.message))}var C0=1e6;async function u(Q={}){let Z=A(Q.env),$=U(Z,"CODEX_LIMITS_ACCESS_TOKEN"),G=U(Z,"CODEX_LIMITS_ACCOUNT_ID");if($&&G)return{credentials:{accessToken:$,accountId:G},status:"configured",diagnostics:[]};if($||G)return{credentials:null,status:"partial",diagnostics:[B("auth.environment.partial","authentication","Codex authentication environment variables are incomplete.")]};let J=await x0(Q);return J?D0(J):{credentials:null,status:"missing",diagnostics:[]}}async function x0(Q){if(Q.authFile)return O0(Q.authFile);let Z=await g(Q);return Z.foundHome?B0(Z.foundHome,"auth.json"):null}async function D0(Q){let Z;try{Z=await p(Q,C0)}catch($){if($ instanceof q&&$.code==="not-found")return{credentials:null,status:"missing",diagnostics:[]};let G=$ instanceof q&&$.code==="too-large";return{credentials:null,status:"unreadable",diagnostics:[B(G?"auth.file.too-large":"auth.file.unreadable","authentication",G?"Codex auth.json is too large to inspect safely.":"Codex auth.json could not be read safely.")]}}try{let $=JSON.parse(Z);if(!W($))return KQ();let G=W($.tokens)?$.tokens:$,J=N(G,"access_token"),z=N(G,"account_id");return J&&z?{credentials:{accessToken:J,accountId:z},status:"configured",diagnostics:[]}:KQ()}catch{return KQ()}}function KQ(){return{credentials:null,status:"malformed",diagnostics:[B("auth.file.malformed","authentication","Codex auth.json is malformed or does not contain required credentials.")]}}var T0=/[\u0000-\u0020\u007f-\u009f]/;function XQ(Q){return Q.length>0&&Q.length<=512&&!T0.test(Q)}import{request as P0}from"node:http";import{request as F0}from"node:https";var A0=new Set(["127.0.0.1","::1","[::1]","localhost"]);function f(Q){try{let Z=new URL(Q);return Z.username="",Z.password="",Z.search="",Z.hash="",Z.href}catch{return"[invalid endpoint]"}}async function dQ(Q){let Z=b0(Q.endpoint);if(!Z.ok)return Z;if(Q.signal?.aborted)return V("aborted");let $=Q.fetch??globalThis.fetch;if(!$)return lQ(Z.url,Q);let G=await I0(Z.url,Q,$);if(G.ok||G.code==="aborted"||!_0(G,Q.fallbackOnHttpError??!1))return G;let J=await lQ(Z.url,Q);if(J.ok||J.code==="http-error"||J.code==="invalid-json"||J.code==="response-too-large")return J;return G}function l(Q){let Z={...Q,method:"GET"};return delete Z.body,dQ(Z)}function b0(Q){let Z;try{Z=new URL(Q)}catch{return V("invalid-url")}if(Z.username||Z.password)return V("invalid-url");if(Z.protocol==="https:")return{ok:!0,url:Z};if(Z.protocol==="http:"&&A0.has(Z.hostname.toLowerCase()))return{ok:!0,url:Z};return V("unsupported-protocol")}async function I0(Q,Z,$){let G=iQ(Z.timeoutMs,Z.signal);try{let J=await $(Q.href,{method:Z.method??"GET",headers:Z.headers,redirect:"error",signal:G.signal,...Z.body===void 0?{}:{body:Z.body}});if(!J.ok)return await rQ(J),V("http-error",WQ(J.status));let z=await k0(J,Z.maxResponseBytes);return{ok:!0,status:WQ(J.status)??200,payload:z,transport:"fetch"}}catch(J){if(J instanceof y)return V("response-too-large");if(J instanceof d)return V("invalid-json");if(Z.signal?.aborted)return V("aborted");if(G.didTimeout())return V("timeout");return V("network-error")}finally{G.dispose()}}async function k0(Q,Z){let $=Number(Q.headers?.get("content-length"));if(Number.isFinite($)&&$>Z)throw await rQ(Q),new y;if(Q.body){let G=Q.body.getReader(),J=[],z=0;while(!0){let K=await G.read();if(K.done)break;if(!K.value)continue;if(z+=K.value.byteLength,z>Z)throw await G.cancel?.(),new y;J.push(K.value)}let j=Buffer.concat(J.map((K)=>Buffer.from(K)),z).toString("utf8");return HQ(j)}if(Q.text){let G=await Q.text();if(Buffer.byteLength(G,"utf8")>Z)throw new y;return HQ(G)}throw new d}async function rQ(Q){if(!Q.body)return;try{await Q.body.getReader().cancel?.()}catch{}}function lQ(Q,Z){return new Promise(($)=>{let G=iQ(Z.timeoutMs,Z.signal),J=!1,z=null,j=(X)=>{if(J)return;J=!0,G.dispose(),$(X)},K=()=>{z?.destroy(),j(V(Z.signal?.aborted?"aborted":"timeout"))};G.signal.addEventListener("abort",K,{once:!0});try{z=(Q.protocol==="http:"?P0:F0)(Q,{method:Z.method??"GET",headers:Z.headers,signal:G.signal},(Y)=>L0(Y,Z.maxResponseBytes,j)),z.on("error",()=>{if(Z.signal?.aborted)j(V("aborted"));else if(G.didTimeout())j(V("timeout"));else j(V("network-error"))}),z.end(Z.body)}catch{j(V("network-error"))}})}function L0(Q,Z,$){let G=WQ(Q.statusCode);if(G===null||G<200||G>=300){$(V("http-error",G)),YQ(Q);return}let J=Number(Q.headers["content-length"]);if(Number.isFinite(J)&&J>Z){$(V("response-too-large")),YQ(Q);return}let z=[],j=0;Q.on("data",(K)=>{let X=Buffer.isBuffer(K)?K:Buffer.from(K);if(j+=X.length,j>Z){$(V("response-too-large")),YQ(Q);return}z.push(X)}),Q.on("end",()=>{try{let K=HQ(Buffer.concat(z,j).toString("utf8"));$({ok:!0,status:G,payload:K,transport:"node"})}catch{$(V("invalid-json"))}}),Q.on("error",()=>$(V("network-error")))}function YQ(Q){Q.destroy(),Q.socket.destroy()}function iQ(Q,Z){let $=new AbortController,G=!1,J=Number.isFinite(Q)&&Q>0?Math.min(Math.floor(Q),2147483647):1,z=setTimeout(()=>{G=!0,$.abort()},J),j=()=>$.abort();if(Z?.addEventListener("abort",j,{once:!0}),Z?.aborted)j();return{signal:$.signal,didTimeout:()=>G,dispose:()=>{clearTimeout(z),Z?.removeEventListener("abort",j)}}}function _0(Q,Z){return Q.code==="network-error"||Q.code==="timeout"||Q.code==="invalid-json"||Z&&Q.code==="http-error"}function HQ(Q){try{return JSON.parse(Q)}catch{throw new d}}function WQ(Q){return typeof Q==="number"&&Number.isInteger(Q)&&Q>=0?Q:null}function V(Q,Z=null){return{ok:!1,code:Q,status:Z}}class y extends Error{}class d extends Error{}function r(Q,Z){switch(Q.code){case"aborted":return B("network.request.aborted","network",`${Z} lookup was cancelled.`);case"http-error":return B("network.response.http","network",Q.status===null?`${Z} endpoint returned an invalid HTTP status.`:`${Z} endpoint returned HTTP ${Q.status}.`);case"invalid-json":return B("network.response.invalid-json","network",`${Z} endpoint returned malformed JSON.`);case"invalid-url":return B("network.endpoint.invalid","network",`${Z} endpoint URL is invalid.`);case"response-too-large":return B("network.response.too-large","network",`${Z} endpoint response was too large.`);case"timeout":return B("network.request.timeout","network",`${Z} lookup timed out.`);case"unsupported-protocol":return B("network.endpoint.protocol","network",`${Z} endpoint must use HTTPS or loopback HTTP.`);case"network-error":return B("network.request.failed","network",`${Z} lookup failed.`)}}var aQ=["credits","reset_credits","items"],tQ=["available_count","availableCount","available"],eQ=["total_earned_count","earned_this_period","earnedThisPeriod","totalEarnedCount"],R0=64,y0=/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.(\d+))?(?:Z|[+-](\d{2}):(\d{2}))$/i;function QZ(Q,Z,$){if(!W(Q)||!f0(Q))return S(Z,["Live reset coupon endpoint returned an unexpected payload."]);let G=v0(Q,aQ);if(G.malformed)return S(Z,["Live reset coupon endpoint returned an unexpected payload."]);let J=G.value,z=J.map((H,M)=>S0(H,M+1,$)).filter((H)=>H!==null).sort(w0).map((H,M)=>({...H,index:M+1})),j=z.find((H)=>H.status?.toLowerCase()==="available")??z[0]??null,K=sQ(Q,tQ),X=sQ(Q,eQ),Y=[];if(J.length!==z.length)Y.push("Live reset coupon endpoint ignored malformed coupon entries.");if(K.malformed||X.malformed)Y.push("Live reset coupon endpoint ignored malformed summary fields.");return{status:Y.length>0?"partial":"available",available:K.value,earnedThisPeriod:X.value,nextExpirationDate:j?.expirationDate??null,nextExpirationIn:j?.expiresIn??null,items:z,warnings:Y,source:{live:!0,label:"live Codex reset-credit endpoint",endpoint:Z}}}function S(Q,Z=[]){return{status:"unavailable",available:null,earnedThisPeriod:null,nextExpirationDate:null,nextExpirationIn:null,items:[],warnings:Z,source:{live:!1,label:"live Codex reset-credit endpoint",endpoint:Q}}}function f0(Q){return[...aQ,...tQ,...eQ].some((Z)=>(Z in Q))}function S0(Q,Z,$){if(!W(Q))return null;let G=Q.id,J=typeof G==="string"&&XQ(G)?G:null,z=Q.reset_type??Q.resetType,j=typeof z==="string"&&/^[a-z][a-z0-9_-]{0,63}$/i.test(z)?z:null,K="expires_at"in Q||"expiresAt"in Q,X="granted_at"in Q||"grantedAt"in Q,Y=N(Q,"expires_at")??N(Q,"expiresAt"),H=N(Q,"granted_at")??N(Q,"grantedAt"),M=oQ(Y),O=oQ(H),C=N(Q,"status"),P=C&&/^[a-z][a-z0-9_-]{0,63}$/i.test(C)?C:null,F=O?H:null,v=M?Y:null;if("id"in Q&&!J||X&&!O||K&&!M||!P&&!F&&!v)return null;return{id:J,resetType:j,index:Z,status:P,grantedAt:F,expiresAt:v,expirationDate:M?LQ(M):null,expiresIn:M?L(M.getTime()-$.getTime()):null}}function oQ(Q){if(!Q||Q.length>R0)return null;let Z=y0.exec(Q);if(!Z)return null;let $=Number(Z[1]),G=Number(Z[2]),J=Number(Z[3]),z=Number(Z[4]),j=Number(Z[5]),K=Number(Z[6]),X=Z[8]===void 0?0:Number(Z[8]),Y=Z[9]===void 0?0:Number(Z[9]);if(G<1||G>12||J<1||J>E0($,G)||z>23||j>59||K>59||X>23||Y>59)return null;let H=new Date(Q);return Number.isNaN(H.getTime())?null:H}function E0(Q,Z){if(Z===2)return Q%4===0&&(Q%100!==0||Q%400===0)?29:28;return Z===4||Z===6||Z===9||Z===11?30:31}function w0(Q,Z){return nQ(Q.expiresAt)-nQ(Z.expiresAt)}function nQ(Q){return T(Q)?.getTime()??Number.POSITIVE_INFINITY}function v0(Q,Z){let $=!1;for(let G of Z){if(!(G in Q))continue;$=!0;let J=Q[G];if(Array.isArray(J))return{value:J,malformed:!1}}return{value:[],malformed:$}}function sQ(Q,Z){let $=!1;for(let G of Z){if(!(G in Q))continue;$=!0;let J=Q[G];if(typeof J==="number"&&Number.isInteger(J)&&J>=0)return{value:J,malformed:!1}}return{value:null,malformed:$}}var VQ="https://chatgpt.com/backend-api/wham/rate-limit-reset-credits",_2=`${VQ}/consume`,g0=1e4,m0=1e6;async function $Z(Q={}){let Z=Q.endpoint??VQ,$=f(Z),G=await u(Q);if(!G.credentials){let z=k(G.diagnostics);return h0($,z.length>0?z:["Live reset coupons require a readable Codex auth.json file or CODEX_LIMITS_ACCESS_TOKEN and CODEX_LIMITS_ACCOUNT_ID."])}let J=c0(Z,G.credentials,Q);try{let z=await(Q.transport??l)(J);return z.ok?QZ(z.payload,$,Q.now??new Date):ZZ($,z)}catch{return ZZ($,{ok:!1,code:"network-error",status:null})}}function h0(Q=VQ,Z=[]){return S(f(Q),Z)}function ZZ(Q,Z){return S(Q,k([r(Z,"Live reset coupon")]))}function c0(Q,Z,$){return{endpoint:Q,headers:p0(Z),timeoutMs:$.timeoutMs??g0,maxResponseBytes:m0,...$.fetch?{fetch:$.fetch}:{},...$.signal?{signal:$.signal}:{}}}function p0(Q){return{Authorization:`Bearer ${Q.accessToken}`,"ChatGPT-Account-ID":Q.accountId,"OpenAI-Beta":"codex-1",originator:"Codex Desktop",Accept:"application/json"}}var KZ=5,UQ="5-hour usage limit",NQ="Weekly usage limit",BQ=["fiveHour","five_hour","fiveHourWindow","five_hour_window","primary","primaryWindow","primary_window","main","mainWindow"],OQ=["weekly","week","weeklyWindow","weekly_window","secondary","secondaryWindow","secondary_window","backup","backupWindow"],u0=["used_percent","usedPercent","used","usage","percentUsed","usagePercent","usagePercentage","percent"],l0=["remaining_percent","remainingPercent","remaining","percentRemaining","availablePercent","available_percentage"],d0=["resets_at","resetsAt","resetAt","resetTime","reset_at","reset","ends_at","endsAt","windowEnd"],r0=["resetsIn","resetIn","resets_in","reset_in","timeUntilReset"],i0=["limit_window_seconds","limitWindowSeconds","window_seconds","windowSeconds","window_length_seconds","windowLengthSeconds"],o0=["window_minutes","windowMinutes","window_length_minutes","windowLengthMinutes"],n0=18000,s0=604800,a0=/^(?:(\d+)d)?(?:\s*(\d+)h)?(?:\s*(\d+)m)?(?:\s*(\d+)s)?$/i;function XZ(Q,Z=new Date){let $=Q.latestSnapshot;if(!$)return DQ(Q.warnings);return n(CQ($.rateLimits,Z),Q.warnings)}function CQ(Q,Z=new Date){return MZ(i(Q,BQ),i(Q,OQ),Z)}function YZ(Q){return i(Q,BQ)!==null||i(Q,OQ)!==null}function E(Q){let Z=jZ(b(Q,i0,!1)),$=jZ(b(Q,o0,!1)),G=Z??($===null?null:$*60);if(G===n0)return"fiveHour";if(G===s0)return"weekly";return null}function HZ(Q,Z){return{...Q,source:Z}}function xQ(Q,Z,$=[]){return{...n(Q,$),source:Z}}function WZ(Q,Z=new Date){let $={fiveHour:null,weekly:null};for(let G of Q.files){if(!G.json)continue;let J=t0(G.json,Z);$=qZ($,J.windows)}return n($,Q.warnings)}function DQ(Q=[]){return{status:"unavailable",windows:{fiveHour:null,weekly:null},warnings:Q}}function VZ(Q,Z){let $=qZ(Q.windows,Z.windows);return n($,[...Q.warnings,...Z.warnings])}function t0(Q,Z){if(!W(Q))return{windows:{fiveHour:null,weekly:null}};let $=qQ(Q,BQ),G=qQ(Q,OQ);if($||G)return{windows:MZ($,G,Z)};let J=E(Q)??"fiveHour",z=MQ(Q,J==="weekly"?NQ:UQ,Z);return{windows:{fiveHour:J==="fiveHour"?z:null,weekly:J==="weekly"?z:null}}}function MZ(Q,Z,$){let G=[];if(Q)G.push({fallbackKind:"fiveHour",value:Q});if(Z)G.push({fallbackKind:"weekly",value:Z});return{fiveHour:MQ(GZ(G,"fiveHour"),UQ,$),weekly:MQ(GZ(G,"weekly"),NQ,$)}}function MQ(Q,Z,$){if(!Q)return null;let G=zZ(b(Q,u0,!0)),J=zZ(b(Q,l0,!0)),z=G??(J===null?null:o(100-J)),j=J??(G===null?null:o(100-G)),K=b(Q,d0,!0),X=T(K),Y=X?X.toISOString():null,H=X?L(X.getTime()-$.getTime()):Z1(b(Q,r0,!0)),M={label:Z,remainingPercent:j,usedPercent:z,resetsAt:Y,resetsIn:H};return UZ(M)?M:null}function n(Q,Z){return{status:e0(Q),windows:Q,warnings:Z}}function e0(Q){let Z=[Q.fiveHour,Q.weekly].filter(($)=>UZ($));if(Z.length===0)return"unavailable";return Z.every(Q1)?"available":"partial"}function GZ(Q,Z){let $=Q.find((G)=>E(G.value)===Z);if($)return $.value;return Q.find((G)=>G.fallbackKind===Z&&E(G.value)===null)?.value??null}function qZ(Q,Z){return{fiveHour:JZ(Q.fiveHour,Z.fiveHour,UQ),weekly:JZ(Q.weekly,Z.weekly,NQ)}}function JZ(Q,Z,$){if(!Q&&!Z)return null;return{label:$,remainingPercent:Q?.remainingPercent??Z?.remainingPercent??null,usedPercent:Q?.usedPercent??Z?.usedPercent??null,resetsAt:Q?.resetsAt??Z?.resetsAt??null,resetsIn:Q?.resetsIn??Z?.resetsIn??null}}function UZ(Q){return Q!==null&&(Q.remainingPercent!==null||Q.usedPercent!==null||Q.resetsAt!==null||Q.resetsIn!==null)}function Q1(Q){return Q!==null&&Q.remainingPercent!==null&&Q.usedPercent!==null&&(Q.resetsAt!==null||Q.resetsIn!==null)}function qQ(Q,Z,$=0){if($>KZ)return null;for(let G of Z){let J=Q[G];if(W(J))return J}for(let G of Object.values(Q)){if(!W(G))continue;let J=qQ(G,Z,$+1);if(J)return J}return null}function i(Q,Z){for(let $ of Z){let G=Q[$];if(W(G))return G}return null}function b(Q,Z,$,G=0){if(G>KZ)return;for(let J of Z)if(J in Q)return Q[J];if(!$)return;for(let J of Object.values(Q)){if(!W(J))continue;let z=b(J,Z,$,G+1);if(z!==void 0)return z}return}function zZ(Q){if(typeof Q==="number"&&Number.isFinite(Q))return o(Q);if(typeof Q==="string"&&Q.trim().length>0){let Z=Q.trim(),$=Z.endsWith("%")?Z.slice(0,-1):Z,G=Number($);return Number.isFinite(G)?o(G):null}return null}function o(Q){return Math.round(Math.min(Math.max(Q,0),100)*10)/10}function jZ(Q){if(typeof Q==="number"&&Number.isFinite(Q))return Q;if(typeof Q==="string"&&Q.trim().length>0){let Z=Number(Q);return Number.isFinite(Z)?Z:null}return null}function Z1(Q){let Z=$1(Q);if(!Z||Z.length>100)return null;let G=a0.exec(Z)?.slice(1);if(!G||G.every((j)=>j===void 0))return null;let J=[86400,3600,60,1],z=0;for(let[j,K]of G.entries()){if(K===void 0)continue;let X=Number(K),Y=X*J[j];if(!Number.isSafeInteger(X)||!Number.isSafeInteger(Y))return null;if(z+=Y,!Number.isSafeInteger(z))return null}return z<=Math.floor(Number.MAX_SAFE_INTEGER/1000)?L(z*1000):null}function $1(Q){if(typeof Q==="string"&&Q.trim().length>0)return Q.trim();return null}var G1=5,J1=1000,z1={kind:"unavailable",label:"Unavailable"};function BZ(Q,Z,$){let G=j1(Q)??K1(Q);if(!G)return w(["Live usage endpoint returned an unexpected payload."]);let J=xQ(CQ(G,$),{kind:"api",label:"API",endpoint:Z});if(J.status==="unavailable")return w(["Live usage endpoint returned an unexpected payload."]);if(J.status==="partial")return{...J,warnings:["Live usage endpoint returned incomplete usage data."]};return J}function w(Q){return xQ({fiveHour:null,weekly:null},z1,Q)}function j1(Q){return OZ(Q,(Z)=>{if(!W(Z))return null;let $=Z.rate_limits??Z.rateLimits??Z.rate_limit??Z.rateLimit;if(W($))return $;return YZ(Z)?Z:null})}function K1(Q){return OZ(Q,(Z)=>{if(!Array.isArray(Z))return null;let $=Z.find((J)=>NZ(J,"fiveHour")),G=Z.find((J)=>NZ(J,"weekly"));return $||G?{fiveHour:$,weekly:G}:null})}function OZ(Q,Z){let $=[{value:Q,depth:0}],G=new WeakSet;for(let J=0;J<$.length;J+=1){let z=$[J];if(!z)break;let j=Z(z.value);if(j)return j;if(z.depth>=G1||typeof z.value!=="object"||!z.value)continue;if(G.has(z.value))continue;G.add(z.value);let K=Array.isArray(z.value)?z.value:W(z.value)?Object.values(z.value):[];for(let X of K){if($.length>=J1)break;$.push({value:X,depth:z.depth+1})}}return null}function NZ(Q,Z){if(!W(Q))return!1;let $=E(Q);if($)return $===Z;let G=String(Q.type??Q.kind??Q.name??Q.label??Q.window??"").toLowerCase();return Z==="fiveHour"?G.includes("primary")||G.includes("5-hour")||G.includes("five"):G.includes("secondary")||G.includes("weekly")||G.includes("week")}var X1="https://chatgpt.com/backend-api/codex/usage",Y1=1e4,H1=1e6;async function CZ(Q={}){return(await W1(Q)).usage}async function W1(Q={}){let Z=M1(Q),$=f(Z),G=await u(Q);if(!G.credentials){let j=k(G.diagnostics);return{usage:w(j.length>0?j:["Live usage requires Codex authentication."]),authenticationFound:!1,endpointStatus:"not-checked"}}let J={endpoint:Z,headers:V1(G.credentials),timeoutMs:Q.timeoutMs??Y1,maxResponseBytes:H1,fallbackOnHttpError:!0,...Q.fetch?{fetch:Q.fetch}:{},...Q.signal?{signal:Q.signal}:{}},z;try{z=await(Q.transport??l)(J)}catch{z={ok:!1,code:"network-error",status:null}}return{usage:z.ok?BZ(z.payload,$,Q.now??new Date):U1(z),authenticationFound:!0,endpointStatus:q1(z)}}function V1(Q){return{Authorization:`Bearer ${Q.accessToken}`,"ChatGPT-Account-ID":Q.accountId,"OpenAI-Beta":"codex-1",originator:"Codex Desktop",Accept:"application/json","User-Agent":"Codex Desktop",Referer:"https://chatgpt.com/codex/cloud/settings/analytics",Origin:"https://chatgpt.com"}}function M1(Q){let Z=A(Q.env);return Q.usageEndpoint??U(Z,"CODEX_LIMITS_USAGE_ENDPOINT")??X1}function q1(Q){if(Q.ok)return"reachable";switch(Q.code){case"http-error":case"invalid-json":case"response-too-large":return"reachable";case"aborted":return"not-checked";case"invalid-url":case"network-error":case"timeout":case"unsupported-protocol":return"unreachable"}}function U1(Q){return w(k([r(Q,"Live usage")]))}var N1={kind:"local",label:"Local"};async function xZ(Q={}){let Z=Q.includeCoupons===!1?Promise.resolve(null):$Z(Q),[$,G]=await Promise.all([B1(Q),Z]),J=G?{...G,warnings:a(G.warnings)}:null;return{windows:$.windows,usageSource:$.source,coupons:J,warnings:a([...$.warnings,...J?.warnings??[]])}}async function B1(Q={}){let Z=await CZ(Q);if(Z.status!=="unavailable")return Z;let $=HZ(await C1(Q),N1);return O1(Z,$)}function O1(Q,Z){if(Q.status!=="unavailable")return Q;if(Z.status!=="unavailable")return Z;return{...Z,warnings:[...Q.warnings,...Z.warnings]}}async function C1(Q={}){let Z=Q.now??new Date,$=await g(Q);if(!$.foundHome)return DQ(["No readable local Codex home directory was found."]);let[G,J]=await Promise.all([vQ($.foundHome),pQ($.foundHome)]);return VZ(XZ(G,Z),WZ(J,Z))}var D1="Codex Limits",TZ="Could not load Codex limits.",T1="Could not display Codex limits.";function P1(Q={}){let Z=Q.getLimits??xZ;return($)=>{$.registerCommand("codex-limits",{description:"Check Codex limits, resets, and credits",handler:async(G,J)=>{if(!J.hasUI||J.mode!=="tui")return;J.ui.setStatus("codex-limits","Loading Codex limits...");let z;try{z=IQ(await Z())}catch{z=TZ,J.ui.notify(TZ,"error")}finally{J.ui.setStatus("codex-limits",void 0)}try{await F1(z,J)}catch{J.ui.notify(T1,"error")}}})}}async function F1(Q,Z){await Z.ui.custom(($,G,J,z)=>{let j=PZ(Q,G);return{render:(K)=>j.render(K),invalidate:()=>{j=PZ(Q,G)},handleInput:(K)=>{if(TQ(K,"enter")||TQ(K,"escape")||TQ(K,"ctrl+c"))z(void 0)}}},{overlay:!0,overlayOptions:{width:56,minWidth:36,maxHeight:"90%",margin:1}})}function PZ(Q,Z){let $=new x1;return $.addChild(new DZ((G)=>Z.fg("accent",G))),$.addChild(new PQ(Z.fg("accent",Z.bold(D1)),1,0)),$.addChild(new PQ(Q,1,1)),$.addChild(new PQ(Z.fg("dim","Press Enter or Esc to close"),1,0)),$.addChild(new DZ((G)=>Z.fg("accent",G))),$}var A1=P1(),J3=A1;export{J3 as default,P1 as createPiPlugin};
package/docs/README.md ADDED
@@ -0,0 +1,67 @@
1
+ # Codex Limits Documentation
2
+
3
+ [← Project README](../README.md) · [npm package](https://www.npmjs.com/package/@simonesiega/codex-limits)
4
+
5
+ This documentation is organized by task. The root README is the product overview; the guides below are the canonical references for automation, compatibility, agent integrations, and safe operation.
6
+
7
+ ## Start here
8
+
9
+ - **Installing or using the CLI?** Begin with the [quick start](../README.md#quick-start), then use the [command reference](../README.md#usage).
10
+ - **Writing a script or integration?** Read [JSON output](readme/json-output.md) and use the versioned [JSON Schema](schema/codex-limits.schema.json).
11
+ - **Installing an agent command?** Open the [agent integrations guide](readme/agent-integrations.md), then choose [OpenCode](readme/agents/opencode.md), [pi](readme/agents/pi.md), or [GitHub Copilot CLI](readme/agents/copilot.md).
12
+ - **Diagnosing an environment?** Run `codex-limits doctor`, then check [compatibility](readme/compatibility.md) and [troubleshooting](../README.md#troubleshooting).
13
+ - **Contributing?** Start with [`CONTRIBUTING.md`](../CONTRIBUTING.md) and review the [security policy](../SECURITY.md).
14
+
15
+ ## CLI and automation
16
+
17
+ | Guide | Use it when |
18
+ | ----------------------------------------------- | ----------------------------------------------------------------------------------------- |
19
+ | [Quick start](../README.md#quick-start) | Installing the published package and opening the dashboard for the first time. |
20
+ | [Command reference](../README.md#usage) | Using `status`, `coupons`, `reset`, `doctor`, `agents`, or the compatible `init` command. |
21
+ | [JSON output](readme/json-output.md) | Consuming stable machine-readable limits, coupon, or doctor documents. |
22
+ | [Compatibility](readme/compatibility.md) | Checking Node.js, operating-system, terminal, Codex-data, network, or agent requirements. |
23
+ | [Troubleshooting](../README.md#troubleshooting) | Resolving missing local data, live-usage failures, permissions, or agent discovery. |
24
+
25
+ ## Agent integrations
26
+
27
+ | Guide | Covers |
28
+ | -------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
29
+ | [Agent integrations](readme/agent-integrations.md) | Shared installation modes, privacy guarantees, adapter architecture, and contribution rules. |
30
+ | [OpenCode](readme/agents/opencode.md) | Global configuration, `/codex-limits`, compatibility, removal, and troubleshooting. |
31
+ | [pi](readme/agents/pi.md) | Package registration, themed overlay behavior, host requirements, removal, and troubleshooting. |
32
+ | [GitHub Copilot CLI](readme/agents/copilot.md) | Experimental extension installation, host lifecycle, timeline output, removal, and troubleshooting. |
33
+
34
+ ## Development and security
35
+
36
+ | Guide | Covers |
37
+ | ---------------------------------- | ----------------------------------------------------------------------------------------------------- |
38
+ | [Contributing](../CONTRIBUTING.md) | Repository setup, architecture boundaries, tests, documentation rules, and pull-request expectations. |
39
+ | [Security](../SECURITY.md) | Responsible disclosure, local-data and network boundaries, command safety, and release security. |
40
+ | [Changelog](../CHANGELOG.md) | Released behavior and current unreleased changes. |
41
+
42
+ ## Schemas, examples, and visual assets
43
+
44
+ | Resource | Purpose |
45
+ | ------------------------------------------------------------------ | ----------------------------------------------------------------- |
46
+ | [Complete JSON example](examples/codex-limits-output.example.json) | Sanitized example produced by `codex-limits --json`. |
47
+ | [JSON Schema](schema/codex-limits.schema.json) | Draft 2020-12 schema for validating the complete limits document. |
48
+ | [`photos/`](photos/) | README screenshots and project identity assets. |
49
+
50
+ Visual assets are grouped by purpose:
51
+
52
+ ```text
53
+ photos/
54
+ ├── agents/ # Supported agent integration screenshots
55
+ ├── logo/ # Project identity and animated README title
56
+ └── terminal/ # Responsive terminal dashboard screenshots
57
+ ```
58
+
59
+ ## Documentation conventions
60
+
61
+ - Commands are shown from the repository root unless a guide says otherwise.
62
+ - Keep internal repository links relative and route readers through this hub when no more specific canonical guide exists.
63
+ - Treat the root [Usage](../README.md#usage) section and generated `--help` output as the command reference; do not duplicate complete command procedures across guides.
64
+ - Keep JSON field claims synchronized with [JSON output](readme/json-output.md), the [schema](schema/codex-limits.schema.json), and the sanitized [example](examples/codex-limits-output.example.json).
65
+ - Use placeholders in examples. Never include tokens, account IDs, authorization headers, cookies, private paths, raw Codex files, or unredacted environment values.
66
+ - Use repository-relative image paths and descriptive alt text. Screenshots must contain only synthetic or safely redacted data.
67
+ - Run `bun run docs:check` after documentation changes.
@@ -0,0 +1,63 @@
1
+ {
2
+ "windows": {
3
+ "fiveHour": {
4
+ "label": "5-hour usage limit",
5
+ "remainingPercent": 80,
6
+ "usedPercent": 20,
7
+ "resetsAt": "2026-07-14T01:30:15.000Z",
8
+ "resetsIn": "3h 55m"
9
+ },
10
+ "weekly": {
11
+ "label": "Weekly usage limit",
12
+ "remainingPercent": 31,
13
+ "usedPercent": 69,
14
+ "resetsAt": "2026-07-18T11:15:15.000Z",
15
+ "resetsIn": "4d 13h 40m"
16
+ }
17
+ },
18
+ "coupons": {
19
+ "available": 4,
20
+ "earnedThisPeriod": 0,
21
+ "nextExpirationDate": "Saturday 18 July 2026",
22
+ "nextExpirationIn": "4d 2h 42m",
23
+ "items": [
24
+ {
25
+ "index": 1,
26
+ "status": "available",
27
+ "grantedAt": "2026-06-18T00:17:20.252556Z",
28
+ "expiresAt": "2026-07-18T00:17:20.252556Z",
29
+ "expirationDate": "Saturday 18 July 2026",
30
+ "expiresIn": "4d 2h 42m"
31
+ },
32
+ {
33
+ "index": 2,
34
+ "status": "available",
35
+ "grantedAt": "2026-06-26T23:48:13.132409Z",
36
+ "expiresAt": "2026-07-26T23:48:13.132409Z",
37
+ "expirationDate": "Monday 27 July 2026",
38
+ "expiresIn": "13d 2h 12m"
39
+ },
40
+ {
41
+ "index": 3,
42
+ "status": "available",
43
+ "grantedAt": "2026-07-01T19:59:47.228684Z",
44
+ "expiresAt": "2026-07-31T19:59:47.228684Z",
45
+ "expirationDate": "Friday 31 July 2026",
46
+ "expiresIn": "17d 22h 24m"
47
+ },
48
+ {
49
+ "index": 4,
50
+ "status": "available",
51
+ "grantedAt": "2026-07-13T17:48:41.527506Z",
52
+ "expiresAt": "2026-08-12T17:48:41.527506Z",
53
+ "expirationDate": "Wednesday 12 August 2026",
54
+ "expiresIn": "29d 20h 13m"
55
+ }
56
+ ],
57
+ "warnings": []
58
+ },
59
+ "warnings": [
60
+ "Skipped a sensitive-looking local file.",
61
+ "Skipped a local cache file because it is too large to inspect safely."
62
+ ]
63
+ }
@@ -0,0 +1,81 @@
1
+ # Agent integrations
2
+
3
+ [← Documentation hub](../README.md) · [Project README](../../README.md)
4
+
5
+ This page is the central index for supported agent integrations. Each agent has a dedicated guide covering installation, usage, compatibility, removal, and troubleshooting.
6
+
7
+ `codex-limits` can expose the shared, read-only limits dashboard inside supported coding agents. Integrations remain thin and load normalized data through the same core as the CLI.
8
+
9
+ ## Installing an integration
10
+
11
+ Install the CLI first:
12
+
13
+ ```bash
14
+ npm install -g @simonesiega/codex-limits@latest
15
+ ```
16
+
17
+ Then choose one of the setup modes:
18
+
19
+ ```bash
20
+ # Prompt for each supported integration in an interactive terminal
21
+ codex-limits agents install
22
+
23
+ # Install one or more integrations directly, including in non-interactive terminals
24
+ codex-limits agents install <agent...>
25
+
26
+ # Install every supported integration
27
+ codex-limits agents install --all
28
+
29
+ # Show the agent-management commands or installation help
30
+ codex-limits agents --help
31
+ codex-limits agents install --help
32
+ ```
33
+
34
+ Replace `<agent>` with an identifier from the [Agents](#agents) table. `--all` cannot be combined with agent names. Unknown or duplicate names and unknown options are rejected before any integration is installed.
35
+
36
+ The existing `codex-limits init`, `codex-limits init --<agent-name>`, and `codex-limits init --all` forms remain supported as compatibility syntax and use the same installation flow.
37
+
38
+ After a successful installation, restart the target agent terminal so it reloads its configuration.
39
+
40
+ ## Agents
41
+
42
+ Each agent name links to its dedicated installation, usage, compatibility, and troubleshooting guide.
43
+
44
+ | Agent | Official page | Status | Command | Installer |
45
+ | --------------------------------------- | ----------------------------------------------------------- | --------- | --------------- | -------------------------------------- |
46
+ | [OpenCode](agents/opencode.md) | [opencode.ai](https://opencode.ai/) | Supported | `/codex-limits` | `codex-limits agents install opencode` |
47
+ | [pi](agents/pi.md) | [pi.dev](https://pi.dev/) | Supported | `/codex-limits` | `codex-limits agents install pi` |
48
+ | [GitHub Copilot CLI](agents/copilot.md) | [github/copilot-cli](https://github.com/github/copilot-cli) | Supported | `/codex-limits` | `codex-limits agents install copilot` |
49
+
50
+ ## Data and privacy
51
+
52
+ All agent integrations run the shared `codex-limits` core locally. They do not send prompts or Codex limit data to an LLM. Tokens, account IDs, authorization headers, cookies, raw local files, and private paths are excluded from displayed output.
53
+
54
+ Agent adapters must reuse the shared core rather than independently reading Codex data, resolving credentials, making live requests, or defining redaction rules.
55
+
56
+ ## Adding another agent
57
+
58
+ Agent adapters live under `src/agents/<agent-name>` and use one consistent layout:
59
+
60
+ ```text
61
+ src/agents/<agent-name>/
62
+ ├── format.ts # Thin host-facing wrapper over shared presentation
63
+ ├── install.ts # Bounded configuration install and inspection
64
+ ├── integration.ts # Metadata plus install/inspect registration contract
65
+ └── plugin.ts # Host API adapter that loads the shared core
66
+ ```
67
+
68
+ Register the exported descriptor once in `src/agents/index.ts`. Shared installation commands, generated compatibility help, and doctor diagnostics consume that registry automatically. Put behavior used by multiple agents in `src/agents/shared` rather than duplicating it.
69
+
70
+ New adapters should remain thin, reuse `src/package/core`, avoid sending limit data to an LLM, and include installer, formatter, and host-behavior tests. Each supported integration should also have a dedicated guide under `docs/readme/agents/<agent-name>.md` and an entry in the [Agents](#agents) table.
71
+
72
+ See [Contributing](../../CONTRIBUTING.md#adding-a-new-agent) for the complete contribution checklist.
73
+
74
+ ## Related documentation
75
+
76
+ - [Compatibility](compatibility.md) — Runtime, operating-system, terminal, network, and agent compatibility.
77
+ - [JSON output](json-output.md) — Machine-readable output, fields, warnings, and scripting behavior.
78
+ - [Contributing](../../CONTRIBUTING.md#adding-a-new-agent) — Complete checklist for developing and submitting another agent adapter.
79
+ - [Security policy](../../SECURITY.md) — Local-data safeguards, network behavior, and vulnerability reporting.
80
+ - [Documentation hub](../README.md) — Task-oriented index for CLI, automation, agent, development, and security guides.
81
+ - [Project README](../../README.md) — Product overview, installation, commands, configuration, and troubleshooting.