ai-burnrate-tool 0.0.0-stage โ 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 +207 -2
- package/config/pricing.json +247 -0
- package/dist/cli/index.js +150 -0
- package/dist/cli/reporter.js +132 -0
- package/dist/core/parser.js +497 -0
- package/dist/core/pricing.js +583 -0
- package/dist/core/types.js +1 -0
- package/dist/core/watcher.js +61 -0
- package/dist/public/assets/index-B9NR2QIc.css +1 -0
- package/dist/public/assets/index-_wmJph4q.js +197 -0
- package/dist/public/index.html +16 -0
- package/dist/server/index.js +156 -0
- package/package.json +61 -4
- package/scripts/install.ps1 +61 -0
- package/scripts/install.sh +52 -0
- package/scripts/uninstall.ps1 +14 -0
- package/scripts/uninstall.sh +19 -0
package/README.md
CHANGED
|
@@ -1,3 +1,208 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
# ๐ฅ ai-burnrate โก
|
|
4
|
+
|
|
5
|
+
**Real-Time Local Token & Equivalent API Cost Tracker for Antigravity CLI & Claude Code**
|
|
6
|
+
|
|
7
|
+
[](https://github.com/Cise07/ai-burnrate-tool)
|
|
8
|
+
[](https://nodejs.org/)
|
|
9
|
+
[](https://github.com/Cise07/ai-burnrate-tool)
|
|
10
|
+
[](#)
|
|
11
|
+
|
|
12
|
+
Track in real time how many tokens you are consuming across **Antigravity CLI** (`~/.gemini`) and **Claude Code** (`~/.claude`), what your equivalent pay-as-you-go API spend would be in **USD (`$`) or EUR (`โฌ`)**, and how much money you are saving through Prompt Caching and your monthly subscriptions.
|
|
13
|
+
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## โจ Key Features
|
|
19
|
+
|
|
20
|
+
- ๐ **100% Local, Dynamic & Cross-Platform:** Automatically resolves your user home directory (`os.homedir()` โ `~/.gemini` and `~/.claude`) on Windows, macOS, and Linux with zero hardcoded paths. You can also override watched folders via `BURNRATE_GEMINI_DIR` and `BURNRATE_CLAUDE_DIR`.
|
|
21
|
+
- ๐ข **Live Dashboard & Server-Sent Events (SSE):** A background file watcher (`chokidar`) monitors your active AI transcripts and pushes instant real-time updates to charts, KPIs, and session tables in the browser via `/api/events`.
|
|
22
|
+
- ๐ **Automatic Official Price Sync & Historical Tariff Protection:** On startup (and on manual rescan), `ai-burnrate` automatically fetches the latest official per-token model prices from the public **LiteLLM Pricing Registry** and the official repository feed. Whenever a model's price changes, a new timestamped rate snapshot (`effectiveFrom`) is appended to `~/.burnrate/pricing-ledger.json`โ**tokens consumed before the price change are never recalculated**, and the new tariff applies strictly to turns recorded after the change.
|
|
23
|
+
- ๐ฑ **Instant `$ USD` / `โฌ EUR` Currency Switch:** Toggle the entire dashboard (KPI cards, monthly subscription comparison, charts, and live session table) between US Dollars and Euros with persistent `localStorage` state.
|
|
24
|
+
- ๐ง **Granular Per-Model Token Breakdown:** Dedicated central widget and ANSI CLI tables breaking down *Input (Uncached)*, *Cache Read (Context)*, and *Output (Thinking + Response/Code)* with automatic streaming chunk deduplication.
|
|
25
|
+
- ๐ฅ๏ธ **Instant Terminal Mode (`--cli`):** Prints colorized ANSI tables (Tool Breakdown, Model Breakdown, and Top 12 Recent Sessions) directly in your terminal and exits immediately.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## ๐ Quick Install (Latest Version)
|
|
30
|
+
|
|
31
|
+
You don't need to manually download or clone the repositoryโsimply paste **one command** into your terminal from any directory. The installer automatically resolves the latest GitHub Release (falling back to `main` if none exist yet).
|
|
32
|
+
|
|
33
|
+
> โ ๏ธ **Prerequisite:** Make sure you have [Node.js (>= 18)](https://nodejs.org/) and `npm` installed.
|
|
34
|
+
|
|
35
|
+
### ๐ช Windows (PowerShell)
|
|
36
|
+
Open PowerShell and run:
|
|
37
|
+
```powershell
|
|
38
|
+
irm https://raw.githubusercontent.com/Cise07/ai-burnrate-tool/main/scripts/install.ps1 | iex
|
|
39
|
+
```
|
|
40
|
+
> ๐ก **Note on Windows permissions:** If PowerShell blocks the script with an `ExecutionPolicy` or permission error, enable script execution for your user by running:
|
|
41
|
+
> ```powershell
|
|
42
|
+
> Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
|
|
43
|
+
> ```
|
|
44
|
+
|
|
45
|
+
### ๐ macOS / ๐ง Linux (Bash / Zsh)
|
|
46
|
+
Open your terminal and run:
|
|
47
|
+
```bash
|
|
48
|
+
curl -fsSL https://raw.githubusercontent.com/Cise07/ai-burnrate-tool/main/scripts/install.sh | bash
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### ๐ฆ Universal Alternative via `npm` (Cross-Platform)
|
|
52
|
+
```bash
|
|
53
|
+
npm install -g https://github.com/Cise07/ai-burnrate-tool/archive/main.tar.gz
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
*(Want to run it once without installing? Use `npx https://github.com/Cise07/ai-burnrate-tool/archive/main.tar.gz`)*
|
|
57
|
+
|
|
58
|
+
### ๐ท๏ธ Install a Specific Release Version
|
|
59
|
+
To pin a specific release tag (e.g., `v1.0.1`), use the release tarball directly or pass `BURNRATE_VERSION` to the installer:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
# Universal (recommended for GitHub Release notes)
|
|
63
|
+
npm install -g https://github.com/Cise07/ai-burnrate-tool/archive/refs/tags/vX.Y.Z.tar.gz
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
```powershell
|
|
67
|
+
# Windows PowerShell
|
|
68
|
+
$env:BURNRATE_VERSION="vX.Y.Z"; irm https://raw.githubusercontent.com/Cise07/ai-burnrate-tool/main/scripts/install.ps1 | iex
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
# macOS / Linux
|
|
73
|
+
BURNRATE_VERSION=vX.Y.Z curl -fsSL https://raw.githubusercontent.com/Cise07/ai-burnrate-tool/main/scripts/install.sh | bash
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## ๐ ๏ธ Install from Local Clone (For Developers)
|
|
79
|
+
|
|
80
|
+
If you clone the repository locally, the installer script automatically detects `package.json`, installs dependencies, compiles both the React frontend (`dist/public`) and CLI (`dist/cli`), and registers the global `burnrate` binary:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
# 1. Clone the repository
|
|
84
|
+
git clone https://github.com/Cise07/ai-burnrate-tool.git
|
|
85
|
+
cd ai-burnrate-tool
|
|
86
|
+
|
|
87
|
+
# 2. Build and install globally
|
|
88
|
+
.\scripts\install.ps1 # Windows PowerShell
|
|
89
|
+
./scripts/install.sh # macOS / Linux
|
|
90
|
+
# Or via npm script:
|
|
91
|
+
npm run setup
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## ๐ฎ Usage & CLI Flags
|
|
97
|
+
|
|
98
|
+
Once installed, the **`burnrate`** (or **`ai-burnrate`**) command is available globally from **any folder** in your terminal:
|
|
99
|
+
|
|
100
|
+
| Command | Description |
|
|
101
|
+
| :--- | :--- |
|
|
102
|
+
| `burnrate` | ๐ข **Live Mode (Default):** Syncs official pricing, starts the local HTTP + SSE server, watches `~/.gemini` & `~/.claude`, and opens the React Dashboard in your browser. |
|
|
103
|
+
| `burnrate --cli` | ๐ **Terminal Mode:** Syncs pricing, prints the full token & cost report in colorized ANSI tables in the terminal, and exits immediately. |
|
|
104
|
+
| `burnrate --no-open` | ๐ **Headless Mode:** Starts the live server and file watcher without automatically opening the browser. |
|
|
105
|
+
| `burnrate -p, --port <number>` | ๐ **Custom Port:** Starts the dashboard on a specific port (default: `4321`, automatically falling back to the next free port if busy). |
|
|
106
|
+
| `burnrate --update` | ๐ **Self-Update:** Updates `ai-burnrate` to the latest release directly from GitHub. |
|
|
107
|
+
| `burnrate --uninstall` | ๐๏ธ **Self-Uninstall:** Completely removes the global `burnrate` package from your system. |
|
|
108
|
+
| `burnrate -V, --version` | ๐ท๏ธ Prints the installed version (`1.0.0`). |
|
|
109
|
+
| `burnrate -h, --help` | โน๏ธ Displays all available CLI options. |
|
|
110
|
+
|
|
111
|
+
> ๐ก **Clean Shutdown:** While running in live mode (`burnrate`), press `Ctrl+C` (`SIGINT`) to cleanly close all SSE streams, active HTTP sockets, and the `chokidar` file watcher.
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## ๐๏ธ How to Uninstall `ai-burnrate`
|
|
116
|
+
|
|
117
|
+
You can remove the tool at any time using any of the following methods:
|
|
118
|
+
|
|
119
|
+
### 1๏ธโฃ Built-in CLI Flag (Recommended)
|
|
120
|
+
From any directory in your terminal, simply run:
|
|
121
|
+
```bash
|
|
122
|
+
burnrate --uninstall
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### 2๏ธโฃ Via `npm`
|
|
126
|
+
```bash
|
|
127
|
+
npm uninstall -g ai-burnrate-tool
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### 3๏ธโฃ Via One-Liner Script
|
|
131
|
+
- **Windows (PowerShell):**
|
|
132
|
+
```powershell
|
|
133
|
+
irm https://raw.githubusercontent.com/Cise07/ai-burnrate-tool/main/scripts/uninstall.ps1 | iex
|
|
134
|
+
```
|
|
135
|
+
- **macOS / Linux:**
|
|
136
|
+
```bash
|
|
137
|
+
curl -fsSL https://raw.githubusercontent.com/Cise07/ai-burnrate-tool/main/scripts/uninstall.sh | bash
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## ๐ฐ How Pricing & Historical Rate Versioning Work
|
|
143
|
+
|
|
144
|
+
`ai-burnrate` uses a time-versioned pricing engine (`src/core/pricing.ts`) so that price updates from AI providers never distort your past spending history:
|
|
145
|
+
|
|
146
|
+
1. **Initial Seed (`config/pricing.json`):** Provides the initial baseline rates (effective from `1970-01-01T00:00:00.000Z`) and offline fallback for **Claude** (*Opus 4.x, Sonnet 4.x, 3.7 Sonnet, 3.5 Sonnet, Haiku*) and **Google Gemini** (*Gemini 4 Argon, Gemini Pro, Gemini 3.8 Flash High, Gemini Flash, Flash-Lite*).
|
|
147
|
+
2. **Automatic Live Sync (`syncOfficialPricing`):** At launch and whenever you click the **Rescan** button in the UI, `ai-burnrate` queries the official **LiteLLM Model Pricing Registry** and the GitHub repository feed (with a 3.5s non-blocking timeout for offline resilience).
|
|
148
|
+
3. **Immutable Historical Ledger (`~/.burnrate/pricing-ledger.json`):**
|
|
149
|
+
- When the sync detects that a provider has changed a model's `input`, `output`, `cacheRead`, or `cacheWrite` rate, it **does not overwrite** previous rates.
|
|
150
|
+
- Instead, it appends a new `RateSnapshot` to the `history` array in `~/.burnrate/pricing-ledger.json` stamped with `effectiveFrom: <current ISO timestamp>`.
|
|
151
|
+
4. **Per-Turn Timestamp Matching (`getHistoricalRate`):**
|
|
152
|
+
- Every turn parsed from `~/.gemini` and `~/.claude` has its own `timestamp`.
|
|
153
|
+
- `calculateTurnCost` matches each turn's timestamp against `pricing.history` (`snapshot.effectiveFrom <= turn.timestamp`).
|
|
154
|
+
- All tokens used **before** a price change remain permanently valued at the old rate, while tokens used **after** the price change are valued at the new rate.
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## ๐ Dashboard Overview
|
|
159
|
+
|
|
160
|
+
- **๐ Non-Wrapping Top Bar:** Displays the pulsing `LIVE` SSE connection badge, tool filter (`All`, `Antigravity`, `Claude`), time window selector (`24h`, `7d`, `30d`, `all`), `$ USD` / `โฌ EUR` currency switch, and manual rescan button.
|
|
161
|
+
- **๐ธ 4 Top KPI Cards:**
|
|
162
|
+
1. **API Equivalent Spend:** Total spend with per-tool split (`AGY` vs `Claude`) and ROI multiplier against monthly subscription plans.
|
|
163
|
+
2. **Total Tokens:** Cumulative tokens processed across all LLM turns, split into `Input`, `Output`, and `Cached`.
|
|
164
|
+
3. **Cache Savings:** Total money saved via context caching and overall *Cache Hit Ratio* percentage.
|
|
165
|
+
4. **Sessions & Projects:** Active sessions count, distinct workspaces count, and average cost per session.
|
|
166
|
+
- **๐ Interactive Charts & Model Token Widget:**
|
|
167
|
+
- **Daily API Burn Rate:** Stacked area chart comparing Antigravity CLI and Claude Code spend over time.
|
|
168
|
+
- **Cost by Model:** Horizontal bar chart ranking spend by model.
|
|
169
|
+
- **Total Token Usage by Model:** Central grid showing total tokens, percentage share, and `Input / Cached / Output` breakdown for every model.
|
|
170
|
+
- **๐๏ธ Live Sessions & Workspaces Table:** Real-time searchable table displaying tool badge, relative workspace path (`~/...`), primary model, turns, input/output tokens, cache read tokens, cache savings, API cost, and relative last-active time.
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## ๐ Project Structure
|
|
175
|
+
|
|
176
|
+
```text
|
|
177
|
+
ai-burnrate/
|
|
178
|
+
โโโ config/
|
|
179
|
+
โ โโโ pricing.json # Initial baseline model rates & subscription references
|
|
180
|
+
โโโ scripts/
|
|
181
|
+
โ โโโ install.ps1 # Windows remote one-liner & local installer
|
|
182
|
+
โ โโโ uninstall.ps1 # Windows one-liner uninstaller
|
|
183
|
+
โ โโโ install.sh # macOS/Linux remote one-liner & local installer
|
|
184
|
+
โ โโโ uninstall.sh # macOS/Linux one-liner uninstaller
|
|
185
|
+
โโโ src/
|
|
186
|
+
โ โโโ cli/
|
|
187
|
+
โ โ โโโ index.ts # CLI entrypoint (#!/usr/bin/env node)
|
|
188
|
+
โ โ โโโ reporter.ts # ANSI terminal table formatter (--cli)
|
|
189
|
+
โ โโโ core/
|
|
190
|
+
โ โ โโโ parser.ts # Dynamic ~/.gemini & ~/.claude JSONL parser
|
|
191
|
+
โ โ โโโ pricing.ts # Official price auto-sync & historical rate ledger
|
|
192
|
+
โ โ โโโ watcher.ts # Real-time file watcher with chokidar
|
|
193
|
+
โ โ โโโ types.ts # Shared TypeScript interfaces
|
|
194
|
+
โ โโโ server/
|
|
195
|
+
โ โ โโโ index.ts # Local HTTP server + SSE stream (/api/events)
|
|
196
|
+
โ โโโ web/
|
|
197
|
+
โ โโโ App.tsx # Dark Mode React Dashboard + USD/EUR toggle
|
|
198
|
+
โ โโโ main.tsx # React entrypoint
|
|
199
|
+
โ โโโ index.css # Tailwind CSS styles
|
|
200
|
+
โโโ dist/ # Prebuilt bundle (CLI + static web assets)
|
|
201
|
+
โโโ package.json
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## ๐ License
|
|
207
|
+
|
|
208
|
+
Distributed under the **MIT** License by [Cise07](https://github.com/Cise07). Feel free to open Issues or Pull Requests! โค๏ธ
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
{
|
|
2
|
+
"updatedAt": "2026-11-13",
|
|
3
|
+
"currency": "USD",
|
|
4
|
+
"unit": "per_1m_tokens",
|
|
5
|
+
"subscriptions": {
|
|
6
|
+
"claude_max": {
|
|
7
|
+
"name": "Claude Pro / Max",
|
|
8
|
+
"monthlyUSD": 20.0
|
|
9
|
+
},
|
|
10
|
+
"antigravity_pro": {
|
|
11
|
+
"name": "Google AI Ultra / Pro",
|
|
12
|
+
"monthlyUSD": 20.0
|
|
13
|
+
},
|
|
14
|
+
"combinedMonthlyUSD": 40.0
|
|
15
|
+
},
|
|
16
|
+
"models": {
|
|
17
|
+
"claude-3-7-sonnet": {
|
|
18
|
+
"label": "Claude 3.7 Sonnet",
|
|
19
|
+
"provider": "anthropic",
|
|
20
|
+
"input": 3.0,
|
|
21
|
+
"output": 15.0,
|
|
22
|
+
"cacheRead": 0.3,
|
|
23
|
+
"cacheWrite": 3.75
|
|
24
|
+
},
|
|
25
|
+
"claude-sonnet-4": {
|
|
26
|
+
"label": "Claude Sonnet 4.x",
|
|
27
|
+
"provider": "anthropic",
|
|
28
|
+
"input": 3.0,
|
|
29
|
+
"output": 15.0,
|
|
30
|
+
"cacheRead": 0.3,
|
|
31
|
+
"cacheWrite": 3.75
|
|
32
|
+
},
|
|
33
|
+
"claude-3-5-sonnet": {
|
|
34
|
+
"label": "Claude 3.5 Sonnet",
|
|
35
|
+
"provider": "anthropic",
|
|
36
|
+
"input": 3.0,
|
|
37
|
+
"output": 15.0,
|
|
38
|
+
"cacheRead": 0.3,
|
|
39
|
+
"cacheWrite": 3.75
|
|
40
|
+
},
|
|
41
|
+
"claude-opus-4": {
|
|
42
|
+
"label": "Claude Opus 4.x",
|
|
43
|
+
"provider": "anthropic",
|
|
44
|
+
"input": 15.0,
|
|
45
|
+
"output": 75.0,
|
|
46
|
+
"cacheRead": 1.5,
|
|
47
|
+
"cacheWrite": 18.75
|
|
48
|
+
},
|
|
49
|
+
"claude-3-opus": {
|
|
50
|
+
"label": "Claude 3 Opus",
|
|
51
|
+
"provider": "anthropic",
|
|
52
|
+
"input": 15.0,
|
|
53
|
+
"output": 75.0,
|
|
54
|
+
"cacheRead": 1.5,
|
|
55
|
+
"cacheWrite": 18.75
|
|
56
|
+
},
|
|
57
|
+
"claude-3-5-haiku": {
|
|
58
|
+
"label": "Claude 3.5 Haiku",
|
|
59
|
+
"provider": "anthropic",
|
|
60
|
+
"input": 0.8,
|
|
61
|
+
"output": 4.0,
|
|
62
|
+
"cacheRead": 0.08,
|
|
63
|
+
"cacheWrite": 1.0
|
|
64
|
+
},
|
|
65
|
+
"claude-haiku-4": {
|
|
66
|
+
"label": "Claude Haiku 4.x",
|
|
67
|
+
"provider": "anthropic",
|
|
68
|
+
"input": 0.8,
|
|
69
|
+
"output": 4.0,
|
|
70
|
+
"cacheRead": 0.08,
|
|
71
|
+
"cacheWrite": 1.0
|
|
72
|
+
},
|
|
73
|
+
"gemini-4-argon": {
|
|
74
|
+
"label": "Gemini 4 Argon",
|
|
75
|
+
"provider": "google",
|
|
76
|
+
"input": 2.0,
|
|
77
|
+
"output": 10.0,
|
|
78
|
+
"cacheRead": 0.1,
|
|
79
|
+
"cacheWrite": 2.0,
|
|
80
|
+
"isPromo": true,
|
|
81
|
+
"promoStart": "2026-10-21T00:00:00.000Z",
|
|
82
|
+
"promoEnd": "2026-11-30T23:59:59.999Z",
|
|
83
|
+
"promoNote": "Promo Google AI Launch (-50% dal 21/10/2026 al 30/11/2026)",
|
|
84
|
+
"standardInput": 4.0,
|
|
85
|
+
"standardOutput": 20.0,
|
|
86
|
+
"standardCacheRead": 0.2,
|
|
87
|
+
"standardCacheWrite": 4.0
|
|
88
|
+
},
|
|
89
|
+
"gemini-4-carbon": {
|
|
90
|
+
"label": "Gemini 4 Carbon",
|
|
91
|
+
"provider": "google",
|
|
92
|
+
"input": 2.0,
|
|
93
|
+
"output": 10.0,
|
|
94
|
+
"cacheRead": 0.1,
|
|
95
|
+
"cacheWrite": 2.0,
|
|
96
|
+
"isPromo": true,
|
|
97
|
+
"promoStart": "2026-10-21T00:00:00.000Z",
|
|
98
|
+
"promoEnd": "2026-11-30T23:59:59.999Z",
|
|
99
|
+
"promoNote": "Promo Google AI Launch (-50% dal 21/10/2026 al 30/11/2026)",
|
|
100
|
+
"standardInput": 4.0,
|
|
101
|
+
"standardOutput": 20.0,
|
|
102
|
+
"standardCacheRead": 0.2,
|
|
103
|
+
"standardCacheWrite": 4.0
|
|
104
|
+
},
|
|
105
|
+
"gemini-4-hydrogen": {
|
|
106
|
+
"label": "Gemini 4 Hydrogen",
|
|
107
|
+
"provider": "google",
|
|
108
|
+
"input": 1.5,
|
|
109
|
+
"output": 7.5,
|
|
110
|
+
"cacheRead": 0.075,
|
|
111
|
+
"cacheWrite": 1.5,
|
|
112
|
+
"isPromo": false
|
|
113
|
+
},
|
|
114
|
+
"orchestrator-carbon": {
|
|
115
|
+
"label": "Orchestrator (Carbon)",
|
|
116
|
+
"provider": "google",
|
|
117
|
+
"input": 1.65,
|
|
118
|
+
"output": 8.25,
|
|
119
|
+
"cacheRead": 0.0825,
|
|
120
|
+
"cacheWrite": 1.65,
|
|
121
|
+
"isPromo": true,
|
|
122
|
+
"promoStart": "2026-10-21T00:00:00.000Z",
|
|
123
|
+
"promoEnd": "2026-11-30T23:59:59.999Z",
|
|
124
|
+
"promoNote": "Promo Google AI Launch su Planner Carbon (-50% fino al 30/11/2026) + Hydrogen",
|
|
125
|
+
"standardInput": 2.25,
|
|
126
|
+
"standardOutput": 11.25,
|
|
127
|
+
"standardCacheRead": 0.1125,
|
|
128
|
+
"standardCacheWrite": 2.25
|
|
129
|
+
},
|
|
130
|
+
"orchestrator-argon": {
|
|
131
|
+
"label": "Orchestrator (Argon)",
|
|
132
|
+
"provider": "google",
|
|
133
|
+
"input": 1.65,
|
|
134
|
+
"output": 8.25,
|
|
135
|
+
"cacheRead": 0.0825,
|
|
136
|
+
"cacheWrite": 1.65,
|
|
137
|
+
"isPromo": true,
|
|
138
|
+
"promoStart": "2026-10-21T00:00:00.000Z",
|
|
139
|
+
"promoEnd": "2026-11-30T23:59:59.999Z",
|
|
140
|
+
"promoNote": "Promo Google AI Launch su Planner Argon (-50% fino al 30/11/2026) + Hydrogen",
|
|
141
|
+
"standardInput": 2.25,
|
|
142
|
+
"standardOutput": 11.25,
|
|
143
|
+
"standardCacheRead": 0.1125,
|
|
144
|
+
"standardCacheWrite": 2.25
|
|
145
|
+
},
|
|
146
|
+
"gemini-2.5-pro": {
|
|
147
|
+
"label": "Gemini Pro",
|
|
148
|
+
"provider": "google",
|
|
149
|
+
"input": 1.25,
|
|
150
|
+
"output": 10.0,
|
|
151
|
+
"cacheRead": 0.125,
|
|
152
|
+
"cacheWrite": 1.25,
|
|
153
|
+
"isPromo": true,
|
|
154
|
+
"promoStart": "2026-06-01T00:00:00.000Z",
|
|
155
|
+
"promoEnd": "2026-12-31T23:59:59.999Z",
|
|
156
|
+
"promoNote": "Promo Google AI (<200k tokens)",
|
|
157
|
+
"standardInput": 2.5,
|
|
158
|
+
"standardOutput": 12.5,
|
|
159
|
+
"standardCacheRead": 0.625,
|
|
160
|
+
"standardCacheWrite": 2.5
|
|
161
|
+
},
|
|
162
|
+
"gemini-pro": {
|
|
163
|
+
"label": "Gemini Pro",
|
|
164
|
+
"provider": "google",
|
|
165
|
+
"input": 1.25,
|
|
166
|
+
"output": 10.0,
|
|
167
|
+
"cacheRead": 0.125,
|
|
168
|
+
"cacheWrite": 1.25,
|
|
169
|
+
"isPromo": true,
|
|
170
|
+
"promoStart": "2026-06-01T00:00:00.000Z",
|
|
171
|
+
"promoEnd": "2026-12-31T23:59:59.999Z",
|
|
172
|
+
"promoNote": "Promo Google AI (<200k tokens)",
|
|
173
|
+
"standardInput": 2.5,
|
|
174
|
+
"standardOutput": 12.5,
|
|
175
|
+
"standardCacheRead": 0.625,
|
|
176
|
+
"standardCacheWrite": 2.5
|
|
177
|
+
},
|
|
178
|
+
"gemini-3.8-flash": {
|
|
179
|
+
"label": "Gemini 3.8 Flash (High)",
|
|
180
|
+
"provider": "google",
|
|
181
|
+
"input": 0.75,
|
|
182
|
+
"output": 3.75,
|
|
183
|
+
"cacheRead": 0.075,
|
|
184
|
+
"cacheWrite": 0.75,
|
|
185
|
+
"isPromo": true,
|
|
186
|
+
"promoStart": "2026-09-15T00:00:00.000Z",
|
|
187
|
+
"promoEnd": "2026-12-31T23:59:59.999Z",
|
|
188
|
+
"promoNote": "Promo Google AI (-50% dal 15/09/2026 al 31/12/2026)",
|
|
189
|
+
"standardInput": 1.5,
|
|
190
|
+
"standardOutput": 7.5,
|
|
191
|
+
"standardCacheRead": 0.15,
|
|
192
|
+
"standardCacheWrite": 1.5
|
|
193
|
+
},
|
|
194
|
+
"gemini-2.5-flash": {
|
|
195
|
+
"label": "Gemini Flash",
|
|
196
|
+
"provider": "google",
|
|
197
|
+
"input": 0.3,
|
|
198
|
+
"output": 2.5,
|
|
199
|
+
"cacheRead": 0.03,
|
|
200
|
+
"cacheWrite": 0.3,
|
|
201
|
+
"isPromo": true,
|
|
202
|
+
"promoStart": "2026-06-01T00:00:00.000Z",
|
|
203
|
+
"promoEnd": "2026-12-31T23:59:59.999Z",
|
|
204
|
+
"promoNote": "Promo Google AI Introductory",
|
|
205
|
+
"standardInput": 0.5,
|
|
206
|
+
"standardOutput": 2.5,
|
|
207
|
+
"standardCacheRead": 0.125,
|
|
208
|
+
"standardCacheWrite": 0.5
|
|
209
|
+
},
|
|
210
|
+
"gemini-flash": {
|
|
211
|
+
"label": "Gemini Flash",
|
|
212
|
+
"provider": "google",
|
|
213
|
+
"input": 0.3,
|
|
214
|
+
"output": 2.5,
|
|
215
|
+
"cacheRead": 0.03,
|
|
216
|
+
"cacheWrite": 0.3,
|
|
217
|
+
"isPromo": true,
|
|
218
|
+
"promoStart": "2026-06-01T00:00:00.000Z",
|
|
219
|
+
"promoEnd": "2026-12-31T23:59:59.999Z",
|
|
220
|
+
"promoNote": "Promo Google AI Introductory",
|
|
221
|
+
"standardInput": 0.5,
|
|
222
|
+
"standardOutput": 2.5,
|
|
223
|
+
"standardCacheRead": 0.125,
|
|
224
|
+
"standardCacheWrite": 0.5
|
|
225
|
+
},
|
|
226
|
+
"gemini-flash-lite": {
|
|
227
|
+
"label": "Gemini Flash-Lite",
|
|
228
|
+
"provider": "google",
|
|
229
|
+
"input": 0.1,
|
|
230
|
+
"output": 0.4,
|
|
231
|
+
"cacheRead": 0.01,
|
|
232
|
+
"cacheWrite": 0.1,
|
|
233
|
+
"isPromo": true,
|
|
234
|
+
"promoStart": "2026-06-01T00:00:00.000Z",
|
|
235
|
+
"promoEnd": "2026-12-31T23:59:59.999Z",
|
|
236
|
+
"promoNote": "Promo Google AI Tier",
|
|
237
|
+
"standardInput": 0.15,
|
|
238
|
+
"standardOutput": 0.6,
|
|
239
|
+
"standardCacheRead": 0.0375,
|
|
240
|
+
"standardCacheWrite": 0.15
|
|
241
|
+
}
|
|
242
|
+
},
|
|
243
|
+
"defaults": {
|
|
244
|
+
"claude": "claude-sonnet-4",
|
|
245
|
+
"antigravity": "gemini-4-argon"
|
|
246
|
+
}
|
|
247
|
+
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { execSync } from 'node:child_process';
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { Command } from 'commander';
|
|
6
|
+
import open from 'open';
|
|
7
|
+
import pc from 'picocolors';
|
|
8
|
+
import { scanAllLogs } from '../core/parser.js';
|
|
9
|
+
import { getPackageRoot, syncOfficialPricing } from '../core/pricing.js';
|
|
10
|
+
import { startLogWatcher } from '../core/watcher.js';
|
|
11
|
+
import { startServer } from '../server/index.js';
|
|
12
|
+
import { printCliReport } from './reporter.js';
|
|
13
|
+
const REPO_SLUG = 'Cise07/ai-burnrate-tool';
|
|
14
|
+
function getPackageVersion() {
|
|
15
|
+
try {
|
|
16
|
+
const pkgPath = path.join(getPackageRoot(), 'package.json');
|
|
17
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
|
18
|
+
return pkg.version || '1.0.0';
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return '1.0.0';
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
async function resolveUpdateTarget() {
|
|
25
|
+
const requested = process.env.BURNRATE_VERSION?.trim();
|
|
26
|
+
if (requested) {
|
|
27
|
+
const tag = requested.startsWith('v') ? requested : `v${requested}`;
|
|
28
|
+
return {
|
|
29
|
+
label: tag,
|
|
30
|
+
url: `https://github.com/${REPO_SLUG}/archive/refs/tags/${tag}.tar.gz`,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
const res = await fetch(`https://api.github.com/repos/${REPO_SLUG}/releases/latest`, {
|
|
35
|
+
headers: { 'User-Agent': 'ai-burnrate-cli' },
|
|
36
|
+
signal: AbortSignal.timeout(4000),
|
|
37
|
+
});
|
|
38
|
+
if (res.ok) {
|
|
39
|
+
const data = (await res.json());
|
|
40
|
+
if (data.tag_name) {
|
|
41
|
+
return {
|
|
42
|
+
label: data.tag_name,
|
|
43
|
+
url: `https://github.com/${REPO_SLUG}/archive/refs/tags/${data.tag_name}.tar.gz`,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
// Fallback to main branch if no GitHub Release exists yet or offline
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
label: 'main',
|
|
53
|
+
url: `https://github.com/${REPO_SLUG}/archive/refs/heads/main.tar.gz`,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
const program = new Command();
|
|
57
|
+
program
|
|
58
|
+
.name('burnrate')
|
|
59
|
+
.description('Real-time local token & API equivalent cost tracker for Antigravity CLI and Claude Code')
|
|
60
|
+
.version(getPackageVersion())
|
|
61
|
+
.option('--cli', 'Print the usage report in ANSI tables in the terminal and exit immediately', false)
|
|
62
|
+
.option('--no-open', 'Start the live server and file watcher without automatically opening the browser')
|
|
63
|
+
.option('-p, --port <number>', 'Specify a custom port for the dashboard server', '4321')
|
|
64
|
+
.option('--update', 'Update ai-burnrate to the latest release from GitHub', false)
|
|
65
|
+
.option('--uninstall', 'Uninstall ai-burnrate globally from your system', false);
|
|
66
|
+
program.parse(process.argv);
|
|
67
|
+
const opts = program.opts();
|
|
68
|
+
async function main() {
|
|
69
|
+
if (opts.update) {
|
|
70
|
+
const target = await resolveUpdateTarget();
|
|
71
|
+
console.log(`\n ${pc.cyan('โ')} Updating ${pc.bold('ai-burnrate')} (${pc.cyan(target.label)}) from GitHub...`);
|
|
72
|
+
try {
|
|
73
|
+
execSync(`npm install -g ${target.url}`, {
|
|
74
|
+
stdio: 'inherit',
|
|
75
|
+
});
|
|
76
|
+
console.log(` ${pc.green('โ')} ${pc.bold('ai-burnrate')} updated successfully to ${pc.bold(target.label)}!\n`);
|
|
77
|
+
process.exit(0);
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
console.error(` ${pc.red('โ')} Failed to update automatically. Try running:\n ${pc.cyan(`npm install -g ${target.url}`)}\n`);
|
|
81
|
+
process.exit(1);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (opts.uninstall) {
|
|
85
|
+
console.log(`\n ${pc.yellow('โ')} Uninstalling ${pc.bold('ai-burnrate')} globally...`);
|
|
86
|
+
try {
|
|
87
|
+
execSync('npm uninstall -g ai-burnrate-tool', { stdio: 'inherit' });
|
|
88
|
+
console.log(` ${pc.green('โ')} ${pc.bold('ai-burnrate')} has been completely removed from your system.\n`);
|
|
89
|
+
process.exit(0);
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
console.error(` ${pc.red('โ')} Failed to uninstall automatically. Run: ${pc.cyan('npm uninstall -g ai-burnrate-tool')}`);
|
|
93
|
+
process.exit(1);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
const syncResult = await syncOfficialPricing();
|
|
97
|
+
if (syncResult.updated && syncResult.effectiveFrom) {
|
|
98
|
+
console.log(` ${pc.cyan('โป')} Official pricing updated (new tariff active for turns from ${pc.bold(syncResult.effectiveFrom)}; past turns preserved).`);
|
|
99
|
+
}
|
|
100
|
+
const snapshot = scanAllLogs(true);
|
|
101
|
+
if (opts.cli) {
|
|
102
|
+
printCliReport(snapshot);
|
|
103
|
+
process.exit(0);
|
|
104
|
+
}
|
|
105
|
+
const preferredPort = Number.parseInt(String(opts.port || '4321'), 10) || 4321;
|
|
106
|
+
const server = await startServer(preferredPort, snapshot);
|
|
107
|
+
const watcherHandle = startLogWatcher((updatedSnapshot, changedPath) => {
|
|
108
|
+
server.broadcast(updatedSnapshot, changedPath);
|
|
109
|
+
const timeStr = new Date().toLocaleTimeString();
|
|
110
|
+
console.log(`${pc.dim(`[${timeStr}]`)} ${pc.green('โ SSE Sync')} ${pc.dim('โ')} ${pc.cyan(changedPath)}`);
|
|
111
|
+
});
|
|
112
|
+
console.log('');
|
|
113
|
+
console.log(` ${pc.bgGreen(pc.black(pc.bold(' AI-BURNRATE ')))} ${pc.green('โ LIVE')} ${pc.bold('Real-Time Token & Cost Tracker')}`);
|
|
114
|
+
console.log(` ${pc.dim('โ'.repeat(58))}`);
|
|
115
|
+
console.log(` ${pc.bold('Dashboard URL:')} ${pc.cyan(pc.underline(server.url))}`);
|
|
116
|
+
console.log(` ${pc.bold('SSE Stream:')} ${pc.dim(`${server.url}/api/events`)}`);
|
|
117
|
+
console.log(` ${pc.bold('Watching:')} ${pc.dim(snapshot.watchedPaths.join(' & '))}`);
|
|
118
|
+
console.log(` ${pc.bold('Sessions Found:')} ${pc.yellow(String(snapshot.sessions.length))}`);
|
|
119
|
+
console.log(` ${pc.dim('โ'.repeat(58))}`);
|
|
120
|
+
console.log(` ${pc.dim('Press Ctrl+C to stop the live watcher and exit.')}\n`);
|
|
121
|
+
if (opts.open !== false) {
|
|
122
|
+
try {
|
|
123
|
+
await open(server.url);
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
console.log(` ${pc.yellow('!')} Could not auto-open browser. Open ${pc.cyan(server.url)} manually.`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
let shuttingDown = false;
|
|
130
|
+
const shutdown = async (signal) => {
|
|
131
|
+
if (shuttingDown)
|
|
132
|
+
return;
|
|
133
|
+
shuttingDown = true;
|
|
134
|
+
console.log(`\n ${pc.yellow('โ')} Received ${signal}. Closing file watcher and SSE connections...`);
|
|
135
|
+
try {
|
|
136
|
+
await Promise.all([watcherHandle.close(), server.close()]);
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
// ignore
|
|
140
|
+
}
|
|
141
|
+
console.log(` ${pc.green('โ')} ai-burnrate stopped cleanly.`);
|
|
142
|
+
process.exit(0);
|
|
143
|
+
};
|
|
144
|
+
process.on('SIGINT', () => void shutdown('SIGINT'));
|
|
145
|
+
process.on('SIGTERM', () => void shutdown('SIGTERM'));
|
|
146
|
+
}
|
|
147
|
+
main().catch((err) => {
|
|
148
|
+
console.error(pc.red('Fatal error starting ai-burnrate:'), err);
|
|
149
|
+
process.exit(1);
|
|
150
|
+
});
|