tokentracker-cli 0.26.5 → 0.26.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.
Files changed (41) hide show
  1. package/dashboard/dist/assets/{ActivityHeatmap-B4vj90T6.js → ActivityHeatmap-CJU00ZDG.js} +1 -1
  2. package/dashboard/dist/assets/{Card-C6hMMI_4.js → Card-D5Ox-4IT.js} +1 -1
  3. package/dashboard/dist/assets/DashboardPage-B5H_NM0T.js +1 -0
  4. package/dashboard/dist/assets/{DevicePage-D0v5ldVS.js → DevicePage-DSN1LzAb.js} +1 -1
  5. package/dashboard/dist/assets/{DialogTitle-c_QAGVA6.js → DialogTitle-VKNbCFwz.js} +1 -1
  6. package/dashboard/dist/assets/{FadeIn-B9CRmzqf.js → FadeIn-CaqdKWxF.js} +1 -1
  7. package/dashboard/dist/assets/{HeaderGithubStar-CNgvRCUc.js → HeaderGithubStar-ttDv-mT0.js} +1 -1
  8. package/dashboard/dist/assets/{IpCheckPage-BV2SZxBg.js → IpCheckPage-BC577uie.js} +1 -1
  9. package/dashboard/dist/assets/{LandingPage-Bk3xCXel.js → LandingPage-Ct80In4B.js} +1 -1
  10. package/dashboard/dist/assets/{LeaderboardAvatar-kZAxtPgR.js → LeaderboardAvatar-rDCsYbZu.js} +1 -1
  11. package/dashboard/dist/assets/{LeaderboardPage-CoONwoqy.js → LeaderboardPage-CghEOSwv.js} +3 -3
  12. package/dashboard/dist/assets/{LeaderboardProfileModal-CntlcMb5.js → LeaderboardProfileModal-ek3za8go.js} +1 -1
  13. package/dashboard/dist/assets/{LeaderboardProfilePage-BPEbL1AU.js → LeaderboardProfilePage-D-Y1E47W.js} +1 -1
  14. package/dashboard/dist/assets/{LimitsPage-hVKBqUjr.js → LimitsPage-Lp0Rd695.js} +1 -1
  15. package/dashboard/dist/assets/{LocalOnlyNotice-rmwpfmHR.js → LocalOnlyNotice-2u7424xK.js} +1 -1
  16. package/dashboard/dist/assets/{LoginPage-BpduG_WF.js → LoginPage-BKsFo757.js} +1 -1
  17. package/dashboard/dist/assets/{PopoverPopup-Dbv8XdJH.js → PopoverPopup-Bs1LZcBw.js} +1 -1
  18. package/dashboard/dist/assets/{ProviderIcon-DSkT5k6O.js → ProviderIcon-DBXRoAM4.js} +1 -1
  19. package/dashboard/dist/assets/{SettingsPage-Wx9gFT4s.js → SettingsPage-CUQDLbpd.js} +1 -1
  20. package/dashboard/dist/assets/{SkillsPage-C1mG0Yg0.js → SkillsPage-DYzYFpB5.js} +1 -1
  21. package/dashboard/dist/assets/{WidgetsPage-CcV2p0y8.js → WidgetsPage-DTs7ozuv.js} +1 -1
  22. package/dashboard/dist/assets/{WrappedPage-JMG44YOJ.js → WrappedPage-DMZBbiTc.js} +1 -1
  23. package/dashboard/dist/assets/{arrow-up-right-Cyexf2d_.js → arrow-up-right-CwqMY1R4.js} +1 -1
  24. package/dashboard/dist/assets/check-BSgM0Ug5.js +1 -0
  25. package/dashboard/dist/assets/{chevron-down-Ca1Vw8XB.js → chevron-down-B_tZ2Od9.js} +1 -1
  26. package/dashboard/dist/assets/{download-Du66ZCdA.js → download-DnhYDPq0.js} +1 -1
  27. package/dashboard/dist/assets/{info-FuzeQ_-E.js → info-C6H3Gand.js} +1 -1
  28. package/dashboard/dist/assets/{main-D6Cw0vCf.js → main-V4PbS8FA.js} +2 -2
  29. package/dashboard/dist/assets/{use-limits-display-prefs-DiZDjG-W.js → use-limits-display-prefs-axbS8qU9.js} +1 -1
  30. package/dashboard/dist/assets/{use-native-settings-BJEB_imh.js → use-native-settings-DpwXv8RZ.js} +1 -1
  31. package/dashboard/dist/assets/{use-reduced-motion-B3DdtuWo.js → use-reduced-motion-B4VOeOuI.js} +1 -1
  32. package/dashboard/dist/assets/{use-usage-limits-q5qxlmRD.js → use-usage-limits-DnLWYRTP.js} +1 -1
  33. package/dashboard/dist/assets/{useCurrency-C0DVD_kj.js → useCurrency-De9Dp4pF.js} +1 -1
  34. package/dashboard/dist/index.html +1 -1
  35. package/dashboard/dist/share.html +1 -1
  36. package/package.json +1 -1
  37. package/src/lib/cursor-config.js +12 -1
  38. package/src/lib/local-api.js +25 -5
  39. package/src/lib/pricing/seed-snapshot.json +1 -1
  40. package/dashboard/dist/assets/DashboardPage-DJcrfsmC.js +0 -1
  41. package/dashboard/dist/assets/check-Ctq0msxB.js +0 -1
