tokentracker-cli 0.24.5 → 0.24.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dashboard/dist/assets/{Card-Dmmj336P.js → Card-BfayTmBt.js} +1 -1
- package/dashboard/dist/assets/{DashboardPage-BHYKJEV6.js → DashboardPage-C_ExwqoB.js} +1 -1
- package/dashboard/dist/assets/{DevicePage-DwsKn4Ov.js → DevicePage-Bzc-tOQ7.js} +1 -1
- package/dashboard/dist/assets/{FadeIn-B8VmShpI.js → FadeIn-C1nCEQAI.js} +1 -1
- package/dashboard/dist/assets/{HeaderGithubStar-B_KecfbF.js → HeaderGithubStar-CalgbIws.js} +1 -1
- package/dashboard/dist/assets/{IpCheckPage-BgG1wCTr.js → IpCheckPage-C2_FdWEa.js} +1 -1
- package/dashboard/dist/assets/{LandingPage-ql_hYK8I.js → LandingPage-Cab2gSJk.js} +1 -1
- package/dashboard/dist/assets/{LeaderboardPage-D_jXlgYG.js → LeaderboardPage-BoWSvv8E.js} +1 -1
- package/dashboard/dist/assets/{LeaderboardProfilePage-DFUaU6I1.js → LeaderboardProfilePage-BxvvRB0p.js} +1 -1
- package/dashboard/dist/assets/{LimitsPage-mQdxcN_z.js → LimitsPage-JTd7ZYkv.js} +1 -1
- package/dashboard/dist/assets/{LoginPage-D1lzth57.js → LoginPage-fU320alu.js} +1 -1
- package/dashboard/dist/assets/{PopoverPopup-DIB4uXcd.js → PopoverPopup-C76-ba7G.js} +1 -1
- package/dashboard/dist/assets/{ProviderIcon-CFDBvFyw.js → ProviderIcon-xv4cUgTy.js} +1 -1
- package/dashboard/dist/assets/{SettingsPage-BN1OqYbm.js → SettingsPage-UtWH1_mF.js} +1 -1
- package/dashboard/dist/assets/{SkillsPage-wBzXeval.js → SkillsPage-9W2jGGps.js} +1 -1
- package/dashboard/dist/assets/{WidgetsPage-DhZSen2-.js → WidgetsPage-BedujTKv.js} +1 -1
- package/dashboard/dist/assets/{WrappedPage-DhDlrrUL.js → WrappedPage-Bms62oTH.js} +1 -1
- package/dashboard/dist/assets/check-DHKWR9eH.js +1 -0
- package/dashboard/dist/assets/{chevron-down-bXSVV-pK.js → chevron-down-g6db-hJJ.js} +1 -1
- package/dashboard/dist/assets/{download-DvJmehef.js → download-UDqrzLfH.js} +1 -1
- package/dashboard/dist/assets/{info-lgmn3oZc.js → info-BB9X3uhm.js} +1 -1
- package/dashboard/dist/assets/{leaderboard-columns-Bbx3-Y6N.js → leaderboard-columns-CTGzd-uH.js} +1 -1
- package/dashboard/dist/assets/{main-DVwx7yxG.js → main-QPJFCBQm.js} +2 -2
- package/dashboard/dist/assets/{use-limits-display-prefs-CeHiE8M0.js → use-limits-display-prefs-DccYvUNZ.js} +1 -1
- package/dashboard/dist/assets/{use-native-settings-iXw-cXKZ.js → use-native-settings-DAbSUv-n.js} +1 -1
- package/dashboard/dist/assets/{use-reduced-motion-BWHrwYlb.js → use-reduced-motion-B_GaKtWC.js} +1 -1
- package/dashboard/dist/assets/{use-usage-limits-DPaSUkzX.js → use-usage-limits-3pTcFcoF.js} +1 -1
- package/dashboard/dist/assets/{useCurrency-DqvOkq1e.js → useCurrency-CLZ2MqvV.js} +1 -1
- package/dashboard/dist/index.html +1 -1
- package/dashboard/dist/share.html +1 -1
- package/package.json +1 -1
- package/src/lib/local-api.js +66 -19
- package/src/lib/pricing/seed-snapshot.json +1 -1
- package/dashboard/dist/assets/check-MvbdiVTJ.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as a}from"./main-
|
|
1
|
+
import{r as a}from"./main-QPJFCBQm.js";const d=["claude","codex","cursor","gemini","kimi","kiro","copilot","antigravity"],S={claude:"Claude",codex:"Codex",cursor:"Cursor",gemini:"Gemini",kimi:"Kimi",kiro:"Kiro",copilot:"GitHub Copilot",antigravity:"Antigravity"},v={claude:"/brand-logos/claude-code.svg",codex:"/brand-logos/codex.svg",cursor:"/brand-logos/cursor.svg",gemini:"/brand-logos/gemini.svg",kimi:"/brand-logos/kimi.svg",kiro:"/brand-logos/kiro.svg",copilot:"/brand-logos/copilot.svg",antigravity:"/brand-logos/antigravity.svg"},l="tt.limits.providerOrder",g="tt.limits.providerVisibility";function w(){if(typeof window>"u")return[...d];try{const i=window.localStorage.getItem(l);if(!i)return[...d];const s=JSON.parse(i);if(!Array.isArray(s))return[...d];const r=s.filter(c=>d.includes(c));for(const c of d)r.includes(c)||r.push(c);return r}catch{return[...d]}}function y(){const i=Object.fromEntries(d.map(s=>[s,!0]));if(typeof window>"u")return i;try{const s=window.localStorage.getItem(g);if(!s)return i;const r=JSON.parse(s);if(!r||typeof r!="object")return i;const c={...i};for(const u of d)typeof r[u]=="boolean"&&(c[u]=r[u]);return c}catch{return i}}function C(){const[i,s]=a.useState(w),[r,c]=a.useState(y);a.useEffect(()=>{if(!(typeof window>"u"))try{window.localStorage.setItem(l,JSON.stringify(i))}catch{}},[i]),a.useEffect(()=>{if(!(typeof window>"u"))try{window.localStorage.setItem(g,JSON.stringify(r))}catch{}},[r]),a.useEffect(()=>{if(typeof window>"u")return;const o=t=>{t.key===l&&s(w()),t.key===g&&c(y())};return window.addEventListener("storage",o),()=>window.removeEventListener("storage",o)},[]);const u=a.useCallback(o=>{c(t=>({...t,[o]:!t[o]}))},[]),b=a.useCallback(o=>{s(t=>{const e=t.indexOf(o);if(e<=0)return t;const n=[...t];return[n[e-1],n[e]]=[n[e],n[e-1]],n})},[]),p=a.useCallback(o=>{s(t=>{const e=t.indexOf(o);if(e<0||e>=t.length-1)return t;const n=[...t];return[n[e],n[e+1]]=[n[e+1],n[e]],n})},[]),O=a.useCallback((o,t)=>{o!==t&&s(e=>{const n=e.indexOf(o),m=e.indexOf(t);if(n<0||m<0)return e;const f=[...e],[I]=f.splice(n,1);return f.splice(m,0,I),f})},[]),k=a.useCallback(()=>{s([...d]),c(Object.fromEntries(d.map(o=>[o,!0])))},[]),x=a.useMemo(()=>i.filter(o=>r[o]!==!1),[i,r]);return{order:i,visibility:r,visibleOrdered:x,toggle:u,moveUp:b,moveDown:p,moveToward:O,reset:k}}export{v as L,S as a,C as u};
|
package/dashboard/dist/assets/{use-native-settings-iXw-cXKZ.js → use-native-settings-DAbSUv-n.js}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{C as a,a7 as x,r as n,aH as g,aI as m,aJ as b,aK as u,aL as f,aF as h}from"./main-
|
|
1
|
+
import{C as a,a7 as x,r as n,aH as g,aI as m,aJ as b,aK as u,aL as f,aF as h}from"./main-QPJFCBQm.js";import{C as y}from"./Card-BfayTmBt.js";function p({checked:s,onChange:t,disabled:e,ariaLabel:i}){return a.jsx("button",{type:"button",role:"switch","aria-checked":s,"aria-label":i,onClick:t,disabled:e,className:x("relative inline-flex h-5 w-9 shrink-0 items-center rounded-full transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-oai-brand-500 disabled:opacity-50 disabled:cursor-not-allowed",s?"bg-oai-brand-500":"bg-oai-gray-300 dark:bg-oai-gray-700"),children:a.jsx("span",{className:x("inline-block h-3.5 w-3.5 rounded-full bg-white transition-transform",s?"translate-x-[18px]":"translate-x-[3px]")})})}function j({label:s,hint:t,control:e}){return a.jsxs("div",{className:"flex items-center justify-between gap-4 py-3",children:[a.jsxs("div",{className:"min-w-0 flex-1",children:[a.jsx("div",{className:"text-sm text-oai-gray-900 dark:text-oai-gray-200",children:s}),t?a.jsx("div",{className:"mt-0.5 text-xs text-oai-gray-500 dark:text-oai-gray-400",children:t}):null]}),a.jsx("div",{className:"shrink-0",children:e})]})}function N({title:s,subtitle:t,action:e,children:i}){return a.jsxs(y,{children:[a.jsxs("div",{className:"mb-3 flex items-start justify-between gap-4",children:[a.jsxs("div",{className:"min-w-0 flex-1",children:[a.jsx("h2",{className:"text-sm font-medium text-oai-gray-500 dark:text-oai-gray-300 uppercase tracking-wide",children:s}),t?a.jsx("p",{className:"mt-1 truncate text-xs text-oai-gray-500 dark:text-oai-gray-400",children:t}):null]}),e?a.jsx("div",{className:"shrink-0",children:e}):null]}),a.jsx("div",{className:"-mb-3 divide-y divide-oai-gray-200/60 dark:divide-oai-gray-800/60",children:i})]})}function w({options:s,value:t,onChange:e}){return a.jsx("div",{className:"inline-flex items-center rounded-lg border border-oai-gray-200 bg-oai-gray-50 p-0.5 dark:border-oai-gray-800 dark:bg-oai-gray-900",children:s.map(({value:i,label:d,Icon:l})=>{const r=t===i;return a.jsxs("button",{type:"button",onClick:()=>e(i),"aria-pressed":r,className:x("inline-flex items-center gap-1.5 rounded-md px-3 py-1.5 text-xs font-medium transition-colors",r?"bg-white text-oai-black shadow-sm dark:bg-oai-gray-800 dark:text-white":"text-oai-gray-500 hover:text-oai-black dark:text-oai-gray-400 dark:hover:text-white"),children:[l?a.jsx(l,{className:"h-3.5 w-3.5","aria-hidden":!0}):null,a.jsx("span",{children:d})]},i)})})}function S(){const[s,t]=n.useState(null),e=g()&&m();n.useEffect(()=>{if(!e)return;const r=b(o=>t(o));return u(),r},[e]);const i=n.useCallback((r,o)=>{e&&(t(c=>c&&{...c,[r]:o}),f(r,o))},[e]),d=n.useCallback(r=>{e&&h(r)},[e]),l=n.useCallback(()=>{e&&u()},[e]);return{available:e,settings:s,setSetting:i,runAction:d,refresh:l}}export{N as S,p as T,j as a,w as b,S as u};
|
package/dashboard/dist/assets/{use-reduced-motion-BWHrwYlb.js → use-reduced-motion-B_GaKtWC.js}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{aM as t,aN as o,r,aO as s}from"./main-
|
|
1
|
+
import{aM as t,aN as o,r,aO as s}from"./main-QPJFCBQm.js";function u(){!t.current&&o();const[e]=r.useState(s.current);return e}export{u};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r,al as l}from"./main-
|
|
1
|
+
import{r,al as l}from"./main-QPJFCBQm.js";function y(i){const[o,a]=r.useState(null),[u,s]=r.useState(null),[c,f]=r.useState(!0),n=!!i?.initialRefresh,g=r.useCallback(async()=>{try{const e=await l({refresh:!0});a(e&&typeof e=="object"?e:null),s(null)}catch(e){s(e?.message||String(e))}},[]);return r.useEffect(()=>{let e=!1;return(async()=>{try{const t=await l(n?{refresh:!0}:{});if(e)return;a(t&&typeof t=="object"?t:null),s(null)}catch(t){if(e)return;s(t?.message||String(t))}finally{e||f(!1)}})(),()=>{e=!0}},[n]),{data:o,error:u,isLoading:c,refresh:g}}export{y as u};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as e,aA as t,aB as r,I as c}from"./main-
|
|
1
|
+
import{r as e,aA as t,aB as r,I as c}from"./main-QPJFCBQm.js";const a=Object.freeze({currency:c,rate:1,symbol:"$",rates:{...r},rateSource:"default",rateFetchedAt:null,setCurrency:()=>{}});function u(){return e.useContext(t)??a}export{u};
|
|
@@ -210,7 +210,7 @@
|
|
|
210
210
|
]
|
|
211
211
|
}
|
|
212
212
|
</script>
|
|
213
|
-
<script type="module" crossorigin src="/assets/main-
|
|
213
|
+
<script type="module" crossorigin src="/assets/main-QPJFCBQm.js"></script>
|
|
214
214
|
<link rel="stylesheet" crossorigin href="/assets/main-C8k06i2w.css">
|
|
215
215
|
</head>
|
|
216
216
|
<body>
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"description": "Shareable Token Tracker dashboard snapshot."
|
|
52
52
|
}
|
|
53
53
|
</script>
|
|
54
|
-
<script type="module" crossorigin src="/assets/main-
|
|
54
|
+
<script type="module" crossorigin src="/assets/main-QPJFCBQm.js"></script>
|
|
55
55
|
<link rel="stylesheet" crossorigin href="/assets/main-C8k06i2w.css">
|
|
56
56
|
</head>
|
|
57
57
|
<body>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tokentracker-cli",
|
|
3
|
-
"version": "0.24.
|
|
3
|
+
"version": "0.24.6",
|
|
4
4
|
"description": "Token usage tracker for AI agent CLIs (Claude Code, Codex, Cursor, Gemini, Kiro, OpenCode, OpenClaw, Every Code, Hermes, GitHub Copilot, Kimi Code, CodeBuddy, Grok Build, oh-my-pi, pi, Craft Agents, Kilo CLI, Kilo Code, Roo Code, Zed Agent, Goose)",
|
|
5
5
|
"main": "src/cli.js",
|
|
6
6
|
"bin": {
|
package/src/lib/local-api.js
CHANGED
|
@@ -653,6 +653,67 @@ function json(res, data, status) {
|
|
|
653
653
|
const IP_CHECK_PROXY_PREFIX = "/proxy/ipcheck";
|
|
654
654
|
const IP_CHECK_TARGET = "https://ip.net.coffee";
|
|
655
655
|
|
|
656
|
+
// HTTP hop-by-hop headers (RFC 7230 §6.1) plus headers undici/fetch manages
|
|
657
|
+
// internally. Forwarding any of these to `fetch(...)` either silently breaks
|
|
658
|
+
// the request (host being wrong) or, on stricter undici versions like the
|
|
659
|
+
// 6.24.1 shipped with Node 22.22.2, throws UND_ERR_INVALID_ARG and turns
|
|
660
|
+
// every proxied POST into a 502. Keep this set authoritative for every
|
|
661
|
+
// reverse-proxy site in this module.
|
|
662
|
+
const HOP_BY_HOP_HEADERS = new Set([
|
|
663
|
+
"host",
|
|
664
|
+
"connection",
|
|
665
|
+
"keep-alive",
|
|
666
|
+
"content-length",
|
|
667
|
+
"transfer-encoding",
|
|
668
|
+
"upgrade",
|
|
669
|
+
"proxy-authorization",
|
|
670
|
+
"proxy-authenticate",
|
|
671
|
+
"proxy-connection",
|
|
672
|
+
"te",
|
|
673
|
+
"trailer",
|
|
674
|
+
"trailers",
|
|
675
|
+
]);
|
|
676
|
+
|
|
677
|
+
// Strip forbidden + hop-by-hop headers when forwarding an inbound request to
|
|
678
|
+
// fetch(). Honours the Connection header's named-headers list (RFC 7230 §6.1)
|
|
679
|
+
// so values like `Connection: keep-alive, x-custom` also drop x-custom.
|
|
680
|
+
function buildProxyHeaders(headers) {
|
|
681
|
+
const entries =
|
|
682
|
+
headers && typeof headers.entries === "function"
|
|
683
|
+
? Array.from(headers.entries())
|
|
684
|
+
: Object.entries(headers || {});
|
|
685
|
+
|
|
686
|
+
const connectionNamed = new Set();
|
|
687
|
+
const normalized = [];
|
|
688
|
+
for (const [rawKey, rawValue] of entries) {
|
|
689
|
+
if (rawValue == null) continue;
|
|
690
|
+
const key = String(rawKey).toLowerCase();
|
|
691
|
+
normalized.push([key, rawValue]);
|
|
692
|
+
if (key === "connection") {
|
|
693
|
+
const values = Array.isArray(rawValue) ? rawValue : [rawValue];
|
|
694
|
+
for (const v of values) {
|
|
695
|
+
String(v)
|
|
696
|
+
.split(",")
|
|
697
|
+
.map((part) => part.trim().toLowerCase())
|
|
698
|
+
.filter(Boolean)
|
|
699
|
+
.forEach((part) => connectionNamed.add(part));
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
const out = {};
|
|
705
|
+
for (const [key, rawValue] of normalized) {
|
|
706
|
+
if (HOP_BY_HOP_HEADERS.has(key) || connectionNamed.has(key)) continue;
|
|
707
|
+
if (Array.isArray(rawValue)) {
|
|
708
|
+
const joined = rawValue.filter((e) => e != null).map(String).join(", ");
|
|
709
|
+
if (joined) out[key] = joined;
|
|
710
|
+
continue;
|
|
711
|
+
}
|
|
712
|
+
out[key] = String(rawValue);
|
|
713
|
+
}
|
|
714
|
+
return out;
|
|
715
|
+
}
|
|
716
|
+
|
|
656
717
|
// ---------------------------------------------------------------------------
|
|
657
718
|
// Main handler factory
|
|
658
719
|
// ---------------------------------------------------------------------------
|
|
@@ -880,23 +941,7 @@ function createLocalApiHandler({ queuePath }) {
|
|
|
880
941
|
const insforgeBase = runtime.baseUrl || DEFAULT_BASE_URL;
|
|
881
942
|
try {
|
|
882
943
|
const targetUrl = `${insforgeBase.replace(/\/$/, "")}${p}${url.search || ""}`;
|
|
883
|
-
const proxyHeaders =
|
|
884
|
-
for (const [key, value] of Object.entries(req.headers)) {
|
|
885
|
-
// Skip headers undici/fetch manages internally. Forwarding the
|
|
886
|
-
// inbound content-length (which describes the request body received
|
|
887
|
-
// here, not what we're about to send) causes undici to throw
|
|
888
|
-
// UND_ERR_INVALID_ARG "invalid content-length header" on every POST,
|
|
889
|
-
// turning every /api/auth/* mutation into a 502 — bug present since
|
|
890
|
-
// this relay was introduced and surfaced after Node updates made
|
|
891
|
-
// undici stricter about forbidden headers.
|
|
892
|
-
if (
|
|
893
|
-
key === "host" ||
|
|
894
|
-
key === "connection" ||
|
|
895
|
-
key === "content-length" ||
|
|
896
|
-
key === "transfer-encoding"
|
|
897
|
-
) continue;
|
|
898
|
-
proxyHeaders[key] = value;
|
|
899
|
-
}
|
|
944
|
+
const proxyHeaders = buildProxyHeaders(req.headers);
|
|
900
945
|
const hasClientCookie = normalizeCookieHeader(proxyHeaders["cookie"]).trim().length > 0;
|
|
901
946
|
const hasCsrfHeader = typeof proxyHeaders["x-csrf-token"] === "string" && proxyHeaders["x-csrf-token"].trim().length > 0;
|
|
902
947
|
const relayCsrfToken = getRelayCookieValue(csrfRelayCookieName);
|
|
@@ -1013,9 +1058,11 @@ function createLocalApiHandler({ queuePath }) {
|
|
|
1013
1058
|
const targetUrl = `${IP_CHECK_TARGET}${targetPath}${url.search || ""}`;
|
|
1014
1059
|
try {
|
|
1015
1060
|
// Whitelist forwarded headers — no cookies, no auth, no fingerprintable
|
|
1016
|
-
// identity. Only what the upstream needs to negotiate content.
|
|
1061
|
+
// identity. Only what the upstream needs to negotiate content. Do not
|
|
1062
|
+
// set `host` explicitly: undici derives it from the URL, and some
|
|
1063
|
+
// versions reject a manual host header on fetch() (same forbidden-
|
|
1064
|
+
// header family that broke /api/auth/* in 5/13).
|
|
1017
1065
|
const proxyHeaders = {
|
|
1018
|
-
host: "ip.net.coffee",
|
|
1019
1066
|
accept: req.headers["accept"] || "*/*",
|
|
1020
1067
|
"accept-language": req.headers["accept-language"] || "en",
|
|
1021
1068
|
"accept-encoding": req.headers["accept-encoding"] || "gzip",
|