@ericdahl.dev/openai-and-claude-usage-report-generator 1.0.3

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,246 @@
1
+ # OpenAI and Claude Usage Report Generator
2
+
3
+ A CLI tool and library for generating billing reports from the **OpenAI** or **Claude (Anthropic)** cost APIs. Outputs Markdown (readable) and CSV (data) reports.
4
+
5
+ Can be used as:
6
+ - **CLI tool**: Run reports from the command line
7
+ - **Library**: Import functions programmatically in your Node.js/TypeScript projects
8
+
9
+ ## Features
10
+
11
+ - Fetches usage/cost data from OpenAI's organization costs API or Anthropic's [Usage and Cost API](https://platform.claude.com/docs/en/build-with-claude/usage-cost-api)
12
+ - Generates detailed Markdown reports with summaries and breakdowns
13
+ - Exports CSV data for further analysis
14
+ - Exports JSON data for programmatic consumption
15
+ - Daily and line-item cost breakdowns
16
+
17
+ ## Prerequisites
18
+
19
+ - Node.js 18+ and Yarn (`.nvmrc` specifies 22)
20
+ - **OpenAI**: **Admin API key** (not a standard API key), Organization ID, and Project ID
21
+ - ⚠️ **Important**: Standard API keys do not work. You need an admin key with organization access.
22
+ - Create one in [OpenAI Platform → Settings → Organization → API keys](https://platform.openai.com/api-keys)
23
+ - **Claude**: Anthropic **Admin API key** (`sk-ant-admin...`)
24
+ - ⚠️ **Important**: Standard API keys do not work. You need an admin key.
25
+ - Create one in [Console → Settings → Admin keys](https://console.anthropic.com/settings/admin-keys)
26
+
27
+ ## Installation
28
+
29
+ ### As a CLI Tool (Development)
30
+
31
+ ```bash
32
+ git clone <repository-url>
33
+ cd openai-and-claude-usage-report-generator
34
+ yarn install
35
+ ```
36
+
37
+ ### As an npm Package (Library)
38
+
39
+ ```bash
40
+ yarn add @ericdahl.dev/openai-and-claude-usage-report-generator
41
+ # or
42
+ npm install @ericdahl.dev/openai-and-claude-usage-report-generator
43
+ ```
44
+
45
+ ## Configuration
46
+
47
+ Create a `.env` file in the root directory (see `.env.example` for a template).
48
+
49
+ ⚠️ **Important**: Both platforms require **admin/administrative API keys**. Standard API keys will not work.
50
+
51
+ **OpenAI** (default):
52
+
53
+ ```env
54
+ OPENAI_ADMIN_KEY=sk-... # Must be an admin key, not a standard API key
55
+ OPENAI_ORG_ID=org-...
56
+ OPENAI_PROJECT_ID=proj_...
57
+ ```
58
+
59
+ **Claude**:
60
+
61
+ ```env
62
+ ANTHROPIC_ADMIN_API_KEY=sk-ant-admin-... # Must be an admin key (starts with sk-ant-admin), not a standard API key
63
+ ```
64
+
65
+ ## Usage
66
+
67
+ ### CLI Usage
68
+
69
+ Generate a report for a date range. Default provider is OpenAI.
70
+
71
+ ```bash
72
+ yarn report 2024-01-01 2024-01-31
73
+ yarn report 2024-01-01 2024-01-31 --provider openai
74
+ yarn report 2024-01-01 2024-01-31 --provider claude
75
+ ```
76
+
77
+ ### Library Usage
78
+
79
+ Import and use the functions programmatically in your code:
80
+
81
+ ```typescript
82
+ import {
83
+ fetchOpenAICosts,
84
+ fetchClaudeCosts,
85
+ aggregateCosts,
86
+ generateMarkdownReport,
87
+ generateCSVReport,
88
+ generateJSONReport,
89
+ writeReports,
90
+ parseDate,
91
+ validateDateRange,
92
+ loadConfig,
93
+ } from '@ericdahl.dev/openai-and-claude-usage-report-generator';
94
+ import type { OpenAIReportConfig, ClaudeReportConfig } from '@ericdahl.dev/openai-and-claude-usage-report-generator';
95
+
96
+ // Example: Fetch and process OpenAI costs
97
+ // Note: OPENAI_ADMIN_KEY must be an admin key, not a standard API key
98
+ async function generateOpenAIReport() {
99
+ const config: OpenAIReportConfig = {
100
+ provider: 'openai',
101
+ startDate: '2024-01-01',
102
+ endDate: '2024-01-31',
103
+ apiKey: process.env.OPENAI_ADMIN_KEY!, // Must be an admin key
104
+ orgId: process.env.OPENAI_ORG_ID!,
105
+ projectId: process.env.OPENAI_PROJECT_ID!,
106
+ };
107
+
108
+ // Fetch cost data
109
+ const buckets = await fetchOpenAICosts(config);
110
+
111
+ // Aggregate the data
112
+ const aggregated = aggregateCosts(
113
+ buckets,
114
+ config.startDate,
115
+ config.endDate,
116
+ config.projectId
117
+ );
118
+
119
+ // Generate reports
120
+ const markdown = generateMarkdownReport(aggregated, config.orgId, 'openai');
121
+ const csv = generateCSVReport(aggregated);
122
+ const json = generateJSONReport(aggregated, config.orgId, 'openai');
123
+
124
+ // Or write directly to files
125
+ const { mdPath, csvPath, jsonPath } = writeReports(aggregated, config.orgId, 'openai');
126
+
127
+ console.log(`Reports written to ${mdPath}, ${csvPath}, and ${jsonPath}`);
128
+ }
129
+
130
+ // Example: Fetch and process Claude costs
131
+ // Note: ANTHROPIC_ADMIN_API_KEY must be an admin key (sk-ant-admin...), not a standard API key
132
+ async function generateClaudeReport() {
133
+ const config: ClaudeReportConfig = {
134
+ provider: 'claude',
135
+ startDate: '2024-01-01',
136
+ endDate: '2024-01-31',
137
+ apiKey: process.env.ANTHROPIC_ADMIN_API_KEY!, // Must be an admin key (starts with sk-ant-admin)
138
+ };
139
+
140
+ const buckets = await fetchClaudeCosts(config);
141
+ const aggregated = aggregateCosts(buckets, config.startDate, config.endDate, 'default');
142
+ const markdown = generateMarkdownReport(aggregated, 'default', 'claude');
143
+
144
+ console.log(markdown);
145
+ }
146
+ ```
147
+
148
+ **Note**: When using as a library, you need to handle environment variables yourself. The `loadConfig` function is available but requires environment variables to be set, or you can construct the config objects directly as shown above.
149
+
150
+ ⚠️ **Important Reminder**: Both platforms require **admin/administrative API keys**. Standard API keys will not work for accessing cost/usage data.
151
+
152
+ ## Output
153
+
154
+ - **OpenAI**: `reports/openai/`
155
+ - **Claude**: `reports/claude/`
156
+
157
+ Each run produces:
158
+
159
+ - `usage-YYYY-MM-DD-to-YYYY-MM-DD.md` – Human-readable Markdown report
160
+ - `usage-YYYY-MM-DD-to-YYYY-MM-DD.csv` – CSV data export
161
+ - `usage-YYYY-MM-DD-to-YYYY-MM-DD.json` – JSON data export for programmatic consumption
162
+
163
+ ## Report Contents
164
+
165
+ The Markdown report includes:
166
+
167
+ - **Summary**: Total cost, billing days, average daily cost
168
+ - **Cost by Model/Service**: Breakdown by line item with percentages
169
+ - **Daily Usage Breakdown**: Detailed daily costs by model/service
170
+ - **Total by Day**: Daily totals for quick overview
171
+
172
+ The CSV export contains:
173
+ - Date, line item, cost (USD), and project ID for each entry
174
+
175
+ The JSON export contains:
176
+ - Metadata (provider, billing period, project/organization IDs, generation timestamp)
177
+ - Summary (total cost, billing days, average daily cost)
178
+ - Costs by line item (sorted by cost, includes percentages)
179
+ - Daily breakdown (all daily costs by date and line item)
180
+ - Daily totals (aggregated totals per day)
181
+
182
+ ## API Reference
183
+
184
+ ### Core Functions
185
+
186
+ #### `fetchOpenAICosts(config: OpenAIReportConfig): Promise<CostBucket[]>`
187
+ Fetches cost data from OpenAI's organization costs API. Returns an array of cost buckets.
188
+
189
+ #### `fetchClaudeCosts(config: ClaudeReportConfig): Promise<CostBucket[]>`
190
+ Fetches cost data from Anthropic's cost report API. Returns an array of cost buckets (normalized to match OpenAI format).
191
+
192
+ #### `aggregateCosts(buckets: CostBucket[], startDate: string, endDate: string, projectId: string): AggregatedCosts`
193
+ Aggregates cost buckets into a structured format with totals, daily breakdowns, and line item summaries.
194
+
195
+ #### `generateMarkdownReport(aggregated: AggregatedCosts, orgId: string, provider: 'openai' | 'claude'): string`
196
+ Generates a human-readable Markdown report from aggregated costs.
197
+
198
+ #### `generateCSVReport(aggregated: AggregatedCosts): string`
199
+ Generates a CSV report from aggregated costs.
200
+
201
+ #### `generateJSONReport(aggregated: AggregatedCosts, orgId: string, provider: 'openai' | 'claude'): string`
202
+ Generates a JSON report from aggregated costs. Returns a formatted JSON string with metadata, summary, costs by line item, daily breakdown, and daily totals.
203
+
204
+ #### `writeReports(aggregated: AggregatedCosts, orgId: string, provider: Provider, baseDir?: string): { mdPath: string; csvPath: string; jsonPath: string }`
205
+ Writes Markdown, CSV, and JSON reports to disk. Returns paths to the generated files.
206
+
207
+ ### Utility Functions
208
+
209
+ #### `parseDate(dateStr: string): Date`
210
+ Parses a date string in YYYY-MM-DD format and returns a Date object.
211
+
212
+ #### `validateDateRange(start: Date, end: Date): void`
213
+ Validates that the end date is after the start date. Throws an error if invalid.
214
+
215
+ #### `loadConfig(startDate: string, endDate: string, provider: Provider): ReportConfig`
216
+ Loads configuration from environment variables. Requires appropriate env vars to be set based on provider.
217
+
218
+ ### Types
219
+
220
+ All TypeScript types are exported. Key types include:
221
+ - `OpenAIReportConfig` - Configuration for OpenAI API
222
+ - `ClaudeReportConfig` - Configuration for Claude API
223
+ - `AggregatedCosts` - Aggregated cost data structure
224
+ - `CostBucket` - Individual cost bucket from API
225
+ - `DailyCost` - Daily cost entry
226
+ - `Provider` - Union type: `'openai' | 'claude'`
227
+
228
+ ## Development
229
+
230
+ ### Running Tests
231
+
232
+ ```bash
233
+ yarn test # watch mode
234
+ yarn test:run # single run (used by CI)
235
+ ```
236
+
237
+ ### Building
238
+
239
+ ```bash
240
+ yarn build
241
+ ```
242
+
243
+ ### CI
244
+
245
+ GitHub Actions runs on push and pull requests to `main`: `yarn install --frozen-lockfile`, `yarn test:run`, then `yarn build`. See [.github/workflows/ci.yml](.github/workflows/ci.yml).
246
+
package/dist/cli.d.ts ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env tsx
2
+ /**
3
+ * CLI Entry Point
4
+ *
5
+ * Command-line interface for generating usage reports.
6
+ * Imports functionality from the library entry point.
7
+ *
8
+ * Usage: yarn report YYYY-MM-DD YYYY-MM-DD [--provider openai|claude]
9
+ */
10
+ import 'dotenv/config';
11
+ import { type Provider } from './index.js';
12
+ export declare function parseArguments(): {
13
+ startDate: string;
14
+ endDate: string;
15
+ provider: Provider;
16
+ };
17
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;;;;;;GAOG;AAEH,OAAO,eAAe,CAAC;AACvB,OAAO,EASL,KAAK,QAAQ,EACd,MAAM,YAAY,CAAC;AAOpB,wBAAgB,cAAc,IAAI;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAA;CAAE,CAyB3F"}
package/dist/cli.js ADDED
@@ -0,0 +1,103 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * CLI Entry Point
4
+ *
5
+ * Command-line interface for generating usage reports.
6
+ * Imports functionality from the library entry point.
7
+ *
8
+ * Usage: yarn report YYYY-MM-DD YYYY-MM-DD [--provider openai|claude]
9
+ */
10
+ import 'dotenv/config';
11
+ import { fetchOpenAICosts, fetchClaudeCosts, aggregateCosts, writeReports, loadConfig, parseDate, validateDateRange, } from './index.js';
12
+ const USAGE = 'Usage: yarn report YYYY-MM-DD YYYY-MM-DD [--provider openai|claude]\n' +
13
+ 'Example: yarn report 2024-01-01 2024-01-31\n' +
14
+ 'Example: yarn report 2024-01-01 2024-01-31 --provider claude';
15
+ export function parseArguments() {
16
+ const args = process.argv.slice(2);
17
+ const providerIdx = args.indexOf('--provider');
18
+ const providerArg = providerIdx >= 0 && args[providerIdx + 1] != null ? args[providerIdx + 1] : null;
19
+ const filtered = providerIdx < 0
20
+ ? args
21
+ : args.filter((_, i) => i !== providerIdx && i !== providerIdx + 1);
22
+ if (filtered.length !== 2) {
23
+ throw new Error(`Invalid arguments\n${USAGE}`);
24
+ }
25
+ const provider = providerArg === 'claude' ? 'claude' : providerArg === 'openai' ? 'openai' : 'openai';
26
+ if (providerArg != null && providerArg !== 'openai' && providerArg !== 'claude') {
27
+ throw new Error(`Invalid --provider: ${providerArg}. Use openai or claude.\n${USAGE}`);
28
+ }
29
+ const [startDate, endDate] = filtered;
30
+ const start = parseDate(startDate);
31
+ const end = parseDate(endDate);
32
+ validateDateRange(start, end);
33
+ return { startDate, endDate, provider };
34
+ }
35
+ function displayTerminalSummary(aggregated, mdPath, csvPath, jsonPath, provider) {
36
+ const title = provider === 'claude' ? 'Claude API Usage Report' : 'OpenAI API Usage Report';
37
+ console.log(title);
38
+ console.log('=======================');
39
+ console.log(`Period: ${aggregated.startDate} to ${aggregated.endDate}`);
40
+ console.log(`Project: ${aggregated.projectId}\n`);
41
+ console.log(`Total Cost: $${aggregated.totalCost.toFixed(2)} USD`);
42
+ console.log(`Total Days: ${aggregated.billingDays}`);
43
+ console.log(`Average Daily Cost: $${aggregated.averageDailyCost.toFixed(2)}\n`);
44
+ if (aggregated.costsByLineItem.size > 0) {
45
+ console.log('Top Models/Services:');
46
+ const sortedLineItems = Array.from(aggregated.costsByLineItem.entries())
47
+ .sort((a, b) => b[1] - a[1])
48
+ .slice(0, 5);
49
+ for (const [lineItem, cost] of sortedLineItems) {
50
+ console.log(` ${lineItem}: $${cost.toFixed(2)}`);
51
+ }
52
+ console.log('');
53
+ }
54
+ console.log('Reports generated:');
55
+ console.log(` - ${mdPath}`);
56
+ console.log(` - ${csvPath}`);
57
+ console.log(` - ${jsonPath}`);
58
+ }
59
+ async function main() {
60
+ try {
61
+ const { startDate, endDate, provider } = parseArguments();
62
+ const config = loadConfig(startDate, endDate, provider);
63
+ const title = provider === 'claude' ? 'Claude API Usage Report' : 'OpenAI API Usage Report';
64
+ console.log(title);
65
+ console.log('=======================\n');
66
+ console.log(`Fetching costs from ${startDate} to ${endDate}...`);
67
+ const buckets = config.provider === 'openai'
68
+ ? await fetchOpenAICosts(config)
69
+ : await fetchClaudeCosts(config);
70
+ console.log(`Received ${buckets.length} daily buckets\n`);
71
+ const projectId = config.provider === 'openai' ? config.projectId : 'default';
72
+ const orgId = config.provider === 'openai' ? config.orgId : 'default';
73
+ const aggregated = aggregateCosts(buckets, startDate, endDate, projectId);
74
+ const { mdPath, csvPath, jsonPath } = writeReports(aggregated, orgId, provider);
75
+ console.log('');
76
+ displayTerminalSummary(aggregated, mdPath, csvPath, jsonPath, provider);
77
+ }
78
+ catch (error) {
79
+ if (error instanceof Error) {
80
+ console.error('Error:', error.message);
81
+ if (error.message.includes('OPENAI_ADMIN_KEY')) {
82
+ console.error('\nHint: Make sure OPENAI_ADMIN_KEY is set in your environment.');
83
+ }
84
+ else if (error.message.includes('OPENAI_ORG_ID')) {
85
+ console.error('\nHint: Make sure OPENAI_ORG_ID is set in your environment.');
86
+ }
87
+ else if (error.message.includes('OPENAI_PROJECT_ID')) {
88
+ console.error('\nHint: Make sure OPENAI_PROJECT_ID is set in your environment.');
89
+ }
90
+ else if (error.message.includes('ANTHROPIC_ADMIN_API_KEY')) {
91
+ console.error('\nHint: Make sure ANTHROPIC_ADMIN_API_KEY is set in your environment.');
92
+ }
93
+ }
94
+ process.exit(1);
95
+ }
96
+ }
97
+ if (!process.env.VITEST) {
98
+ main().catch((error) => {
99
+ console.error('Unexpected error:', error);
100
+ process.exit(1);
101
+ });
102
+ }
103
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Library Entry Point
3
+ *
4
+ * Exports all public API functions and types for programmatic use.
5
+ * This is the main entry point when using this package as a library.
6
+ */
7
+ export type { AggregatedCosts, ClaudeCostBucket, ClaudeCostReport, ClaudeCostResult, ClaudeReportConfig, CostBucket, CostsResponse, DailyCost, OpenAIReportConfig, Provider, ReportConfig, } from './types.js';
8
+ export { parseDate, validateDateRange, loadConfig, aggregateCosts, generateMarkdownReport, generateCSVReport, generateJSONReport, writeReports, fetchOpenAICosts, fetchClaudeCosts, } from './usage-report.js';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,YAAY,EACV,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,EAClB,UAAU,EACV,aAAa,EACb,SAAS,EACT,kBAAkB,EAClB,QAAQ,EACR,YAAY,GACb,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,SAAS,EACT,iBAAiB,EACjB,UAAU,EACV,cAAc,EACd,sBAAsB,EACtB,iBAAiB,EACjB,kBAAkB,EAClB,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Library Entry Point
3
+ *
4
+ * Exports all public API functions and types for programmatic use.
5
+ * This is the main entry point when using this package as a library.
6
+ */
7
+ // Re-export public utility functions
8
+ export { parseDate, validateDateRange, loadConfig, aggregateCosts, generateMarkdownReport, generateCSVReport, generateJSONReport, writeReports, fetchOpenAICosts, fetchClaudeCosts, } from './usage-report.js';
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAiBH,qCAAqC;AACrC,OAAO,EACL,SAAS,EACT,iBAAiB,EACjB,UAAU,EACV,cAAc,EACd,sBAAsB,EACtB,iBAAiB,EACjB,kBAAkB,EAClB,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,46 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ // Test that the library entry point exists and exports all expected functions
3
+ describe('Library Entry Point (index.ts)', () => {
4
+ it('should export all public API functions', async () => {
5
+ // Dynamic import to test the library entry point
6
+ const lib = await import('./index.js');
7
+ // Core functions
8
+ expect(typeof lib.parseDate).toBe('function');
9
+ expect(typeof lib.validateDateRange).toBe('function');
10
+ expect(typeof lib.loadConfig).toBe('function');
11
+ expect(typeof lib.fetchOpenAICosts).toBe('function');
12
+ expect(typeof lib.fetchClaudeCosts).toBe('function');
13
+ expect(typeof lib.aggregateCosts).toBe('function');
14
+ expect(typeof lib.generateMarkdownReport).toBe('function');
15
+ expect(typeof lib.generateCSVReport).toBe('function');
16
+ expect(typeof lib.writeReports).toBe('function');
17
+ });
18
+ it('should export all types', async () => {
19
+ const lib = await import('./index.js');
20
+ // Types should be available (as TypeScript types, not runtime values)
21
+ // We can't directly test types at runtime, but we can verify the module exports
22
+ expect(lib).toBeDefined();
23
+ });
24
+ it('should NOT export CLI-specific functions', async () => {
25
+ const lib = await import('./index.js');
26
+ // CLI-specific functions should not be exported
27
+ expect('parseArguments' in lib).toBe(false);
28
+ expect('main' in lib).toBe(false);
29
+ });
30
+ it('should allow importing without CLI dependencies', async () => {
31
+ // This test verifies the library can be imported without dotenv/config
32
+ // which is only needed for CLI
33
+ const lib = await import('./index.js');
34
+ expect(lib).toBeDefined();
35
+ expect(typeof lib.fetchOpenAICosts).toBe('function');
36
+ expect(typeof lib.fetchClaudeCosts).toBe('function');
37
+ });
38
+ it('should export fetchOpenAICosts (renamed from fetchCosts)', async () => {
39
+ const lib = await import('./index.js');
40
+ // Verify the renamed function exists
41
+ expect(typeof lib.fetchOpenAICosts).toBe('function');
42
+ // Verify old name doesn't exist
43
+ expect('fetchCosts' in lib).toBe(false);
44
+ });
45
+ });
46
+ //# sourceMappingURL=index.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAS9C,8EAA8E;AAC9E,QAAQ,CAAC,gCAAgC,EAAE,GAAG,EAAE;IAC9C,EAAE,CAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;QACtD,iDAAiD;QACjD,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;QAEvC,iBAAiB;QACjB,MAAM,CAAC,OAAO,GAAG,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC9C,MAAM,CAAC,OAAO,GAAG,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACtD,MAAM,CAAC,OAAO,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC/C,MAAM,CAAC,OAAO,GAAG,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACrD,MAAM,CAAC,OAAO,GAAG,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACrD,MAAM,CAAC,OAAO,GAAG,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACnD,MAAM,CAAC,OAAO,GAAG,CAAC,sBAAsB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC3D,MAAM,CAAC,OAAO,GAAG,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACtD,MAAM,CAAC,OAAO,GAAG,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yBAAyB,EAAE,KAAK,IAAI,EAAE;QACvC,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;QAEvC,sEAAsE;QACtE,gFAAgF;QAChF,MAAM,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;QACxD,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;QAEvC,gDAAgD;QAChD,MAAM,CAAC,gBAAgB,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;QAC/D,uEAAuE;QACvE,+BAA+B;QAC/B,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;QAEvC,MAAM,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;QAC1B,MAAM,CAAC,OAAO,GAAG,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACrD,MAAM,CAAC,OAAO,GAAG,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0DAA0D,EAAE,KAAK,IAAI,EAAE;QACxE,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;QAEvC,qCAAqC;QACrC,MAAM,CAAC,OAAO,GAAG,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACrD,gCAAgC;QAChC,MAAM,CAAC,YAAY,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=integration.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration.test.d.ts","sourceRoot":"","sources":["../src/integration.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,44 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ /**
3
+ * Integration tests to verify both CLI and library usage patterns work
4
+ */
5
+ describe('Integration: CLI and Library Usage', () => {
6
+ it('should allow importing CLI functions', async () => {
7
+ const cli = await import('./cli.js');
8
+ // Verify CLI-specific functions are available
9
+ expect(typeof cli.parseArguments).toBe('function');
10
+ });
11
+ it('should allow importing library functions', async () => {
12
+ const lib = await import('./index.js');
13
+ // Verify core library functions are available
14
+ expect(typeof lib.fetchOpenAICosts).toBe('function');
15
+ expect(typeof lib.fetchClaudeCosts).toBe('function');
16
+ expect(typeof lib.aggregateCosts).toBe('function');
17
+ expect(typeof lib.generateMarkdownReport).toBe('function');
18
+ expect(typeof lib.generateCSVReport).toBe('function');
19
+ expect(typeof lib.writeReports).toBe('function');
20
+ expect(typeof lib.parseDate).toBe('function');
21
+ expect(typeof lib.validateDateRange).toBe('function');
22
+ expect(typeof lib.loadConfig).toBe('function');
23
+ });
24
+ it('should allow importing types from library', async () => {
25
+ const lib = await import('./index.js');
26
+ // Types are available at compile time, but we can verify the module exports
27
+ expect(lib).toBeDefined();
28
+ });
29
+ it('should have CLI import from library (verify separation)', async () => {
30
+ // This test verifies that cli.ts imports from index.ts (the library)
31
+ // We can't directly test imports, but we can verify both modules work
32
+ const cli = await import('./cli.js');
33
+ const lib = await import('./index.js');
34
+ // Both should be importable
35
+ expect(cli).toBeDefined();
36
+ expect(lib).toBeDefined();
37
+ // CLI should have parseArguments (CLI-specific)
38
+ expect(typeof cli.parseArguments).toBe('function');
39
+ // Library should have core functions but NOT CLI functions
40
+ expect(typeof lib.fetchOpenAICosts).toBe('function');
41
+ expect('parseArguments' in lib).toBe(false);
42
+ });
43
+ });
44
+ //# sourceMappingURL=integration.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration.test.js","sourceRoot":"","sources":["../src/integration.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE9C;;GAEG;AAEH,QAAQ,CAAC,oCAAoC,EAAE,GAAG,EAAE;IAClD,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;QACpD,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;QAErC,8CAA8C;QAC9C,MAAM,CAAC,OAAO,GAAG,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;QACxD,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;QAEvC,8CAA8C;QAC9C,MAAM,CAAC,OAAO,GAAG,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACrD,MAAM,CAAC,OAAO,GAAG,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACrD,MAAM,CAAC,OAAO,GAAG,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACnD,MAAM,CAAC,OAAO,GAAG,CAAC,sBAAsB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC3D,MAAM,CAAC,OAAO,GAAG,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACtD,MAAM,CAAC,OAAO,GAAG,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACjD,MAAM,CAAC,OAAO,GAAG,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC9C,MAAM,CAAC,OAAO,GAAG,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACtD,MAAM,CAAC,OAAO,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;QACzD,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;QAEvC,4EAA4E;QAC5E,MAAM,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;QACvE,qEAAqE;QACrE,sEAAsE;QACtE,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;QACrC,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;QAEvC,4BAA4B;QAC5B,MAAM,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;QAC1B,MAAM,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;QAE1B,gDAAgD;QAChD,MAAM,CAAC,OAAO,GAAG,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAEnD,2DAA2D;QAC3D,MAAM,CAAC,OAAO,GAAG,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACrD,MAAM,CAAC,gBAAgB,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * OpenAI Organization Costs API Types
3
+ * https://platform.openai.com/docs/api-reference/usage
4
+ *
5
+ * Claude (Anthropic) Cost API Types
6
+ * https://platform.claude.com/docs/en/build-with-claude/usage-cost-api
7
+ */
8
+ export type Provider = 'openai' | 'claude';
9
+ export interface CostsResponse {
10
+ object: 'page';
11
+ data: CostBucket[];
12
+ has_more: boolean;
13
+ next_page: string | null;
14
+ }
15
+ export interface CostBucket {
16
+ object: 'bucket';
17
+ start_time: number;
18
+ end_time: number;
19
+ results: CostResult[];
20
+ }
21
+ export interface CostResult {
22
+ object: 'organization.costs.result';
23
+ amount: {
24
+ value: number | string;
25
+ currency: string;
26
+ };
27
+ line_item: string | null;
28
+ project_id: string | null;
29
+ }
30
+ /** Anthropic cost_report API response (raw). */
31
+ export interface ClaudeCostReport {
32
+ data: ClaudeCostBucket[];
33
+ has_more: boolean;
34
+ next_page: string | null;
35
+ }
36
+ export interface ClaudeCostBucket {
37
+ starting_at: string;
38
+ ending_at: string;
39
+ results: ClaudeCostResult[];
40
+ }
41
+ export interface ClaudeCostResult {
42
+ amount: string;
43
+ currency: string;
44
+ description: string | null;
45
+ model: string | null;
46
+ cost_type: string | null;
47
+ context_window: string | null;
48
+ token_type: string | null;
49
+ service_tier: string | null;
50
+ workspace_id: string | null;
51
+ }
52
+ export interface AggregatedCosts {
53
+ totalCost: number;
54
+ startDate: string;
55
+ endDate: string;
56
+ projectId: string;
57
+ dailyCosts: DailyCost[];
58
+ costsByLineItem: Map<string, number>;
59
+ billingDays: number;
60
+ averageDailyCost: number;
61
+ }
62
+ export interface DailyCost {
63
+ date: string;
64
+ lineItem: string;
65
+ cost: number;
66
+ }
67
+ export interface OpenAIReportConfig {
68
+ provider: 'openai';
69
+ startDate: string;
70
+ endDate: string;
71
+ apiKey: string;
72
+ orgId: string;
73
+ projectId: string;
74
+ }
75
+ export interface ClaudeReportConfig {
76
+ provider: 'claude';
77
+ startDate: string;
78
+ endDate: string;
79
+ apiKey: string;
80
+ }
81
+ export type ReportConfig = OpenAIReportConfig | ClaudeReportConfig;
82
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE3C,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,UAAU,EAAE,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,QAAQ,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,UAAU,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,2BAA2B,CAAC;IACpC,MAAM,EAAE;QACN,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;QACvB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,gDAAgD;AAChD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,gBAAgB,EAAE,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,gBAAgB,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,QAAQ,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,QAAQ,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,YAAY,GAAG,kBAAkB,GAAG,kBAAkB,CAAC"}
package/dist/types.js ADDED
@@ -0,0 +1,9 @@
1
+ /**
2
+ * OpenAI Organization Costs API Types
3
+ * https://platform.openai.com/docs/api-reference/usage
4
+ *
5
+ * Claude (Anthropic) Cost API Types
6
+ * https://platform.claude.com/docs/en/build-with-claude/usage-cost-api
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
@@ -0,0 +1,17 @@
1
+ import { AggregatedCosts, CostBucket, type ClaudeReportConfig, type OpenAIReportConfig, type ReportConfig, type Provider } from './types.js';
2
+ export declare function parseDate(dateStr: string): Date;
3
+ export declare function validateDateRange(start: Date, end: Date): void;
4
+ export declare function toUnixTimestamp(date: Date): number;
5
+ export declare function loadConfig(startDate: string, endDate: string, provider: Provider): ReportConfig;
6
+ export declare function fetchOpenAICosts(config: OpenAIReportConfig): Promise<CostBucket[]>;
7
+ export declare function fetchClaudeCosts(config: ClaudeReportConfig): Promise<CostBucket[]>;
8
+ export declare function aggregateCosts(buckets: CostBucket[], startDate: string, endDate: string, projectId: string): AggregatedCosts;
9
+ export declare function generateMarkdownReport(aggregated: AggregatedCosts, orgId: string, provider: 'openai' | 'claude'): string;
10
+ export declare function generateCSVReport(aggregated: AggregatedCosts): string;
11
+ export declare function generateJSONReport(aggregated: AggregatedCosts, orgId: string, provider: 'openai' | 'claude'): string;
12
+ export declare function writeReports(aggregated: AggregatedCosts, orgId: string, provider: Provider, baseDir?: string): {
13
+ mdPath: string;
14
+ csvPath: string;
15
+ jsonPath: string;
16
+ };
17
+ //# sourceMappingURL=usage-report.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage-report.d.ts","sourceRoot":"","sources":["../src/usage-report.ts"],"names":[],"mappings":"AASA,OAAO,EACL,eAAe,EAGf,UAAU,EAGV,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,YAAY,EACjB,KAAK,QAAQ,EACd,MAAM,YAAY,CAAC;AAOpB,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAkB/C;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,GAAG,IAAI,CAI9D;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAElD;AAED,wBAAgB,UAAU,CACxB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,QAAQ,GACjB,YAAY,CAyBd;AAED,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAsCxF;AA2BD,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAoCxF;AAED,wBAAgB,cAAc,CAC5B,OAAO,EAAE,UAAU,EAAE,EACrB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB,eAAe,CA2CjB;AAED,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,eAAe,EAC3B,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,QAAQ,GAAG,QAAQ,GAC5B,MAAM,CAgFR;AAaD,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,eAAe,GAAG,MAAM,CAoBrE;AAED,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAqDpH;AAmBD,wBAAgB,YAAY,CAC1B,UAAU,EAAE,eAAe,EAC3B,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,QAAQ,EAClB,OAAO,CAAC,EAAE,MAAM,GACf;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAiBvD"}