@@ -1 +1 @@
1
- import{r as a}from"./main-D6Cw0vCf.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};
1
+ import{r as a}from"./main-V4PbS8FA.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};
@@ -1 +1 @@
1
- import{C as a,S as x,r as n,aG as g,aH as m,aI as b,aJ as u,aK as f,aE as h}from"./main-D6Cw0vCf.js";import{C as y}from"./Card-C6hMMI_4.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};
1
+ import{C as a,S as x,r as n,aG as g,aH as m,aI as b,aJ as u,aK as f,aE as h}from"./main-V4PbS8FA.js";import{C as y}from"./Card-D5Ox-4IT.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};
@@ -1 +1 @@
1
- import{aL as t,aM as o,r,aN as s}from"./main-D6Cw0vCf.js";function u(){!t.current&&o();const[e]=r.useState(s.current);return e}export{u};
1
+ import{aL as t,aM as o,r,aN as s}from"./main-V4PbS8FA.js";function u(){!t.current&&o();const[e]=r.useState(s.current);return e}export{u};
@@ -1 +1 @@
1
- import{r,am as l}from"./main-D6Cw0vCf.js";function m(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{m as u};
1
+ import{r,am as l}from"./main-V4PbS8FA.js";function m(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{m as u};
@@ -1 +1 @@
1
- import{r as e,aB as t,aC as r,H as c}from"./main-D6Cw0vCf.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};
1
+ import{r as e,aB as t,aC as r,H as c}from"./main-V4PbS8FA.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-D6Cw0vCf.js"></script>
213
+ <script type="module" crossorigin src="/assets/main-V4PbS8FA.js"></script>
214
214
  <link rel="stylesheet" crossorigin href="/assets/main-smnMFIqE.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-D6Cw0vCf.js"></script>
54
+ <script type="module" crossorigin src="/assets/main-V4PbS8FA.js"></script>
55
55
  <link rel="stylesheet" crossorigin href="/assets/main-smnMFIqE.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.26.5",
3
+ "version": "0.26.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": {
@@ -347,7 +347,18 @@ function normalizeCursorUsage(record) {
347
347
  output_tokens: outputTokens,
348
348
  reasoning_output_tokens: 0,
349
349
  total_tokens: totalTokens,
350
- billable_total_tokens: isCursorBillableKind(record?.kind) ? totalTokens : 0,
350
+ // Usage tracking and billing are orthogonal: a Cursor Enterprise /
351
+ // Included-in-Pro request still consumes tokens even when the user
352
+ // pays nothing for them. Cost is computed independently from
353
+ // per-column tokens × MODEL_PRICING (see computeRowCost — it never
354
+ // reads this field), while the dashboard headline reads
355
+ // billable_total_tokens. Writing 0 here silently hides non-billable
356
+ // Cursor usage from the headline once any other source pushes the
357
+ // aggregate billable above 0 (see GitHub issue #106).
358
+ // isCursorBillableKind is retained for a future paid-vs-included
359
+ // breakdown via a separate is_billable field, not by overloading the
360
+ // token count.
361
+ billable_total_tokens: totalTokens,
351
362
  };
352
363
  }
353
364
 
@@ -91,11 +91,31 @@ function isLegacyInclusiveCodexRow(row) {
91
91
  }
92
92
 
93
93
  function normalizeQueueRow(row) {
94
- if (!isLegacyInclusiveCodexRow(row)) return row;
95
- return {
96
- ...row,
97
- input_tokens: Number(row.input_tokens || 0) - Number(row.cached_input_tokens || 0),
98
- };
94
+ let normalized = row;
95
+ if (isLegacyInclusiveCodexRow(normalized)) {
96
+ normalized = {
97
+ ...normalized,
98
+ input_tokens:
99
+ Number(normalized.input_tokens || 0) - Number(normalized.cached_input_tokens || 0),
100
+ };
101
+ }
102
+ // Legacy Cursor rows from versions ≤ 0.26.5 wrote billable_total_tokens = 0
103
+ // for "Included in Pro" / "Enterprise" / "no charge" records (kind-based
104
+ // gating in cursor-config.js#normalizeCursorUsage). The dashboard headline
105
+ // sums billable_total_tokens across sources, so those rows silently
106
+ // disappeared from the displayed total once any other source contributed
107
+ // non-zero billable usage (GitHub issue #106). Treat billing and usage as
108
+ // orthogonal: bump billable up to total_tokens at read time so historical
109
+ // queue.jsonl entries render correctly without requiring a file rewrite.
110
+ const sourceName = String(normalized.source || "").toLowerCase();
111
+ if (sourceName === "cursor") {
112
+ const totalTokens = Number(normalized.total_tokens || 0);
113
+ const billable = Number(normalized.billable_total_tokens || 0);
114
+ if (totalTokens > 0 && billable < totalTokens) {
115
+ normalized = { ...normalized, billable_total_tokens: totalTokens };
116
+ }
117
+ }
118
+ return normalized;
99
119
  }
100
120
 
101
121
  function readQueueData(queuePath) {