grammata 0.1.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 ADDED
@@ -0,0 +1,237 @@
1
+ # grammata
2
+
3
+ Read and aggregate coding agent usage data from your local machine. Parses session files from **Claude Code** (`~/.claude/`) and **Codex** (`~/.codex/`) to give you accurate cost, token, and activity breakdowns.
4
+
5
+ Zero external dependencies. Reads session JSONL files directly from disk for accurate cost and token breakdowns.
6
+
7
+ Part of the [Pella Labs](https://github.com/pella-labs) ecosystem. See also [@pella-labs/pinakes](https://www.npmjs.com/package/@pella-labs/pinakes) for building knowledge graphs over your codebase.
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ npm install grammata
13
+ ```
14
+
15
+ ## Quick Start
16
+
17
+ ```typescript
18
+ import { readAll } from 'grammata';
19
+
20
+ const data = await readAll();
21
+
22
+ console.log(`Total cost: $${data.combined.totalCost.toFixed(2)}`);
23
+ console.log(`Sessions: ${data.combined.totalSessions}`);
24
+ console.log(`Claude: $${data.claude.cost.toFixed(2)} (${data.claude.sessions} sessions)`);
25
+ console.log(`Codex: $${data.codex.cost.toFixed(2)} (${data.codex.sessions} sessions)`);
26
+ ```
27
+
28
+ ## API
29
+
30
+ ### `readAll()`
31
+
32
+ Returns a combined summary across all sources.
33
+
34
+ ```typescript
35
+ const data = await readAll();
36
+
37
+ data.claude.sessions // number of Claude Code sessions
38
+ data.claude.cost // total cost in USD
39
+ data.claude.inputTokens // total input tokens
40
+ data.claude.outputTokens // total output tokens
41
+ data.claude.cacheReadTokens // total cache read tokens
42
+ data.claude.cacheSavingsUsd // how much caching saved you
43
+ data.claude.models // { 'claude-opus-4-6': { sessions: 100, cost: 500 } }
44
+ data.claude.topTools // [{ name: 'Bash', count: 14877 }, ...]
45
+ data.claude.hourDistribution // 24-element array, index = hour
46
+ data.claude.activeDays // number of unique days with sessions
47
+
48
+ data.codex.sessions // number of Codex sessions
49
+ data.codex.cost // total cost in USD
50
+ data.codex.inputTokens // total input tokens (includes cached)
51
+ data.codex.cachedInputTokens // cached portion of input
52
+ data.codex.outputTokens // total output tokens
53
+ data.codex.models // { 'gpt-5.3-codex': { sessions: 47, cost: 558 } }
54
+
55
+ data.combined.totalCost // claude + codex
56
+ data.combined.totalSessions // claude + codex
57
+ ```
58
+
59
+ ### `readClaude(dir?)`
60
+
61
+ Read only Claude Code data. Optionally pass a custom directory (defaults to `~/.claude/projects`).
62
+
63
+ ```typescript
64
+ import { readClaude } from 'grammata';
65
+
66
+ const claude = await readClaude();
67
+
68
+ for (const session of claude.sessions) {
69
+ console.log(session.sessionName, session.model, `$${session.costUsd.toFixed(2)}`);
70
+ }
71
+ ```
72
+
73
+ **Session fields:** `sessionId`, `sessionName`, `project`, `model`, `inputTokens`, `outputTokens`, `cacheReadTokens`, `cacheCreateTokens`, `costUsd`, `turnCount`, `toolCalls`, `toolBreakdown`, `startHour`, `firstTimestamp`, `lastTimestamp`
74
+
75
+ ### `readCodex(dir?)`
76
+
77
+ Read only Codex data. Optionally pass a custom directory (defaults to `~/.codex`).
78
+
79
+ ```typescript
80
+ import { readCodex } from 'grammata';
81
+
82
+ const codex = await readCodex();
83
+
84
+ for (const session of codex.sessions) {
85
+ console.log(session.model, `$${session.costUsd.toFixed(2)}`, session.project);
86
+ }
87
+ ```
88
+
89
+ **Session fields:** `sessionId`, `sessionName`, `project`, `model`, `modelProvider`, `inputTokens`, `cachedInputTokens`, `outputTokens`, `costUsd`, `durationMs`, `createdAt`, `updatedAt`, `source`, `gitBranch`
90
+
91
+ ### Formatting Helpers
92
+
93
+ ```typescript
94
+ import { formatCost, formatTokens, formatDuration } from 'grammata';
95
+
96
+ formatCost(4382.95) // "$4383"
97
+ formatCost(42.5) // "$42.50"
98
+ formatCost(0.003) // "$0.0030"
99
+
100
+ formatTokens(6_771_925_747) // "6.8B"
101
+ formatTokens(2_300_000) // "2.3M"
102
+ formatTokens(45_000) // "45.0K"
103
+
104
+ formatDuration(5_400_000) // "1.5h"
105
+ formatDuration(300_000) // "5m"
106
+ ```
107
+
108
+ ### Pricing Tables
109
+
110
+ Access the pricing tables directly if you need custom cost calculations:
111
+
112
+ ```typescript
113
+ import { CLAUDE_PRICING, CODEX_PRICING, getClaudePricing, getCodexPricing } from 'grammata';
114
+
115
+ // Per-million-token rates
116
+ const opus = getClaudePricing('claude-opus-4-6');
117
+ // { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }
118
+
119
+ const codex = getCodexPricing('gpt-5.3-codex');
120
+ // { input: 1.75, output: 14, cachedInput: 0.175 }
121
+ ```
122
+
123
+ ## CLI
124
+
125
+ ```bash
126
+ npx grammata # full summary (default)
127
+ npx grammata claude # Claude Code: cost, tokens, models, tools, projects
128
+ npx grammata codex # Codex: cost, tokens, models, projects
129
+ npx grammata sessions # list all sessions (most recent first)
130
+ npx grammata models # model breakdown across both sources
131
+ npx grammata tools # tool usage ranking with bar chart
132
+ npx grammata tokens # token breakdown by source
133
+ npx grammata cost # cost summary + cache savings
134
+ npx grammata daily # day-by-day costs with chart
135
+ npx grammata hours # activity by hour of day
136
+ ```
137
+
138
+ All commands support `--json` for machine-readable output:
139
+
140
+ ```bash
141
+ npx grammata cost --json
142
+ npx grammata models --json
143
+ npx grammata daily --json
144
+ ```
145
+
146
+ Example output (`npx grammata`):
147
+
148
+ ```
149
+ grammata
150
+ ─────────────────────────────────────
151
+
152
+ Claude Code
153
+ Sessions: 3024
154
+ Cost: $6683
155
+ Input tokens: 2.4M
156
+ Output tokens: 23.5M
157
+ Cache read: 9.2B
158
+ Cache savings: $40979
159
+ Active days: 32
160
+ Top tools: Bash(14885), Read(13768), Edit(6998), Grep(3142), Write(2972)
161
+
162
+ Models:
163
+ claude-opus-4-6 $6467 (1525 sessions)
164
+ claude-haiku-4-5-20251001 $62.43 (1253 sessions)
165
+ claude-sonnet-4-6 $24.64 (75 sessions)
166
+
167
+ Codex
168
+ Sessions: 80
169
+ Cost: $698.25
170
+ Input tokens: 2.3B
171
+ Cached input: 2.2B
172
+ Output tokens: 9.1M
173
+
174
+ Models:
175
+ gpt-5.3-codex $558.32 (47 sessions)
176
+ gpt-5.2-codex $66.24 (7 sessions)
177
+ gpt-5.4 $56.41 (12 sessions)
178
+
179
+ ─────────────────────────────────────
180
+ Combined: $7381 (3104 sessions)
181
+ ```
182
+
183
+ ## How It Works
184
+
185
+ ### Claude Code
186
+
187
+ Reads JSONL session files from `~/.claude/projects/<project>/<session-id>.jsonl`. Each file contains per-turn `assistant` messages with token usage breakdowns:
188
+
189
+ - `input_tokens` — direct input tokens
190
+ - `output_tokens` — model output tokens
191
+ - `cache_read_input_tokens` — tokens served from prompt cache
192
+ - `cache_creation_input_tokens` — tokens written to prompt cache
193
+
194
+ Cost is calculated as: `(input * input_price + output * output_price + cache_read * cache_read_price + cache_create * cache_write_price) / 1M`
195
+
196
+ ### Codex
197
+
198
+ Reads JSONL rollout files from `~/.codex/sessions/YYYY/MM/DD/<rollout>.jsonl`. Each file contains `token_count` events with per-turn usage:
199
+
200
+ - `input_tokens` — total input (includes cached)
201
+ - `cached_input_tokens` — cached portion
202
+ - `output_tokens` — model output
203
+ - `reasoning_output_tokens` — chain-of-thought tokens
204
+
205
+ Cost is calculated as: `(uncached_input * input_price + cached * cached_price + output * output_price) / 1M`
206
+
207
+ Model names come from `turn_context` events. Session metadata (title, cwd, git branch) comes from the SQLite threads table as a fallback.
208
+
209
+ ### Pricing
210
+
211
+ Pricing tables are sourced from [LiteLLM](https://github.com/BerriAI/litellm) and official pricing pages. Supported models:
212
+
213
+ | Model | Input | Output | Cache Read | Cache Write |
214
+ |-------|------:|-------:|-----------:|------------:|
215
+ | claude-opus-4-6 | $5.00 | $25.00 | $0.50 | $6.25 |
216
+ | claude-sonnet-4-6 | $3.00 | $15.00 | $0.30 | $3.75 |
217
+ | claude-haiku-4-5 | $1.00 | $5.00 | $0.10 | $1.25 |
218
+ | gpt-5.3-codex | $1.75 | $14.00 | $0.175 | — |
219
+ | gpt-5.2-codex | $1.75 | $14.00 | $0.175 | — |
220
+ | gpt-5.1-codex | $1.25 | $10.00 | $0.125 | — |
221
+ | gpt-5.1-codex-mini | $0.25 | $2.00 | $0.025 | — |
222
+ | gpt-5.4 | $2.50 | $15.00 | $0.25 | — |
223
+
224
+ Unknown models fall back to Sonnet pricing (Claude) or gpt-5.2-codex pricing (Codex).
225
+
226
+ ## Requirements
227
+
228
+ - Node.js 18+
229
+ - `sqlite3` CLI tool in PATH (for Codex session metadata; Codex token data and all Claude data work without it)
230
+
231
+ ## Related
232
+
233
+ - [@pella-labs/pinakes](https://www.npmjs.com/package/@pella-labs/pinakes) — Build knowledge graphs over your codebase
234
+
235
+ ## License
236
+
237
+ MIT
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Reads Claude Code session JSONL files from ~/.claude/projects/
3
+ * and aggregates token usage, cost, and model data.
4
+ */
5
+ import { CLAUDE_PRICING } from './pricing.js';
6
+ export { CLAUDE_PRICING };
7
+ export interface ClaudeSession {
8
+ sessionId: string;
9
+ sessionName: string;
10
+ project: string;
11
+ firstTimestamp: string;
12
+ lastTimestamp: string;
13
+ model: string;
14
+ inputTokens: number;
15
+ outputTokens: number;
16
+ cacheReadTokens: number;
17
+ cacheCreateTokens: number;
18
+ costUsd: number;
19
+ turnCount: number;
20
+ toolCalls: number;
21
+ toolBreakdown: Record<string, number>;
22
+ startHour: number;
23
+ }
24
+ export interface ClaudeSummary {
25
+ sessions: ClaudeSession[];
26
+ totalCost: number;
27
+ totalInputTokens: number;
28
+ totalOutputTokens: number;
29
+ totalCacheReadTokens: number;
30
+ totalCacheCreateTokens: number;
31
+ cacheSavingsUsd: number;
32
+ toolBreakdown: Record<string, number>;
33
+ hourDistribution: number[];
34
+ }
35
+ export declare function readClaude(dir?: string): Promise<ClaudeSummary>;
36
+ //# sourceMappingURL=claude.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../src/claude.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,cAAc,EAAoB,MAAM,cAAc,CAAC;AAEhE,OAAO,EAAE,cAAc,EAAE,CAAC;AAI1B,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,sBAAsB,EAAE,MAAM,CAAC;IAC/B,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,gBAAgB,EAAE,MAAM,EAAE,CAAC;CAC5B;AA0HD,wBAAsB,UAAU,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAuErE"}
package/dist/claude.js ADDED
@@ -0,0 +1,170 @@
1
+ /**
2
+ * Reads Claude Code session JSONL files from ~/.claude/projects/
3
+ * and aggregates token usage, cost, and model data.
4
+ */
5
+ import { lstat, readdir, readFile } from 'fs/promises';
6
+ import { join } from 'path';
7
+ import { homedir } from 'os';
8
+ import { CLAUDE_PRICING, getClaudePricing } from './pricing.js';
9
+ export { CLAUDE_PRICING };
10
+ const MAX_FILE_SIZE = 50 * 1024 * 1024; // 50 MB
11
+ function isAssistantWithUsage(d) {
12
+ const obj = d;
13
+ return obj?.type === 'assistant' && typeof obj?.message === 'object' && obj.message !== null;
14
+ }
15
+ async function parseSessionFile(filePath, projectName) {
16
+ try {
17
+ const fileInfo = await lstat(filePath);
18
+ if (fileInfo.isSymbolicLink())
19
+ return null;
20
+ if (fileInfo.size > MAX_FILE_SIZE)
21
+ return null;
22
+ const content = await readFile(filePath, 'utf-8');
23
+ const lines = content.split('\n').filter((l) => l.trim());
24
+ let model = 'unknown';
25
+ let totalInput = 0;
26
+ let totalOutput = 0;
27
+ let cacheRead = 0;
28
+ let cacheCreate = 0;
29
+ let turnCount = 0;
30
+ let toolCalls = 0;
31
+ const toolBreakdown = {};
32
+ let firstTs = '';
33
+ let lastTs = '';
34
+ let sessionName = '';
35
+ for (const line of lines) {
36
+ try {
37
+ const d = JSON.parse(line);
38
+ if (d.timestamp) {
39
+ if (!firstTs)
40
+ firstTs = d.timestamp;
41
+ lastTs = d.timestamp;
42
+ }
43
+ if (!sessionName && d.type === 'queue-operation' && d.content) {
44
+ const text = typeof d.content === 'string' ? d.content : '';
45
+ sessionName = text.replace(/^-\n?/, '').trim().slice(0, 80);
46
+ }
47
+ if (isAssistantWithUsage(d)) {
48
+ const usage = d.message.usage;
49
+ if (usage) {
50
+ totalInput += usage.input_tokens || 0;
51
+ totalOutput += usage.output_tokens || 0;
52
+ cacheRead += usage.cache_read_input_tokens || 0;
53
+ cacheCreate += usage.cache_creation_input_tokens || 0;
54
+ turnCount++;
55
+ }
56
+ if (d.message.model && d.message.model !== '<synthetic>') {
57
+ model = d.message.model;
58
+ }
59
+ if (d.message.content) {
60
+ for (const c of d.message.content) {
61
+ if (c && typeof c === 'object' && c.type === 'tool_use') {
62
+ toolCalls++;
63
+ const toolName = c.name || 'unknown';
64
+ toolBreakdown[toolName] = (toolBreakdown[toolName] || 0) + 1;
65
+ }
66
+ }
67
+ }
68
+ }
69
+ }
70
+ catch {
71
+ // Skip malformed lines
72
+ }
73
+ }
74
+ if (turnCount === 0)
75
+ return null;
76
+ const pricing = getClaudePricing(model);
77
+ const costUsd = (totalInput * pricing.input +
78
+ totalOutput * pricing.output +
79
+ cacheRead * pricing.cacheRead +
80
+ cacheCreate * pricing.cacheWrite) /
81
+ 1_000_000;
82
+ const sessionId = filePath.split('/').pop()?.replace('.jsonl', '') || '';
83
+ const startHour = firstTs ? new Date(firstTs).getHours() : 0;
84
+ return {
85
+ sessionId,
86
+ sessionName: sessionName || sessionId.slice(0, 8),
87
+ project: projectName,
88
+ firstTimestamp: firstTs,
89
+ lastTimestamp: lastTs,
90
+ model,
91
+ inputTokens: totalInput,
92
+ outputTokens: totalOutput,
93
+ cacheReadTokens: cacheRead,
94
+ cacheCreateTokens: cacheCreate,
95
+ costUsd,
96
+ turnCount,
97
+ toolCalls,
98
+ toolBreakdown,
99
+ startHour,
100
+ };
101
+ }
102
+ catch {
103
+ return null;
104
+ }
105
+ }
106
+ export async function readClaude(dir) {
107
+ const claudeDir = dir || join(homedir(), '.claude', 'projects');
108
+ const result = {
109
+ sessions: [],
110
+ totalCost: 0,
111
+ totalInputTokens: 0,
112
+ totalOutputTokens: 0,
113
+ totalCacheReadTokens: 0,
114
+ totalCacheCreateTokens: 0,
115
+ cacheSavingsUsd: 0,
116
+ toolBreakdown: {},
117
+ hourDistribution: new Array(24).fill(0),
118
+ };
119
+ try {
120
+ const projects = await readdir(claudeDir);
121
+ for (const project of projects) {
122
+ const projectDir = join(claudeDir, project);
123
+ try {
124
+ const dirInfo = await lstat(projectDir);
125
+ if (dirInfo.isSymbolicLink())
126
+ continue;
127
+ }
128
+ catch {
129
+ continue;
130
+ }
131
+ let files;
132
+ try {
133
+ files = (await readdir(projectDir)).filter((f) => f.endsWith('.jsonl'));
134
+ }
135
+ catch {
136
+ continue;
137
+ }
138
+ const BATCH_SIZE = 50;
139
+ for (let i = 0; i < files.length; i += BATCH_SIZE) {
140
+ const batch = files.slice(i, i + BATCH_SIZE);
141
+ const sessions = await Promise.all(batch.map((f) => parseSessionFile(join(projectDir, f), project)));
142
+ for (const session of sessions) {
143
+ if (session) {
144
+ result.sessions.push(session);
145
+ result.totalCost += session.costUsd;
146
+ result.totalInputTokens += session.inputTokens;
147
+ result.totalOutputTokens += session.outputTokens;
148
+ result.totalCacheReadTokens += session.cacheReadTokens;
149
+ result.totalCacheCreateTokens += session.cacheCreateTokens;
150
+ for (const [tool, count] of Object.entries(session.toolBreakdown)) {
151
+ result.toolBreakdown[tool] = (result.toolBreakdown[tool] || 0) + count;
152
+ }
153
+ result.hourDistribution[session.startHour]++;
154
+ }
155
+ }
156
+ }
157
+ }
158
+ for (const session of result.sessions) {
159
+ const pricing = getClaudePricing(session.model);
160
+ const savingsPerToken = (pricing.input - pricing.cacheRead) / 1_000_000;
161
+ result.cacheSavingsUsd += session.cacheReadTokens * savingsPerToken;
162
+ }
163
+ result.sessions.sort((a, b) => new Date(b.firstTimestamp).getTime() - new Date(a.firstTimestamp).getTime());
164
+ }
165
+ catch {
166
+ // Directory doesn't exist or is unreadable
167
+ }
168
+ return result;
169
+ }
170
+ //# sourceMappingURL=claude.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude.js","sourceRoot":"","sources":["../src/claude.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}