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.
@@ -10,7 +10,7 @@ on:
10
10
  - "index.html"
11
11
 
12
12
  permissions:
13
- contents: read
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 YOUR_VERCEL_DOMAIN with your actual Vercel deployment URL -->
16
- ![AI Heatmap](https://seunggabi-ai-heatmap/api/heatmap)
15
+ <!-- Replace seunggabi-ai-heatmap.vercel.app with your actual Vercel deployment URL -->
16
+ ![AI Heatmap](https://seunggabi-ai-heatmap.vercel.app/api/heatmap)
17
17
 
18
18
  ### Variations
19
-
20
19
  ```markdown
21
20
  <!-- Dark mode with full stats -->
22
- ![](https://YOUR_VERCEL_DOMAIN/api/heatmap?colorScheme=dark)
21
+ ![](https://{user}-ai-heatmap.vercel.app/api/heatmap?colorScheme=dark)
23
22
 
24
23
  <!-- Blue theme, heatmap + stats only -->
25
- ![](https://YOUR_VERCEL_DOMAIN/api/heatmap?theme=blue&weekday=false)
24
+ ![](https://{user}-ai-heatmap.vercel.app/api/heatmap?theme=blue&weekday=false)
26
25
 
27
26
  <!-- Heatmap only (clean embed) -->
28
- ![](https://YOUR_VERCEL_DOMAIN/api/heatmap?stats=false&weekday=false)
27
+ ![](https://{user}-ai-heatmap.vercel.app/api/heatmap?stats=false&weekday=false)
29
28
 
30
29
  <!-- Custom date range -->
31
- ![](https://YOUR_VERCEL_DOMAIN/api/heatmap?start=2026-01-01&end=2026-02-18)
30
+ ![](https://{user}-ai-heatmap.vercel.app/api/heatmap?start=2026-01-01&end=2026-02-18)
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
- ~~Deploy~~ this repo to Vercel for a dynamic SVG endpoint. Embed it in any README:
49
+ Embed it in any README:
49
50
 
50
51
  ```markdown
51
- ![AI Heatmap](https://your-app.vercel.app/api/heatmap)
52
+ ![AI Heatmap](https://{user}}-ai-heatmap.vercel.app/api/heatmap)
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
+ ![AI Heatmap](https://{user}.github.io/{user}-ai-heatmap/heatmap.svg)
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
- # crontab -e (runs daily at midnight)
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
- npm install
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
- ## Project Structure
201
+ Or manually:
203
202
 
204
- ```
205
- ai-heatmap/
206
- api/heatmap.ts # Vercel serverless SVG endpoint
207
- bin/cli.mjs # CLI entrypoint
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 [repo-name] Create a new heatmap repo and generate initial data
17
- update [--repo <owner/repo>] Generate data + push to repo (default: {user}/{user}-ai-heatmap)
18
- delete [repo-name] Delete the heatmap GitHub repo
19
- deploy Deploy to Vercel (SVG API endpoint)
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
- Update options:
22
- --since YYYYMMDD Start date
23
- --until YYYYMMDD End date
24
- --repo <owner/repo> Target repo (default: auto-detect)
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 {user}-ai-heatmap
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
- execSync(`node ${script} ${args.join(" ")}`, { stdio: "inherit" });
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
- execSync(`node ${script} ${args.join(" ")}`, { stdio: "inherit" });
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: argument > auto-detect {user}-ai-heatmap > cwd
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.10.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)} spent in ${yearLabel}`,
298
+ totalCount: `💰 Total: ${formatUSD(totalCost)} across ${filtered.length} days (${yearLabel})`,
303
299
  }}
304
300
  theme={{
305
301
  light: themeColors,