claude-cost 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/README.md +15 -0
- package/dist/index.js +22 -0
- package/package.json +48 -0
package/README.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# claude-cost
|
|
2
|
+
|
|
3
|
+
To install dependencies:
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
bun install
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
To run:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
bun run index.ts
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
This project was created using `bun init` in bun v1.3.5. [Bun](https://bun.com) is a fast all-in-one JavaScript runtime.
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
var ho=Object.defineProperty;var ko=(c,o)=>{for(var A in o)ho(c,A,{get:o[A],enumerable:!0,configurable:!0,set:(b)=>o[A]=()=>b})};var $o=(c,o)=>()=>(c&&(o=c(c=0)),o);function Oo(c){if(O[c])return O[c];let o=c.toLowerCase();for(let[A,b]of Object.entries(O))if(o.includes(A.toLowerCase())||A.toLowerCase().includes(o))return b;if(o.includes("opus-4-5")||o.includes("opus-4.5")||o.includes("opus4.5"))return O["claude-opus-4-5-20251101"];if(o.includes("sonnet-4-5")||o.includes("sonnet-4.5")||o.includes("sonnet4.5"))return O["claude-sonnet-4-5-20241022"];if(o.includes("haiku-4-5")||o.includes("haiku-4.5")||o.includes("haiku4.5"))return O["claude-3-5-haiku-20241022"];if(o.includes("opus-4")||o.includes("opus4"))return O["claude-opus-4-20250514"];if(o.includes("sonnet-4")||o.includes("sonnet4"))return O["claude-sonnet-4-20250514"];if(o.includes("3-5-haiku")||o.includes("3.5-haiku"))return O["claude-3-5-haiku-20241022"];if(o.includes("haiku"))return O["claude-3-haiku-20240307"];if(o.includes("opus"))return O["claude-3-opus-20240229"];if(o.includes("sonnet"))return O["claude-3-5-sonnet-20241022"];return Io}function Xo(c,o,A,b=0,F=0){let P=Oo(c),$=o/1e6*P.input,g=A/1e6*P.output,f=b/1e6*P.cacheWrite,X=F/1e6*P.cacheRead;return $+g+f+X}function Uo(c){let o=c.toLowerCase();if(o.includes("opus-4-5")||o.includes("opus-4.5"))return"Opus 4.5";if(o.includes("sonnet-4-5")||o.includes("sonnet-4.5"))return"Sonnet 4.5";if(o.includes("haiku-4-5")||o.includes("haiku-4.5"))return"Haiku 4.5";if(o.includes("opus-4")||o.includes("opus4"))return"Opus 4";if(o.includes("sonnet-4")||o.includes("sonnet4"))return"Sonnet 4";if(o.includes("3-7-sonnet")||o.includes("3.7"))return"Sonnet 3.7";if(o.includes("3-5-sonnet")||o.includes("3.5-sonnet"))return"Sonnet 3.5";if(o.includes("3-5-haiku")||o.includes("3.5-haiku"))return"Haiku 3.5";if(o.includes("opus"))return"Opus 3";if(o.includes("sonnet"))return"Sonnet 3";if(o.includes("haiku"))return"Haiku 3";return c.slice(0,20)}var O,Io;var Yo=$o(()=>{O={"claude-opus-4-5-20251101":{input:5,output:25,cacheWrite:6.25,cacheRead:0.5},"claude-sonnet-4-5-20250929":{input:3,output:15,cacheWrite:3.75,cacheRead:0.3},"claude-haiku-4-5-20251001":{input:0.8,output:4,cacheWrite:1,cacheRead:0.08},"claude-opus-4-20250514":{input:15,output:75,cacheWrite:18.75,cacheRead:1.5},"claude-sonnet-4-5-20241022":{input:3,output:15,cacheWrite:3.75,cacheRead:0.3},"claude-sonnet-4-20250514":{input:3,output:15,cacheWrite:3.75,cacheRead:0.3},"claude-3-7-sonnet-20250219":{input:3,output:15,cacheWrite:3.75,cacheRead:0.3},"claude-3-5-sonnet-20241022":{input:3,output:15,cacheWrite:3.75,cacheRead:0.3},"claude-3-5-sonnet-20240620":{input:3,output:15,cacheWrite:3.75,cacheRead:0.3},"claude-3-5-haiku-20241022":{input:0.8,output:4,cacheWrite:1,cacheRead:0.08},"claude-3-opus-20240229":{input:15,output:75,cacheWrite:18.75,cacheRead:1.5},"claude-3-sonnet-20240229":{input:3,output:15,cacheWrite:3.75,cacheRead:0.3},"claude-3-haiku-20240307":{input:0.25,output:1.25,cacheWrite:0.3,cacheRead:0.03}},Io={input:3,output:15,cacheWrite:3.75,cacheRead:0.3}});var Ho={};ko(Ho,{parseAllUsage:()=>t,getProjectName:()=>Ao,getAllJsonlFiles:()=>zo,formatTokens:()=>L,formatCost:()=>G});import{homedir as Co}from"os";import{join as x}from"path";import{readdirSync as Zo,existsSync as Ro,readFileSync as mo}from"fs";function Lo(c){let o=[];try{let b=mo(c,"utf-8").split(`
|
|
3
|
+
`).filter(Boolean);for(let F of b)try{let P=JSON.parse(F);if(P.type!=="assistant")continue;let $=P.message;if(!$?.usage||!$?.model)continue;let g=$.usage,f=g.input_tokens||0,X=g.output_tokens||0,H=g.cache_creation_input_tokens||0,r=g.cache_read_input_tokens||0;if(f===0&&X===0&&H===0&&r===0)continue;let n=Xo($.model,f,X,H,r);o.push({timestamp:new Date(P.timestamp),model:$.model,usage:{inputTokens:f,outputTokens:X,cacheCreationTokens:H,cacheReadTokens:r},cost:n,sessionId:P.sessionId||"unknown",project:P.cwd||"unknown",messageId:$.id||P.uuid||"unknown"})}catch{}}catch{}return o}function zo(){let c=[];if(!Ro(go))return c;try{let o=Zo(go,{withFileTypes:!0});for(let A of o){if(!A.isDirectory())continue;let b=x(go,A.name),F=Zo(b).filter((P)=>P.endsWith(".jsonl"));for(let P of F)c.push(x(b,P))}}catch{}return c}function t(c,o){let A=zo(),b=[];for(let g of A){let f=Lo(g);b.push(...f)}let F=b;if(c)F=F.filter((g)=>g.timestamp>=c);if(o)F=F.filter((g)=>g.timestamp<=o);let P=new Set,$=[];F.sort((g,f)=>f.timestamp.getTime()-g.timestamp.getTime());for(let g of F){let f=`${g.sessionId}-${g.messageId}`;if(!P.has(f))P.add(f),$.push(g)}return $.sort((g,f)=>g.timestamp.getTime()-f.timestamp.getTime()),yo($)}function yo(c){let o={inputTokens:0,outputTokens:0,cacheCreationTokens:0,cacheReadTokens:0},A=0,b={},F=new Map,P=new Map,$=new Map,g=new Date;g.setHours(0,0,0,0);for(let r of c){if(A+=r.cost,o.inputTokens+=r.usage.inputTokens,o.outputTokens+=r.usage.outputTokens,o.cacheCreationTokens+=r.usage.cacheCreationTokens,o.cacheReadTokens+=r.usage.cacheReadTokens,!b[r.model])b[r.model]={cost:0,tokens:{inputTokens:0,outputTokens:0,cacheCreationTokens:0,cacheReadTokens:0},displayName:Uo(r.model)};let n=b[r.model];if(n.cost+=r.cost,n.tokens.inputTokens+=r.usage.inputTokens,n.tokens.outputTokens+=r.usage.outputTokens,n.tokens.cacheCreationTokens+=r.usage.cacheCreationTokens,n.tokens.cacheReadTokens+=r.usage.cacheReadTokens,!F.has(r.sessionId))F.set(r.sessionId,[]);F.get(r.sessionId).push(r);let Y=`${r.timestamp.getFullYear()}-${String(r.timestamp.getMonth()+1).padStart(2,"0")}-${String(r.timestamp.getDate()).padStart(2,"0")}`;if(!P.has(Y))P.set(Y,[]);if(P.get(Y).push(r),r.timestamp>=g){let p=r.timestamp.getHours();if(!$.has(p))$.set(p,{cost:0,tokens:0,messageCount:0});let K=$.get(p);K.cost+=r.cost,K.tokens+=r.usage.inputTokens+r.usage.outputTokens+r.usage.cacheCreationTokens+r.usage.cacheReadTokens,K.messageCount+=1}}let f=[];for(let[r,n]of F){let Y=n.sort((T,co)=>T.timestamp.getTime()-co.timestamp.getTime()),p={inputTokens:0,outputTokens:0,cacheCreationTokens:0,cacheReadTokens:0},K=0;for(let T of Y)K+=T.cost,p.inputTokens+=T.usage.inputTokens,p.outputTokens+=T.usage.outputTokens,p.cacheCreationTokens+=T.usage.cacheCreationTokens,p.cacheReadTokens+=T.usage.cacheReadTokens;let R=Y[0],B=Y[Y.length-1];f.push({sessionId:r,project:R.project,firstMessage:R.timestamp,lastMessage:B.timestamp,totalCost:K,totalTokens:p,messageCount:Y.length,model:B.model})}f.sort((r,n)=>n.lastMessage.getTime()-r.lastMessage.getTime());let X=[];for(let[r,n]of P){let Y={inputTokens:0,outputTokens:0,cacheCreationTokens:0,cacheReadTokens:0},p=0,K={},R=new Set;for(let B of n){if(p+=B.cost,Y.inputTokens+=B.usage.inputTokens,Y.outputTokens+=B.usage.outputTokens,Y.cacheCreationTokens+=B.usage.cacheCreationTokens,Y.cacheReadTokens+=B.usage.cacheReadTokens,R.add(B.sessionId),!K[B.model])K[B.model]={cost:0,tokens:{inputTokens:0,outputTokens:0,cacheCreationTokens:0,cacheReadTokens:0}};let T=K[B.model];T.cost+=B.cost,T.tokens.inputTokens+=B.usage.inputTokens,T.tokens.outputTokens+=B.usage.outputTokens,T.tokens.cacheCreationTokens+=B.usage.cacheCreationTokens,T.tokens.cacheReadTokens+=B.usage.cacheReadTokens}X.push({date:r,totalCost:p,totalTokens:Y,sessionCount:R.size,messageCount:n.length,byModel:K})}X.sort((r,n)=>n.date.localeCompare(r.date));let H=[];for(let[r,n]of $)H.push({hour:r,cost:n.cost,tokens:n.tokens,messageCount:n.messageCount});return H.sort((r,n)=>r.hour-n.hour),{entries:c,sessions:f,daily:X,hourly:H,totalCost:A,totalTokens:o,byModel:b}}function G(c){if(c>=1000)return`$${(c/1000).toFixed(2)}K`;if(c>=1)return`$${c.toFixed(2)}`;if(c>=0.01)return`$${c.toFixed(2)}`;return`${(c*100).toFixed(2)}¢`}function L(c){if(c>=1e6)return`${(c/1e6).toFixed(2)}M`;if(c>=1000)return`${(c/1000).toFixed(1)}K`;return c.toString()}function Ao(c){let o=c.split("/");return o[o.length-1]||c}var wo,go;var E=$o(()=>{Yo();wo=x(Co(),".claude"),go=x(wo,"projects")});import{render as Fc}from"ink";import{useState as w,useEffect as vo}from"react";import{Box as _,Text as k,useApp as ao,useInput as so}from"ink";import{Box as no,Text as W}from"ink";import{jsxDEV as l}from"react/jsx-dev-runtime";function j(){return l(no,{flexDirection:"column",alignItems:"center",marginBottom:1,children:[l(no,{children:[l(W,{color:"#FF6B6B",bold:!0,children:"C"},void 0,!1,void 0,this),l(W,{color:"#FF8E53",bold:!0,children:"L"},void 0,!1,void 0,this),l(W,{color:"#FFBA49",bold:!0,children:"A"},void 0,!1,void 0,this),l(W,{color:"#7BED9F",bold:!0,children:"U"},void 0,!1,void 0,this),l(W,{color:"#70A1FF",bold:!0,children:"D"},void 0,!1,void 0,this),l(W,{color:"#5352ED",bold:!0,children:"E"},void 0,!1,void 0,this),l(W,{color:"white",children:" "},void 0,!1,void 0,this),l(W,{color:"#A29BFE",bold:!0,children:"C"},void 0,!1,void 0,this),l(W,{color:"#FD79A8",bold:!0,children:"O"},void 0,!1,void 0,this),l(W,{color:"#FF6B6B",bold:!0,children:"S"},void 0,!1,void 0,this),l(W,{color:"#FF8E53",bold:!0,children:"T"},void 0,!1,void 0,this),l(W,{color:"gray",dimColor:!0,children:" │ Usage Analytics Dashboard"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),l(no,{children:[l(W,{color:"gray",children:"Press "},void 0,!1,void 0,this),l(W,{color:"yellow",children:"↑↓"},void 0,!1,void 0,this),l(W,{color:"gray",children:" scroll • "},void 0,!1,void 0,this),l(W,{color:"yellow",children:"tab"},void 0,!1,void 0,this),l(W,{color:"gray",children:" switch view • "},void 0,!1,void 0,this),l(W,{color:"yellow",children:"r"},void 0,!1,void 0,this),l(W,{color:"gray",children:" refresh • "},void 0,!1,void 0,this),l(W,{color:"yellow",children:"q"},void 0,!1,void 0,this),l(W,{color:"gray",children:" quit"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}import{Box as h,Text as u}from"ink";import{Box as bo,Text as D}from"ink";import{jsxDEV as V}from"react/jsx-dev-runtime";function M({title:c,children:o,width:A,borderColor:b="gray",titleColor:F="white"}){return V(bo,{flexDirection:"column",borderStyle:"round",borderColor:b,paddingX:1,width:A,children:[c&&V(bo,{marginBottom:0,children:V(D,{color:F,bold:!0,children:c},void 0,!1,void 0,this)},void 0,!1,void 0,this),o]},void 0,!0,void 0,this)}function fo({value:c,max:o,width:A=20,color:b="green",showPercent:F=!1}){let P=o>0?Math.min(c/o,1):0,$=Math.round(P*A),g=A-$,f="█".repeat($)+"░".repeat(g);return V(bo,{children:[V(D,{color:b,children:f},void 0,!1,void 0,this),F&&V(D,{color:"gray",children:[" ",(P*100).toFixed(0),"%"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}var Fo=["▁","▂","▃","▄","▅","▆","▇","█"];function qo({data:c,width:o=20,color:A="cyan"}){if(c.length===0)return V(D,{color:"gray",children:"─".repeat(o)},void 0,!1,void 0,this);let b=[],F=Math.max(1,Math.floor(c.length/o));for(let H=0;H<c.length;H+=F){let r=c.slice(H,Math.min(H+F,c.length));b.push(r.reduce((n,Y)=>n+Y,0)/r.length)}let P=Math.max(...b,0.001),$=Math.min(...b,0),g=P-$||1,X=b.slice(-o).map((H)=>{let r=(H-$)/g,n=Math.min(Math.floor(r*Fo.length),Fo.length-1);return Fo[n]}).join("").padStart(o," ");return V(D,{color:A,children:X},void 0,!1,void 0,this)}E();import{startOfWeek as io,startOfMonth as Vo}from"date-fns";import{jsxDEV as z}from"react/jsx-dev-runtime";function Qo({stats:c,periodLabel:o}){let A=c.totalTokens.inputTokens+c.totalTokens.outputTokens+c.totalTokens.cacheCreationTokens+c.totalTokens.cacheReadTokens,b=c.totalTokens.cacheReadTokens/1e6*3,F=c.totalTokens.cacheReadTokens/1e6*0.3,P=Math.max(0,b-F),$=c.daily.slice().reverse().map((g)=>g.totalCost);return z(M,{title:`\uD83D\uDCB0 ${o} Summary`,borderColor:"green",titleColor:"green",children:z(h,{flexDirection:"column",gap:0,children:[z(h,{children:[z(h,{width:18,children:z(u,{color:"gray",children:"Total Cost"},void 0,!1,void 0,this)},void 0,!1,void 0,this),z(u,{color:"green",bold:!0,children:G(c.totalCost)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),z(h,{children:[z(h,{width:18,children:z(u,{color:"gray",children:"Total Tokens"},void 0,!1,void 0,this)},void 0,!1,void 0,this),z(u,{color:"cyan",children:L(A)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),z(h,{children:[z(h,{width:18,children:z(u,{color:"gray",children:"Sessions"},void 0,!1,void 0,this)},void 0,!1,void 0,this),z(u,{color:"yellow",children:c.sessions.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),z(h,{children:[z(h,{width:18,children:z(u,{color:"gray",children:"Messages"},void 0,!1,void 0,this)},void 0,!1,void 0,this),z(u,{color:"magenta",children:c.entries.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P>0&&z(h,{children:[z(h,{width:18,children:z(u,{color:"gray",children:"Cache Savings"},void 0,!1,void 0,this)},void 0,!1,void 0,this),z(u,{color:"#7BED9F",children:["~",G(P)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),z(h,{marginTop:1,children:[z(u,{color:"gray",dimColor:!0,children:"Daily trend: "},void 0,!1,void 0,this),z(qo,{data:$,width:18,color:"#70A1FF"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)}function Jo({stats:c}){let o=new Date,A=`${o.getFullYear()}-${String(o.getMonth()+1).padStart(2,"0")}-${String(o.getDate()).padStart(2,"0")}`,b=c.daily.find((n)=>n.date===A),F=io(o,{weekStartsOn:0}),P=c.daily.filter((n)=>new Date(n.date)>=F),$=P.reduce((n,Y)=>n+Y.totalCost,0),g=P.reduce((n,Y)=>n+Y.messageCount,0),f=Vo(o),X=c.daily.filter((n)=>new Date(n.date)>=f),H=X.reduce((n,Y)=>n+Y.totalCost,0),r=X.reduce((n,Y)=>n+Y.messageCount,0);return z(h,{flexDirection:"row",gap:2,children:[z(M,{title:"Today",borderColor:"cyan",titleColor:"cyan",children:[z(u,{color:"green",bold:!0,children:G(b?.totalCost||0)},void 0,!1,void 0,this),z(u,{color:"gray",dimColor:!0,children:[" ",b?.messageCount||0," msgs"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),z(M,{title:"This Week",borderColor:"blue",titleColor:"blue",children:[z(u,{color:"green",bold:!0,children:G($)},void 0,!1,void 0,this),z(u,{color:"gray",dimColor:!0,children:[" ",g," msgs"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),z(M,{title:"This Month",borderColor:"magenta",titleColor:"magenta",children:[z(u,{color:"green",bold:!0,children:G(H)},void 0,!1,void 0,this),z(u,{color:"gray",dimColor:!0,children:[" ",r," msgs"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),z(M,{title:"All Time",borderColor:"yellow",titleColor:"yellow",children:[z(u,{color:"green",bold:!0,children:G(c.totalCost)},void 0,!1,void 0,this),z(u,{color:"gray",dimColor:!0,children:[" ",c.entries.length," msgs"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}import{Box as e,Text as d}from"ink";E();import{jsxDEV as C}from"react/jsx-dev-runtime";var Eo={"Opus 4.5":"#FF6B6B","Opus 4":"#FF8E53","Opus 3":"#FFBA49","Sonnet 4":"#70A1FF","Sonnet 3.7":"#5352ED","Sonnet 3.5":"#A29BFE","Sonnet 3":"#B8B5FF","Haiku 3.5":"#7BED9F","Haiku 3":"#2ECC71"};function po({stats:c}){let o=Object.entries(c.byModel).sort(([,b],[,F])=>F.cost-b.cost),A=Math.max(...o.map(([,b])=>b.cost),0.01);return C(M,{title:"\uD83D\uDCCA Cost by Model",borderColor:"cyan",titleColor:"cyan",children:C(e,{flexDirection:"column",gap:0,children:o.length===0?C(d,{color:"gray",dimColor:!0,children:"No usage data"},void 0,!1,void 0,this):o.map(([b,F])=>{let P=Eo[F.displayName]||"#888",$=F.tokens.inputTokens+F.tokens.outputTokens+F.tokens.cacheCreationTokens+F.tokens.cacheReadTokens;return C(e,{flexDirection:"column",marginBottom:0,children:C(e,{children:[C(e,{width:12,children:C(d,{color:P,bold:!0,children:F.displayName},void 0,!1,void 0,this)},void 0,!1,void 0,this),C(e,{width:10,children:C(d,{color:"white",bold:!0,children:G(F.cost)},void 0,!1,void 0,this)},void 0,!1,void 0,this),C(fo,{value:F.cost,max:A,width:16,color:P},void 0,!1,void 0,this),C(d,{color:"gray",dimColor:!0,children:[" ",L($)," tok"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},b,!1,void 0,this)})},void 0,!1,void 0,this)},void 0,!1,void 0,this)}import{Box as m,Text as N}from"ink";E();import{formatDistanceToNow as jo,format as Do}from"date-fns";import{jsxDEV as J}from"react/jsx-dev-runtime";var y={"Opus 4.5":{symbol:"◆",color:"#FF6B6B"},"Opus 4":{symbol:"◆",color:"#FF8E53"},"Opus 3":{symbol:"◆",color:"#FFBA49"},"Sonnet 4":{symbol:"●",color:"#70A1FF"},"Sonnet 3.7":{symbol:"●",color:"#5352ED"},"Sonnet 3.5":{symbol:"●",color:"#A29BFE"},"Sonnet 3":{symbol:"●",color:"#B8B5FF"},"Haiku 3.5":{symbol:"○",color:"#7BED9F"},"Haiku 3":{symbol:"○",color:"#2ECC71"}};function eo(c){let o=c.toLowerCase();if(o.includes("opus-4-5")||o.includes("opus-4.5"))return y["Opus 4.5"];if(o.includes("opus-4")||o.includes("opus4"))return y["Opus 4"];if(o.includes("sonnet-4")||o.includes("sonnet4"))return y["Sonnet 4"];if(o.includes("3-7-sonnet")||o.includes("3.7"))return y["Sonnet 3.7"];if(o.includes("3-5-sonnet")||o.includes("3.5-sonnet"))return y["Sonnet 3.5"];if(o.includes("3-5-haiku")||o.includes("3.5-haiku"))return y["Haiku 3.5"];if(o.includes("opus"))return y["Opus 3"];if(o.includes("sonnet"))return y["Sonnet 3"];if(o.includes("haiku"))return y["Haiku 3"];return{symbol:"◯",color:"#888"}}function lo({sessions:c,selectedIndex:o,maxVisible:A=8,focused:b=!1}){let F=Math.max(0,Math.min(o-Math.floor(A/2),c.length-A)),P=c.slice(F,F+A),$=F>0,g=F+A<c.length;return J(M,{title:`\uD83D\uDCDD Recent Sessions${b?" (↑↓)":""}`,borderColor:b?"cyan":"yellow",titleColor:b?"cyan":"yellow",children:J(m,{flexDirection:"column",children:[$&&J(m,{justifyContent:"center",children:J(N,{color:"gray",children:["▲ ",F," more"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),P.length===0?J(N,{color:"gray",dimColor:!0,children:"No sessions found"},void 0,!1,void 0,this):P.map((f,X)=>{let r=F+X===o,n=eo(f.model),Y=Ao(f.project),p=jo(f.lastMessage,{addSuffix:!0}),K=f.totalTokens.inputTokens+f.totalTokens.outputTokens+f.totalTokens.cacheCreationTokens+f.totalTokens.cacheReadTokens;return J(m,{flexDirection:"column",paddingX:1,paddingY:0,borderStyle:r?"round":void 0,borderColor:r?"cyan":void 0,children:[J(m,{children:[J(N,{color:n.color,children:[n.symbol," "]},void 0,!0,void 0,this),J(N,{color:r?"cyan":"white",bold:!0,children:Y.slice(0,24).padEnd(24)},void 0,!1,void 0,this),J(N,{color:"green",bold:!0,children:[" ",G(f.totalCost).padStart(8)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),J(m,{children:[J(N,{color:"gray",children:" "},void 0,!1,void 0,this),J(N,{color:"gray",dimColor:!0,children:p.padEnd(20)},void 0,!1,void 0,this),J(N,{color:"gray",dimColor:!0,children:[L(K)," tok"]},void 0,!0,void 0,this),J(N,{color:"gray",dimColor:!0,children:[" • ",f.messageCount," msgs"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},`${f.sessionId}-${X}`,!0,void 0,this)}),g&&J(m,{justifyContent:"center",children:J(N,{color:"gray",children:["▼ ",c.length-F-A," more"]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)}function Ko({daily:c,selectedIndex:o,maxVisible:A=8,focused:b=!1}){let F=Math.max(0,Math.min(o-Math.floor(A/2),c.length-A)),P=c.slice(F,F+A),$=Math.max(...c.map((X)=>X.totalCost),0.01),g=F>0,f=F+A<c.length;return J(M,{title:`\uD83D\uDCC5 Daily Costs${b?" (↑↓)":""}`,borderColor:b?"cyan":"green",titleColor:b?"cyan":"green",children:J(m,{flexDirection:"column",children:[g&&J(m,{justifyContent:"center",children:J(N,{color:"gray",children:["▲ ",F," more"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),P.length===0?J(N,{color:"gray",dimColor:!0,children:"No daily data"},void 0,!1,void 0,this):P.map((X,H)=>{let n=F+H===o,Y=X.date===new Date().toISOString().slice(0,10),p=Math.max(1,Math.round(X.totalCost/$*20)),K="█".repeat(p),R=X.totalTokens.inputTokens+X.totalTokens.outputTokens+X.totalTokens.cacheCreationTokens+X.totalTokens.cacheReadTokens;return J(m,{paddingX:1,borderStyle:n?"round":void 0,borderColor:n?"cyan":void 0,children:[J(N,{color:Y?"cyan":"gray",children:Do(new Date(X.date),"MMM dd")},void 0,!1,void 0,this),J(N,{color:"green",bold:!0,children:[" ",G(X.totalCost).padStart(8)," "]},void 0,!0,void 0,this),J(N,{color:"#70A1FF",children:K.padEnd(20)},void 0,!1,void 0,this),J(N,{color:"gray",dimColor:!0,children:[" ",L(R)]},void 0,!0,void 0,this)]},`${X.date}-${H}`,!0,void 0,this)}),f&&J(m,{justifyContent:"center",children:J(N,{color:"gray",children:["▼ ",c.length-F-A," more"]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)}import{Box as v,Text as Q}from"ink";E();import{format as a,startOfWeek as Wo,eachDayOfInterval as xo,subDays as to}from"date-fns";import{jsxDEV as q}from"react/jsx-dev-runtime";var S=["#161b22","#0e4429","#006d32","#26a641","#39d353"];function s(c,o){if(c===0)return S[0];let A=c/o;if(A<0.25)return S[1];if(A<0.5)return S[2];if(A<0.75)return S[3];return S[4]}function Bo({hourlyData:c}){let o=[];for(let P=0;P<24;P++){let $=c.find((g)=>g.hour===P);o.push($?.cost||0)}let A=Math.max(...o,0.01),b=o.reduce((P,$)=>P+$,0),F=o.indexOf(Math.max(...o));return q(M,{title:"Activity (Today)",borderColor:"gray",titleColor:"gray",children:q(v,{flexDirection:"column",children:[q(v,{flexDirection:"row",gap:0,children:o.map((P,$)=>q(Q,{color:s(P,A),children:"██"},$,!1,void 0,this))},void 0,!1,void 0,this),q(v,{marginTop:0,children:q(Q,{color:"gray",dimColor:!0,children:"0 6 12 18 23"},void 0,!1,void 0,this)},void 0,!1,void 0,this),q(v,{marginTop:0,gap:2,children:[q(Q,{color:"gray",dimColor:!0,children:"Total: "},void 0,!1,void 0,this),q(Q,{color:"green",children:G(b)},void 0,!1,void 0,this),q(Q,{color:"gray",dimColor:!0,children:" Peak hour: "},void 0,!1,void 0,this),q(Q,{color:"cyan",children:[F,":00"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)}function uo({dailyData:c}){let o=new Date,A=Wo(o,{weekStartsOn:0}),F=xo({start:A,end:o}).map((g)=>{let f=a(g,"yyyy-MM-dd"),X=c.find((H)=>H.date===f);return{day:g,cost:X?.cost||0,label:a(g,"EEE")}}),P=Math.max(...F.map((g)=>g.cost),0.01),$=F.reduce((g,f)=>g+f.cost,0);return q(M,{title:"Activity (This Week)",borderColor:"gray",titleColor:"gray",children:q(v,{flexDirection:"column",children:[q(v,{flexDirection:"row",gap:2,children:F.map((g,f)=>q(v,{flexDirection:"column",alignItems:"center",children:[q(Q,{color:s(g.cost,P),children:"██████"},void 0,!1,void 0,this),q(Q,{color:"gray",dimColor:!0,children:g.label},void 0,!1,void 0,this)]},f,!0,void 0,this))},void 0,!1,void 0,this),q(v,{marginTop:1,gap:2,children:[q(Q,{color:"gray",dimColor:!0,children:"Total: "},void 0,!1,void 0,this),q(Q,{color:"green",children:G($)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)}function Go({dailyData:c}){let o=new Date,A=o.getFullYear(),b=o.getMonth(),F=new Date(A,b,1),P=new Date(A,b+1,0),$=F.getDay(),g=[];for(let n=0;n<$;n++)g.push({day:null,cost:0});for(let n=1;n<=P.getDate();n++){let Y=`${A}-${String(b+1).padStart(2,"0")}-${String(n).padStart(2,"0")}`,p=c.find((K)=>K.date===Y);g.push({day:n,cost:p?.cost||0})}while(g.length%7!==0)g.push({day:null,cost:0});let f=Math.max(...g.map((n)=>n.cost),0.01),X=g.reduce((n,Y)=>n+Y.cost,0),H=[];for(let n=0;n<g.length;n+=7)H.push(g.slice(n,n+7));let r=["S","M","T","W","T","F","S"];return q(M,{title:`Activity (${a(o,"MMMM yyyy")})`,borderColor:"gray",titleColor:"gray",children:q(v,{flexDirection:"column",children:[q(v,{flexDirection:"row",gap:1,children:r.map((n,Y)=>q(Q,{color:"gray",dimColor:!0,children:[n," "]},Y,!0,void 0,this))},void 0,!1,void 0,this),H.map((n,Y)=>q(v,{flexDirection:"row",gap:1,children:n.map((p,K)=>q(Q,{color:p.day?s(p.cost,f):"#0d1117",children:"██"},K,!1,void 0,this))},Y,!1,void 0,this)),q(v,{marginTop:1,gap:2,children:[q(Q,{color:"gray",dimColor:!0,children:"Total: "},void 0,!1,void 0,this),q(Q,{color:"green",children:G(X)},void 0,!1,void 0,this),q(v,{marginLeft:1,children:[q(Q,{color:S[0],children:"█"},void 0,!1,void 0,this),q(Q,{color:"gray",dimColor:!0,children:" Less "},void 0,!1,void 0,this),q(Q,{color:S[1],children:"█"},void 0,!1,void 0,this),q(Q,{color:S[2],children:"█"},void 0,!1,void 0,this),q(Q,{color:S[3],children:"█"},void 0,!1,void 0,this),q(Q,{color:S[4],children:"█"},void 0,!1,void 0,this),q(Q,{color:"gray",dimColor:!0,children:" More"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)}function No({dailyData:c}){let o=new Date,A=Math.min(26,Math.ceil(c.length/7)||12),b=Array.from({length:7},()=>[]);for(let f=A-1;f>=0;f--){let X=Wo(to(o,f*7),{weekStartsOn:0});for(let H=0;H<7;H++){let r=new Date(X);r.setDate(X.getDate()+H);let n=a(r,"yyyy-MM-dd"),Y=c.find((p)=>p.date===n);b[H].push(Y?.cost||0)}}let F=b.flat(),P=Math.max(...F,0.01),$=F.reduce((f,X)=>f+X,0),g=["S","M","T","W","T","F","S"];return q(M,{title:"Activity (All Time)",borderColor:"gray",titleColor:"gray",children:q(v,{flexDirection:"column",children:[b.map((f,X)=>q(v,{flexDirection:"row",children:[q(Q,{color:"gray",dimColor:!0,children:[g[X]," "]},void 0,!0,void 0,this),f.map((H,r)=>q(Q,{color:s(H,P),children:"██"},r,!1,void 0,this))]},X,!0,void 0,this)),q(v,{marginTop:1,gap:2,children:[q(Q,{color:"gray",dimColor:!0,children:"Total: "},void 0,!1,void 0,this),q(Q,{color:"green",children:G($)},void 0,!1,void 0,this),q(Q,{color:"gray",dimColor:!0,children:[" (",c.length," days)"]},void 0,!0,void 0,this),q(v,{marginLeft:1,children:[q(Q,{color:S[0],children:"█"},void 0,!1,void 0,this),q(Q,{color:"gray",dimColor:!0,children:" Less "},void 0,!1,void 0,this),q(Q,{color:S[1],children:"█"},void 0,!1,void 0,this),q(Q,{color:S[2],children:"█"},void 0,!1,void 0,this),q(Q,{color:S[3],children:"█"},void 0,!1,void 0,this),q(Q,{color:S[4],children:"█"},void 0,!1,void 0,this),q(Q,{color:"gray",dimColor:!0,children:" More"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)}E();import{startOfWeek as oc,startOfMonth as cc,endOfMonth as rc,format as nc}from"date-fns";import{jsxDEV as Z}from"react/jsx-dev-runtime";function Mo(){let{exit:c}=ao(),[o,A]=w(null),[b,F]=w(null),[P,$]=w(!0),[g,f]=w(null),[X,H]=w("sessions"),[r,n]=w("today"),[Y,p]=w(0),[K,R]=w(0),[B,T]=w(new Date),[co,Po]=w(5),$c=5,ro=()=>{$(!0),f(null);try{let U,I,i=new Date;switch(r){case"today":U=new Date(i),U.setHours(0,0,0,0);break;case"week":U=oc(i,{weekStartsOn:0});break;case"month":U=cc(i),I=rc(i);break;case"all":default:U=void 0}let So=t(U,I);A(So);let _o=t();F(_o),T(new Date)}catch(U){f(U instanceof Error?U.message:"Unknown error")}finally{$(!1)}};if(vo(()=>{ro()},[r]),vo(()=>{let U=setInterval(()=>{Po((I)=>{if(I<=1)return ro(),5;return I-1})},1000);return()=>clearInterval(U)},[r]),so((U,I)=>{if(U==="q"||I.ctrl&&U==="c"){c();return}if(U==="r"){ro(),Po(5);return}if(I.tab||U==="\t"){H(X==="sessions"?"daily":"sessions");return}if(U==="1")n("today");if(U==="2")n("week");if(U==="3")n("month");if(U==="4")n("all");if(I.upArrow)if(X==="sessions")p(Math.max(0,Y-1));else R(Math.max(0,K-1));if(I.downArrow)if(X==="sessions"){let i=(o?.sessions.length||1)-1;p(Math.min(i,Y+1))}else{let i=(o?.daily.length||1)-1;R(Math.min(i,K+1))}}),P&&!o)return Z(_,{flexDirection:"column",alignItems:"center",padding:2,children:[Z(j,{},void 0,!1,void 0,this),Z(k,{color:"cyan",children:"Loading usage data..."},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(g)return Z(_,{flexDirection:"column",alignItems:"center",padding:2,children:[Z(j,{},void 0,!1,void 0,this),Z(k,{color:"red",children:["Error: ",g]},void 0,!0,void 0,this),Z(k,{color:"gray",children:"Press r to retry"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(!o)return Z(_,{flexDirection:"column",alignItems:"center",padding:2,children:[Z(j,{},void 0,!1,void 0,this),Z(k,{color:"yellow",children:"No usage data found"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);let To={today:"Today",week:"This Week",month:nc(new Date,"MMMM yyyy"),all:"All Time"}[r];return Z(_,{flexDirection:"column",padding:1,children:[Z(j,{},void 0,!1,void 0,this),Z(_,{marginBottom:1,gap:1,children:[Z(k,{color:"gray",children:"Time: "},void 0,!1,void 0,this),["today","week","month","all"].map((U,I)=>Z(_,{children:Z(k,{color:r===U?"cyan":"gray",bold:r===U,inverse:r===U,children:` ${I+1}:${U.charAt(0).toUpperCase()+U.slice(1)} `},void 0,!1,void 0,this)},U,!1,void 0,this)),Z(k,{color:"gray",children:" │ Focus: "},void 0,!1,void 0,this),["sessions","daily"].map((U)=>Z(k,{color:X===U?"yellow":"gray",bold:X===U,children:[X===U?`[${U}]`:U," "]},U,!0,void 0,this)),Z(k,{color:"gray",dimColor:!0,children:[" ","│ ",B.toLocaleTimeString()]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Z(Jo,{stats:b||o},void 0,!1,void 0,this),Z(_,{flexDirection:"column",marginTop:1,gap:1,children:[Z(_,{flexDirection:"row",gap:1,children:[Z(_,{flexDirection:"column",gap:1,width:"50%",children:[Z(Qo,{stats:o,periodLabel:To},void 0,!1,void 0,this),Z(po,{stats:o},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Z(_,{flexDirection:"column",gap:1,width:"50%",children:Z(lo,{sessions:o.sessions,selectedIndex:X==="sessions"?Y:-1,maxVisible:8,focused:X==="sessions"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Z(_,{flexDirection:"row",gap:1,children:[Z(_,{width:"50%",children:[r==="today"&&Z(Bo,{hourlyData:o.hourly.map((U)=>({hour:U.hour,cost:U.cost}))},void 0,!1,void 0,this),r==="week"&&Z(uo,{dailyData:o.daily.map((U)=>({date:U.date,cost:U.totalCost}))},void 0,!1,void 0,this),r==="month"&&Z(Go,{dailyData:o.daily.map((U)=>({date:U.date,cost:U.totalCost}))},void 0,!1,void 0,this),r==="all"&&Z(No,{dailyData:(b||o).daily.map((U)=>({date:U.date,cost:U.totalCost}))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Z(_,{width:"50%",children:Z(Ko,{daily:o.daily,selectedIndex:X==="daily"?K:-1,maxVisible:8,focused:X==="daily"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Z(_,{marginTop:1,justifyContent:"center",children:[Z(k,{color:"gray",dimColor:!0,children:[o.entries.length," messages from ",o.sessions.length," sessions"]},void 0,!0,void 0,this),Z(k,{color:"gray",children:" • "},void 0,!1,void 0,this),P?Z(k,{color:"cyan",children:"↻ Refreshing..."},void 0,!1,void 0,this):Z(k,{color:"gray",dimColor:!0,children:["Next refresh in ",co,"s"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}import{jsxDEV as Pc}from"react/jsx-dev-runtime";var oo=process.argv.slice(2),bc=oo.includes("--json")||oo.includes("-j"),gc=oo.includes("--help")||oo.includes("-h");if(gc)console.log(`
|
|
4
|
+
\x1B[1m\x1B[36mCLAUDE COST\x1B[0m - Beautiful Claude Code Usage Analytics
|
|
5
|
+
|
|
6
|
+
\x1B[33mUsage:\x1B[0m
|
|
7
|
+
claude-cost Launch interactive TUI dashboard
|
|
8
|
+
claude-cost --json Output stats as JSON (for scripts)
|
|
9
|
+
claude-cost --help Show this help message
|
|
10
|
+
|
|
11
|
+
\x1B[33mKeyboard Controls (TUI):\x1B[0m
|
|
12
|
+
↑/↓ Scroll through lists
|
|
13
|
+
Tab Switch between views (overview/sessions/daily)
|
|
14
|
+
1/2/3/4 Filter by time (today/week/month/all)
|
|
15
|
+
r Refresh data
|
|
16
|
+
q Quit
|
|
17
|
+
|
|
18
|
+
\x1B[33mData Source:\x1B[0m
|
|
19
|
+
Reads from ~/.claude/projects/*/*.jsonl
|
|
20
|
+
|
|
21
|
+
\x1B[90mPricing based on LiteLLM model costs\x1B[0m
|
|
22
|
+
`),process.exit(0);var Ac=process.stdin.isTTY&&process.stdout.isTTY;if(!Ac||bc){let{parseAllUsage:c,formatCost:o,formatTokens:A}=await Promise.resolve().then(() => (E(),Ho)),b=c(),F={totalCost:o(b.totalCost),totalTokens:A(b.totalTokens.inputTokens+b.totalTokens.outputTokens+b.totalTokens.cacheCreationTokens+b.totalTokens.cacheReadTokens),sessions:b.sessions.length,messages:b.entries.length,breakdown:Object.fromEntries(Object.entries(b.byModel).map(([P,$])=>[$.displayName,{cost:o($.cost),tokens:A($.tokens.inputTokens+$.tokens.outputTokens+$.tokens.cacheCreationTokens+$.tokens.cacheReadTokens)}]))};console.log(JSON.stringify(F,null,2)),process.exit(0)}console.clear();Fc(Pc(Mo,{},void 0,!1,void 0,this));
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "claude-cost",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Beautiful TUI for Claude Code cost analytics",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"claude-cost": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist"
|
|
12
|
+
],
|
|
13
|
+
"publishConfig": {
|
|
14
|
+
"access": "public"
|
|
15
|
+
},
|
|
16
|
+
"scripts": {
|
|
17
|
+
"start": "bun run src/index.tsx",
|
|
18
|
+
"dev": "bun --watch src/index.tsx",
|
|
19
|
+
"build": "bun run build.ts",
|
|
20
|
+
"prepublishOnly": "bun run build"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"claude",
|
|
24
|
+
"claude-code",
|
|
25
|
+
"anthropic",
|
|
26
|
+
"cost",
|
|
27
|
+
"analytics",
|
|
28
|
+
"tui",
|
|
29
|
+
"cli",
|
|
30
|
+
"usage",
|
|
31
|
+
"tokens"
|
|
32
|
+
],
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"engines": {
|
|
35
|
+
"node": ">=18",
|
|
36
|
+
"bun": ">=1.0"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@types/bun": "latest",
|
|
40
|
+
"@types/react": "^19.2.7"
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"chalk": "^5.6.2",
|
|
44
|
+
"date-fns": "^4.1.0",
|
|
45
|
+
"ink": "^6.6.0",
|
|
46
|
+
"react": "^19.2.3"
|
|
47
|
+
}
|
|
48
|
+
}
|