ai-heatmap 1.10.1 → 1.12.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/.github/workflows/deploy.yml +8 -1
- package/README.md +34 -43
- package/bin/cli.mjs +26 -13
- package/package.json +2 -1
- package/src/App.tsx +1 -5
|
@@ -10,7 +10,7 @@ on:
|
|
|
10
10
|
- "index.html"
|
|
11
11
|
|
|
12
12
|
permissions:
|
|
13
|
-
contents:
|
|
13
|
+
contents: write
|
|
14
14
|
pages: write
|
|
15
15
|
id-token: write
|
|
16
16
|
|
|
@@ -33,6 +33,13 @@ jobs:
|
|
|
33
33
|
- name: Generate static SVG from data.json
|
|
34
34
|
run: npm run generate:svg --if-present
|
|
35
35
|
|
|
36
|
+
- name: Commit heatmap.svg if changed
|
|
37
|
+
run: |
|
|
38
|
+
git config user.name "github-actions[bot]"
|
|
39
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
40
|
+
git add public/heatmap.svg
|
|
41
|
+
git diff --staged --quiet || (git commit -m "chore: update heatmap.svg [skip ci]" && git push)
|
|
42
|
+
|
|
36
43
|
- run: npm run build
|
|
37
44
|
|
|
38
45
|
- uses: actions/upload-pages-artifact@v3
|
package/README.md
CHANGED
|
@@ -12,23 +12,22 @@ Powered by [ccusage](https://github.com/ryoppippi/ccusage) + [react-activity-cal
|
|
|
12
12
|
|
|
13
13
|
## Preview
|
|
14
14
|
|
|
15
|
-
<!-- Replace
|
|
16
|
-

|
|
15
|
+
<!-- Replace seunggabi-ai-heatmap.vercel.app with your actual Vercel deployment URL -->
|
|
16
|
+

|
|
17
17
|
|
|
18
18
|
### Variations
|
|
19
|
-
|
|
20
19
|
```markdown
|
|
21
20
|
<!-- Dark mode with full stats -->
|
|
22
|
-

|
|
23
22
|
|
|
24
23
|
<!-- Blue theme, heatmap + stats only -->
|
|
25
|
-

|
|
26
25
|
|
|
27
26
|
<!-- Heatmap only (clean embed) -->
|
|
28
|
-

|
|
29
28
|
|
|
30
29
|
<!-- Custom date range -->
|
|
31
|
-

|
|
32
31
|
```
|
|
33
32
|
|
|
34
33
|
## Quick Start
|
|
@@ -36,19 +35,21 @@ Powered by [ccusage](https://github.com/ryoppippi/ccusage) + [react-activity-cal
|
|
|
36
35
|
```bash
|
|
37
36
|
# Init a new heatmap repo (creates repo + generates data + pushes)
|
|
38
37
|
npx ai-heatmap init
|
|
39
|
-
npx ai-heatmap init {user}-ai-heatmap
|
|
38
|
+
# npx ai-heatmap init --repo {user}-ai-heatmap
|
|
40
39
|
|
|
41
40
|
# Update data (generate + push)
|
|
42
41
|
npx ai-heatmap update
|
|
43
|
-
npx ai-heatmap update --repo {user}-ai-heatmap
|
|
42
|
+
# npx ai-heatmap update --repo {user}-ai-heatmap
|
|
44
43
|
```
|
|
45
44
|
|
|
46
|
-
## SVG API (Vercel)
|
|
45
|
+
## SVG API (Vercel Only)
|
|
46
|
+
|
|
47
|
+
Deploy this repo to Vercel for a dynamic SVG endpoint. This is Vercel-only — GitHub Pages does not support serverless API routes.
|
|
47
48
|
|
|
48
|
-
|
|
49
|
+
Embed it in any README:
|
|
49
50
|
|
|
50
51
|
```markdown
|
|
51
|
-

|
|
52
53
|
```
|
|
53
54
|
|
|
54
55
|
The SVG is generated on each request from `public/data.json`, so you can control the output with query parameters.
|
|
@@ -88,10 +89,18 @@ The SVG is generated on each request from `public/data.json`, so you can control
|
|
|
88
89
|
/api/heatmap?start=2026-01-01&end=2026-02-18
|
|
89
90
|
```
|
|
90
91
|
|
|
91
|
-
## GitHub Pages (Interactive)
|
|
92
|
+
## GitHub Pages (Interactive + Static SVG)
|
|
92
93
|
|
|
93
94
|
The interactive version with tooltips is deployed via GitHub Pages. Tooltips show cost, tokens, cache hit rate, and per-model breakdown.
|
|
94
95
|
|
|
96
|
+
A static SVG (`heatmap.svg`) is also generated during build. You can embed it as an image:
|
|
97
|
+
|
|
98
|
+
```markdown
|
|
99
|
+

|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
> Static SVG is pre-generated at build time. For real-time rendering, use the [Vercel SVG API](#svg-api-vercel-only).
|
|
103
|
+
|
|
95
104
|
### GitHub Pages Options
|
|
96
105
|
|
|
97
106
|
All options are controlled via query string:
|
|
@@ -127,6 +136,10 @@ https://owner.github.io/{user}-ai-heatmap/?colorScheme=dark&blockSize=14
|
|
|
127
136
|
|
|
128
137
|
## Configuration
|
|
129
138
|
|
|
139
|
+
```
|
|
140
|
+
https://owner.github.io/{user}-ai-heatmap/heatmap.svg
|
|
141
|
+
```
|
|
142
|
+
|
|
130
143
|
Customize the static SVG output by editing `heatmap.config.json` in the project root:
|
|
131
144
|
|
|
132
145
|
```json
|
|
@@ -160,8 +173,7 @@ npx ai-heatmap update
|
|
|
160
173
|
For automated updates, use a local cron job or macOS LaunchAgent:
|
|
161
174
|
|
|
162
175
|
```bash
|
|
163
|
-
|
|
164
|
-
0 0 * * * npx ai-heatmap update
|
|
176
|
+
0 0 * * * npx --yes ai-heatmap@latest update
|
|
165
177
|
```
|
|
166
178
|
|
|
167
179
|
## Upgrade
|
|
@@ -169,10 +181,6 @@ For automated updates, use a local cron job or macOS LaunchAgent:
|
|
|
169
181
|
To use the latest version of ai-heatmap:
|
|
170
182
|
|
|
171
183
|
```bash
|
|
172
|
-
# Always uses latest (npx caches, so clear if needed)
|
|
173
|
-
npx ai-heatmap@latest generate
|
|
174
|
-
|
|
175
|
-
# Clear npx cache and run
|
|
176
184
|
npx --yes ai-heatmap@latest update
|
|
177
185
|
```
|
|
178
186
|
|
|
@@ -184,35 +192,18 @@ npx --yes ai-heatmap@latest update
|
|
|
184
192
|
2. Push `data.json` to `main` to trigger the first deploy
|
|
185
193
|
3. Manual deploy: Actions tab > "Deploy AI Heatmap" > "Run workflow"
|
|
186
194
|
|
|
187
|
-
### Vercel
|
|
188
|
-
|
|
189
|
-
1. Import this repo on [vercel.com](https://vercel.com)
|
|
190
|
-
2. Deploy (zero config — `vercel.json` included)
|
|
191
|
-
3. Use the deployed URL for dynamic SVG embeds
|
|
192
|
-
|
|
193
|
-
## Local Development
|
|
195
|
+
### Vercel (SVG API)
|
|
194
196
|
|
|
195
197
|
```bash
|
|
196
|
-
|
|
197
|
-
npm run generate # Generate data.json from ccusage
|
|
198
|
-
npm run dev # Vite dev server (interactive heatmap)
|
|
199
|
-
node scripts/serve-svg.mjs # Local SVG API on :3333
|
|
198
|
+
npx --yes ai-heatmap@latest deploy
|
|
200
199
|
```
|
|
201
200
|
|
|
202
|
-
|
|
201
|
+
Or manually:
|
|
203
202
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
bin/init.mjs # Repo scaffolding
|
|
209
|
-
bin/push.mjs # Push data to GitHub
|
|
210
|
-
scripts/generate.mjs # ccusage -> data.json
|
|
211
|
-
scripts/generate-svg.mjs # data.json -> static heatmap.svg
|
|
212
|
-
scripts/serve-svg.mjs # Local SVG dev server
|
|
213
|
-
src/App.tsx # React interactive heatmap
|
|
214
|
-
public/data.json # Generated activity data
|
|
215
|
-
```
|
|
203
|
+
1. Import this repo on [vercel.com](https://vercel.com)
|
|
204
|
+
2. Deploy (zero config — `vercel.json` included)
|
|
205
|
+
3. Make public: Project Settings > Deployment Protection > Vercel Authentication > **OFF**
|
|
206
|
+
4. Use the deployed URL for dynamic SVG embeds
|
|
216
207
|
|
|
217
208
|
## Star History
|
|
218
209
|
|
package/bin/cli.mjs
CHANGED
|
@@ -13,28 +13,35 @@ const HELP = `
|
|
|
13
13
|
ai-heatmap - AI usage cost heatmap
|
|
14
14
|
|
|
15
15
|
Commands:
|
|
16
|
-
init
|
|
17
|
-
update
|
|
18
|
-
delete
|
|
19
|
-
deploy
|
|
16
|
+
init [--repo <name>] Create a new heatmap repo and generate initial data
|
|
17
|
+
update [--repo <owner/repo>] Generate data + push to repo
|
|
18
|
+
delete [--repo <name>] Delete the heatmap GitHub repo
|
|
19
|
+
deploy [--repo <name>] Deploy to Vercel (SVG API endpoint)
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
--
|
|
23
|
-
--
|
|
24
|
-
--
|
|
21
|
+
Options:
|
|
22
|
+
--repo <name> Target repo (default: {user}-ai-heatmap)
|
|
23
|
+
--since YYYYMMDD Start date (update only)
|
|
24
|
+
--until YYYYMMDD End date (update only)
|
|
25
25
|
|
|
26
26
|
Examples:
|
|
27
27
|
npx ai-heatmap init
|
|
28
|
+
npx ai-heatmap init --repo my-heatmap
|
|
28
29
|
npx ai-heatmap update
|
|
29
|
-
npx ai-heatmap update --repo
|
|
30
|
+
npx ai-heatmap update --repo owner/repo-name
|
|
30
31
|
npx ai-heatmap delete
|
|
31
32
|
npx ai-heatmap deploy
|
|
32
33
|
`;
|
|
33
34
|
|
|
35
|
+
function getArg(flag) {
|
|
36
|
+
const idx = args.indexOf(flag);
|
|
37
|
+
return idx !== -1 && args[idx + 1] ? args[idx + 1] : null;
|
|
38
|
+
}
|
|
39
|
+
|
|
34
40
|
switch (command) {
|
|
35
41
|
case "init": {
|
|
36
42
|
const script = resolve(__dirname, "init.mjs");
|
|
37
|
-
|
|
43
|
+
const repoName = getArg("--repo") || args[0] || "";
|
|
44
|
+
execSync(`node ${script} ${repoName}`, { stdio: "inherit" });
|
|
38
45
|
break;
|
|
39
46
|
}
|
|
40
47
|
case "update": {
|
|
@@ -50,7 +57,8 @@ switch (command) {
|
|
|
50
57
|
}
|
|
51
58
|
case "delete": {
|
|
52
59
|
const script = resolve(__dirname, "delete.mjs");
|
|
53
|
-
|
|
60
|
+
const repoName = getArg("--repo") || args[0] || "";
|
|
61
|
+
execSync(`node ${script} ${repoName}`, { stdio: "inherit" });
|
|
54
62
|
break;
|
|
55
63
|
}
|
|
56
64
|
case "deploy": {
|
|
@@ -60,9 +68,9 @@ switch (command) {
|
|
|
60
68
|
console.log("Installing Vercel CLI...");
|
|
61
69
|
execSync("npm install -g vercel", { stdio: "inherit" });
|
|
62
70
|
}
|
|
63
|
-
// Determine target directory:
|
|
71
|
+
// Determine target directory: --repo > positional arg > auto-detect {user}-ai-heatmap > cwd
|
|
64
72
|
let deployDir = process.cwd();
|
|
65
|
-
const repoArg = args[0];
|
|
73
|
+
const repoArg = getArg("--repo") || args[0];
|
|
66
74
|
if (repoArg) {
|
|
67
75
|
deployDir = resolve(process.cwd(), repoArg);
|
|
68
76
|
} else {
|
|
@@ -75,6 +83,11 @@ switch (command) {
|
|
|
75
83
|
} catch {}
|
|
76
84
|
}
|
|
77
85
|
console.log(`Deploying from ${deployDir}...`);
|
|
86
|
+
try {
|
|
87
|
+
execSync("git pull", { cwd: deployDir, stdio: "inherit" });
|
|
88
|
+
} catch {
|
|
89
|
+
console.log("git pull skipped (not a git repo or no remote)");
|
|
90
|
+
}
|
|
78
91
|
execSync(`vercel --prod`, {
|
|
79
92
|
cwd: deployDir,
|
|
80
93
|
stdio: "inherit",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ai-heatmap",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.12.0",
|
|
4
4
|
"description": "AI usage cost heatmap powered by ccusage + react-activity-calendar",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
"build": "vite build",
|
|
25
25
|
"preview": "vite preview",
|
|
26
26
|
"generate:svg": "node scripts/generate-svg.mjs",
|
|
27
|
+
"update": "node bin/cli.mjs update",
|
|
27
28
|
"deploy": "npm run generate && npm run generate:svg && npm run build"
|
|
28
29
|
},
|
|
29
30
|
"keywords": [],
|
package/src/App.tsx
CHANGED
|
@@ -282,10 +282,6 @@ export default function App() {
|
|
|
282
282
|
style={containerStyle}
|
|
283
283
|
>
|
|
284
284
|
<h1>AI Usage Heatmap</h1>
|
|
285
|
-
<p className="summary">
|
|
286
|
-
💰 Total: {formatUSD(totalCost)} across {filtered.length} days ({yearLabel})
|
|
287
|
-
</p>
|
|
288
|
-
|
|
289
285
|
<ActivityCalendar
|
|
290
286
|
data={filtered}
|
|
291
287
|
blockSize={options.blockSize}
|
|
@@ -299,7 +295,7 @@ export default function App() {
|
|
|
299
295
|
weekStart={options.weekStart}
|
|
300
296
|
colorScheme={options.colorScheme}
|
|
301
297
|
labels={{
|
|
302
|
-
totalCount: `💰 ${formatUSD(totalCost)}
|
|
298
|
+
totalCount: `💰 Total: ${formatUSD(totalCost)} across ${filtered.length} days (${yearLabel})`,
|
|
303
299
|
}}
|
|
304
300
|
theme={{
|
|
305
301
|
light: themeColors,
|