ccgauge 0.4.0 → 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.
- package/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/app-build-manifest.json +42 -42
- package/.next/standalone/.next/app-path-routes-manifest.json +7 -7
- package/.next/standalone/.next/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/blocks/route.js +1 -1
- package/.next/standalone/.next/server/app/api/blocks/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/export/usage/route.js +1 -1
- package/.next/standalone/.next/server/app/api/export/usage/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/export/usage/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/pricing/route.js +1 -1
- package/.next/standalone/.next/server/app/api/pricing/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/route.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/scan/route.js +1 -1
- package/.next/standalone/.next/server/app/api/scan/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/sessions/route.js +1 -1
- package/.next/standalone/.next/server/app/api/sessions/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/usage/route.js +1 -1
- package/.next/standalone/.next/server/app/api/usage/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/models/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/page.js +2 -2
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/projects/[id]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/projects/page.js +1 -1
- package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/sessions/[id]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/sessions/page.js +1 -1
- package/.next/standalone/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/settings/page.js +2 -2
- package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/usage/page.js +2 -2
- package/.next/standalone/.next/server/app/usage/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app-paths-manifest.json +7 -7
- package/.next/standalone/.next/server/chunks/426.js +9 -4
- package/.next/standalone/.next/server/chunks/716.js +1 -1
- package/.next/standalone/.next/server/chunks/775.js +1 -1
- package/.next/standalone/.next/server/functions-config-manifest.json +3 -3
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/.next/static/chunks/148-557ee562aff993b1.js +1 -0
- package/.next/standalone/.next/static/chunks/app/{error-89ee9e078058915d.js → error-3e48784f89c5ae8d.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/layout-6c973d790f015707.js +1 -0
- package/.next/standalone/.next/static/chunks/app/models/page-dff43b9050382020.js +1 -0
- package/.next/standalone/.next/static/chunks/app/page-6d87d7a8aa752100.js +1 -0
- package/.next/standalone/.next/static/chunks/app/projects/[id]/page-3f812f0e20137f2b.js +1 -0
- package/.next/standalone/.next/static/chunks/app/sessions/[id]/page-3f812f0e20137f2b.js +1 -0
- package/.next/standalone/.next/static/chunks/app/settings/{page-334168b522eac1b1.js → page-d1af886a5c22af9b.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/usage/page-26297e0641d51da8.js +1 -0
- package/.next/standalone/.next/static/css/b07523b7c353538d.css +3 -0
- package/.next/standalone/node_modules/next/node_modules/postcss/package.json +0 -0
- package/.next/standalone/package.json +15 -4
- package/CHANGELOG.md +147 -0
- package/README.md +41 -2
- package/README.zh-CN.md +39 -2
- package/bin/cli.mjs +83 -3
- package/dist/mcp/server.mjs +71 -29
- package/dist/report/index.mjs +2098 -0
- package/package.json +26 -17
- package/.next/standalone/.next/static/chunks/454-d0e7d0fa6f643c41.js +0 -1
- package/.next/standalone/.next/static/chunks/app/layout-a6e30ba3a7f39737.js +0 -1
- package/.next/standalone/.next/static/chunks/app/models/page-e0e1b5979547421a.js +0 -1
- package/.next/standalone/.next/static/chunks/app/page-9347dfa20dabb24b.js +0 -1
- package/.next/standalone/.next/static/chunks/app/projects/[id]/page-5804875e3dc384df.js +0 -1
- package/.next/standalone/.next/static/chunks/app/sessions/[id]/page-5804875e3dc384df.js +0 -1
- package/.next/standalone/.next/static/chunks/app/usage/page-7789fec27778df9a.js +0 -1
- package/.next/standalone/.next/static/css/c34cd36ce5fc39e2.css +0 -3
- /package/.next/standalone/.next/static/{w_l54xHgbhALYXmZcmUxC → ZPycmg0NLiIflO5NXMT75}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{w_l54xHgbhALYXmZcmUxC → ZPycmg0NLiIflO5NXMT75}/_ssgManifest.js +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[430],{1189:(e,t,r)=>{"use strict";r.d(t,{V:()=>o});var a=r(95155),n=r(20063),s=r(12115),l=r(25016),i=r(51148);function o(e){let{paramKey:t,defaultValue:r,options:o,ariaLabel:c}=e,d=(0,n.useRouter)(),u=(0,n.usePathname)(),m=(0,n.useSearchParams)(),x=(0,i.kj)(),h=m.get(t)||r,p=o.some(e=>e.value===h)?h:r,b=(0,s.useRef)(null);function g(e){let r=new URLSearchParams(m.toString());r.set(t,e),d.push("".concat(u,"?").concat(r.toString()))}return(0,a.jsx)("div",{ref:b,role:"radiogroup","aria-label":c,onKeyDown:function(e){var t,r;if("ArrowLeft"!==e.key&&"ArrowRight"!==e.key)return;e.preventDefault();let a=(o.findIndex(e=>e.value===p)+("ArrowRight"===e.key?1:-1)+o.length)%o.length;g(o[a].value);let n=null==(t=b.current)?void 0:t.querySelectorAll('button[role="radio"]');null==n||null==(r=n[a])||r.focus()},className:"inline-flex rounded-button border border-border bg-bg-surface p-0.5 gap-0.5",children:o.map(e=>{let t=p===e.value;return(0,a.jsx)("button",{role:"radio","aria-checked":t,tabIndex:t?0:-1,onClick:()=>g(e.value),className:(0,l.cn)("px-2.5 py-1 text-xs rounded transition-all","focus:outline-none focus-visible:ring-2 focus-visible:ring-brand/40",t?"bg-brand text-white font-semibold shadow-sm ring-1 ring-brand/40":"text-text-tertiary font-medium hover:text-text-primary hover:bg-bg-surface-hi"),children:x(e.tk)},e.value)})})}},5248:(e,t,r)=>{"use strict";r.d(t,{OverviewToggle:()=>i});var a=r(95155),n=r(12115),s=r(25016),l=r(51148);function i(){let e=(0,l.kj)(),[t,r]=(0,n.useState)(!1);return(0,n.useEffect)(()=>{r("hidden"===document.documentElement.getAttribute("data-usage-overview"))},[]),(0,a.jsxs)("button",{type:"button",onClick:function(){let e=!t;r(e);try{localStorage.setItem("ccgauge.usage.overview.hidden",e?"1":"0")}catch(e){}e?document.documentElement.setAttribute("data-usage-overview","hidden"):document.documentElement.removeAttribute("data-usage-overview")},"aria-pressed":!t,title:e(t?"usage.overview.show":"usage.overview.hide"),className:(0,s.cn)("inline-flex items-center gap-1.5 px-2.5 py-1.5 rounded-button text-xs font-medium","border transition-colors duration-150",t?"border-border bg-bg-surface text-text-secondary hover:text-text-primary hover:bg-bg-surface-hi":"border-brand/40 bg-brand/12 text-brand hover:bg-brand/20 hover:border-brand/60"),children:[(0,a.jsx)(o,{open:!t}),(0,a.jsx)("span",{className:"hidden sm:inline",children:e("usage.overview.label")})]})}function o(e){let{open:t}=e;return(0,a.jsx)("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":!0,children:t?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("path",{d:"M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7-10-7-10-7Z"}),(0,a.jsx)("circle",{cx:"12",cy:"12",r:"3"})]}):(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("path",{d:"M9.88 9.88a3 3 0 0 0 4.24 4.24"}),(0,a.jsx)("path",{d:"M10.73 5.08A11 11 0 0 1 12 5c6.5 0 10 7 10 7a13.16 13.16 0 0 1-1.67 2.68"}),(0,a.jsx)("path",{d:"M6.61 6.61A13.526 13.526 0 0 0 2 12s3.5 7 10 7a9.74 9.74 0 0 0 5.39-1.61"}),(0,a.jsx)("line",{x1:"2",y1:"2",x2:"22",y2:"22"})]})})}},7152:(e,t,r)=>{"use strict";r.d(t,{RangePicker:()=>i});var a=r(95155),n=r(1189),s=r(51148);let l=[{value:"1d",tk:"range.today"},{value:"7d",tk:"range.7d"},{value:"30d",tk:"range.30d"},{value:"90d",tk:"range.90d"},{value:"all",tk:"range.all"}];function i(e){let{defaultValue:t="7d"}=e,r=(0,s.kj)();return(0,a.jsx)(n.V,{paramKey:"range",defaultValue:t,options:l,ariaLabel:r("range.label")})}},8336:(e,t,r)=>{"use strict";r.d(t,{ModelFilter:()=>i});var a=r(95155),n=r(35850),s=r(25016),l=r(51148);function i(e){let{all:t,selected:r}=e,i=(0,l.kj)();return(0,a.jsx)(n.K,{paramKey:"models",all:t,selected:r,render:s.P6,labelAllKey:"filter.modelAll",labelSingleKey:"filter.modelSingle",labelMultiKey:"filter.modelMulti",ariaLabel:i("filter.modelLabel")})}},14920:(e,t,r)=>{"use strict";r.d(t,{ProjectFilter:()=>i});var a=r(95155),n=r(35850),s=r(25016),l=r(51148);function i(e){let{all:t,selected:r}=e,i=(0,l.kj)();return(0,a.jsx)(n.K,{paramKey:"projects",all:t,selected:r,render:s.PJ,labelAllKey:"filter.projectAll",labelSingleKey:"filter.projectSingle",labelMultiKey:"filter.projectMulti",ariaLabel:i("filter.projectLabel")})}},16633:(e,t,r)=>{"use strict";r.d(t,{GranularityPicker:()=>i});var a=r(95155),n=r(1189),s=r(51148);let l=[{value:"hour",tk:"gran.hour"},{value:"day",tk:"gran.day"},{value:"week",tk:"gran.week"},{value:"month",tk:"gran.month"}];function i(e){let{defaultValue:t="day"}=e,r=(0,s.kj)();return(0,a.jsx)(n.V,{paramKey:"gran",defaultValue:t,options:l,ariaLabel:r("gran.label")})}},20857:(e,t,r)=>{"use strict";r.d(t,{H:()=>l});var a=r(95155),n=r(12115),s=r(25016);function l(e){let{children:t,className:r}=e,l=(0,n.useRef)(null),[i,o]=(0,n.useState)(!1),[c,d]=(0,n.useState)(!1);return(0,n.useEffect)(()=>{let e=l.current;if(!e)return;function t(){if(!e)return;let{scrollLeft:t,scrollWidth:r,clientWidth:a}=e;o(t>4),d(t+a<r-4)}t(),e.addEventListener("scroll",t,{passive:!0});let r=new ResizeObserver(t);return r.observe(e),()=>{e.removeEventListener("scroll",t),r.disconnect()}},[]),(0,a.jsxs)("div",{className:(0,s.cn)("relative",r),children:[(0,a.jsx)("div",{ref:l,className:"overflow-x-auto",children:t}),(0,a.jsx)("div",{"aria-hidden":!0,className:(0,s.cn)("pointer-events-none absolute left-0 top-0 bottom-0 w-8 bg-gradient-to-r from-bg-surface to-transparent transition-opacity duration-150",i?"opacity-100":"opacity-0")}),(0,a.jsx)("div",{"aria-hidden":!0,className:(0,s.cn)("pointer-events-none absolute right-0 top-0 bottom-0 w-8 bg-gradient-to-l from-bg-surface to-transparent transition-opacity duration-150",c?"opacity-100":"opacity-0")})]})}},25016:(e,t,r)=>{"use strict";r.d(t,{BC:()=>x,P6:()=>p,PJ:()=>m,R8:()=>d,az:()=>o,cn:()=>s,jh:()=>i,l7:()=>c,r6:()=>u});var a=r(2821),n=r(75889);function s(){for(var e=arguments.length,t=Array(e),r=0;r<e;r++)t[r]=arguments[r];return(0,n.QP)((0,a.$)(t))}function l(e,t){var r;return new Intl.NumberFormat("en-US",{maximumFractionDigits:null!=(r=null==t?void 0:t.maxFrac)?r:0}).format(e)}function i(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"en";return Number.isFinite(e)?"zh"===t?e>=1e8?(e/1e8).toFixed(2)+"亿":e>=1e4?(e/1e4).toFixed(1)+"万":l(e):e>=1e9?(e/1e9).toFixed(2)+"B":e>=1e6?(e/1e6).toFixed(2)+"M":e>=1e3?(e/1e3).toFixed(1)+"K":l(e):"0"}function o(e,t){var r,a;return new Intl.NumberFormat("en-US",{style:"currency",currency:"USD",minimumFractionDigits:null!=(r=null==t?void 0:t.minFrac)?r:2,maximumFractionDigits:null!=(a=null==t?void 0:t.maxFrac)?a:2}).format(e)}function c(e){return 0===e?"$0":e<.01?new Intl.NumberFormat("en-US",{style:"currency",currency:"USD",minimumFractionDigits:4,maximumFractionDigits:6}).format(e):o(e)}function d(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1;return Number.isFinite(e)?"".concat((100*e).toFixed(t),"%"):"0%"}function u(e){let t="string"==typeof e||"number"==typeof e?new Date(e):e;if(Number.isNaN(t.getTime()))return"";let r=t.getFullYear(),a=String(t.getMonth()+1).padStart(2,"0"),n=String(t.getDate()).padStart(2,"0"),s=String(t.getHours()).padStart(2,"0"),l=String(t.getMinutes()).padStart(2,"0"),i=String(t.getSeconds()).padStart(2,"0");return"".concat(r,"-").concat(a,"-").concat(n," ").concat(s,":").concat(l,":").concat(i)}function m(e){if(!e)return"(unknown)";let t=e.replace(/[/\\]+$/,"").split(/[/\\]+/);return t[t.length-1]||e}function x(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:8;return e?e.replace(/-/g,"").slice(0,t):""}let h={mini:"Mini",nano:"Nano",pro:"Pro",turbo:"Turbo",preview:"Preview"};function p(e){if(!e)return"(unknown)";let t=e.replace(/^(vertex_ai|bedrock|anthropic|openai)\//,""),r=t.toLowerCase();if(r.startsWith("gpt-")||/^o\d/.test(r))return r.startsWith("gpt-")?"GPT-"+t.slice(4).split("-").map(e=>{var t;return null!=(t=h[e.toLowerCase()])?t:e}).join(" "):t.toUpperCase();let a=t.replace(/-(\d{8})$/,""),n=(a=a.replace(/^claude-/,"")).split("-");if(n.length>=2){let e=n[0],t=n.slice(1).join(".");return b(e)+" "+t}return b(a.replace(/-/g," "))}function b(e){return e.replace(/\b\w/g,e=>e.toUpperCase())}},25577:(e,t,r)=>{"use strict";r.d(t,{UsageTable:()=>h});var a=r(95155),n=r(12115),s=r(20063),l=r(25016),i=r(51148),o=r(47650);function c(e){let{children:t,content:r,className:s,panelClassName:i,align:c="left",delay:d=100,maxWidth:u=360}=e,m=(0,n.useRef)(null),x=(0,n.useRef)(null),h=(0,n.useRef)(null),[p,b]=(0,n.useState)(null),[g,f]=(0,n.useState)(!1),[j,y]=(0,n.useState)(!1);function v(){h.current&&(window.clearTimeout(h.current),h.current=null),j||(x.current=window.setTimeout(()=>{let e=function(){let e,t=m.current;if(!t)return null;let r=t.getBoundingClientRect(),a=Math.min(u,window.innerWidth-16),n=window.innerHeight-r.bottom<200?"top":"bottom";return"right"===c?(e=Math.min(r.right,window.innerWidth-8))-a<8&&(e=a+8):(e=Math.max(r.left,8))+a>window.innerWidth-8&&(e=window.innerWidth-a-8),{x:e,y:"bottom"===n?r.bottom+8:r.top-8,placement:n,align:c}}();e&&(b(e),y(!0))},d))}function w(){x.current&&(window.clearTimeout(x.current),x.current=null),h.current=window.setTimeout(()=>y(!1),80)}return(0,n.useEffect)(()=>f(!0),[]),(0,n.useEffect)(()=>()=>{x.current&&window.clearTimeout(x.current),h.current&&window.clearTimeout(h.current)},[]),(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("span",{ref:m,onMouseEnter:v,onMouseLeave:w,onFocus:v,onBlur:w,className:(0,l.cn)("inline-block",s),children:t}),g&&p&&(0,o.createPortal)((0,a.jsx)("div",{onMouseEnter:()=>{h.current&&(window.clearTimeout(h.current),h.current=null)},onMouseLeave:w,style:{position:"fixed",left:"right"===p.align?void 0:p.x,right:"right"===p.align?window.innerWidth-p.x:void 0,top:"bottom"===p.placement?p.y:void 0,bottom:"top"===p.placement?window.innerHeight-p.y:void 0,maxWidth:u,transform:j?"translateY(0) scale(1)":"bottom"===p.placement?"translateY(-4px) scale(0.98)":"translateY(4px) scale(0.98)",opacity:+!!j,transitionProperty:"opacity, transform",transitionDuration:"120ms",transitionTimingFunction:"cubic-bezier(0.16, 1, 0.3, 1)",transformOrigin:"bottom"===p.placement?"top":"bottom",pointerEvents:j?"auto":"none"},className:(0,l.cn)("z-50 card border-border-hi shadow-xl rounded-button",i),children:r}),document.body)]})}var d=r(20857);let u=[{id:"time",labelKey:"usage.col.time",sortKey:"timestamp",defaultVisible:!0},{id:"prompt",labelKey:"usage.col.userMessage",defaultVisible:!0},{id:"model",labelKey:"usage.col.model",defaultVisible:!0},{id:"project",labelKey:"usage.col.project",defaultVisible:!0},{id:"session",labelKey:"usage.col.session",defaultVisible:!1},{id:"calls",labelKey:"usage.col.calls",align:"right",sortKey:"callCount",defaultVisible:!1},{id:"input",labelKey:"usage.col.input",align:"right",sortKey:"inputTokens",defaultVisible:!1},{id:"output",labelKey:"usage.col.output",align:"right",sortKey:"outputTokens",defaultVisible:!1},{id:"cacheRead",labelKey:"usage.col.cacheRead",align:"right",sortKey:"cacheReadTokens",defaultVisible:!1},{id:"cacheWrite",labelKey:"usage.col.cacheWrite",align:"right",sortKey:"cacheCreationTokens",defaultVisible:!1},{id:"total",labelKey:"usage.col.total",align:"right",sortKey:"totalTokens",defaultVisible:!0},{id:"cost",labelKey:"usage.col.cost",align:"right",sortKey:"cost",defaultVisible:!1},{id:"tools",labelKey:"usage.col.tools",defaultVisible:!0}],m="ccgauge.usage.cols.v3";function x(){return u.reduce((e,t)=>(e[t.id]=t.defaultVisible,e),{})}function h(e){let{rows:t,totalCount:r,page:l,pageCount:o,sort:c,query:h}=e,b=(0,i.kj)(),{locale:f}=(0,i.s9)(),j=(0,s.useRouter)(),y=(0,s.usePathname)(),v=(0,s.useSearchParams)(),[w,N]=(0,n.useState)(new Set),[k,S]=(0,n.useState)(x),[C,K]=(0,n.useState)(!1),[R,T]=(0,n.useState)(h),P=(0,n.useRef)(null),E=(0,n.useRef)(null);function L(e){let t=new URLSearchParams(v.toString());for(let[r,a]of Object.entries(e))void 0===a||""===a?t.delete(r):t.set(r,a);let r=t.toString();j.push(r?"".concat(y,"?").concat(r):y)}function F(e){L({page:e>0?String(e+1):void 0})}(0,n.useEffect)(()=>{S(function(){try{let e=window.localStorage.getItem(m);if(!e)return x();let t=JSON.parse(e),r=x();for(let e of u)"boolean"==typeof t[e.id]&&(r[e.id]=t[e.id]);return r}catch(e){return x()}}())},[]),(0,n.useEffect)(()=>{window.localStorage.setItem(m,JSON.stringify(k))},[k]),(0,n.useEffect)(()=>{T(h)},[h]),(0,n.useEffect)(()=>{function e(e){P.current&&!P.current.contains(e.target)&&K(!1)}return document.addEventListener("mousedown",e),()=>document.removeEventListener("mousedown",e)},[]),(0,n.useEffect)(()=>()=>{E.current&&(window.clearTimeout(E.current),E.current=null)},[]);let A=u.filter(e=>k[e.id]),M=A.length+1,I=A.length;return(0,a.jsxs)("div",{children:[(0,a.jsxs)("div",{className:"flex items-center justify-between gap-3 mb-3 flex-wrap",children:[(0,a.jsx)("input",{value:R,onChange:e=>{var t;T(t=e.target.value),E.current&&window.clearTimeout(E.current),E.current=window.setTimeout(()=>{L({q:t.trim()||void 0,page:void 0})},300)},placeholder:b("common.searchPlaceholder"),className:"px-3 py-1.5 text-sm rounded-button border border-border bg-bg-surface focus:outline-none focus:border-border-hi w-72 placeholder:text-text-tertiary text-text-primary"}),(0,a.jsxs)("div",{className:"flex items-center gap-3",children:[(0,a.jsx)("span",{className:"text-xs text-text-tertiary tabular-nums",children:b("common.rows",{count:r.toLocaleString()})}),(0,a.jsxs)("div",{ref:P,className:"relative",children:[(0,a.jsxs)("button",{onClick:()=>K(e=>!e),className:"btn",children:[b("usage.columns.button"),(0,a.jsx)("span",{className:"ml-1 text-text-tertiary tabular-nums",children:I})]}),C&&(0,a.jsxs)("div",{className:"absolute right-0 mt-1 w-56 card border-border-hi shadow-lg p-2 z-30",children:[(0,a.jsxs)("div",{className:"flex items-center justify-between px-1.5 pb-1.5 mb-1 border-b border-border",children:[(0,a.jsx)("span",{className:"text-xs text-text-tertiary uppercase tracking-wide",children:b("usage.columns.title")}),(0,a.jsx)("button",{onClick:()=>S(x()),className:"text-xs text-text-tertiary hover:text-text-primary",children:b("usage.columns.reset")})]}),(0,a.jsx)("div",{className:"max-h-72 overflow-auto",children:u.map(e=>(0,a.jsxs)("label",{className:"flex items-center gap-2 px-1.5 py-1.5 text-sm rounded hover:bg-bg-surface-hi cursor-pointer",children:[(0,a.jsx)("input",{type:"checkbox",checked:!!k[e.id],onChange:t=>S(r=>({...r,[e.id]:t.target.checked})),className:"accent-brand"}),(0,a.jsx)("span",{className:"text-text-secondary",children:b(e.labelKey)})]},e.id))})]})]}),(0,a.jsx)("button",{onClick:function(){let e=new URLSearchParams(v.toString());window.location.href="/api/export/usage?".concat(e.toString())},className:"btn",children:b("common.exportCsv")})]})]}),(0,a.jsx)("div",{className:"card overflow-hidden",children:(0,a.jsx)(d.H,{children:(0,a.jsxs)("table",{className:"w-full text-sm",children:[(0,a.jsx)("thead",{children:(0,a.jsxs)("tr",{className:"border-b border-border bg-bg-surface-hi/30",children:[(0,a.jsx)(g,{children:(0,a.jsx)("span",{className:"sr-only",children:"expand"})}),A.map(e=>(0,a.jsx)(g,{align:e.align,sorted:!!e.sortKey&&c.key===e.sortKey,dir:c.dir,onClick:e.sortKey?()=>{var t;let r;return t=e.sortKey,r="desc",void(c.key===t&&(r="asc"===c.dir?"desc":"asc"),L({sort:"timestamp"===t?void 0:t,dir:"desc"===r?void 0:r,page:void 0}))}:void 0,children:b(e.labelKey)},e.id))]})}),(0,a.jsxs)("tbody",{children:[t.map(e=>{let t=w.has(e.turnId),r=e.userText.trim()||b("usage.turn.noPrompt");return(0,a.jsx)(p,{turn:e,isOpen:t,onToggle:()=>{var t;return t=e.turnId,void N(e=>{let r=new Set(e);return r.has(t)?r.delete(t):r.add(t),r})},userText:r,expandLabel:b("usage.turn.expand"),collapseLabel:b("usage.turn.collapse"),activeColumns:A,locale:f,t:b},e.turnId)}),0===t.length&&(0,a.jsx)("tr",{children:(0,a.jsx)("td",{colSpan:M,className:"px-3 py-8 text-center text-text-tertiary text-sm",children:b("common.noMatchingRows")})})]})]})})}),o>1&&(0,a.jsxs)("div",{className:"flex items-center justify-between mt-3 text-xs text-text-secondary",children:[(0,a.jsx)("span",{children:b("common.pageOf",{page:l+1,total:o})}),(0,a.jsxs)("div",{className:"flex items-center gap-2",children:[(0,a.jsx)("button",{onClick:()=>F(0),disabled:0===l,className:"btn-ghost disabled:opacity-40",children:b("common.first")}),(0,a.jsx)("button",{onClick:()=>F(l-1),disabled:0===l,className:"btn-ghost disabled:opacity-40",children:b("common.prev")}),(0,a.jsx)("button",{onClick:()=>F(l+1),disabled:l>=o-1,className:"btn-ghost disabled:opacity-40",children:b("common.next")}),(0,a.jsx)("button",{onClick:()=>F(o-1),disabled:l>=o-1,className:"btn-ghost disabled:opacity-40",children:b("common.last")})]})]})]})}function p(e){let{turn:t,isOpen:r,onToggle:n,userText:s,expandLabel:i,collapseLabel:o,activeColumns:d,locale:u,t:m}=e,x=(1===t.models.length?(0,l.P6)(t.models[0]):"".concat((0,l.P6)(t.models[0])," +").concat(t.models.length-1))+(t.efforts.length?1===t.efforts.length?" \xb7 ".concat(t.efforts[0]):" \xb7 ".concat(t.efforts[0],"+").concat(t.efforts.length-1):""),h=t.toolNames.length?t.toolNames.slice(0,3).join(", ")+(t.toolNames.length>3?"…":""):"—";return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)("tr",{className:"border-b border-border last:border-b-0 hover:bg-bg-surface-hi/40 cursor-pointer",onClick:n,children:[(0,a.jsx)("td",{className:"px-2 py-2 text-text-tertiary w-6 text-center select-none",children:(0,a.jsx)("span",{title:r?o:i,className:"inline-block w-4",children:r?"▾":"▸"})}),d.map(e=>(0,a.jsx)("td",{className:(0,l.cn)("px-3 py-2","right"===e.align?"text-right":"text-left"),children:function(e,t,r,n,s,i,o){switch(e){case"time":return(0,a.jsx)("span",{className:"num-mono text-text-secondary whitespace-nowrap text-xs",children:(0,l.r6)(t.endTimestamp)});case"prompt":return(0,a.jsx)(c,{maxWidth:460,panelClassName:"p-3 text-sm text-text-secondary leading-relaxed",content:(0,a.jsx)("div",{className:"whitespace-pre-wrap break-words",children:s}),children:(0,a.jsx)("span",{className:"block text-text-secondary truncate max-w-[280px]",children:s})});case"model":return(0,a.jsx)("span",{className:"text-text-primary whitespace-nowrap",children:r});case"project":return(0,a.jsx)("span",{className:"block text-text-secondary truncate max-w-[180px]",title:t.cwd,children:t.projectLabel||(0,l.PJ)(t.cwd)});case"session":return(0,a.jsx)("span",{className:"num-mono text-text-tertiary text-xs",title:t.sessionId,children:(0,l.BC)(t.sessionId)});case"calls":return(0,a.jsx)("span",{className:"num-mono text-text-secondary",children:t.callCount});case"input":return(0,a.jsx)("span",{className:"num-mono text-text-secondary",children:(0,l.jh)(t.inputTokens,i)});case"output":return(0,a.jsx)("span",{className:"num-mono text-text-secondary",children:(0,l.jh)(t.outputTokens,i)});case"cacheRead":return(0,a.jsx)("span",{className:"num-mono text-success",children:(0,l.jh)(t.cacheReadTokens,i)});case"cacheWrite":return(0,a.jsx)("span",{className:"num-mono text-text-secondary",children:(0,l.jh)(t.cacheCreationTokens,i)});case"total":return(0,a.jsx)(c,{align:"right",maxWidth:300,panelClassName:"p-0 overflow-hidden",content:(0,a.jsx)(b,{row:t,locale:i,t:o}),children:(0,a.jsx)("span",{className:"num-mono text-text-primary font-medium border-b border-dashed border-border hover:border-text-tertiary cursor-help",children:(0,l.jh)(t.totalTokens,i)})});case"cost":return(0,a.jsx)("span",{className:"num-mono text-text-primary font-medium",children:(0,l.l7)(t.cost)});case"tools":return(0,a.jsx)("span",{className:"block text-xs text-text-tertiary truncate max-w-[160px]",title:t.toolNames.join(", "),children:n})}}(e.id,t,x,h,s,u,m)},e.id))]}),r&&t.children.map(e=>(0,a.jsxs)("tr",{className:"border-b border-border last:border-b-0 bg-bg-surface-hi/20 text-text-tertiary",children:[(0,a.jsx)("td",{className:"px-2 py-1.5 w-6"}),d.map(r=>(0,a.jsx)("td",{className:(0,l.cn)("px-3 py-1.5","right"===r.align?"text-right":"text-left"),children:function(e,t,r,n,s){switch(e){case"time":return(0,a.jsx)("span",{className:"num-mono whitespace-nowrap pl-5 text-xs",children:(0,l.r6)(t.timestamp)});case"prompt":{var i;let e=(null!=(i=t.directPrompt)?i:"").trim();if(e&&e!==r.trim())return(0,a.jsx)("span",{className:"block text-xs text-text-secondary truncate max-w-[320px]",title:e,children:e});if(!t.toolNames.length)return(0,a.jsx)("span",{className:"text-xs text-text-tertiary",children:"—"});let n=t.toolNames.join(", "),s=t.toolNames.slice(0,3).join(", ")+(t.toolNames.length>3?"…":"");return(0,a.jsx)("span",{className:"block text-xs text-text-secondary truncate max-w-[280px]",title:n,children:s})}case"model":return(0,a.jsxs)("span",{className:"whitespace-nowrap",children:[(0,l.P6)(t.model),t.effort?" \xb7 ".concat(t.effort):""]});case"project":return(0,a.jsx)("span",{className:"block truncate max-w-[180px]",title:t.cwd,children:t.projectLabel||(0,l.PJ)(t.cwd)});case"session":return(0,a.jsx)("span",{className:"num-mono text-xs",title:t.sessionId,children:(0,l.BC)(t.sessionId)});case"calls":return(0,a.jsx)("span",{className:"num-mono",children:"1"});case"input":return(0,a.jsx)("span",{className:"num-mono",children:(0,l.jh)(t.inputTokens,n)});case"output":return(0,a.jsx)("span",{className:"num-mono",children:(0,l.jh)(t.outputTokens,n)});case"cacheRead":return(0,a.jsx)("span",{className:"num-mono text-success",children:(0,l.jh)(t.cacheReadTokens,n)});case"cacheWrite":return(0,a.jsx)("span",{className:"num-mono",children:(0,l.jh)(t.cacheCreationTokens,n)});case"total":return(0,a.jsx)(c,{align:"right",maxWidth:300,panelClassName:"p-0 overflow-hidden",content:(0,a.jsx)(b,{row:t,locale:n,t:s}),children:(0,a.jsx)("span",{className:"num-mono border-b border-dashed border-border/60 hover:border-text-tertiary cursor-help",children:(0,l.jh)(t.totalTokens,n)})});case"cost":return(0,a.jsx)("span",{className:"num-mono",children:(0,l.l7)(t.cost)});case"tools":return(0,a.jsx)("span",{className:"block text-xs truncate max-w-[160px]",title:t.toolNames.join(", "),children:t.toolNames.length?t.toolNames.join(", "):"—"})}}(r.id,e,t.userText,u,m)},r.id))]},e.uuid))]})}function b(e){let{row:t,locale:r,t:s}=e,i=[{key:"input",label:s("usage.col.input"),tokens:t.inputTokens,cost:t.costInput,tone:"text-text-primary",dot:"bg-chart-input"},{key:"output",label:s("usage.col.output"),tokens:t.outputTokens,cost:t.costOutput,tone:"text-text-primary",dot:"bg-chart-output"},{key:"cacheRead",label:s("usage.col.cacheRead"),tokens:t.cacheReadTokens,cost:t.costCacheRead,tone:"text-success",dot:"bg-chart-cache-read"},{key:"cacheWrite",label:s("usage.col.cacheWrite"),tokens:t.cacheCreationTokens,cost:t.costCacheWrite,tone:"text-text-primary",dot:"bg-chart-cache-create"}];return(0,a.jsxs)("div",{className:"text-xs",children:[(0,a.jsx)("div",{className:"px-3 py-2 border-b border-border bg-bg-surface-hi/40 text-text-tertiary uppercase tracking-wide font-medium",children:s("usage.breakdown.title")}),(0,a.jsxs)("div",{className:"px-3 py-2",children:[(0,a.jsxs)("div",{className:"grid grid-cols-[auto_1fr_auto] gap-x-3 gap-y-1.5 items-center",children:[(0,a.jsx)("span",{}),(0,a.jsx)("span",{className:"text-text-tertiary text-[10px] uppercase tracking-wide text-right",children:s("usage.breakdown.headerTokens")}),(0,a.jsx)("span",{className:"text-text-tertiary text-[10px] uppercase tracking-wide text-right",children:s("usage.breakdown.headerCost")}),i.map(e=>(0,a.jsxs)(n.Fragment,{children:[(0,a.jsxs)("span",{className:"inline-flex items-center gap-2 text-text-secondary",children:[(0,a.jsx)("span",{className:(0,l.cn)("w-2 h-2 rounded-sm",e.dot)}),e.label]}),(0,a.jsx)("span",{className:(0,l.cn)("num-mono text-right",e.tone),children:(0,l.jh)(e.tokens,r)}),(0,a.jsx)("span",{className:"num-mono text-right text-text-secondary",children:(0,l.l7)(e.cost)}),"output"===e.key&&t.reasoningTokens>0&&(0,a.jsxs)(n.Fragment,{children:[(0,a.jsxs)("span",{className:"inline-flex items-center gap-2 text-text-tertiary pl-4 text-[11px]",children:[(0,a.jsx)("span",{className:"text-text-tertiary",children:"↳"}),s("usage.breakdown.reasoning")]}),(0,a.jsx)("span",{className:"num-mono text-right text-text-tertiary text-[11px]",children:(0,l.jh)(t.reasoningTokens,r)}),(0,a.jsx)("span",{className:"text-right text-text-tertiary text-[11px]",children:s("usage.breakdown.reasoningNote")})]},"reasoning-detail")]},e.key))]}),(0,a.jsxs)("div",{className:"mt-2 pt-2 border-t border-border grid grid-cols-[auto_1fr_auto] gap-x-3 items-center",children:[(0,a.jsx)("span",{className:"text-text-secondary font-medium",children:s("usage.breakdown.total")}),(0,a.jsx)("span",{className:"num-mono text-right text-text-primary font-medium",children:(0,l.jh)(t.totalTokens,r)}),(0,a.jsx)("span",{className:"num-mono text-right text-text-primary font-medium",children:(0,l.l7)(t.cost)})]})]})]})}function g(e){let{children:t,align:r="left",sorted:n,dir:s,onClick:i}=e;return(0,a.jsx)("th",{className:(0,l.cn)("px-3 py-2 text-xs font-medium text-text-tertiary uppercase tracking-wide whitespace-nowrap","right"===r?"text-right":"text-left",i&&"cursor-pointer hover:text-text-primary select-none"),onClick:i,children:(0,a.jsxs)("span",{className:"inline-flex items-center gap-1",children:[t,n&&(0,a.jsx)("span",{className:"text-[10px]",children:"asc"===s?"▲":"▼"})]})})}},35850:(e,t,r)=>{"use strict";r.d(t,{K:()=>o});var a=r(95155),n=r(20063),s=r(12115),l=r(25016),i=r(51148);function o(e){let t,{paramKey:r,all:o,selected:c,render:d=e=>e,labelAllKey:u,labelSingleKey:m,labelMultiKey:x,ariaLabel:h,searchThreshold:p=6}=e,b=(0,n.useRouter)(),g=(0,n.usePathname)(),f=(0,n.useSearchParams)(),j=(0,i.kj)(),[y,v]=(0,s.useState)(!1),[w,N]=(0,s.useState)(""),[k,S]=(0,s.useState)(0),C=(0,s.useRef)(null),K=(0,s.useRef)(null),R=(0,s.useRef)(null),T=(0,s.useRef)(null),P=(0,s.useId)(),E=(0,s.useId)();(0,s.useEffect)(()=>{if(y)return document.addEventListener("mousedown",e),document.addEventListener("keydown",t),()=>{document.removeEventListener("mousedown",e),document.removeEventListener("keydown",t)};function e(e){C.current&&!C.current.contains(e.target)&&v(!1)}function t(e){if("Escape"===e.key){var t;v(!1),null==(t=K.current)||t.focus()}}},[y]),(0,s.useEffect)(()=>{y&&o.length>=p&&requestAnimationFrame(()=>{var e;return null==(e=R.current)?void 0:e.focus()}),y||(N(""),S(0))},[y,o.length,p]);let L=(0,s.useMemo)(()=>{let e=w.trim().toLowerCase();return e?o.filter(t=>d(t).toLowerCase().includes(e)||t.toLowerCase().includes(e)):o},[o,w,d]);function F(e){let t=new URLSearchParams(f.toString());0===e.size?t.delete(r):t.set(r,Array.from(e).join(","));let a=t.toString();b.push(a?"".concat(g,"?").concat(a):g)}function A(e){let t=new Set(c);t.has(e)?t.delete(e):t.add(e),F(t)}function M(e){if("ArrowDown"===e.key)e.preventDefault(),S(e=>Math.min(L.length-1,e+1));else if("ArrowUp"===e.key)e.preventDefault(),S(e=>Math.max(0,e-1));else if("Enter"===e.key){e.preventDefault();let t=L[k];t&&A(t)}else"Home"===e.key?(e.preventDefault(),S(0)):"End"===e.key&&(e.preventDefault(),S(L.length-1))}t=0===c.length?j(u):1===c.length?j(m,{value:d(c[0])}):j(x,{count:c.length});let I=o.length>=p;return(0,a.jsxs)("div",{ref:C,className:"relative",children:[(0,a.jsxs)("button",{ref:K,id:P,onClick:()=>v(e=>!e),className:"btn focus:outline-none focus-visible:ring-2 focus-visible:ring-brand/40","aria-haspopup":"listbox","aria-expanded":y,"aria-controls":E,"aria-label":h,children:[t,(0,a.jsx)("span",{className:"text-text-tertiary ml-1","aria-hidden":!0,children:"▾"})]}),y&&(0,a.jsxs)("div",{id:E,role:"listbox","aria-multiselectable":"true","aria-labelledby":P,className:"absolute right-0 mt-1 w-72 card border-border-hi shadow-lg z-20 overflow-hidden",children:[c.length>0&&(0,a.jsxs)("div",{className:"px-2 pt-2 pb-1.5 border-b border-border flex flex-wrap gap-1 items-center",children:[c.slice(0,6).map(e=>(0,a.jsxs)("button",{onClick:()=>A(e),className:"inline-flex items-center gap-1 max-w-[160px] pl-2 pr-1.5 py-0.5 text-[11px] rounded-full bg-brand/10 text-brand border border-brand/20 hover:bg-brand/15","aria-label":"Remove ".concat(d(e)),title:d(e),children:[(0,a.jsx)("span",{className:"truncate",children:d(e)}),(0,a.jsx)("span",{"aria-hidden":!0,className:"text-brand/70",children:"\xd7"})]},e)),c.length>6&&(0,a.jsxs)("span",{className:"text-[11px] text-text-tertiary px-1",children:["+",c.length-6]}),(0,a.jsx)("button",{onClick:function(){F(new Set)},className:"ml-auto text-[11px] text-text-tertiary hover:text-text-primary px-1.5 py-0.5",children:j("filter.clearAll")})]}),I&&(0,a.jsx)("div",{className:"p-2 border-b border-border",children:(0,a.jsx)("input",{ref:R,value:w,onChange:e=>{N(e.target.value),S(0)},onKeyDown:e=>{("ArrowDown"===e.key||"ArrowUp"===e.key||"Enter"===e.key||"Home"===e.key||"End"===e.key)&&M(e)},placeholder:j("common.searchPlaceholder"),className:"w-full px-2 py-1 text-sm rounded border border-border bg-bg-surface focus:outline-none focus:border-border-hi placeholder:text-text-tertiary text-text-primary"})}),(0,a.jsxs)("div",{ref:T,onKeyDown:M,className:"max-h-64 overflow-y-auto p-1 outline-none",tabIndex:-1,children:[0===L.length&&(0,a.jsx)("div",{className:"text-xs text-text-tertiary px-2 py-3 text-center",children:j("filter.noOptions")}),L.map((e,t)=>{let r=c.includes(e),n=t===k;return(0,a.jsxs)("button",{role:"option","aria-selected":r,onMouseEnter:()=>S(t),onClick:()=>A(e),className:(0,l.cn)("w-full text-left text-sm px-2 py-1.5 rounded flex items-center gap-2 transition-colors",n?"bg-bg-surface-hi":"hover:bg-bg-surface-hi",r&&"text-text-primary"),children:[(0,a.jsx)("span",{className:(0,l.cn)("w-3.5 h-3.5 rounded-sm border flex items-center justify-center text-[10px] flex-shrink-0",r?"bg-brand border-brand text-white":"border-border-hi"),"aria-hidden":!0,children:r?"✓":""}),(0,a.jsx)("span",{className:"truncate",children:d(e)})]},e)})]})]})]})}},36392:(e,t,r)=>{Promise.resolve().then(r.bind(r,77549)),Promise.resolve().then(r.bind(r,38059)),Promise.resolve().then(r.bind(r,16633)),Promise.resolve().then(r.bind(r,8336)),Promise.resolve().then(r.bind(r,5248)),Promise.resolve().then(r.bind(r,14920)),Promise.resolve().then(r.bind(r,7152)),Promise.resolve().then(r.bind(r,25577))},38059:(e,t,r)=>{"use strict";r.d(t,{TokenStackChart:()=>h});var a=r(95155),n=r(26991),s=r(94632),l=r(68425),i=r(47734),o=r(73697),c=r(23508),d=r(26736),u=r(25016),m=r(51148);let x={input:"rgb(var(--chart-input))",output:"rgb(var(--chart-output))",cacheRead:"rgb(var(--chart-cache-read))",cacheCreation:"rgb(var(--chart-cache-create))"};function h(e){let{data:t,height:r="h-72"}=e,h=(0,m.kj)(),{locale:g}=(0,m.s9)();return t.length?(0,a.jsxs)("div",{className:"".concat(r," w-full"),children:[(0,a.jsx)(n.u,{width:"100%",height:"100%",children:(0,a.jsxs)(s.E,{data:t,margin:{top:12,right:8,bottom:4,left:8},barCategoryGap:"22%",children:[(0,a.jsx)(l.d,{stroke:"rgb(var(--chart-grid))",strokeOpacity:.6,strokeDasharray:"3 3",vertical:!1}),(0,a.jsx)(i.W,{dataKey:"label",tick:{fill:"rgb(var(--chart-axis))",fontSize:11},tickLine:!1,axisLine:!1,interval:"preserveStartEnd",minTickGap:32,tickMargin:8}),(0,a.jsx)(o.h,{tickFormatter:e=>(0,u.jh)(Number(e),g),tick:{fill:"rgb(var(--chart-axis))",fontSize:11},tickLine:!1,axisLine:!1,width:56,tickMargin:4}),(0,a.jsx)(c.m,{content:(0,a.jsx)(b,{}),cursor:{fill:"rgb(var(--text-primary) / 0.05)",radius:4}}),(0,a.jsx)(d.y,{dataKey:"input",stackId:"a",fill:x.input,isAnimationActive:!1}),(0,a.jsx)(d.y,{dataKey:"cacheCreation",stackId:"a",fill:x.cacheCreation,isAnimationActive:!1}),(0,a.jsx)(d.y,{dataKey:"cacheRead",stackId:"a",fill:x.cacheRead,isAnimationActive:!1}),(0,a.jsx)(d.y,{dataKey:"output",stackId:"a",fill:x.output,radius:[4,4,0,0],isAnimationActive:!1})]})}),(0,a.jsxs)("div",{className:"flex items-center flex-wrap justify-center gap-4 text-xs text-text-secondary mt-2",children:[(0,a.jsx)(p,{color:x.input,label:h("chart.legend.input")}),(0,a.jsx)(p,{color:x.cacheCreation,label:h("chart.legend.cacheWrite")}),(0,a.jsx)(p,{color:x.cacheRead,label:h("chart.legend.cacheRead")}),(0,a.jsx)(p,{color:x.output,label:h("chart.legend.output")})]})]}):(0,a.jsx)("div",{className:"".concat(r," flex items-center justify-center text-text-tertiary text-sm"),children:h("chart.empty")})}function p(e){let{color:t,label:r}=e;return(0,a.jsxs)("span",{className:"inline-flex items-center gap-1.5",children:[(0,a.jsx)("span",{className:"w-2.5 h-2.5 rounded-sm",style:{background:t}}),(0,a.jsx)("span",{children:r})]})}function b(e){let t=(0,m.kj)(),{locale:r}=(0,m.s9)();if(!e.active||!e.payload||!e.payload.length)return null;let n=e.payload[0].payload,s=n.input+n.output+n.cacheRead+n.cacheCreation;return(0,a.jsxs)("div",{className:"card-elevated border border-border-hi rounded-card p-3 text-xs min-w-[200px]",children:[(0,a.jsx)("div",{className:"font-medium text-text-primary mb-2",children:e.label}),(0,a.jsxs)("div",{className:"space-y-1",children:[(0,a.jsx)(g,{color:x.input,label:t("chart.legend.input"),value:n.input,locale:r}),(0,a.jsx)(g,{color:x.cacheCreation,label:t("chart.legend.cacheWrite"),value:n.cacheCreation,locale:r}),(0,a.jsx)(g,{color:x.cacheRead,label:t("chart.legend.cacheRead"),value:n.cacheRead,locale:r}),(0,a.jsx)(g,{color:x.output,label:t("chart.legend.output"),value:n.output,locale:r})]}),(0,a.jsxs)("div",{className:"mt-2 pt-2 border-t border-border flex items-center justify-between",children:[(0,a.jsx)("span",{className:"text-text-secondary",children:t("chart.tooltip.total")}),(0,a.jsx)("span",{className:"num-mono text-text-primary",children:(0,u.jh)(s,r)})]}),(0,a.jsxs)("div",{className:"flex items-center justify-between mt-1",children:[(0,a.jsx)("span",{className:"text-text-secondary",children:t("chart.tooltip.cost")}),(0,a.jsx)("span",{className:"num-mono text-brand",children:(0,u.az)(n.cost)})]}),(0,a.jsxs)("div",{className:"flex items-center justify-between mt-1",children:[(0,a.jsx)("span",{className:"text-text-secondary",children:t("chart.tooltip.requests")}),(0,a.jsx)("span",{className:"num-mono text-text-primary",children:n.requests})]})]})}function g(e){let{color:t,label:r,value:n,locale:s}=e;return(0,a.jsxs)("div",{className:"flex items-center justify-between gap-3",children:[(0,a.jsxs)("span",{className:"inline-flex items-center gap-1.5 text-text-secondary",children:[(0,a.jsx)("span",{className:"w-2 h-2 rounded-sm",style:{background:t}}),r]}),(0,a.jsx)("span",{className:"num-mono text-text-primary",children:(0,u.jh)(n,s)})]})}},77549:(e,t,r)=>{"use strict";r.d(t,{AutoRefresh:()=>s});var a=r(12115),n=r(20063);function s(e){let{intervalMs:t=15e3}=e,r=(0,n.useRouter)(),s=(0,a.useRef)(!1);return(0,a.useEffect)(()=>{if(t<=0)return;let e=null;function a(){if(!document.hidden&&!s.current){s.current=!0;try{r.refresh()}finally{Promise.resolve().then(()=>{s.current=!1})}}}return e=window.setInterval(a,t),document.addEventListener("visibilitychange",a),()=>{null!==e&&window.clearInterval(e),document.removeEventListener("visibilitychange",a)}},[r,t]),null}}},e=>{e.O(0,[760,930,148,441,255,358],()=>e(e.s=36392)),_N_E=e.O()}]);
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgb(59 130 246/0.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgb(59 130 246/0.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/*
|
|
2
|
+
! tailwindcss v3.4.19 | MIT License | https://tailwindcss.com
|
|
3
|
+
*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:var(--font-sans),ui-sans-serif,system-ui,sans-serif;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:var(--font-mono),ui-monospace,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.card{border-radius:12px;border-width:1px;--tw-border-opacity:1;border-color:rgb(var(--border)/var(--tw-border-opacity,1));--tw-bg-opacity:1;background-color:rgb(var(--bg-surface)/var(--tw-bg-opacity,1));box-shadow:var(--shadow-card)}.card-elevated{background:rgb(var(--bg-elevated));box-shadow:var(--shadow-popover)}.card-pad{padding:1.25rem}@media (min-width:640px){.card-pad{padding:1.5rem}}.label{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.06em;--tw-text-opacity:1;color:rgb(var(--text-tertiary)/var(--tw-text-opacity,1))}.num-hero{overflow-wrap:break-word;font-size:1.875rem;line-height:2.25rem;font-weight:600;--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction);letter-spacing:-.025em;--tw-text-opacity:1;color:rgb(var(--text-primary)/var(--tw-text-opacity,1))}@media (min-width:640px){.num-hero{font-size:2rem;line-height:2.25rem}}.num-mid{font-size:1.5rem;line-height:2rem;font-weight:600;--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction);--tw-text-opacity:1;color:rgb(var(--text-primary)/var(--tw-text-opacity,1))}.num-mono{font-family:var(--font-mono),ui-monospace,monospace;--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)}.pill{display:inline-flex;align-items:center;border-radius:8px;padding:.125rem .5rem;font-size:.75rem;font-weight:500;line-height:1.25rem}.pill-muted{padding:.125rem .5rem;font-size:.75rem;background-color:rgb(var(--bg-surface-hi)/var(--tw-bg-opacity,1));color:rgb(var(--text-secondary)/var(--tw-text-opacity,1))}.btn,.pill-muted{display:inline-flex;align-items:center;border-radius:8px;font-weight:500;line-height:1.25rem;border-width:1px;--tw-border-opacity:1;border-color:rgb(var(--border)/var(--tw-border-opacity,1));--tw-bg-opacity:1;--tw-text-opacity:1}.btn{justify-content:center;gap:.375rem;background-color:rgb(var(--bg-surface)/var(--tw-bg-opacity,1));padding:.375rem .75rem;font-size:.875rem;color:rgb(var(--text-primary)/var(--tw-text-opacity,1));transition:background-color .15s,border-color .15s,color .15s,transform .1s,box-shadow .15s}.btn:hover:not(:disabled){background:rgb(var(--bg-surface-hi));border-color:rgb(var(--border-hi))}.btn:active:not(:disabled){transform:translateY(1px)}.btn:disabled{cursor:not-allowed;opacity:.5}.btn-ghost{display:inline-flex;align-items:center;justify-content:center;gap:.375rem;border-radius:8px;padding:.375rem .75rem;font-size:.875rem;line-height:1.25rem;font-weight:500;--tw-text-opacity:1;color:rgb(var(--text-secondary)/var(--tw-text-opacity,1));transition:background-color .15s,color .15s}.btn-ghost:hover:not(:disabled){color:rgb(var(--text-primary));background:rgb(var(--bg-surface-hi))}.btn-ghost:disabled{cursor:not-allowed;opacity:.4}.section-header{background:linear-gradient(to bottom,rgb(var(--bg-surface)) 0,rgb(var(--bg-surface-hi)/.4) 100%)}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.pointer-events-none{pointer-events:none}.\!visible{visibility:visible!important}.visible{visibility:visible}.collapse{visibility:collapse}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.-bottom-\[12px\]{bottom:-12px}.bottom-0{bottom:0}.left-0{left:0}.left-2{left:.5rem}.right-0{right:0}.right-2{right:.5rem}.top-0{top:0}.z-20{z-index:20}.z-30{z-index:30}.z-50{z-index:50}.mx-auto{margin-left:auto;margin-right:auto}.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.ml-1{margin-left:.25rem}.ml-1\.5{margin-left:.375rem}.ml-auto{margin-left:auto}.mr-1{margin-right:.25rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-1\.5{margin-top:.375rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-auto{margin-top:auto}.\!block{display:block!important}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.contents{display:contents}.\!hidden{display:none!important}.hidden{display:none}.aspect-square{aspect-ratio:1/1}.h-1{height:.25rem}.h-1\.5{height:.375rem}.h-12{height:3rem}.h-14{height:3.5rem}.h-2{height:.5rem}.h-2\.5{height:.625rem}.h-3{height:.75rem}.h-3\.5{height:.875rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-64{height:16rem}.h-7{height:1.75rem}.h-72{height:18rem}.h-8{height:2rem}.h-\[2px\]{height:2px}.h-\[3px\]{height:3px}.h-full{height:100%}.max-h-48{max-height:12rem}.max-h-64{max-height:16rem}.max-h-72{max-height:18rem}.min-h-\[132px\]{min-height:132px}.min-h-\[180px\]{min-height:180px}.min-h-\[280px\]{min-height:280px}.min-h-\[64px\]{min-height:64px}.min-h-screen{min-height:100vh}.w-1\.5{width:.375rem}.w-12{width:3rem}.w-2{width:.5rem}.w-2\.5{width:.625rem}.w-20{width:5rem}.w-24{width:6rem}.w-3\.5{width:.875rem}.w-32{width:8rem}.w-4{width:1rem}.w-48{width:12rem}.w-5{width:1.25rem}.w-56{width:14rem}.w-6{width:1.5rem}.w-7{width:1.75rem}.w-72{width:18rem}.w-8{width:2rem}.w-9{width:2.25rem}.w-full{width:100%}.min-w-0{min-width:0}.min-w-\[120px\]{min-width:120px}.min-w-\[180px\]{min-width:180px}.min-w-\[200px\]{min-width:200px}.min-w-\[80px\]{min-width:80px}.max-w-2xl{max-width:42rem}.max-w-7xl{max-width:80rem}.max-w-\[160px\]{max-width:160px}.max-w-\[180px\]{max-width:180px}.max-w-\[280px\]{max-width:280px}.max-w-\[320px\]{max-width:320px}.max-w-full{max-width:100%}.max-w-md{max-width:28rem}.flex-1{flex:1 1 0%}.flex-shrink-0,.shrink-0{flex-shrink:0}.grow{flex-grow:1}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}.cursor-help{cursor:help}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.list-inside{list-style-position:inside}.list-disc{list-style-type:disc}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-\[auto_1fr\]{grid-template-columns:auto 1fr}.grid-cols-\[auto_1fr_auto\]{grid-template-columns:auto 1fr auto}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-center{align-items:center}.items-baseline{align-items:baseline}.items-stretch{align-items:stretch}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-0\.5{gap:.125rem}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-2\.5{gap:.625rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-5{gap:1.25rem}.gap-\[3px\]{gap:3px}.gap-x-3{-moz-column-gap:.75rem;column-gap:.75rem}.gap-y-0\.5{row-gap:.125rem}.gap-y-1\.5{row-gap:.375rem}.gap-y-\[3px\]{row-gap:3px}.space-y-0\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.125rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.125rem * var(--tw-space-y-reverse))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-1\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.375rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.375rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-3\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.875rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.875rem * var(--tw-space-y-reverse))}.space-y-5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.25rem * var(--tw-space-y-reverse))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis}.truncate,.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.break-words{overflow-wrap:break-word}.rounded{border-radius:.25rem}.rounded-\[3px\]{border-radius:3px}.rounded-button{border-radius:8px}.rounded-card{border-radius:12px}.rounded-full{border-radius:9999px}.rounded-md{border-radius:.375rem}.rounded-sm{border-radius:.125rem}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-t{border-top-width:1px}.border-dashed{border-style:dashed}.border-border{--tw-border-opacity:1;border-color:rgb(var(--border)/var(--tw-border-opacity,1))}.border-border-hi{--tw-border-opacity:1;border-color:rgb(var(--border-hi)/var(--tw-border-opacity,1))}.border-border\/60{border-color:rgb(var(--border)/.6)}.border-brand{--tw-border-opacity:1;border-color:rgb(var(--brand)/var(--tw-border-opacity,1))}.border-brand\/20{border-color:rgb(var(--brand)/.2)}.border-brand\/40{border-color:rgb(var(--brand)/.4)}.border-danger\/20{border-color:rgb(var(--danger)/.2)}.border-success\/20{border-color:rgb(var(--success)/.2)}.border-warning\/20{border-color:rgb(var(--warning)/.2)}.bg-bg{--tw-bg-opacity:1;background-color:rgb(var(--bg-base)/var(--tw-bg-opacity,1))}.bg-bg-surface{--tw-bg-opacity:1;background-color:rgb(var(--bg-surface)/var(--tw-bg-opacity,1))}.bg-bg-surface-hi{--tw-bg-opacity:1;background-color:rgb(var(--bg-surface-hi)/var(--tw-bg-opacity,1))}.bg-bg-surface-hi\/20{background-color:rgb(var(--bg-surface-hi)/.2)}.bg-bg-surface-hi\/30{background-color:rgb(var(--bg-surface-hi)/.3)}.bg-bg-surface-hi\/40{background-color:rgb(var(--bg-surface-hi)/.4)}.bg-bg-surface-hi\/60{background-color:rgb(var(--bg-surface-hi)/.6)}.bg-brand{--tw-bg-opacity:1;background-color:rgb(var(--brand)/var(--tw-bg-opacity,1))}.bg-brand\/10{background-color:rgb(var(--brand)/.1)}.bg-chart-cache-create{--tw-bg-opacity:1;background-color:rgb(var(--chart-cache-create)/var(--tw-bg-opacity,1))}.bg-chart-cache-create\/15{background-color:rgb(var(--chart-cache-create)/.15)}.bg-chart-cache-read{--tw-bg-opacity:1;background-color:rgb(var(--chart-cache-read)/var(--tw-bg-opacity,1))}.bg-chart-input{--tw-bg-opacity:1;background-color:rgb(var(--chart-input)/var(--tw-bg-opacity,1))}.bg-chart-output{--tw-bg-opacity:1;background-color:rgb(var(--chart-output)/var(--tw-bg-opacity,1))}.bg-danger{--tw-bg-opacity:1;background-color:rgb(var(--danger)/var(--tw-bg-opacity,1))}.bg-danger\/10{background-color:rgb(var(--danger)/.1)}.bg-success{--tw-bg-opacity:1;background-color:rgb(var(--success)/var(--tw-bg-opacity,1))}.bg-success\/10{background-color:rgb(var(--success)/.1)}.bg-warning{--tw-bg-opacity:1;background-color:rgb(var(--warning)/var(--tw-bg-opacity,1))}.bg-warning\/10{background-color:rgb(var(--warning)/.1)}.bg-gradient-to-l{background-image:linear-gradient(to left,var(--tw-gradient-stops))}.bg-gradient-to-r{background-image:linear-gradient(to right,var(--tw-gradient-stops))}.from-bg-surface{--tw-gradient-from:rgb(var(--bg-surface)/1) var(--tw-gradient-from-position);--tw-gradient-to:rgb(var(--bg-surface)/0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.from-brand{--tw-gradient-from:rgb(var(--brand)/1) var(--tw-gradient-from-position);--tw-gradient-to:rgb(var(--brand)/0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.from-brand\/0{--tw-gradient-from:rgb(var(--brand)/0) var(--tw-gradient-from-position);--tw-gradient-to:rgb(var(--brand)/0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.from-success\/0{--tw-gradient-from:rgb(var(--success)/0) var(--tw-gradient-from-position);--tw-gradient-to:rgb(var(--success)/0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.from-warning\/0{--tw-gradient-from:rgb(var(--warning)/0) var(--tw-gradient-from-position);--tw-gradient-to:rgb(var(--warning)/0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.via-brand\/70{--tw-gradient-to:rgb(var(--brand)/0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),rgb(var(--brand)/0.7) var(--tw-gradient-via-position),var(--tw-gradient-to)}.via-success\/70{--tw-gradient-to:rgb(var(--success)/0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),rgb(var(--success)/0.7) var(--tw-gradient-via-position),var(--tw-gradient-to)}.via-warning\/70{--tw-gradient-to:rgb(var(--warning)/0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),rgb(var(--warning)/0.7) var(--tw-gradient-via-position),var(--tw-gradient-to)}.to-brand-hover{--tw-gradient-to:rgb(var(--brand-hover)/1) var(--tw-gradient-to-position)}.to-brand\/0{--tw-gradient-to:rgb(var(--brand)/0) var(--tw-gradient-to-position)}.to-success\/0{--tw-gradient-to:rgb(var(--success)/0) var(--tw-gradient-to-position)}.to-transparent{--tw-gradient-to:transparent var(--tw-gradient-to-position)}.to-warning\/0{--tw-gradient-to:rgb(var(--warning)/0) var(--tw-gradient-to-position)}.fill-brand{fill:rgb(var(--brand)/1)}.fill-white{fill:#fff}.p-0{padding:0}.p-0\.5{padding:.125rem}.p-1{padding:.25rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-5{padding:1.25rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-3\.5{padding-left:.875rem;padding-right:.875rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-12{padding-top:3rem;padding-bottom:3rem}.py-14{padding-top:3.5rem;padding-bottom:3.5rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pb-1\.5{padding-bottom:.375rem}.pb-3{padding-bottom:.75rem}.pl-2{padding-left:.5rem}.pl-4{padding-left:1rem}.pl-5{padding-left:1.25rem}.pr-1\.5{padding-right:.375rem}.pr-2{padding-right:.5rem}.pr-2\.5{padding-right:.625rem}.pt-2{padding-top:.5rem}.pt-3{padding-top:.75rem}.pt-4{padding-top:1rem}.pt-\[18px\]{padding-top:18px}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.text-2xl{font-size:1.5rem;line-height:2rem}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[15px\]{font-size:15px}.text-\[9px\]{font-size:9px}.text-base{font-size:1rem;line-height:1.5rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.lowercase{text-transform:lowercase}.capitalize{text-transform:capitalize}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)}.leading-none{line-height:1}.leading-relaxed{line-height:1.625}.leading-snug{line-height:1.375}.leading-tight{line-height:1.25}.tracking-\[0\.06em\]{letter-spacing:.06em}.tracking-tight{letter-spacing:-.025em}.tracking-wide{letter-spacing:.025em}.text-brand{--tw-text-opacity:1;color:rgb(var(--brand)/var(--tw-text-opacity,1))}.text-brand\/70{color:rgb(var(--brand)/.7)}.text-chart-cache-create{--tw-text-opacity:1;color:rgb(var(--chart-cache-create)/var(--tw-text-opacity,1))}.text-danger{--tw-text-opacity:1;color:rgb(var(--danger)/var(--tw-text-opacity,1))}.text-success{--tw-text-opacity:1;color:rgb(var(--success)/var(--tw-text-opacity,1))}.text-text-primary{--tw-text-opacity:1;color:rgb(var(--text-primary)/var(--tw-text-opacity,1))}.text-text-secondary{--tw-text-opacity:1;color:rgb(var(--text-secondary)/var(--tw-text-opacity,1))}.text-text-tertiary{--tw-text-opacity:1;color:rgb(var(--text-tertiary)/var(--tw-text-opacity,1))}.text-warning{--tw-text-opacity:1;color:rgb(var(--warning)/var(--tw-text-opacity,1))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.accent-brand{accent-color:rgb(var(--brand)/1)}.opacity-0{opacity:0}.opacity-100{opacity:1}.shadow-lg{--tw-shadow:0 10px 15px -3px rgb(0 0 0/0.1),0 4px 6px -4px rgb(0 0 0/0.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color)}.shadow-lg,.shadow-sm{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 2px 0 rgb(0 0 0/0.05);--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color)}.shadow-xl{--tw-shadow:0 20px 25px -5px rgb(0 0 0/0.1),0 8px 10px -6px rgb(0 0 0/0.1);--tw-shadow-colored:0 20px 25px -5px var(--tw-shadow-color),0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.outline-none{outline:2px solid transparent;outline-offset:2px}.ring-1{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.ring-brand\/40{--tw-ring-color:rgb(var(--brand)/0.4)}.ring-white\/40{--tw-ring-color:rgb(255 255 255/0.4)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur-md{--tw-backdrop-blur:blur(12px)}.backdrop-blur-md,.backdrop-filter{backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-100{transition-duration:.1s}.duration-150{transition-duration:.15s}.duration-500{transition-duration:.5s}.ease-out-soft{transition-timing-function:cubic-bezier(.16,1,.3,1)}.\[ccgauge\:api\]{ccgauge:api}.\[ccgauge\:indexer\]{ccgauge:indexer}.\[grid-template-columns\:auto_1fr\]{grid-template-columns:auto 1fr}.\[grid-template-columns\:repeat\(24\2c minmax\(0\2c 1fr\)\)\]{grid-template-columns:repeat(24,minmax(0,1fr))}.theme-dark,:root{--bg-base:10 10 10;--bg-surface:22 22 22;--bg-surface-hi:32 32 34;--bg-elevated:38 38 42;--border:38 38 42;--border-hi:64 64 70;--text-primary:250 250 250;--text-secondary:168 168 174;--text-tertiary:120 120 128;--brand:129 140 248;--brand-hover:165 180 252;--success:34 197 94;--warning:250 204 21;--danger:248 113 113;--chart-input:96 165 250;--chart-output:251 146 60;--chart-cache-read:52 211 153;--chart-cache-create:167 139 250;--chart-grid:38 38 42;--chart-axis:120 120 128;--shadow-card:0 1px 0 0 rgb(255 255 255/0.02),0 4px 12px -4px rgb(0 0 0/0.4);--shadow-card-hover:0 1px 0 0 rgb(255 255 255/0.04),0 8px 24px -8px rgb(0 0 0/0.6);--shadow-popover:0 4px 12px -2px rgb(0 0 0/0.4),0 16px 48px -8px rgb(0 0 0/0.6);--ring-focus:129 140 248}.theme-light{--bg-base:252 252 253;--bg-surface:255 255 255;--bg-surface-hi:247 247 249;--bg-elevated:250 250 252;--border:226 226 232;--border-hi:200 200 208;--text-primary:17 17 23;--text-secondary:82 82 91;--text-tertiary:145 145 156;--brand:79 70 229;--brand-hover:67 56 202;--success:22 163 74;--warning:217 119 6;--danger:220 38 38;--chart-input:37 99 235;--chart-output:234 88 12;--chart-cache-read:22 163 74;--chart-cache-create:124 58 237;--chart-grid:232 232 238;--chart-axis:113 113 122;--shadow-card:0 1px 2px 0 rgb(15 23 42/0.04),0 1px 3px 0 rgb(15 23 42/0.04);--shadow-card-hover:0 4px 12px -2px rgb(15 23 42/0.08),0 8px 32px -8px rgb(15 23 42/0.06);--shadow-popover:0 8px 24px -4px rgb(15 23 42/0.08),0 16px 48px -8px rgb(15 23 42/0.08);--ring-focus:79 70 229}:root{--font-sans:"Geist Sans","Inter",-apple-system,BlinkMacSystemFont,"Segoe UI",system-ui,"PingFang SC","Hiragino Sans GB","Microsoft YaHei",sans-serif;--font-mono:"Geist Mono","JetBrains Mono",ui-monospace,SFMono-Regular,Menlo,monospace}*{border-color:rgb(var(--border))}html{overflow-y:scroll;scrollbar-gutter:stable}body,html{background:rgb(var(--bg-base));color:rgb(var(--text-primary));font-family:var(--font-sans);font-feature-settings:"cv11","ss01","ss03";-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-rendering:optimizeLegibility}body{min-height:100vh}::-moz-selection{background:rgb(var(--brand)/.25);color:rgb(var(--text-primary))}::selection{background:rgb(var(--brand)/.25);color:rgb(var(--text-primary))}::-webkit-scrollbar{width:10px;height:10px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:rgb(var(--border-hi)/.7);border:2px solid transparent;background-clip:padding-box;border-radius:6px}::-webkit-scrollbar-thumb:hover{background:rgb(var(--text-tertiary)/.7);background-clip:padding-box}.scrollbar-thin::-webkit-scrollbar{width:6px;height:6px}.scrollbar-thin::-webkit-scrollbar-thumb{background:rgb(var(--border-hi)/.5);border:0;border-radius:3px}.nav-scroller{scrollbar-width:none}.nav-scroller::-webkit-scrollbar{display:none;width:0;height:0}:where(button,a,input,select,textarea,[tabindex]):focus-visible{outline:2px solid rgb(var(--ring-focus)/.6);outline-offset:2px;border-radius:6px}@media (prefers-reduced-motion:reduce){*,:after,:before{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important;scroll-behavior:auto!important}}.divider-soft{border-top:1px solid rgb(var(--border))}html[data-usage-overview=hidden] .usage-overview-block{display:none}.placeholder\:text-text-tertiary::-moz-placeholder{--tw-text-opacity:1;color:rgb(var(--text-tertiary)/var(--tw-text-opacity,1))}.placeholder\:text-text-tertiary::placeholder{--tw-text-opacity:1;color:rgb(var(--text-tertiary)/var(--tw-text-opacity,1))}.last\:border-b-0:last-child{border-bottom-width:0}.hover\:z-10:hover{z-index:10}.hover\:scale-125:hover{--tw-scale-x:1.25;--tw-scale-y:1.25;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hover\:border-border-hi:hover{--tw-border-opacity:1;border-color:rgb(var(--border-hi)/var(--tw-border-opacity,1))}.hover\:border-brand\/60:hover{border-color:rgb(var(--brand)/.6)}.hover\:border-text-tertiary:hover{--tw-border-opacity:1;border-color:rgb(var(--text-tertiary)/var(--tw-border-opacity,1))}.hover\:bg-bg-surface-hi:hover{--tw-bg-opacity:1;background-color:rgb(var(--bg-surface-hi)/var(--tw-bg-opacity,1))}.hover\:bg-bg-surface-hi\/30:hover{background-color:rgb(var(--bg-surface-hi)/.3)}.hover\:bg-bg-surface-hi\/40:hover{background-color:rgb(var(--bg-surface-hi)/.4)}.hover\:bg-bg-surface-hi\/60:hover{background-color:rgb(var(--bg-surface-hi)/.6)}.hover\:bg-brand\/15:hover{background-color:rgb(var(--brand)/.15)}.hover\:bg-brand\/20:hover{background-color:rgb(var(--brand)/.2)}.hover\:text-brand:hover{--tw-text-opacity:1;color:rgb(var(--brand)/var(--tw-text-opacity,1))}.hover\:text-text-primary:hover{--tw-text-opacity:1;color:rgb(var(--text-primary)/var(--tw-text-opacity,1))}.hover\:opacity-90:hover{opacity:.9}.hover\:ring-1:hover{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.hover\:ring-brand\/60:hover{--tw-ring-color:rgb(var(--brand)/0.6)}.focus\:border-border-hi:focus{--tw-border-opacity:1;border-color:rgb(var(--border-hi)/var(--tw-border-opacity,1))}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus-visible\:ring-2:focus-visible{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus-visible\:ring-brand\/40:focus-visible{--tw-ring-color:rgb(var(--brand)/0.4)}.disabled\:opacity-40:disabled{opacity:.4}.group:hover .group-hover\:text-brand{--tw-text-opacity:1;color:rgb(var(--brand)/var(--tw-text-opacity,1))}.group:hover .group-hover\:brightness-110{--tw-brightness:brightness(1.1);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}@media (min-width:640px){.sm\:mt-0{margin-top:0}.sm\:inline{display:inline}.sm\:flex{display:flex}.sm\:flex-row{flex-direction:row}.sm\:items-start{align-items:flex-start}.sm\:items-end{align-items:flex-end}.sm\:items-baseline{align-items:baseline}.sm\:justify-between{justify-content:space-between}.sm\:gap-2\.5{gap:.625rem}.sm\:gap-4{gap:1rem}.sm\:space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.sm\:p-6{padding:1.5rem}.sm\:px-3{padding-left:.75rem;padding-right:.75rem}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}.sm\:py-16{padding-top:4rem;padding-bottom:4rem}.sm\:py-8{padding-top:2rem;padding-bottom:2rem}.sm\:pt-5{padding-top:1.25rem}.sm\:pt-\[22px\]{padding-top:22px}.sm\:text-\[1\.75rem\]{font-size:1.75rem}}@media (min-width:768px){.md\:flex{display:flex}.md\:inline-flex{display:inline-flex}.md\:w-\[170px\]{width:170px}.md\:shrink-0{flex-shrink:0}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.md\:flex-row{flex-direction:row}.md\:flex-col{flex-direction:column}.md\:gap-8{gap:2rem}}@media (min-width:1024px){.lg\:col-span-2{grid-column:span 2/span 2}.lg\:inline{display:inline}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}
|
|
File without changes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ccgauge",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "Local web dashboard for Claude Code and OpenAI Codex CLI token usage and cost",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude",
|
|
@@ -32,6 +32,15 @@
|
|
|
32
32
|
"engines": {
|
|
33
33
|
"node": ">=20"
|
|
34
34
|
},
|
|
35
|
+
"os": [
|
|
36
|
+
"darwin",
|
|
37
|
+
"linux",
|
|
38
|
+
"win32"
|
|
39
|
+
],
|
|
40
|
+
"cpu": [
|
|
41
|
+
"x64",
|
|
42
|
+
"arm64"
|
|
43
|
+
],
|
|
35
44
|
"packageManager": "pnpm@10.30.3",
|
|
36
45
|
"bin": {
|
|
37
46
|
"ccgauge": "bin/cli.mjs"
|
|
@@ -40,22 +49,24 @@
|
|
|
40
49
|
"bin/cli.mjs",
|
|
41
50
|
".next/standalone",
|
|
42
51
|
"dist/mcp",
|
|
52
|
+
"dist/report",
|
|
43
53
|
"README.md",
|
|
44
54
|
"README.zh-CN.md",
|
|
45
55
|
"CHANGELOG.md",
|
|
46
56
|
"LICENSE"
|
|
47
57
|
],
|
|
48
58
|
"scripts": {
|
|
49
|
-
"dev": "next dev -p
|
|
50
|
-
"build": "next build && node scripts/build-mcp.mjs && node scripts/postbuild.mjs",
|
|
59
|
+
"dev": "next dev -p 3738",
|
|
60
|
+
"build": "next build && node scripts/build-mcp.mjs && node scripts/build-report.mjs && node scripts/postbuild.mjs",
|
|
51
61
|
"build:mcp": "node scripts/build-mcp.mjs",
|
|
62
|
+
"build:report": "node scripts/build-report.mjs",
|
|
52
63
|
"start": "node bin/cli.mjs",
|
|
53
64
|
"start:next": "next start -p 3737",
|
|
54
65
|
"lint": "eslint .",
|
|
55
66
|
"typecheck": "tsc --noEmit",
|
|
56
67
|
"test": "node --experimental-strip-types --no-warnings scripts/test-codex-parser.mjs",
|
|
57
68
|
"test:mcp": "node scripts/test-mcp-server.mjs",
|
|
58
|
-
"clean": "
|
|
69
|
+
"clean": "node -e \"for (const p of ['.next','node_modules','tsconfig.tsbuildinfo']) require('node:fs').rmSync(p,{recursive:true,force:true})\"",
|
|
59
70
|
"screenshots": "node scripts/screenshots.mjs",
|
|
60
71
|
"prepack": "pnpm build"
|
|
61
72
|
},
|
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,153 @@ All notable changes to **ccgauge** are documented here.
|
|
|
5
5
|
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and
|
|
6
6
|
this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.0.0] — 2026-05-12
|
|
9
|
+
|
|
10
|
+
A polish release. Everything from 0.x — Claude + Codex parsers, the web
|
|
11
|
+
dashboard, the CLI report, the MCP server — is now considered stable and
|
|
12
|
+
documented. Calling it **1.0** to signal feature-complete: the data layer,
|
|
13
|
+
the cost math, the turn grouping, and the published-tarball shape are all
|
|
14
|
+
settled. Future minor versions will keep the existing surfaces working.
|
|
15
|
+
|
|
16
|
+
### Highlights
|
|
17
|
+
|
|
18
|
+
- **Overview "Activity" card** — sessions, messages, total tokens, active
|
|
19
|
+
days, current/longest streak, peak hour, favorite model, plus a 7×24
|
|
20
|
+
day-of-week × hour-of-day heatmap with hover tooltips (messages +
|
|
21
|
+
tokens + share-of-total + share-of-peak). Heat-map cells size to the
|
|
22
|
+
container so the card looks right at any width. Includes a tongue-in-
|
|
23
|
+
cheek "you've used ~N× more tokens than _The Little Prince_" comparison.
|
|
24
|
+
- **Conversation-turn grouping handles Skills correctly.** When Claude
|
|
25
|
+
Code invokes a `Skill`, it injects a synthetic `Base directory for this
|
|
26
|
+
skill: ...` user message that previously fragmented a single
|
|
27
|
+
conversation into 2–3 rows in the usage table. We now flag these
|
|
28
|
+
injections (also `<system-reminder>` blocks and `Caveat:` preludes) as
|
|
29
|
+
synthetic — they skip turn-boundary detection but still surface as the
|
|
30
|
+
per-call "prompt" on child rows so you can tell which Skill produced
|
|
31
|
+
each API call.
|
|
32
|
+
- **`ccgauge report` (CLI)** — formatted terminal usage report. Tokens +
|
|
33
|
+
Cost summary, trend bar chart, top-N breakdown table, all 0.2 s end to
|
|
34
|
+
end. Supports `--range`, `--source`, `--by model|project|session`,
|
|
35
|
+
`--since/--until`, `--model/--project` filters, `--json` machine
|
|
36
|
+
output, and `--level call|turn` for CSV-style detail.
|
|
37
|
+
- **MCP-aware ergonomics.** The Codex parser records the `effort` field
|
|
38
|
+
from `turn_context` and surfaces it in the usage table model column
|
|
39
|
+
(e.g. `GPT-5.2 Codex · high`). The 5h-block card now carries a small
|
|
40
|
+
disclaimer ("wall-clock progress of the 5h window — not your plan
|
|
41
|
+
quota") so users don't confuse our local block tracker with Anthropic's
|
|
42
|
+
actual rate-limit counter.
|
|
43
|
+
|
|
44
|
+
### Added
|
|
45
|
+
|
|
46
|
+
- **Activity stats** — `lib/aggregator/activity.ts` computes streaks /
|
|
47
|
+
heat-map / favorite model / token-comparison; rendered by
|
|
48
|
+
`components/activity-stats.tsx` on the overview.
|
|
49
|
+
- **Silent auto-refresh on the usage page** — `components/auto-refresh.tsx`
|
|
50
|
+
re-runs the server render every 15 s via `router.refresh()`. No spinner,
|
|
51
|
+
no scroll reset, no search/expand state loss; pauses on hidden tabs.
|
|
52
|
+
- **Overview show/hide toggle** on the usage page —
|
|
53
|
+
`components/overview-toggle.tsx` hides the KPI grid + trend chart for
|
|
54
|
+
users who only want the table. State persists to localStorage and is
|
|
55
|
+
applied pre-paint by the no-flash script so collapsed users don't see
|
|
56
|
+
a flash.
|
|
57
|
+
- **Token-breakdown popover** in the usage table — hover the total cell
|
|
58
|
+
to see input / output / cache-read / cache-create tokens with their
|
|
59
|
+
per-component cost.
|
|
60
|
+
- **Codex `effort` field** plumbed from JSONL → AssistantRecord →
|
|
61
|
+
UsageTableRow → model column display.
|
|
62
|
+
- **Per-call "direct prompt"** on child rows — surfaces skill metadata
|
|
63
|
+
(`Base directory for this skill: /Users/.../skills/mf-commit`) on the
|
|
64
|
+
individual API calls inside a Skill block, while the parent turn row
|
|
65
|
+
shows the real human prompt.
|
|
66
|
+
- **CSV export overhaul** (`app/api/export/usage/route.ts`):
|
|
67
|
+
- UTF-8 BOM so Excel for Windows / Mac opens it without mojibake.
|
|
68
|
+
- Expanded column set: `turn_started_at`, `turn_ended_at`, `source`,
|
|
69
|
+
`model_short`, `effort`, `reasoning_tokens`, `project_name`,
|
|
70
|
+
`project_path`, `user_prompt`, etc.
|
|
71
|
+
- `?level=turn` for one row per conversation turn instead of one per
|
|
72
|
+
API call.
|
|
73
|
+
- Filename embeds range + level (e.g.
|
|
74
|
+
`ccgauge-usage-claude-7d-turn-2026-05-12.csv`).
|
|
75
|
+
- **Cross-platform CLI hardening** (`bin/cli.mjs`):
|
|
76
|
+
- `safeKill(pid, signal)` wraps `process.kill` with `ESRCH` tolerance.
|
|
77
|
+
- `windowsHide: true` on the background `spawn` so Windows doesn't flash
|
|
78
|
+
a console window.
|
|
79
|
+
- `restart` inherits the previous session's `port / host / dir / log`
|
|
80
|
+
when the user doesn't override them.
|
|
81
|
+
- `0.0.0.0 / ::` is rewritten to `127.0.0.1` for the browser-open URL.
|
|
82
|
+
- `getPort` candidates widened to 20 ports past the preferred.
|
|
83
|
+
- `waitForUrl` per-attempt `AbortSignal.timeout(500)`.
|
|
84
|
+
- `logs --follow` uses incremental `createReadStream` instead of
|
|
85
|
+
reading the whole file every tick.
|
|
86
|
+
- `state.json` carries a `version` field; readers ignore unknown shapes.
|
|
87
|
+
- **`AGENTS.md`** — working agreement for AI coding agents editing the
|
|
88
|
+
repo. Architecture invariants, common pitfalls, "first file to open"
|
|
89
|
+
table for typical symptoms.
|
|
90
|
+
|
|
91
|
+
### Changed
|
|
92
|
+
|
|
93
|
+
- **Default theme is `dark`** (previously `system`). Existing users keep
|
|
94
|
+
their explicit choice.
|
|
95
|
+
- **Tools column visible by default** in the usage table; `STORAGE_KEY`
|
|
96
|
+
bumped to `cols.v3` so existing visibility prefs are reset to the new
|
|
97
|
+
defaults.
|
|
98
|
+
- **SegmentedPicker (range / granularity) active state** matches the
|
|
99
|
+
source-switcher: brand-color fill instead of muted gray. Visible in
|
|
100
|
+
both the page header (`今天 / 7天 / 30天 / 90天 / 全部`) and Section
|
|
101
|
+
headers (`小时 / 天 / 周 / 月`).
|
|
102
|
+
- **Page header layout** on the usage page — model / project filters
|
|
103
|
+
moved from the Trend section's right slot up to the page header
|
|
104
|
+
alongside the range picker. They apply to all of KPI / trend / table,
|
|
105
|
+
so they belong at the page level rather than scoped to one card.
|
|
106
|
+
- **Overview header** dropped the `costToday` and `activeSessions` KPI
|
|
107
|
+
cards — they overlapped with the existing trend chart + activity
|
|
108
|
+
stats.
|
|
109
|
+
- **5h block card** — `{pct}% elapsed` renamed to `Time elapsed {pct}%`
|
|
110
|
+
/ `时间进度 {pct}%`, with a disclaimer line clarifying it's wall-clock
|
|
111
|
+
progress, not plan quota.
|
|
112
|
+
- **CLI option `-h, --host` → `-H, --host`.** `-h` now reliably resolves
|
|
113
|
+
to `--help` for `ccgauge start` and friends. Long form `--host` is
|
|
114
|
+
unchanged.
|
|
115
|
+
- **CLI auto-open semantics:** foreground opens the browser by default
|
|
116
|
+
(`--no-open` to disable); background never auto-opens (`ccgauge open`
|
|
117
|
+
to open the running one).
|
|
118
|
+
- **Build pipeline:** moved from `prepublishOnly` to `prepack` so
|
|
119
|
+
`pnpm pack` also runs the build. Build now strips `@img/sharp-*`
|
|
120
|
+
binaries + the bundled `typescript` package from `.next/standalone` so
|
|
121
|
+
the published tarball is cross-platform (no `.node` / `.dylib` files
|
|
122
|
+
ship). Tarball is ~6.8 MB compressed.
|
|
123
|
+
- **pnpm `node-linker = hoisted`** in `.npmrc`. Next.js standalone +
|
|
124
|
+
pnpm's default isolated layout produced tarballs missing top-level
|
|
125
|
+
`node_modules/next` (npm pack drops symlinks). Hoisted sidesteps it.
|
|
126
|
+
- **i18n / Chinese day-of-week labels** changed from one-char (`一 / 二`)
|
|
127
|
+
to full `周一 / 周二 / …` for clarity.
|
|
128
|
+
|
|
129
|
+
### Fixed
|
|
130
|
+
|
|
131
|
+
- **Skill-injection turn splitting** — see Highlights.
|
|
132
|
+
- **5h block height** in the overview row now matches the activity card.
|
|
133
|
+
- **Nav scrollbar artefact** — the nav's `overflow-x-auto` rendered a
|
|
134
|
+
thin gray scrollbar track on macOS even when content didn't overflow,
|
|
135
|
+
which read as a divider against the navbar background. Replaced
|
|
136
|
+
`scrollbar-thin` with a `nav-scroller` rule that hides the bar
|
|
137
|
+
entirely.
|
|
138
|
+
- **Activity heatmap labels** — y-axis now shows every row (was every
|
|
139
|
+
other), x-axis labels every 3 hours (was every 6).
|
|
140
|
+
|
|
141
|
+
### Notes for users upgrading from 0.4.x
|
|
142
|
+
|
|
143
|
+
- No data-file or storage migration is required. Cached entries are
|
|
144
|
+
re-parsed automatically on first run (`parserVersion` bumped to
|
|
145
|
+
`claude-v3-synthetic-flag` and `codex-v4-effort`).
|
|
146
|
+
- Two localStorage keys you may want to clear if you want pristine
|
|
147
|
+
defaults: `ccgauge.usage.cols.*` (column visibility) and
|
|
148
|
+
`ccgauge.usage.overview.hidden` (overview collapsed). Otherwise we
|
|
149
|
+
honor whatever you had.
|
|
150
|
+
- If you scripted around the CSV column order, note that headers have
|
|
151
|
+
been renamed (`cost` → `cost_usd`, `input` → `input_tokens`, etc.)
|
|
152
|
+
and new columns were added. The metadata header (lines starting with
|
|
153
|
+
`#`) now also lists `level=call|turn`.
|
|
154
|
+
|
|
8
155
|
## [0.4.0] — 2026-05-05
|
|
9
156
|
|
|
10
157
|
This release ships an **MCP (Model Context Protocol) server** so any
|
package/README.md
CHANGED
|
@@ -128,7 +128,46 @@ Background mode persists state under `~/.ccgauge/`:
|
|
|
128
128
|
| `ccgauge restart [options]` | Stop and re-start with new options. |
|
|
129
129
|
| `ccgauge status [--json]` | Inspect the background service. |
|
|
130
130
|
| `ccgauge open` | Open the running dashboard in your browser. |
|
|
131
|
-
| `ccgauge logs [-f] [-n <lines>]` | Print background
|
|
131
|
+
| `ccgauge logs [-f] [-n <lines>]` | Print background-service log file (the server's stdout). |
|
|
132
|
+
| `ccgauge report [options]` | Print a formatted **usage report** to stdout (one-shot, no server). |
|
|
133
|
+
| `ccgauge mcp` | Start the MCP server on stdio so LLMs can query usage. |
|
|
134
|
+
|
|
135
|
+
### Report
|
|
136
|
+
|
|
137
|
+
A no-server one-shot summary that reads the same JSONL files the dashboard does
|
|
138
|
+
and prints a colored, aligned report:
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
ccgauge report # last 7d, all sources, top 10 models
|
|
142
|
+
ccgauge report -r 30d -b project # 30 days, broken down by project
|
|
143
|
+
ccgauge report -s codex -m gpt-5.5 # only codex, only gpt-5.5*
|
|
144
|
+
ccgauge report --json # JSON output for scripting
|
|
145
|
+
ccgauge report --since 2026-05-01 --until 2026-05-08
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Report options:
|
|
149
|
+
|
|
150
|
+
| Option | Default | Purpose |
|
|
151
|
+
| --- | --- | --- |
|
|
152
|
+
| `-r, --range <range>` | `7d` | `today` / `1d` / `7d` / `30d` / `90d` / `all` |
|
|
153
|
+
| `-s, --source <provider>` | `all` | `claude` / `codex` / `all` |
|
|
154
|
+
| `-b, --by <dim>` | `model` | Breakdown dimension: `model` / `project` / `session` |
|
|
155
|
+
| `-g, --gran <granularity>` | `day` | Trend bucket: `hour` / `day` / `week` / `month` |
|
|
156
|
+
| `-n, --limit <n>` | `10` | Rows in the breakdown table |
|
|
157
|
+
| `--since <date>` | — | Override range start (ISO date or `YYYY-MM-DD`) |
|
|
158
|
+
| `--until <date>` | — | Override range end |
|
|
159
|
+
| `-m, --model <pat>` | — | Filter records whose model contains `<pat>` |
|
|
160
|
+
| `--project <pat>` | — | Filter by project basename / cwd substring |
|
|
161
|
+
| `-j, --json` | off | Machine-readable JSON instead of formatted text |
|
|
162
|
+
| `--no-color` | — | Disable ANSI colors (auto-disabled when piped) |
|
|
163
|
+
| `--no-trend` | — | Skip the trend chart |
|
|
164
|
+
| `--no-breakdown` | — | Skip the breakdown table |
|
|
165
|
+
|
|
166
|
+
Date-only `--since/--until` values use local calendar-day boundaries, so
|
|
167
|
+
`--until 2026-05-08` includes all of May 8.
|
|
168
|
+
|
|
169
|
+
> The name `report` (not `logs`) avoids clashing with `ccgauge logs`, which tails
|
|
170
|
+
> the background server's stdout log file.
|
|
132
171
|
|
|
133
172
|
### Startup options
|
|
134
173
|
|
|
@@ -397,7 +436,7 @@ This repo is a working Next.js project — run the dashboard against your live d
|
|
|
397
436
|
git clone https://github.com/chengzuopeng/ccgauge.git
|
|
398
437
|
cd ccgauge
|
|
399
438
|
pnpm install
|
|
400
|
-
pnpm dev # http://localhost:
|
|
439
|
+
pnpm dev # http://localhost:3738
|
|
401
440
|
```
|
|
402
441
|
|
|
403
442
|
Scripts:
|
package/README.zh-CN.md
CHANGED
|
@@ -128,7 +128,44 @@ ccgauge stop
|
|
|
128
128
|
| `ccgauge restart [options]` | 停止再用新参数启动。 |
|
|
129
129
|
| `ccgauge status [--json]` | 查看后台状态。 |
|
|
130
130
|
| `ccgauge open` | 在浏览器打开正在运行的看板。 |
|
|
131
|
-
| `ccgauge logs [-f] [-n <lines>]` |
|
|
131
|
+
| `ccgauge logs [-f] [-n <lines>]` | 查看后台服务的日志(server stdout)。 |
|
|
132
|
+
| `ccgauge report [options]` | 命令行**用量报告**,直接打到终端(一次性,不起服务)。 |
|
|
133
|
+
| `ccgauge mcp` | 起 MCP 服务(stdio),让 LLM 查你的用量。 |
|
|
134
|
+
|
|
135
|
+
### 命令行报告(report)
|
|
136
|
+
|
|
137
|
+
不需要起 server,直接读 JSONL,在终端打印漂亮的彩色对齐报告:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
ccgauge report # 默认:近 7 天 / 所有数据源 / 前 10 个模型
|
|
141
|
+
ccgauge report -r 30d -b project # 30 天,按项目分组
|
|
142
|
+
ccgauge report -s codex -m gpt-5.5 # 只看 codex 的 gpt-5.5*
|
|
143
|
+
ccgauge report --json # 输出 JSON 给脚本用
|
|
144
|
+
ccgauge report --since 2026-05-01 --until 2026-05-08
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
report 参数:
|
|
148
|
+
|
|
149
|
+
| 参数 | 默认 | 作用 |
|
|
150
|
+
| --- | --- | --- |
|
|
151
|
+
| `-r, --range <range>` | `7d` | `today` / `1d` / `7d` / `30d` / `90d` / `all` |
|
|
152
|
+
| `-s, --source <provider>` | `all` | `claude` / `codex` / `all` |
|
|
153
|
+
| `-b, --by <dim>` | `model` | 分组维度:`model` / `project` / `session` |
|
|
154
|
+
| `-g, --gran <granularity>` | `day` | 趋势粒度:`hour` / `day` / `week` / `month` |
|
|
155
|
+
| `-n, --limit <n>` | `10` | 分组表显示行数 |
|
|
156
|
+
| `--since <date>` | — | 自定义起始日期(覆盖 `--range`,支持 `YYYY-MM-DD`) |
|
|
157
|
+
| `--until <date>` | — | 自定义截止日期 |
|
|
158
|
+
| `-m, --model <pat>` | — | 按模型名子串过滤 |
|
|
159
|
+
| `--project <pat>` | — | 按项目名 / cwd 子串过滤 |
|
|
160
|
+
| `-j, --json` | off | 输出 JSON 而不是格式化文本 |
|
|
161
|
+
| `--no-color` | — | 关掉 ANSI 颜色(管道里会自动关) |
|
|
162
|
+
| `--no-trend` | — | 不画趋势条 |
|
|
163
|
+
| `--no-breakdown` | — | 不打分组表 |
|
|
164
|
+
|
|
165
|
+
只写日期的 `--since/--until` 会按本地自然日边界处理,所以
|
|
166
|
+
`--until 2026-05-08` 会包含 5 月 8 日整天。
|
|
167
|
+
|
|
168
|
+
> 用 `report` 而不是 `logs` 是为了避免和 `ccgauge logs`(tail 后台 server 的 stdout)混淆。
|
|
132
169
|
|
|
133
170
|
### 启动参数
|
|
134
171
|
|
|
@@ -392,7 +429,7 @@ lib/providers/<name>/
|
|
|
392
429
|
git clone https://github.com/chengzuopeng/ccgauge.git
|
|
393
430
|
cd ccgauge
|
|
394
431
|
pnpm install
|
|
395
|
-
pnpm dev # http://localhost:
|
|
432
|
+
pnpm dev # http://localhost:3738
|
|
396
433
|
```
|
|
397
434
|
|
|
398
435
|
常用脚本:
|
package/bin/cli.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import { closeSync, createReadStream, existsSync, openSync } from 'node:fs';
|
|
|
4
4
|
import { mkdir, readFile, rm, stat, writeFile } from 'node:fs/promises';
|
|
5
5
|
import os from 'node:os';
|
|
6
6
|
import { dirname, join, resolve } from 'node:path';
|
|
7
|
-
import { fileURLToPath } from 'node:url';
|
|
7
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
8
8
|
import { createRequire } from 'node:module';
|
|
9
9
|
|
|
10
10
|
const require = createRequire(import.meta.url);
|
|
@@ -25,8 +25,15 @@ const DEFAULT_LOG_FILE = join(STATE_DIR, 'ccgauge.log');
|
|
|
25
25
|
const STATE_VERSION = 1;
|
|
26
26
|
const DEFAULT_PORT = '3737';
|
|
27
27
|
const DEFAULT_HOST = '127.0.0.1';
|
|
28
|
-
const COMMAND_NAMES = new Set([
|
|
29
|
-
|
|
28
|
+
const COMMAND_NAMES = new Set([
|
|
29
|
+
'start', 'stop', 'restart', 'status', 'open', 'logs', 'mcp',
|
|
30
|
+
'report',
|
|
31
|
+
]);
|
|
32
|
+
const VALUE_OPTIONS = new Set([
|
|
33
|
+
'-p', '--port', '-H', '--host', '--dir', '--log', '-n', '--lines',
|
|
34
|
+
'-r', '--range', '-s', '--source', '-b', '--by', '-g', '--gran',
|
|
35
|
+
'-m', '--model', '--project', '--since', '--until',
|
|
36
|
+
]);
|
|
30
37
|
|
|
31
38
|
function browserHost(host) {
|
|
32
39
|
if (!host || host === '0.0.0.0' || host === '::' || host === '[::]') return '127.0.0.1';
|
|
@@ -139,6 +146,28 @@ program
|
|
|
139
146
|
await startMcp();
|
|
140
147
|
});
|
|
141
148
|
|
|
149
|
+
function addReportOptions(cmd) {
|
|
150
|
+
return cmd
|
|
151
|
+
.option('-r, --range <range>', 'today | 1d | 7d | 30d | 90d | all', '7d')
|
|
152
|
+
.option('-s, --source <provider>', 'claude | codex | all', 'all')
|
|
153
|
+
.option('-b, --by <dim>', 'breakdown dimension: model | project | session', 'model')
|
|
154
|
+
.option('-g, --gran <granularity>', 'trend granularity: hour | day | week | month', 'day')
|
|
155
|
+
.option('-n, --limit <n>', 'rows in breakdown table', '10')
|
|
156
|
+
.option('--since <date>', 'override range start (ISO date or YYYY-MM-DD)')
|
|
157
|
+
.option('--until <date>', 'override range end (ISO date or YYYY-MM-DD)')
|
|
158
|
+
.option('-m, --model <pat>', 'filter by model substring')
|
|
159
|
+
.option('--project <pat>', 'filter by project (cwd basename match)')
|
|
160
|
+
.option('-j, --json', 'output JSON instead of formatted text')
|
|
161
|
+
.option('--no-color', 'disable ANSI colors')
|
|
162
|
+
.option('--no-trend', 'skip the trend chart')
|
|
163
|
+
.option('--no-breakdown', 'skip the breakdown table');
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
addReportOptions(program.command('report').description('print a formatted usage report to stdout'))
|
|
167
|
+
.action(async (opts) => {
|
|
168
|
+
await report(opts);
|
|
169
|
+
});
|
|
170
|
+
|
|
142
171
|
await program.parseAsync(normalizeArgv(process.argv));
|
|
143
172
|
|
|
144
173
|
function normalizeArgv(argv) {
|
|
@@ -228,6 +257,9 @@ async function startBackground(standaloneEntry, opts) {
|
|
|
228
257
|
env,
|
|
229
258
|
detached: true,
|
|
230
259
|
stdio: ['ignore', out, err],
|
|
260
|
+
// Suppress the fleeting console window that Windows pops up for a
|
|
261
|
+
// detached background child. No-op on macOS/Linux.
|
|
262
|
+
windowsHide: true,
|
|
231
263
|
});
|
|
232
264
|
child.unref();
|
|
233
265
|
// Once spawn() has dup'd these fds into the child, the parent can release them.
|
|
@@ -351,6 +383,54 @@ or run the dev server with
|
|
|
351
383
|
process.exit(1);
|
|
352
384
|
}
|
|
353
385
|
|
|
386
|
+
async function report(opts) {
|
|
387
|
+
const bundle = join(packageRoot, 'dist', 'report', 'index.mjs');
|
|
388
|
+
if (!existsSync(bundle)) {
|
|
389
|
+
console.error(`
|
|
390
|
+
[ccgauge] Report bundle not found:
|
|
391
|
+
${bundle}
|
|
392
|
+
|
|
393
|
+
If you installed ccgauge from npm: please reinstall — the published package
|
|
394
|
+
should include the report bundle.
|
|
395
|
+
|
|
396
|
+
If you are running from source: build it first with
|
|
397
|
+
$ pnpm build:report
|
|
398
|
+
or run the full build with
|
|
399
|
+
$ pnpm build
|
|
400
|
+
`);
|
|
401
|
+
process.exit(1);
|
|
402
|
+
}
|
|
403
|
+
const limit = parseInt(String(opts.limit ?? '10'), 10);
|
|
404
|
+
const reportOpts = {
|
|
405
|
+
range: String(opts.range ?? '7d'),
|
|
406
|
+
source: String(opts.source ?? 'all'),
|
|
407
|
+
by: String(opts.by ?? 'model'),
|
|
408
|
+
gran: String(opts.gran ?? 'day'),
|
|
409
|
+
limit: Number.isFinite(limit) && limit > 0 ? limit : 10,
|
|
410
|
+
since: opts.since ? String(opts.since) : undefined,
|
|
411
|
+
until: opts.until ? String(opts.until) : undefined,
|
|
412
|
+
json: Boolean(opts.json),
|
|
413
|
+
color: opts.color !== false && process.stdout.isTTY,
|
|
414
|
+
showTrend: opts.trend !== false,
|
|
415
|
+
showBreakdown: opts.breakdown !== false,
|
|
416
|
+
model: opts.model ? String(opts.model) : undefined,
|
|
417
|
+
project: opts.project ? String(opts.project) : undefined,
|
|
418
|
+
};
|
|
419
|
+
try {
|
|
420
|
+
const mod = await import(pathToFileURL(bundle).href);
|
|
421
|
+
const out = await mod.runReport(reportOpts);
|
|
422
|
+
process.stdout.write(out);
|
|
423
|
+
if (!out.endsWith('\n')) process.stdout.write('\n');
|
|
424
|
+
} catch (err) {
|
|
425
|
+
console.error(`[ccgauge] report failed: ${(err && err.message) || err}`);
|
|
426
|
+
process.exit(1);
|
|
427
|
+
}
|
|
428
|
+
// The indexer keeps fs watchers alive, which would block process exit.
|
|
429
|
+
// For a one-shot report we explicitly exit once stdout is drained.
|
|
430
|
+
process.stdout.once?.('drain', () => process.exit(0));
|
|
431
|
+
if (process.stdout.writableLength === 0) process.exit(0);
|
|
432
|
+
}
|
|
433
|
+
|
|
354
434
|
async function startMcp() {
|
|
355
435
|
const bundle = join(packageRoot, 'dist', 'mcp', 'server.mjs');
|
|
356
436
|
if (!existsSync(bundle)) {
|