vibe-roast 0.98.2 → 0.98.4
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 +45 -10
- package/assests/README.md +1 -0
- package/assests/readme/vibe-roast-16-types-banner.webp +0 -0
- package/assests/readme/vibe-roast-promo-landscape.gif +0 -0
- package/assests/screenshots/roast-result-hero.jpg +0 -0
- package/bin/vibe-roast.js +22 -0
- package/dashboard/dist/assets/{index-BPhMyUU4.js → index-BU-4n-Cw.js} +1 -1
- package/dashboard/dist/index.html +1 -1
- package/package.json +8 -2
- package/src/inspect.js +9 -32
- package/src/lib/activity-metrics.js +8 -1
- package/src/lib/ai-roast.js +23 -14
- package/src/lib/roast-evidence.js +178 -3
- package/src/lib/roast-snapshot.js +3 -1
- package/src/lib/terminal-ui.js +10 -1
- package/src/lib/token-tracker-runtime.js +108 -0
- package/src/server.js +9 -1
- package/src/sources/codex.js +30 -1
- package/assests/badges/.gitkeep +0 -0
- package/assests/badges/01-builder/builder-badge.png +0 -0
- package/assests/badges/01-builder/builder-badge.svg +0 -4
- package/assests/badges/02-debugger/debugger-badge.png +0 -0
- package/assests/badges/02-debugger/debugger-badge.svg +0 -4
- package/assests/badges/03-architect/architect-badge.png +0 -0
- package/assests/badges/03-architect/architect-badge.svg +0 -4
- package/assests/badges/04-codex-believer/codex-believer-badge.png +0 -0
- package/assests/badges/04-codex-believer/codex-believer-badge.svg +0 -4
- package/assests/badges/05-prompt-priest/prompt-priest-badge.png +0 -0
- package/assests/badges/05-prompt-priest/prompt-priest-badge.svg +0 -4
- package/assests/badges/06-tab-hoarder/tab-hoarder-badge.png +0 -0
- package/assests/badges/06-tab-hoarder/tab-hoarder-badge.svg +0 -4
- package/assests/badges/07-context-maxxer/context-maxxer-badge.png +0 -0
- package/assests/badges/07-context-maxxer/context-maxxer-badge.svg +0 -4
- package/assests/badges/08-yolo-shipper/yolo-shipper-badge.png +0 -0
- package/assests/badges/08-yolo-shipper/yolo-shipper-badge.svg +0 -4
- package/assests/banners/.gitkeep +0 -0
- package/assests/banners/home-hero.png +0 -0
- package/assests/banners/home-hero.svg +0 -3
- package/assests/banners/result-header.png +0 -0
- package/assests/banners/result-header.svg +0 -3
- package/assests/banners/share-strip.png +0 -0
- package/assests/banners/share-strip.svg +0 -3
- package/assests/scripts/compose-banners.py +0 -148
- package/assests/scripts/profiles.json +0 -104
- package/assests/scripts/qa-faces.mjs +0 -72
- package/assests/scripts/score-engine.js +0 -62
- package/assests/scripts/split-badges.py +0 -49
- package/assests/scripts/split-reference.py +0 -38
- package/assests/scripts/sync-banners.mjs +0 -45
- package/assests/scripts/sync-cards.mjs +0 -50
- package/assests/scripts/sync-raster.mjs +0 -118
- package/assests/scripts/vibe-types.json +0 -22
- package/assests/source/design-system.md +0 -50
- package/assests/source/prompts/01-builder.md +0 -19
- package/assests/source/prompts/02-debugger.md +0 -17
- package/assests/source/prompts/03-architect.md +0 -16
- package/assests/source/prompts/04-codex-believer.md +0 -13
- package/assests/source/prompts/05-prompt-priest.md +0 -13
- package/assests/source/prompts/06-tab-hoarder.md +0 -13
- package/assests/source/prompts/07-context-maxxer.md +0 -13
- package/assests/source/prompts/08-yolo-shipper.md +0 -13
- package/assests/source/references/sbti-style-reference-board.png +0 -0
- package/assests/source/references/vibe-badges-v6-board.png +0 -0
- package/assests/source/references/vibe-mascots-v4-reference.png +0 -0
- package/assests/source/references/vibe-profiles-v5-board-a.png +0 -0
- package/assests/source/references/vibe-profiles-v5-board-b.png +0 -0
- package/assests/source/vibe-types-visual-brief.md +0 -38
package/README.md
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
<div align="center">
|
|
4
4
|
<img
|
|
5
|
-
src="./assests/
|
|
6
|
-
width="
|
|
7
|
-
alt="Vibe Roaster
|
|
5
|
+
src="./assests/readme/vibe-roast-16-types-banner.webp"
|
|
6
|
+
width="1100"
|
|
7
|
+
alt="All sixteen Vibe Roaster coding personalities gathered around the Vibe Roast title"
|
|
8
8
|
/>
|
|
9
9
|
|
|
10
10
|
<h1>Vibe Roaster</h1>
|
|
@@ -53,6 +53,28 @@ Vibe Roaster reads supported local coding-agent histories, separates real user i
|
|
|
53
53
|
|
|
54
54
|
The personality calculation is deterministic and local. AI writing is optional.
|
|
55
55
|
|
|
56
|
+
<p align="center">
|
|
57
|
+
<a href="./media/promo/masters/landscape.mp4">
|
|
58
|
+
<img
|
|
59
|
+
src="./assests/readme/vibe-roast-promo-landscape.gif"
|
|
60
|
+
width="1100"
|
|
61
|
+
alt="Vibe Roaster turns prompt fragments into a four-axis personality verdict, one of sixteen characters, and a shareable roast"
|
|
62
|
+
/>
|
|
63
|
+
</a>
|
|
64
|
+
</p>
|
|
65
|
+
|
|
66
|
+
<p align="center">
|
|
67
|
+
<sub>Watch the 15-second launch film · click for the 1080p version</sub>
|
|
68
|
+
</p>
|
|
69
|
+
|
|
70
|
+
<p align="center">
|
|
71
|
+
<img
|
|
72
|
+
src="./assests/screenshots/roast-result-hero.jpg"
|
|
73
|
+
width="1100"
|
|
74
|
+
alt="Vibe Roaster result showing the Builder personality, topic-aware hashtags, token statistics, behavioral radar, and type axes"
|
|
75
|
+
/>
|
|
76
|
+
</p>
|
|
77
|
+
|
|
56
78
|
## Quick start
|
|
57
79
|
|
|
58
80
|
### Run from npm
|
|
@@ -69,6 +91,17 @@ Vibe Roaster scans the supported local stores it can find, starts the local dash
|
|
|
69
91
|
http://localhost:7681
|
|
70
92
|
```
|
|
71
93
|
|
|
94
|
+
`tokentracker-cli` ships as a runtime dependency. On first launch, Vibe Roaster
|
|
95
|
+
initializes its local-only collectors and compatible Agent hooks; later launches
|
|
96
|
+
sync the TokenTracker queue before opening the report. Activity therefore stays
|
|
97
|
+
in Token mode instead of silently changing its unit to Prompt count. If the
|
|
98
|
+
operating system blocks a source, the UI shows zero Token data for that source
|
|
99
|
+
rather than presenting Prompt counts as Tokens.
|
|
100
|
+
|
|
101
|
+
Vibe Roaster invokes TokenTracker in local-only, no-auth mode. TokenTracker's
|
|
102
|
+
optional account, GitHub OAuth, leaderboard, and cloud sync are not required or
|
|
103
|
+
opened by `vibe-roast`.
|
|
104
|
+
|
|
72
105
|
Interactive terminals get a short branded launch sequence with rotating English humour. Piped output, CI, and `NO_COLOR` environments automatically use stable plain text.
|
|
73
106
|
|
|
74
107
|
Missing agents are ignored safely. You do not need to configure every source, create an account, or provide an API key to see the local result.
|
|
@@ -220,7 +253,7 @@ The writer cannot change the deterministic type. In one model call it produces:
|
|
|
220
253
|
|
|
221
254
|
- three-beat English and Chinese roasts;
|
|
222
255
|
- bilingual TL;DR punchlines;
|
|
223
|
-
-
|
|
256
|
+
- five paired Hashtags with `en`, `zh`, semantic `kind`, and a short shared `meaning`.
|
|
224
257
|
|
|
225
258
|
Hashtags are interpretations rather than frequency labels. Chinese is localized from the intended joke instead of translated word for word. Proper names, framework names, and meaningful acronyms may remain unchanged when translation would lose their identity.
|
|
226
259
|
|
|
@@ -258,7 +291,7 @@ Vibe Roaster inspects the sources it can find and treats missing roots as empty.
|
|
|
258
291
|
| Copilot Chat | `copilot` | VS Code/Cursor global storage |
|
|
259
292
|
| Amazon Q | `amazonq` | `~/.aws/amazonq/history` |
|
|
260
293
|
| Antigravity | `antigravity` | `~/.gemini/antigravity(-ide)/conversations` |
|
|
261
|
-
| TokenTracker | activity only | `~/.tokentracker/tracker/queue.jsonl` |
|
|
294
|
+
| TokenTracker (bundled) | activity only | `~/.tokentracker/tracker/queue.jsonl` |
|
|
262
295
|
| Vibe tracker | `vibe-tracker` | `~/.vibe-roast/sessions.jsonl` |
|
|
263
296
|
|
|
264
297
|
Cursor is best-effort and requires the local `sqlite3` command. Encrypted or binary histories are skipped rather than guessed.
|
|
@@ -269,7 +302,7 @@ Cursor is best-effort and requires the local `sqlite3` command. Encrypted or bin
|
|
|
269
302
|
- Windsurf Cascade and Antigravity protobuf trajectories are not parsed without a plaintext export.
|
|
270
303
|
- ChatGPT desktop history is encrypted.
|
|
271
304
|
- Cursor cloud-only threads may not have readable local bubbles.
|
|
272
|
-
-
|
|
305
|
+
- TokenTracker covers supported local histories and keeps the Activity unit in Tokens. Platform permissions and upstream log formats can still leave an individual source at zero.
|
|
273
306
|
- Agent context categories are aggregate estimates. Codex tool attribution is turn-based; Claude content-block attribution is approximate.
|
|
274
307
|
|
|
275
308
|
</details>
|
|
@@ -312,14 +345,16 @@ Additional overrides:
|
|
|
312
345
|
--token-tracker-queue
|
|
313
346
|
```
|
|
314
347
|
|
|
315
|
-
###
|
|
348
|
+
### Token collection diagnostics
|
|
316
349
|
|
|
317
350
|
```bash
|
|
318
|
-
npx
|
|
319
|
-
npx
|
|
351
|
+
npx tokentracker-cli status
|
|
352
|
+
npx tokentracker-cli doctor
|
|
320
353
|
```
|
|
321
354
|
|
|
322
|
-
|
|
355
|
+
Installing the npm package does not edit Agent configuration. The first
|
|
356
|
+
`vibe-roast` execution announces and performs TokenTracker initialization;
|
|
357
|
+
TokenTracker owns its compatible hooks and local queue from that point onward.
|
|
323
358
|
|
|
324
359
|
## Configuration
|
|
325
360
|
|
package/assests/README.md
CHANGED
|
@@ -29,6 +29,7 @@ assests/
|
|
|
29
29
|
│ └── *.sbti-archive.svg # old SBTI diamond cards
|
|
30
30
|
├── badges/01-builder … 08-yolo-shipper/
|
|
31
31
|
├── banners/ home-hero.* share-strip.* result-header.*
|
|
32
|
+
├── screenshots/ # anonymized product screenshots used in README
|
|
32
33
|
├── scripts/score-engine.js # type and behavior-dimension reference helpers
|
|
33
34
|
├── scripts/vibe-types.json # 16-type figure manifest
|
|
34
35
|
├── source/design-system.md
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/bin/vibe-roast.js
CHANGED
|
@@ -6,6 +6,7 @@ loadLocalEnv();
|
|
|
6
6
|
const { inspectSources } = require("../src/inspect");
|
|
7
7
|
const { start } = require("../src/server");
|
|
8
8
|
const { install, uninstall } = require("../src/hooks/install");
|
|
9
|
+
const { ensureTokenTracker } = require("../src/lib/token-tracker-runtime");
|
|
9
10
|
const { KNOWN_SOURCES } = require("../src/sources");
|
|
10
11
|
|
|
11
12
|
async function main(argv) {
|
|
@@ -38,6 +39,9 @@ async function main(argv) {
|
|
|
38
39
|
}
|
|
39
40
|
|
|
40
41
|
const opts = parseArgs(rest);
|
|
42
|
+
if (!opts.tokenTrackerQueue && !hasFixtureRoots(opts)) {
|
|
43
|
+
await ensureTokenTracker();
|
|
44
|
+
}
|
|
41
45
|
const report = await inspectSources({
|
|
42
46
|
from: opts.from,
|
|
43
47
|
to: opts.to,
|
|
@@ -64,6 +68,24 @@ async function main(argv) {
|
|
|
64
68
|
process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
|
|
65
69
|
}
|
|
66
70
|
|
|
71
|
+
function hasFixtureRoots(opts) {
|
|
72
|
+
return [
|
|
73
|
+
"home",
|
|
74
|
+
"codexRoot",
|
|
75
|
+
"claudeRoot",
|
|
76
|
+
"cursorDb",
|
|
77
|
+
"clineRoot",
|
|
78
|
+
"rooRoot",
|
|
79
|
+
"continueRoot",
|
|
80
|
+
"geminiRoot",
|
|
81
|
+
"aiderRoot",
|
|
82
|
+
"windsurfRoot",
|
|
83
|
+
"copilotRoot",
|
|
84
|
+
"amazonqRoot",
|
|
85
|
+
"antigravityRoot",
|
|
86
|
+
].some((key) => opts[key]);
|
|
87
|
+
}
|
|
88
|
+
|
|
67
89
|
function parseArgs(args) {
|
|
68
90
|
const opts = {};
|
|
69
91
|
for (let i = 0; i < args.length; i++) {
|
|
@@ -157,7 +157,7 @@ Error generating stack: `+l.message+`
|
|
|
157
157
|
*
|
|
158
158
|
* This source code is licensed under the ISC license.
|
|
159
159
|
* See the LICENSE file in the root directory of this source tree.
|
|
160
|
-
*/const Bc=lt("X",[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]]);var Wc=Rc();function vl(a){const c=a.getUTCFullYear(),u=String(a.getUTCMonth()+1).padStart(2,"0"),d=String(a.getUTCDate()).padStart(2,"0");return`${c}-${u}-${d}`}function yl(a,c){return new Date(Date.UTC(a.getUTCFullYear(),a.getUTCMonth(),a.getUTCDate()+c))}function yp(a,c){return Math.floor((Date.UTC(c.getUTCFullYear(),c.getUTCMonth(),c.getUTCDate())-Date.UTC(a.getUTCFullYear(),a.getUTCMonth(),a.getUTCDate()))/864e5)}function ms(a,c){if(!Array.isArray(a)||a.length===0)return 0;const u=a.length,d=(u-1)*c,f=Math.floor(d),v=d-f,m=a[f]??a[u-1],g=a[Math.min(u-1,f+1)]??a[u-1];return Math.round(m+(g-m)*v)}function kp(a){return a<=0?0:a>=4?4:a}function Cs({prompts:a=[],dailyRows:c=null,weeks:u=52}){var ue;const d=new Date,f=new Date(Date.UTC(d.getFullYear(),d.getMonth(),d.getDate())),v=yl(f,-(u*7-1)),m=v.getUTCDay(),g=yl(v,-m),p=new Map;if(Array.isArray(c)&&c.length>0)for(const F of c){if(!(F!=null&&F.day))continue;const Q=Cl(F.billable_total_tokens??F.total_tokens??F.value),U=p.get(F.day)||{value:0,models:{},sources:{},conversation_count:0};U.value+=Q,U.total_tokens=(U.total_tokens||0)+Cl(F.total_tokens??Q),U.billable_total_tokens=(U.billable_total_tokens||0)+Q,U.conversation_count+=Cl(F.conversation_count),xc(U.models,F.models),xc(U.sources,F.sources),p.set(F.day,U)}else for(const F of a||[]){if(!F.timestamp)continue;const Q=String(F.timestamp).slice(0,10),U=p.get(Q)||{value:0,models:{}};U.value++;const I=F.source||"unknown";U.models[I]=(U.models[I]||0)+1,p.set(Q,U)}const y=yp(g,f)+1,C=Math.ceil(y/7),E=[];for(let F=0;F<y;F++){const Q=yl(g,F),U=vl(Q),I=((ue=p.get(U))==null?void 0:ue.value)||0;I>0&&E.push(I)}E.sort((F,Q)=>F-Q);const w=ms(E,.5),G=ms(E,.75),O=ms(E,.9);function T(F){return!F||F<=0?0:F<=w?1:F<=G?2:F<=O?3:4}const P=[];for(let F=0;F<C;F++){const Q=[];for(let U=0;U<7;U++){const I=F*7+U,he=yl(g,I);if(he.getTime()>f.getTime()){Q.push(null);continue}const Se=vl(he),ce=p.get(Se),Me=ce?ce.value:0;Q.push({day:Se,value:Me,total_tokens:ce==null?void 0:ce.total_tokens,billable_total_tokens:ce==null?void 0:ce.billable_total_tokens,conversation_count:ce==null?void 0:ce.conversation_count,level:kp(T(Me)),models:(ce==null?void 0:ce.models)||null,sources:(ce==null?void 0:ce.sources)||null})}P.push(Q)}const ie=P.length>u?P.slice(P.length-u):P;return{from:vl(g),to:vl(f),weeks:ie,thresholds:{t1:w,t2:G,t3:O}}}function xc(a,c){if(!(!c||typeof c!="object"))for(const[u,d]of Object.entries(c))a[u]=(a[u]||0)+Cl(d)}function Cl(a){const c=Number(a||0);return Number.isFinite(c)&&c>0?Math.floor(c):0}const lo={emerald:{light:["#ebedf0","#a7f3d0","#6ee7b7","#34d399","#10b981"],dark:["#2d333b","#065f46","#059669","#10b981","#34d399"],gridColor:{light:"rgba(16, 185, 129, 0.12)",dark:"rgba(52, 211, 153, 0.08)"}},ocean:{light:["#f1f5f9","#93c5fd","#60a5fa","#3b82f6","#1d4ed8"],dark:["#1e293b","#1e3a8a","#2563eb","#3b82f6","#60a5fa"],gridColor:{light:"rgba(59, 130, 246, 0.12)",dark:"rgba(96, 165, 250, 0.08)"}},neon:{light:["#faf5ff","#ebd5ff","#c084fc","#a855f7","#7e22ce"],dark:["#2e1065","#581c87","#8b5cf6","#a855f7","#c084fc"],gridColor:{light:"rgba(168, 85, 247, 0.12)",dark:"rgba(192, 132, 252, 0.08)"}},amber:{light:["#fffbeb","#fde68a","#f59e0b","#d97706","#b45309"],dark:["#451a03","#78350f","#b45309","#d97706","#f59e0b"],gridColor:{light:"rgba(245, 158, 11, 0.12)",dark:"rgba(245, 158, 11, 0.08)"}}};function wp(a,c){const u=/^#([0-9a-f]{6})$/i.exec(a);if(!u)return a;const d=parseInt(u[1],16),f=d>>16&255,v=d>>8&255,m=d&255,g=p=>Math.max(0,Math.min(255,Math.round(p*c)));return`rgb(${g(f)}, ${g(v)}, ${g(m)})`}function tn(a,c,u,d,f){const v=Math.cos(d),m=Math.sin(d),g=a*v-c*m,p=a*m+c*v,y=u,C=Math.cos(f),E=Math.sin(f);return{x:g,y:p*C-y*E,z:p*E+y*C}}function Sp(a,c,u,d,f){return tn(a,c,u,d,f)}function Cp(a,c){const u=Number(c).toLocaleString();return a>=4?`${u} prompts — an epic day of coding!`:a===3?`${u} prompts — you were in the zone.`:a===2?`${u} prompts — a solid session.`:a===1?`${u} prompts — dipping your toes in.`:"No activity this day."}function vc({prompts:a=[],dailyRows:c=null,weeks:u=26,palette:d="emerald",isDark:f=!0,interactive:v=!0,autoRotateInit:m=!0,onResetViewRef:g=null,unitLabel:p="Prompts"}){const C=M.useMemo(()=>Cs({prompts:a,dailyRows:c,weeks:u}),[a,c,u]).weeks,E=lo[d]||lo.emerald,w=f?E.dark:E.light,G=f?E.gridColor.dark:E.gridColor.light,O=-.2,T=.88,[P,ie]=M.useState({yaw:O,pitch:T}),[ue,F]=M.useState(m),[Q,U]=M.useState(1),I=v?13:10.5;M.useEffect(()=>{g&&(g.current={reset:()=>{ie({yaw:O,pitch:T}),F(!1),U(1),K()},toggleAutoRotate:D=>{F(D)}})},[g]);const he=M.useMemo(()=>{const D=[],V=C.length;if(V===0||!v)return[];for(let ae=0;ae<=7;ae++){const Y=(ae-3.5)*I,de=tn(-V/2*I,Y,0,P.yaw,P.pitch),ve=tn(V/2*I,Y,0,P.yaw,P.pitch);D.push({d:`M${de.x},${de.y} L${ve.x},${ve.y}`,key:`h-${ae}`})}for(let ae=0;ae<=V;ae+=4){const Y=(ae-V/2)*I,de=tn(Y,-3.5*I,0,P.yaw,P.pitch),ve=tn(Y,3.5*I,0,P.yaw,P.pitch);D.push({d:`M${de.x},${de.y} L${ve.x},${ve.y}`,key:`v-${ae}`})}if(V%4!==0){const ae=(V-V/2)*I,Y=tn(ae,-3.5*I,0,P.yaw,P.pitch),de=tn(ae,3.5*I,0,P.yaw,P.pitch);D.push({d:`M${Y.x},${Y.y} L${de.x},${de.y}`,key:"v-last"})}return D},[C.length,P,I,v]),Se=M.useRef(null),ce=M.useRef(null),Me=M.useRef(!1),Fe=M.useRef({x:0,y:0}),ee=M.useRef({yaw:O,pitch:T}),je=M.useRef({x:0,y:0}),te=M.useRef({x:0,y:0,time:0}),ye=M.useRef(null),[Pe,Ne]=M.useState(v?0:1),H=M.useRef(null),oe=M.useRef(!0);M.useEffect(()=>(oe.current=!0,()=>{oe.current=!1}),[]);const K=()=>{H.current&&cancelAnimationFrame(H.current),Ne(0);const D=performance.now(),V=ae=>{if(!oe.current)return;const Y=Math.min(1,(ae-D)/1200);Ne(1-Math.pow(1-Y,3)),Y<1&&(H.current=requestAnimationFrame(V))};H.current=requestAnimationFrame(V)};M.useEffect(()=>(K(),()=>{H.current&&cancelAnimationFrame(H.current)}),[v]),M.useEffect(()=>{var ae;if(!ue||Me.current||typeof window<"u"&&((ae=window.matchMedia)!=null&&ae.call(window,"(prefers-reduced-motion: reduce)").matches))return;let D;const V=()=>{if(typeof document<"u"&&document.visibilityState==="hidden"){D=requestAnimationFrame(V);return}ie(Y=>({yaw:Y.yaw+.002,pitch:Y.pitch})),D=requestAnimationFrame(V)};return D=requestAnimationFrame(V),()=>cancelAnimationFrame(D)},[ue]);const S=(D,V)=>{v&&(Me.current=!0,Fe.current={x:D,y:V},ee.current={yaw:P.yaw,pitch:P.pitch},je.current={x:0,y:0},te.current={x:D,y:V,time:performance.now()},ye.current&&cancelAnimationFrame(ye.current))},_=(D,V)=>{if(!Me.current)return;const ae=D-Fe.current.x,Y=V-Fe.current.y,de=performance.now(),ve=de-te.current.time;ve>0&&(je.current={x:(D-te.current.x)/ve,y:(V-te.current.y)/ve}),te.current={x:D,y:V,time:de};const De=.005,Ke=ee.current.yaw-ae*De,He=Math.PI/2.3,qe=Math.max(-He,Math.min(He,ee.current.pitch-Y*De));ie({yaw:Ke,pitch:qe})},z=()=>{if(!Me.current)return;Me.current=!1;let D=-je.current.x*12,V=-je.current.y*12;const ae=()=>{Me.current||(D*=.95,V*=.95,!(Math.abs(D)<.01&&Math.abs(V)<.01)&&(ie(Y=>{const de=Math.PI/2.3;return{yaw:Y.yaw+D*.005,pitch:Math.max(-de,Math.min(de,Y.pitch+V*.005))}}),ye.current=requestAnimationFrame(ae)))};ye.current=requestAnimationFrame(ae)},[W,me]=M.useState(null),[X,Ce]=M.useState({x:0,y:0,shiftX:0}),fe=M.useRef(null);M.useEffect(()=>()=>{fe.current&&clearTimeout(fe.current)},[]),M.useEffect(()=>{if(!v||!ce.current)return;const D=V=>{V.preventDefault(),U(ae=>Math.max(.5,Math.min(3,ae-V.deltaY*.0025)))};return ce.current.addEventListener("wheel",D,{passive:!1}),()=>{var V;return(V=ce.current)==null?void 0:V.removeEventListener("wheel",D)}},[v]);const Ee=M.useMemo(()=>{const D=[];return C.forEach((V,ae)=>{(Array.isArray(V)?V:[]).forEach((Y,de)=>{Y&&D.push({key:Y.day||`${ae}-${de}`,col:ae,row:de,level:Y.level||0,value:Y.value||0,day:Y.day,models:Y.models||null})})}),D},[C]),nn=I-(v?1.8:1.5),_e=v?38:28,A=D=>Math.max(1.8,Number(D)/4*_e),Z=M.useMemo(()=>{if(Ee.length===0)return[];const D=C.length;return Ee.map(V=>{const ae=A(V.level),Y=Math.sqrt(Math.pow(V.col-D/2,2)+Math.pow(V.row-3.5,2)),de=Math.sqrt(Math.pow(D/2,2)+Math.pow(3.5,2)),ve=Y/de*.4,De=Math.min(1,Math.max(0,(Pe-ve)*(1/.6))),Ke=ae*De,He=(V.col-D/2)*I,qe=(V.row-3.5)*I,We=nn/2,rt=[{x:He-We,y:qe-We,z:0},{x:He+We,y:qe-We,z:0},{x:He+We,y:qe+We,z:0},{x:He-We,y:qe+We,z:0},{x:He-We,y:qe-We,z:Ke},{x:He+We,y:qe-We,z:Ke},{x:He+We,y:qe+We,z:Ke},{x:He-We,y:qe+We,z:Ke}].map(mt=>tn(mt.x,mt.y,mt.z,P.yaw,P.pitch)),At=tn(He,qe,Ke/2,P.yaw,P.pitch),Lt=[{name:"top",indices:[4,5,6,7],scale:1,normal:[0,0,1]},{name:"bottom",indices:[3,2,1,0],scale:.4,normal:[0,0,-1]},{name:"left",indices:[3,0,4,7],scale:.55,normal:[-1,0,0]},{name:"right",indices:[1,2,6,5],scale:.75,normal:[1,0,0]},{name:"front",indices:[0,1,5,4],scale:.85,normal:[0,-1,0]},{name:"back",indices:[2,3,7,6],scale:.65,normal:[0,1,0]}],yt=w[Math.min(4,Math.max(0,Number(V.level)||0))],Qt=[],Rt=.35,ao=-.4,so=.83;return Lt.forEach(mt=>{const An=Sp(mt.normal[0],mt.normal[1],mt.normal[2],P.yaw,P.pitch);if(An.z>.001){const kr=rt[mt.indices[0]],Zn=rt[mt.indices[1]],wr=rt[mt.indices[2]],fn=rt[mt.indices[3]],Sr=`M${kr.x},${kr.y} L${Zn.x},${Zn.y} L${wr.x},${wr.y} L${fn.x},${fn.y} Z`,Ln=An.x*Rt+An.y*ao+An.z*so,El=f?.18:0,Rn=mt.scale*(.82+.28*Math.max(0,Ln))+El;Qt.push({name:mt.name,d:Sr,fill:wp(yt,Rn)})}}),{...V,centerProj:At,renderedFaces:Qt}})},[Ee,P,w,C.length,Pe,I,nn,_e,f]),J=M.useMemo(()=>[...Z].sort((D,V)=>D.centerProj.z-V.centerProj.z),[Z]),ke=M.useMemo(()=>{if(J.length===0)return{minX:-100,minY:-100,maxX:100,maxY:100};let D=1/0,V=1/0,ae=-1/0,Y=-1/0;return J.forEach(de=>{const ve=I*2;de.centerProj.x-ve<D&&(D=de.centerProj.x-ve),de.centerProj.x+ve>ae&&(ae=de.centerProj.x+ve),de.centerProj.y-ve<V&&(V=de.centerProj.y-ve),de.centerProj.y+ve>Y&&(Y=de.centerProj.y+ve)}),{minX:D,minY:V,maxX:ae,maxY:Y}},[J,I]),pe=12,Te=ke.maxX-ke.minX+pe*2,Ae=ke.maxY-ke.minY+pe*2,Le=Te/Q,be=Ae/Q,Ye=ke.minX-pe+(Te-Le)/2,Re=ke.minY-pe+(Ae-be)/2,Ue=`${Ye} ${Re} ${Le} ${be}`;return Ee.length===0?s.jsx("div",{className:"py-8 text-center text-sm text-oai-gray-500",children:"No activity data yet."}):s.jsxs("div",{ref:ce,className:`relative select-none outline-none ${v?"cursor-grab active:cursor-grabbing w-full h-full flex items-center justify-center":"w-full h-full min-h-[220px] overflow-hidden flex items-center justify-center"}`,onMouseDown:D=>{if(!v)return;S(D.clientX,D.clientY);const V=Y=>_(Y.clientX,Y.clientY),ae=()=>{z(),window.removeEventListener("mousemove",V),window.removeEventListener("mouseup",ae)};window.addEventListener("mousemove",V),window.addEventListener("mouseup",ae)},onTouchStart:D=>{v&&D.touches.length&&S(D.touches[0].clientX,D.touches[0].clientY)},onTouchMove:D=>{v&&D.touches.length&&_(D.touches[0].clientX,D.touches[0].clientY)},onTouchEnd:()=>{v&&z()},children:[s.jsxs("svg",{ref:Se,viewBox:Ue,width:"100%",height:"100%",preserveAspectRatio:"xMidYMid meet",role:"img","aria-label":"Interactive activity heatmap",style:{display:"block",width:"100%",height:"100%",maxHeight:v?"78vh":"100%"},className:"transition-transform duration-300 ease-out",children:[v&&he.map(D=>s.jsx("path",{d:D.d,fill:"none",stroke:G,strokeWidth:.25,strokeDasharray:"1.5 2.5",strokeLinecap:"round"},D.key)),J.map(D=>{const V=W&&W.key===D.key;return s.jsxs("g",{onMouseEnter:ae=>{var Y;if(fe.current&&(clearTimeout(fe.current),fe.current=null),me(D),v&&Se.current){const de=tn((D.col-C.length/2)*I,(D.row-3.5)*I,A(D.level),P.yaw,P.pitch);let ve=0,De=0;const Ke=Se.current;if(ce.current&&typeof Ke.createSVGPoint=="function"&&typeof Ke.getScreenCTM=="function")try{const pt=Ke.createSVGPoint();pt.x=de.x,pt.y=de.y;const rt=Ke.getScreenCTM();if(rt){const At=pt.matrixTransform(rt),Lt=ce.current.getBoundingClientRect();ve=At.x-Lt.left,De=At.y-Lt.top}}catch{}const He=140,qe=((Y=ce.current)==null?void 0:Y.getBoundingClientRect().width)||Ke.getBoundingClientRect().width;let We=0;ve<He?We=He-ve:ve>qe-He&&(We=qe-He-ve),Ce({x:ve,y:De,shiftX:We})}},onMouseLeave:()=>{fe.current&&clearTimeout(fe.current),fe.current=setTimeout(()=>me(null),150)},className:"transition-all duration-200",style:{filter:V?"brightness(1.15) drop-shadow(0 4px 6px rgba(0,0,0,0.15))":"none",cursor:v?"pointer":"default"},children:[!v&&D.day&&s.jsx("title",{children:`${D.day}: ${Number(D.value).toLocaleString()} ${p.toLowerCase()}`}),D.renderedFaces.map((ae,Y)=>s.jsx("path",{d:ae.d,fill:ae.fill,stroke:ae.fill,strokeWidth:.25,strokeLinejoin:"round"},Y))]},D.key)})]}),v&&W&&s.jsxs("div",{onMouseEnter:()=>{fe.current&&(clearTimeout(fe.current),fe.current=null)},onMouseLeave:()=>{fe.current&&clearTimeout(fe.current),fe.current=setTimeout(()=>me(null),150)},className:"absolute z-[9999] w-0 h-0 transition-all duration-100 ease-out",style:{left:`${X.x}px`,top:`${X.y}px`},children:[s.jsxs("div",{className:"absolute left-0 bottom-[10px] backdrop-blur-md bg-white/90 dark:bg-oai-gray-900/90 border border-oai-gray-200/50 dark:border-oai-gray-800/50 shadow-xl rounded-xl p-3.5 max-w-[280px] min-w-[200px] flex flex-col gap-2 animate-in fade-in zoom-in-95 duration-100",style:{transform:`translateX(calc(-50% + ${X.shiftX}px))`},children:[s.jsxs("div",{className:"flex items-center justify-between border-b border-oai-gray-100 dark:border-oai-gray-800/80 pb-1.5",children:[s.jsx("span",{className:"text-[11px] font-semibold text-oai-gray-500 dark:text-oai-gray-400",children:W.day}),s.jsxs("span",{className:"text-[10px] px-2 py-0.5 rounded-full font-medium",style:{backgroundColor:(W.level===0?f?"#9ca3af":"#6b7280":w[W.level])+"22",color:W.level===0?f?"#9ca3af":"#6b7280":w[W.level],border:`1px solid ${W.level===0?f?"#9ca3af":"#6b7280":w[W.level]}44`},children:["Level ",W.level]})]}),s.jsxs("div",{className:"flex flex-col gap-2",children:[s.jsxs("div",{className:"flex items-baseline gap-1",children:[s.jsx("span",{className:"text-lg font-bold text-oai-gray-900 dark:text-white leading-none",children:Number(W.value).toLocaleString()}),s.jsx("span",{className:"text-[10px] text-oai-gray-400 uppercase tracking-wider font-semibold",children:p})]}),W.models&&Object.keys(W.models).length>0?s.jsxs("div",{className:"mt-1.5 border-t border-oai-gray-100 dark:border-oai-gray-800/60 pt-2 flex flex-col gap-1.5",children:[s.jsx("div",{className:"text-[10px] font-semibold text-oai-gray-400 dark:text-oai-gray-500 uppercase tracking-wider",children:"Source Breakdown"}),s.jsx("div",{className:"flex flex-col gap-2 max-h-[150px] overflow-y-auto pr-1.5",children:Object.entries(W.models).map(([D,V])=>({name:D,val:Number(V)||0})).sort((D,V)=>V.val-D.val).map(({name:D,val:V})=>{const ae=Number(W.value)||1,Y=Math.round(V/ae*100);return s.jsxs("div",{className:"flex flex-col gap-1",children:[s.jsxs("div",{className:"flex items-center justify-between text-[11px] gap-3",children:[s.jsx("span",{className:"font-medium text-oai-gray-700 dark:text-oai-gray-200 truncate max-w-[120px]",title:D,children:D}),s.jsxs("div",{className:"flex items-center gap-1.5 shrink-0",children:[s.jsx("span",{className:"font-mono text-oai-gray-900 dark:text-oai-gray-100 font-semibold",children:V.toLocaleString()}),s.jsxs("span",{className:"text-[9px] text-oai-gray-400 dark:text-oai-gray-500 min-w-[28px] text-right font-medium",children:[Y,"%"]})]})]}),s.jsx("div",{className:"w-full h-1 bg-oai-gray-100 dark:bg-oai-gray-800/85 rounded-full overflow-hidden",children:s.jsx("div",{className:"h-full rounded-full transition-all duration-300",style:{width:`${Y}%`,backgroundColor:w[4],boxShadow:`0 0 4px ${w[4]}55`}})})]},D)})})]}):s.jsx("p",{className:"text-[11px] text-oai-gray-600 dark:text-oai-gray-300 leading-relaxed font-normal mt-1 border-t border-dashed border-oai-gray-100 dark:border-oai-gray-800/60 pt-1.5",children:Cp(W.level,W.value)})]})]}),s.jsx("div",{className:"absolute bottom-[6px] left-0 -translate-x-1/2 w-2.5 h-2.5 rotate-45 bg-white dark:bg-oai-gray-900 border-r border-b border-oai-gray-200/50 dark:border-oai-gray-800/50 shadow-sm",style:{marginBottom:"1px"}})]})]})}const jp=["#ebedf0","#a7f3d0","#6ee7b7","#34d399","#10b981"],bp=["#121212","#065f46","#059669","#10b981","#34d399"],zn=11,ro=2,hs=26;function Np({prompts:a=[],dailyRows:c=null,weeks:u=26,dark:d=!1,compact:f=!1,dense:v=!1}){const{locale:m,t:g}=Xn(),p=M.useMemo(()=>Cs({prompts:a,dailyRows:c,weeks:u}),[a,c,u]),y=d?bp:jp,C=p.weeks||[],E=Math.max(C.length*(zn+ro)+hs,120),w=m==="zh"?["日","一","二","三","四","五","六"]:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],G=M.useMemo(()=>{const O=[];return C.forEach((T,P)=>{var F;const ie=(F=(T||[]).find(Q=>{var U;return(U=Q==null?void 0:Q.day)==null?void 0:U.endsWith("-01")}))==null?void 0:F.day;if(!ie)return;const ue=new Date(`${ie}T00:00:00Z`);O.push({index:P,text:new Intl.DateTimeFormat(m==="zh"?"zh-CN":"en-US",{month:"short",timeZone:"UTC"}).format(ue)})}),O},[C,m]);return s.jsxs("div",{className:"w-full",children:[s.jsx("div",{className:"activity-scroll overflow-x-auto overflow-y-hidden pb-1",children:s.jsxs("div",{style:{width:E},children:[s.jsx("div",{className:"relative mb-1 h-3 text-[10px] uppercase text-[#8b8680] dark:text-[#8f8f8f]",children:G.map(O=>s.jsx("span",{className:"absolute whitespace-nowrap",style:{left:hs+O.index*(zn+ro)},children:O.text},`${O.text}-${O.index}`))}),s.jsxs("div",{className:"flex",style:{gap:ro},children:[s.jsx("div",{className:"grid shrink-0 text-[10px] text-[#8b8680] dark:text-[#8f8f8f]",style:{width:hs,gridTemplateRows:`repeat(7, ${zn}px)`,rowGap:ro},children:w.map(O=>s.jsx("span",{className:"leading-none",children:O},O))}),s.jsx("div",{className:"grid",style:{gridAutoFlow:"column",gridTemplateRows:`repeat(7, ${zn}px)`,gap:ro},children:C.map((O,T)=>(O||[]).map((P,ie)=>P?s.jsx("span",{className:"activity-cell cursor-pointer rounded-[2px] transition-transform hover:z-10 hover:scale-125",style:{width:zn,height:zn,background:y[P.level]||y[0],"--motion-delay":`${Math.min(420,T*7+ie*5)}ms`},title:`${P.day}: ${Number(P.value||0).toLocaleString()}`},P.day||`${T}-${ie}`):s.jsx("span",{style:{width:zn,height:zn}},`${T}-${ie}`)))})]})]})}),s.jsxs("div",{className:"mt-3 flex items-center justify-center gap-2",children:[s.jsx("span",{className:"text-[10px] text-[#8b8680] dark:text-[#8f8f8f]",children:g("heatmap.less")}),s.jsx("span",{className:"flex gap-0.5",children:y.map((O,T)=>s.jsx("span",{className:"rounded-[1px]",style:{width:10,height:10,background:O},title:`Level ${T}`},O))}),s.jsx("span",{className:"text-[10px] text-[#8b8680] dark:text-[#8f8f8f]",children:g("heatmap.more")})]})]})}const yc={emerald:{rawColor:"#10b981"},ocean:{rawColor:"#3b82f6"},neon:{rawColor:"#a855f7"},amber:{rawColor:"#f59e0b"}};function kc(a){const c=Number(a)||0;return c<1e3?c.toLocaleString():c<1e6?`${(c/1e3).toFixed(c>=1e4?0:1)}K`:c<1e9?`${(c/1e6).toFixed(c>=1e7?0:2)}M`:`${(c/1e9).toFixed(c>=1e10?0:2)}B`}function Ep(a){const c=[];for(const p of a)for(const y of Array.isArray(p)?p:[])y!=null&&y.day&&c.push(y);c.sort((p,y)=>p.day.localeCompare(y.day));let u=0,d=0,f=0,v=0,m={day:"—",value:0};for(const p of c){const y=Number(p.value)||0;u+=y,y>0?(d+=1,v+=1,f=Math.max(f,v)):v=0,y>m.value&&(m={day:p.day,value:y})}const g=c.length?(d/c.length*100).toFixed(1):"0.0";return{totalValue:u,activeDays:d,activeRate:g,maxStreak:f,peakDay:m}}function Tp({prompts:a=[],activity:c=null,weeks:u=20,className:d="",forceLight:f=!1,defaultPalette:v="emerald",roastStyle:m=!1,showViewToggle:g=!1,defaultViewMode:p}){var me;const{theme:y}=Ic(),{t:C}=Xn(),E=f?!1:y==="dark"||y==="system"&&typeof window<"u"&&((me=window.matchMedia)==null?void 0:me.call(window,"(prefers-color-scheme: dark)").matches),w=Array.isArray(c==null?void 0:c.daily_rows)&&c.daily_rows.length>0,G=w?c.metric||"tokens":"prompts",O=w?c.daily_rows:null,T=G==="tokens"?Math.max(u,52):u,P=C(G==="tokens"?"heatmap.tokens":"heatmap.prompts"),ie=M.useMemo(()=>Cs({prompts:a,dailyRows:O,weeks:T}),[a,O,T]),ue=M.useMemo(()=>Ep(ie.weeks||[]),[ie.weeks]),[F,Q]=M.useState(!1),[U,I]=M.useState(!1),he=lo[v]?v:"emerald",[Se,ce]=M.useState(p??(g||m?"2d":"3d")),[Me,Fe]=M.useState(0),[ee,je]=M.useState("in"),te=M.useRef(null),ye=M.useRef(null),Pe=m||g,Ne=Pe?"min-h-[190px]":"min-h-[240px]",H=Pe?"max-h-[320px]":"",oe=yc[he]||yc.emerald,K=E?lo[he].dark:lo[he].light,S=M.useMemo(()=>{const X=-new Date().getTimezoneOffset(),Ce=X>=0?"+":"-",fe=String(Math.floor(Math.abs(X)/60)).padStart(2,"0"),Ee=String(Math.abs(X)%60).padStart(2,"0");return`UTC${Ce}${fe}:${Ee}`},[]),_=()=>I(!0),z=X=>{X!==Se&&(ye.current&&clearTimeout(ye.current),je("out"),ye.current=setTimeout(()=>{ce(X),Fe(Ce=>Ce+1),je("in")},160))};M.useEffect(()=>()=>{ye.current&&clearTimeout(ye.current)},[]),M.useEffect(()=>{if(!F||U)return;const X=Ce=>{Ce.key==="Escape"&&_()};return window.addEventListener("keydown",X),()=>window.removeEventListener("keydown",X)},[F,U]);const W=F&&typeof document<"u"?Wc.createPortal(s.jsx("div",{onAnimationEnd:X=>{X.target===X.currentTarget&&U&&(Q(!1),I(!1))},onClick:X=>{X.target===X.currentTarget&&_()},className:`fixed inset-0 z-50 flex items-center justify-center p-3 md:p-6 backdrop-blur-md bg-black/40 ${U?"animate-tt-fade-out":"animate-tt-fade-in"}`,children:s.jsxs("div",{className:`relative flex h-[88vh] w-full max-w-6xl flex-col overflow-hidden rounded-[22px] border border-black/[0.07] bg-[#fffcf7] shadow-[0_24px_70px_rgba(45,30,18,0.22)] dark:border-white/[0.08] dark:bg-[#171717] md:flex-row ${U?"animate-tt-modal-exit":"animate-tt-modal"}`,children:[s.jsxs("div",{className:"absolute right-4 top-4 z-50 flex items-center gap-1",children:[s.jsx("button",{type:"button",onClick:()=>{var X;return(X=te.current)==null?void 0:X.reset()},className:"inline-flex h-9 w-9 items-center justify-center rounded-full border border-black/[0.07] bg-[#fffcf7] text-[#8b8680] hover:text-[#1a1a1a] dark:border-white/[0.08] dark:bg-[#171717] dark:text-[#8f8f8f] dark:hover:text-white",title:C("heatmap.reset"),children:s.jsx(gp,{size:14})}),s.jsx("button",{type:"button",onClick:_,className:"inline-flex h-9 w-9 items-center justify-center rounded-full border border-black/[0.07] bg-[#fffcf7] text-[#8b8680] hover:text-[#1a1a1a] dark:border-white/[0.08] dark:bg-[#171717] dark:text-[#8f8f8f] dark:hover:text-white",title:C("heatmap.close"),children:s.jsx(Bc,{size:15})})]}),s.jsxs("aside",{className:"flex w-full flex-col gap-6 overflow-y-auto border-b border-black/[0.06] bg-[#f7f4ef] p-5 dark:border-white/[0.07] dark:bg-[#121212] md:w-[320px] md:border-b-0 md:border-r md:p-6",children:[s.jsxs("div",{children:[s.jsxs("div",{className:"flex items-center gap-1.5 select-none",children:[s.jsx("span",{className:"h-1.5 w-1.5 rounded-full",style:{backgroundColor:oe.rawColor}}),s.jsx("span",{className:"text-[10px] font-bold uppercase tracking-[0.16em] text-[#8b8680] dark:text-[#8f8f8f]",children:C("heatmap.insight")})]}),s.jsx("h4",{className:"mt-2 text-xl font-extrabold leading-none tracking-tight text-[#1a1a1a] dark:text-[#fafafa]",children:C(G==="tokens"?"heatmap.tokenTitle":"heatmap.promptTitle")}),s.jsx("p",{className:"mt-2 text-xs leading-5 text-[#716b65] dark:text-[#aaa49e]",children:C(G==="tokens"?"heatmap.tokenDesc":"heatmap.promptDesc")})]}),s.jsxs("div",{className:"grid grid-cols-2 gap-x-5 gap-y-5 border-y border-black/[0.07] py-5 dark:border-white/[0.08]",children:[s.jsx(kl,{label:C(G==="tokens"?"heatmap.totalTokens":"heatmap.totalPrompts"),value:kc(ue.totalValue),exact:`${ue.totalValue.toLocaleString()} ${P.toLowerCase()}`}),s.jsx(kl,{label:C(G==="tokens"?"heatmap.activeRateDays":"heatmap.activeDays"),value:`${ue.activeRate}%`,suffix:G==="tokens"?`(${ue.activeDays}D)`:void 0,exact:C("heatmap.activeDayCount",{count:ue.activeDays})}),s.jsx(kl,{label:C(G==="tokens"?"heatmap.longestStreak":"heatmap.maxStreak"),value:ue.maxStreak,suffix:C("heatmap.days")}),s.jsx(kl,{label:C("heatmap.peakDay"),value:ue.peakDay.value>0?kc(ue.peakDay.value):C("heatmap.noData"),suffix:ue.peakDay.day,exact:`${ue.peakDay.value.toLocaleString()} ${P.toLowerCase()}`})]}),s.jsx("div",{className:"mt-auto border-t border-black/[0.07] pt-4 dark:border-white/[0.08]",children:s.jsxs("div",{className:"flex flex-col gap-2",children:[s.jsx("span",{className:"text-[10px] font-bold uppercase tracking-[0.16em] text-[#8b8680] dark:text-[#8f8f8f]",children:C(G==="tokens"?"heatmap.activityLevels":"heatmap.legend")}),s.jsx("div",{className:"flex gap-1",children:K.map((X,Ce)=>s.jsx("div",{className:"flex-1 h-1 rounded-[2px]",style:{backgroundColor:X},title:`Level ${Ce}`},Ce))})]})})]}),s.jsxs("section",{className:"relative flex h-full flex-1 items-center justify-center overflow-hidden p-4",children:[s.jsx("div",{className:"absolute inset-0 pointer-events-none transition-colors duration-500",style:{background:`linear-gradient(135deg, ${oe.rawColor}0f, transparent 42%)`}}),s.jsx(vc,{prompts:a,dailyRows:O,weeks:T,isDark:E,interactive:!0,palette:he,autoRotateInit:!1,onResetViewRef:te,unitLabel:P}),s.jsxs("div",{className:"absolute bottom-4 right-4 flex items-center gap-1.5 text-[9px] font-bold text-oai-gray-400 bg-white/80 dark:bg-oai-gray-900/80 border border-oai-gray-200/50 dark:border-oai-gray-800/80 rounded-md px-2.5 py-1.5 select-none pointer-events-none backdrop-blur-md shadow-sm",children:[s.jsx(cp,{size:10,style:{color:oe.rawColor}}),s.jsx("span",{children:C("heatmap.footerTip")})]})]})]})}),document.body):null;return s.jsxs(s.Fragment,{children:[s.jsxs("div",{className:`relative w-full h-full ${Ne} ${H} ${d}`,children:[s.jsxs("div",{className:"mb-4 flex min-h-7 items-center justify-between gap-3",children:[s.jsx("h2",{className:"m-0 text-sm font-semibold uppercase tracking-[0.03em] text-[#393633] dark:text-[#d4d4d4]",children:C("profile.activity")}),s.jsxs("div",{className:"flex items-center gap-2",children:[g&&s.jsx("div",{role:"tablist","aria-label":C("heatmap.viewLabel"),className:"flex items-center rounded-lg border border-black/[0.07] bg-black/[0.02] p-0.5 text-[10px] font-medium text-[#8b8680] dark:border-white/[0.08] dark:bg-white/[0.02] dark:text-[#8f8f8f]",children:["2d","3d"].map(X=>s.jsx("button",{type:"button",role:"tab","aria-selected":Se===X,onClick:()=>z(X),className:`rounded-md px-2 py-0.5 uppercase transition-colors ${Se===X?"bg-white text-[#1a1a1a] shadow-sm dark:bg-[#2a2a2a] dark:text-white":"hover:text-[#1a1a1a] dark:hover:text-white"}`,children:C(X==="2d"?"heatmap.viewGrid":"heatmap.viewTerrain")},X))}),s.jsx("span",{className:"text-xs text-[#8b8680] dark:text-[#8f8f8f]",children:S})]})]}),s.jsx("div",{className:`h-full w-full ${Ne} ${H} ${ee==="out"?"heatmap-view-exit":"heatmap-view-enter"}`,children:Se==="2d"?s.jsx("div",{className:"flex w-full items-center justify-center overflow-hidden",children:s.jsx(Np,{prompts:a,dailyRows:O,weeks:T,dark:E,compact:!1,dense:!1})}):s.jsxs("button",{type:"button",onClick:()=>{I(!1),Q(!0)},className:`group relative w-full h-[170px] overflow-hidden rounded-lg border transition-all cursor-pointer ${m?"border-black/[0.04] bg-[#f7f4ef] hover:border-emerald-500/30 dark:border-white/[0.06] dark:bg-[#121212]":"border-transparent hover:border-oai-gray-700"}`,title:C("heatmap.openTitle"),children:[s.jsx(vc,{prompts:a,dailyRows:O,weeks:T,interactive:!1,autoRotateInit:!1,isDark:E,palette:he,unitLabel:P}),s.jsx("div",{className:`absolute inset-0 pointer-events-none opacity-0 group-hover:opacity-100 transition-opacity flex items-end justify-center pb-2 ${m?"bg-gradient-to-t from-[#f3f1ec]/70 to-transparent":"bg-gradient-to-t from-oai-gray-950/20 to-transparent"}`,children:s.jsxs("span",{className:`text-[10px] shadow px-2.5 py-1 rounded-full font-medium flex items-center gap-1 transform translate-y-2 group-hover:translate-y-0 transition-transform duration-200 ${m?"bg-[#fffcf7]/95 border border-black/5 text-[#6b6560]":"bg-white/95 dark:bg-oai-gray-900/95 border border-oai-gray-200/60 dark:border-oai-gray-800/80 text-oai-gray-500 dark:text-oai-gray-400"}`,children:[s.jsx(pp,{size:9}),C("heatmap.open")]})})]})},`${Se}-${Me}`)]}),W]})}function kl({label:a,value:c,suffix:u,exact:d}){return s.jsxs("div",{className:"flex flex-col gap-1 relative group cursor-default",children:[d&&s.jsx("div",{className:"absolute left-0 bottom-full mb-2 pointer-events-none opacity-0 translate-y-1 group-hover:opacity-100 group-hover:translate-y-0 transition-all duration-200 z-50",children:s.jsx("div",{className:"bg-white dark:bg-zinc-950 text-zinc-900 dark:text-zinc-50 text-[10px] font-semibold font-mono rounded-lg px-2.5 py-1.5 shadow-xl border border-zinc-200 dark:border-zinc-800/80 whitespace-nowrap",children:d})}),s.jsx("span",{className:"text-[10px] font-bold uppercase tracking-[0.12em] text-[#8b8680] dark:text-[#8f8f8f]",children:a}),s.jsxs("div",{className:"flex items-baseline gap-1.5",children:[s.jsx("span",{className:"font-[JetBrains_Mono,ui-monospace,monospace] text-xl font-bold tracking-tight text-[#1a1a1a] transition-transform duration-200 group-hover:-translate-y-[1px] dark:text-[#fafafa]",children:c}),u&&s.jsx("span",{className:"text-[10px] font-bold text-[#8b8680] dark:text-[#8f8f8f]",children:u})]})]})}const Vc={cursor:{label:"Cursor",glyph:"cursor",color:"#ffffff",background:"#171717"},codex:{label:"Codex",glyph:"codex",color:"#ffffff",background:"#111827"},claude:{label:"Claude Code",glyph:"claude",color:"#fff8f0",background:"#d97757"},gemini:{label:"Gemini CLI",glyph:"gemini",color:"#ffffff",background:"#4285f4"},copilot:{label:"GitHub Copilot",glyph:"copilot",color:"#ffffff",background:"#24292f"},antigravity:{label:"Antigravity",glyph:"antigravity",color:"#ffffff",background:"#1769ff"},cline:{label:"Cline",mark:"C",color:"#ffffff",background:"#2563eb"},roo:{label:"Roo Code",mark:"R",color:"#ffffff",background:"#ea580c"},continue:{label:"Continue",mark:"▶",color:"#ffffff",background:"#7c3aed"},aider:{label:"Aider",mark:"A",color:"#ffffff",background:"#15803d"},windsurf:{label:"Windsurf",mark:"≋",color:"#062a2e",background:"#5eead4"},amazonq:{label:"Amazon Q",mark:"Q",color:"#ffffff",background:"#ff9900"},opencode:{label:"OpenCode",glyph:"code",color:"#ffffff",background:"#334155"}};function js(a){const c=String(a||"").trim().toLowerCase().replace(/[\s_]+/g,"-");return{"claude-code":"claude","github-copilot":"copilot","amazon-q":"amazonq","gemini-cli":"gemini","roo-code":"roo"}[c]||c}function Nl(a){var u;const c=js(a);return((u=Vc[c])==null?void 0:u.label)||String(a||"Agent")}function _p({glyph:a,mark:c}){if(!a)return c;const u={width:"72%",height:"72%",viewBox:"0 0 24 24",fill:"none","aria-hidden":!0};return a==="cursor"?s.jsx("svg",{...u,children:s.jsx("path",{d:"M5.5 3.5 19 12l-6.1 1.35 3.25 5.7-2.6 1.45-3.2-5.7L6 19Z",fill:"currentColor"})}):a==="codex"?s.jsxs("svg",{...u,children:[s.jsx("path",{d:"M12 3.2 16 5.5l4 6.5-4 6.5-4 2.3-4-2.3L4 12l4-6.5Z",stroke:"currentColor",strokeWidth:"1.75"}),s.jsx("circle",{cx:"12",cy:"12",r:"3.25",stroke:"currentColor",strokeWidth:"1.75"})]}):a==="claude"?s.jsx("svg",{...u,children:s.jsx("path",{d:"M12 3v18M3 12h18M5.6 5.6l12.8 12.8M18.4 5.6 5.6 18.4M7.2 3.9l9.6 16.2M20.1 7.2 3.9 16.8",stroke:"currentColor",strokeWidth:"1.6",strokeLinecap:"round"})}):a==="gemini"?s.jsx("svg",{...u,children:s.jsx("path",{d:"M12 2.8c.5 5.55 3.65 8.7 9.2 9.2-5.55.5-8.7 3.65-9.2 9.2-.5-5.55-3.65-8.7-9.2-9.2 5.55-.5 8.7-3.65 9.2-9.2Z",fill:"currentColor"})}):a==="copilot"?s.jsxs("svg",{...u,children:[s.jsx("path",{d:"M5 10.5 7.2 6h9.6l2.2 4.5v6L16 19H8l-3-2.5Z",stroke:"currentColor",strokeWidth:"1.6",strokeLinejoin:"round"}),s.jsx("circle",{cx:"9",cy:"12",r:"1.25",fill:"currentColor"}),s.jsx("circle",{cx:"15",cy:"12",r:"1.25",fill:"currentColor"})]}):a==="antigravity"?s.jsxs("svg",{...u,children:[s.jsx("path",{d:"M5 17 17 5M9 5h8v8",stroke:"currentColor",strokeWidth:"2.2",strokeLinecap:"round",strokeLinejoin:"round"}),s.jsx("path",{d:"M5 8v9h9",stroke:"currentColor",strokeWidth:"1.4",strokeLinecap:"round",opacity:".7"})]}):a==="code"?s.jsx("svg",{...u,children:s.jsx("path",{d:"m9 5-4 7 4 7M15 5l4 7-4 7",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})}):c}function bs({agent:a,size:c=22,className:u=""}){const d=js(a),f=Vc[d]||{label:Nl(a),mark:String(d||"?").slice(0,1).toUpperCase(),color:"#ffffff",background:"#6b7280"};return s.jsx("span",{className:`inline-flex shrink-0 items-center justify-center rounded-[28%] font-black leading-none shadow-[inset_0_0_0_1px_rgba(255,255,255,0.18)] ${u}`,style:{width:c,height:c,color:f.color,background:f.background,fontSize:Math.max(9,Math.round(c*.48))},role:"img","aria-label":f.label,title:f.label,children:s.jsx(_p,{glyph:f.glyph,mark:f.mark})})}function Mp({open:a,previewUrl:c,accent:u,busy:d,nativeShareSupported:f,notice:v,onClose:m,onDownload:g,onNativeShare:p,onCopyCaption:y,t:C}){return M.useEffect(()=>{if(!a)return;const E=G=>{G.key==="Escape"&&m()};window.addEventListener("keydown",E);const w=document.body.style.overflow;return document.body.style.overflow="hidden",()=>{window.removeEventListener("keydown",E),document.body.style.overflow=w}},[a,m]),!a||typeof document>"u"?null:Wc.createPortal(s.jsx("div",{className:"fixed inset-0 z-[80] flex items-end justify-center bg-black/50 backdrop-blur-[3px] sm:items-center sm:p-5",onClick:E=>{E.target===E.currentTarget&&m()},role:"presentation",children:s.jsxs("div",{role:"dialog","aria-modal":"true","aria-label":C("profile.posterTitle"),className:"flex max-h-[96vh] w-full max-w-[820px] flex-col overflow-hidden rounded-t-[26px] bg-[#fffcf7] text-[#1a1a1a] shadow-[0_-16px_50px_rgba(20,14,8,0.2)] dark:bg-[#171717] dark:text-[#fafafa] sm:max-h-[92vh] sm:rounded-[26px] sm:shadow-[0_30px_80px_rgba(20,14,8,0.28)]",children:[s.jsxs("div",{className:"flex items-center justify-between border-b border-black/[0.06] px-5 py-3.5 dark:border-white/[0.08]",children:[s.jsx("div",{className:"text-[10px] font-extrabold uppercase tracking-[0.18em]",style:{color:u},children:C("profile.posterKicker")}),s.jsx("button",{type:"button",onClick:m,className:"motion-button inline-flex h-10 w-10 items-center justify-center rounded-xl text-[#6b6560] hover:bg-black/[0.05] hover:text-[#1a1a1a] dark:text-[#a3a3a3] dark:hover:bg-white/[0.06] dark:hover:text-white","aria-label":C("profile.posterClose"),children:s.jsx(Bc,{size:18})})]}),s.jsxs("div",{className:"grid min-h-0 flex-1 overflow-auto md:grid-cols-[minmax(280px,0.9fr)_minmax(320px,1.1fr)]",children:[s.jsx("div",{className:"flex items-center justify-center bg-[#ece8df] px-5 py-5 dark:bg-[#101010] sm:px-8 sm:py-7",children:s.jsx("div",{className:"aspect-[3/4] w-full max-w-[250px] overflow-hidden rounded-[16px] border border-black/[0.08] bg-[#f3f1ec] shadow-[0_20px_45px_rgba(40,28,12,0.18)] dark:border-white/[0.1] dark:bg-[#202020] sm:max-w-[320px]",children:c?s.jsx("img",{src:c,alt:C("profile.posterTitle"),className:"h-full w-full object-cover"}):s.jsxs("div",{className:"flex h-full flex-col items-center justify-center gap-3 text-sm font-semibold text-[#8b8680]",children:[s.jsx("span",{className:"h-8 w-8 animate-spin rounded-full border-2 border-current border-t-transparent"}),d?C("profile.posterBusy"):"…"]})})}),s.jsxs("div",{className:"flex min-h-0 flex-col px-5 py-6 sm:px-8 sm:py-8",children:[s.jsxs("div",{children:[s.jsx("h2",{className:"m-0 max-w-sm text-[30px] font-extrabold leading-[1.02] tracking-tight sm:text-[36px]",children:C("profile.posterTitle")}),s.jsx("p",{className:"mb-0 mt-3 max-w-sm text-[13px] leading-relaxed text-[#6b6560] dark:text-[#b0b0b0]",children:C("profile.posterHint")}),s.jsx("div",{className:"mt-4 inline-flex items-center rounded-full border border-black/[0.07] px-3 py-1.5 text-[10px] font-bold uppercase tracking-[0.12em] text-[#8b8680] dark:border-white/[0.09]",children:C("profile.posterFormat")})]}),s.jsxs("button",{type:"button",onClick:f?p:g,disabled:!c||d,className:"motion-button mt-7 inline-flex min-h-[54px] w-full items-center justify-center gap-2 rounded-2xl px-4 text-sm font-extrabold text-white shadow-[0_12px_26px_rgba(0,0,0,0.12)] disabled:opacity-50",style:{background:u},children:[f?s.jsx(xp,{size:18}):s.jsx(mc,{size:18}),C(f?"profile.posterNativeShare":"profile.posterDownload")]}),s.jsxs("div",{className:"mt-3 grid grid-cols-2 gap-2",children:[s.jsxs("button",{type:"button",onClick:y,disabled:!c||d,className:"motion-button inline-flex h-12 items-center justify-center gap-2 rounded-xl border border-black/[0.08] bg-white text-[13px] font-bold text-[#1a1a1a] disabled:opacity-50 dark:border-white/[0.08] dark:bg-[#242424] dark:text-white",children:[s.jsx(up,{size:16}),C("profile.posterCopyCaption")]}),s.jsxs("button",{type:"button",onClick:g,disabled:!c||d,className:"motion-button inline-flex h-12 items-center justify-center gap-2 rounded-xl border border-black/[0.08] bg-white text-[13px] font-bold text-[#1a1a1a] disabled:opacity-50 dark:border-white/[0.08] dark:bg-[#242424] dark:text-white",children:[s.jsx(mc,{size:16}),C("profile.posterDownload")]})]}),v&&s.jsxs("div",{className:"mt-4 flex items-start gap-2 rounded-xl bg-black/[0.035] px-3 py-2.5 text-[11px] font-semibold leading-relaxed text-[#6b6560] dark:bg-white/[0.05] dark:text-[#b0b0b0]",children:[s.jsx(Uc,{size:15,className:"mt-0.5 shrink-0",style:{color:u}}),s.jsx("span",{children:v})]}),s.jsx("p",{className:"mb-0 mt-auto pt-8 text-[10px] font-medium leading-relaxed text-[#8b8680] dark:text-[#8f8f8f]",children:C("profile.posterFootnote")})]})]})]})}),document.body)}var jl={exports:{}};/*!
|
|
160
|
+
*/const Bc=lt("X",[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]]);var Wc=Rc();function vl(a){const c=a.getUTCFullYear(),u=String(a.getUTCMonth()+1).padStart(2,"0"),d=String(a.getUTCDate()).padStart(2,"0");return`${c}-${u}-${d}`}function yl(a,c){return new Date(Date.UTC(a.getUTCFullYear(),a.getUTCMonth(),a.getUTCDate()+c))}function yp(a,c){return Math.floor((Date.UTC(c.getUTCFullYear(),c.getUTCMonth(),c.getUTCDate())-Date.UTC(a.getUTCFullYear(),a.getUTCMonth(),a.getUTCDate()))/864e5)}function ms(a,c){if(!Array.isArray(a)||a.length===0)return 0;const u=a.length,d=(u-1)*c,f=Math.floor(d),v=d-f,m=a[f]??a[u-1],g=a[Math.min(u-1,f+1)]??a[u-1];return Math.round(m+(g-m)*v)}function kp(a){return a<=0?0:a>=4?4:a}function Cs({prompts:a=[],dailyRows:c=null,weeks:u=52}){var ue;const d=new Date,f=new Date(Date.UTC(d.getFullYear(),d.getMonth(),d.getDate())),v=yl(f,-(u*7-1)),m=v.getUTCDay(),g=yl(v,-m),p=new Map;if(Array.isArray(c))for(const F of c){if(!(F!=null&&F.day))continue;const Q=Cl(F.billable_total_tokens??F.total_tokens??F.value),U=p.get(F.day)||{value:0,models:{},sources:{},conversation_count:0};U.value+=Q,U.total_tokens=(U.total_tokens||0)+Cl(F.total_tokens??Q),U.billable_total_tokens=(U.billable_total_tokens||0)+Q,U.conversation_count+=Cl(F.conversation_count),xc(U.models,F.models),xc(U.sources,F.sources),p.set(F.day,U)}else for(const F of a||[]){if(!F.timestamp)continue;const Q=String(F.timestamp).slice(0,10),U=p.get(Q)||{value:0,models:{}};U.value++;const I=F.source||"unknown";U.models[I]=(U.models[I]||0)+1,p.set(Q,U)}const y=yp(g,f)+1,C=Math.ceil(y/7),E=[];for(let F=0;F<y;F++){const Q=yl(g,F),U=vl(Q),I=((ue=p.get(U))==null?void 0:ue.value)||0;I>0&&E.push(I)}E.sort((F,Q)=>F-Q);const w=ms(E,.5),G=ms(E,.75),O=ms(E,.9);function T(F){return!F||F<=0?0:F<=w?1:F<=G?2:F<=O?3:4}const P=[];for(let F=0;F<C;F++){const Q=[];for(let U=0;U<7;U++){const I=F*7+U,he=yl(g,I);if(he.getTime()>f.getTime()){Q.push(null);continue}const Se=vl(he),ce=p.get(Se),Me=ce?ce.value:0;Q.push({day:Se,value:Me,total_tokens:ce==null?void 0:ce.total_tokens,billable_total_tokens:ce==null?void 0:ce.billable_total_tokens,conversation_count:ce==null?void 0:ce.conversation_count,level:kp(T(Me)),models:(ce==null?void 0:ce.models)||null,sources:(ce==null?void 0:ce.sources)||null})}P.push(Q)}const ie=P.length>u?P.slice(P.length-u):P;return{from:vl(g),to:vl(f),weeks:ie,thresholds:{t1:w,t2:G,t3:O}}}function xc(a,c){if(!(!c||typeof c!="object"))for(const[u,d]of Object.entries(c))a[u]=(a[u]||0)+Cl(d)}function Cl(a){const c=Number(a||0);return Number.isFinite(c)&&c>0?Math.floor(c):0}const lo={emerald:{light:["#ebedf0","#a7f3d0","#6ee7b7","#34d399","#10b981"],dark:["#2d333b","#065f46","#059669","#10b981","#34d399"],gridColor:{light:"rgba(16, 185, 129, 0.12)",dark:"rgba(52, 211, 153, 0.08)"}},ocean:{light:["#f1f5f9","#93c5fd","#60a5fa","#3b82f6","#1d4ed8"],dark:["#1e293b","#1e3a8a","#2563eb","#3b82f6","#60a5fa"],gridColor:{light:"rgba(59, 130, 246, 0.12)",dark:"rgba(96, 165, 250, 0.08)"}},neon:{light:["#faf5ff","#ebd5ff","#c084fc","#a855f7","#7e22ce"],dark:["#2e1065","#581c87","#8b5cf6","#a855f7","#c084fc"],gridColor:{light:"rgba(168, 85, 247, 0.12)",dark:"rgba(192, 132, 252, 0.08)"}},amber:{light:["#fffbeb","#fde68a","#f59e0b","#d97706","#b45309"],dark:["#451a03","#78350f","#b45309","#d97706","#f59e0b"],gridColor:{light:"rgba(245, 158, 11, 0.12)",dark:"rgba(245, 158, 11, 0.08)"}}};function wp(a,c){const u=/^#([0-9a-f]{6})$/i.exec(a);if(!u)return a;const d=parseInt(u[1],16),f=d>>16&255,v=d>>8&255,m=d&255,g=p=>Math.max(0,Math.min(255,Math.round(p*c)));return`rgb(${g(f)}, ${g(v)}, ${g(m)})`}function tn(a,c,u,d,f){const v=Math.cos(d),m=Math.sin(d),g=a*v-c*m,p=a*m+c*v,y=u,C=Math.cos(f),E=Math.sin(f);return{x:g,y:p*C-y*E,z:p*E+y*C}}function Sp(a,c,u,d,f){return tn(a,c,u,d,f)}function Cp(a,c){const u=Number(c).toLocaleString();return a>=4?`${u} prompts — an epic day of coding!`:a===3?`${u} prompts — you were in the zone.`:a===2?`${u} prompts — a solid session.`:a===1?`${u} prompts — dipping your toes in.`:"No activity this day."}function vc({prompts:a=[],dailyRows:c=null,weeks:u=26,palette:d="emerald",isDark:f=!0,interactive:v=!0,autoRotateInit:m=!0,onResetViewRef:g=null,unitLabel:p="Prompts"}){const C=M.useMemo(()=>Cs({prompts:a,dailyRows:c,weeks:u}),[a,c,u]).weeks,E=lo[d]||lo.emerald,w=f?E.dark:E.light,G=f?E.gridColor.dark:E.gridColor.light,O=-.2,T=.88,[P,ie]=M.useState({yaw:O,pitch:T}),[ue,F]=M.useState(m),[Q,U]=M.useState(1),I=v?13:10.5;M.useEffect(()=>{g&&(g.current={reset:()=>{ie({yaw:O,pitch:T}),F(!1),U(1),K()},toggleAutoRotate:D=>{F(D)}})},[g]);const he=M.useMemo(()=>{const D=[],V=C.length;if(V===0||!v)return[];for(let ae=0;ae<=7;ae++){const Y=(ae-3.5)*I,de=tn(-V/2*I,Y,0,P.yaw,P.pitch),ve=tn(V/2*I,Y,0,P.yaw,P.pitch);D.push({d:`M${de.x},${de.y} L${ve.x},${ve.y}`,key:`h-${ae}`})}for(let ae=0;ae<=V;ae+=4){const Y=(ae-V/2)*I,de=tn(Y,-3.5*I,0,P.yaw,P.pitch),ve=tn(Y,3.5*I,0,P.yaw,P.pitch);D.push({d:`M${de.x},${de.y} L${ve.x},${ve.y}`,key:`v-${ae}`})}if(V%4!==0){const ae=(V-V/2)*I,Y=tn(ae,-3.5*I,0,P.yaw,P.pitch),de=tn(ae,3.5*I,0,P.yaw,P.pitch);D.push({d:`M${Y.x},${Y.y} L${de.x},${de.y}`,key:"v-last"})}return D},[C.length,P,I,v]),Se=M.useRef(null),ce=M.useRef(null),Me=M.useRef(!1),Fe=M.useRef({x:0,y:0}),ee=M.useRef({yaw:O,pitch:T}),je=M.useRef({x:0,y:0}),te=M.useRef({x:0,y:0,time:0}),ye=M.useRef(null),[Pe,Ne]=M.useState(v?0:1),H=M.useRef(null),oe=M.useRef(!0);M.useEffect(()=>(oe.current=!0,()=>{oe.current=!1}),[]);const K=()=>{H.current&&cancelAnimationFrame(H.current),Ne(0);const D=performance.now(),V=ae=>{if(!oe.current)return;const Y=Math.min(1,(ae-D)/1200);Ne(1-Math.pow(1-Y,3)),Y<1&&(H.current=requestAnimationFrame(V))};H.current=requestAnimationFrame(V)};M.useEffect(()=>(K(),()=>{H.current&&cancelAnimationFrame(H.current)}),[v]),M.useEffect(()=>{var ae;if(!ue||Me.current||typeof window<"u"&&((ae=window.matchMedia)!=null&&ae.call(window,"(prefers-reduced-motion: reduce)").matches))return;let D;const V=()=>{if(typeof document<"u"&&document.visibilityState==="hidden"){D=requestAnimationFrame(V);return}ie(Y=>({yaw:Y.yaw+.002,pitch:Y.pitch})),D=requestAnimationFrame(V)};return D=requestAnimationFrame(V),()=>cancelAnimationFrame(D)},[ue]);const S=(D,V)=>{v&&(Me.current=!0,Fe.current={x:D,y:V},ee.current={yaw:P.yaw,pitch:P.pitch},je.current={x:0,y:0},te.current={x:D,y:V,time:performance.now()},ye.current&&cancelAnimationFrame(ye.current))},_=(D,V)=>{if(!Me.current)return;const ae=D-Fe.current.x,Y=V-Fe.current.y,de=performance.now(),ve=de-te.current.time;ve>0&&(je.current={x:(D-te.current.x)/ve,y:(V-te.current.y)/ve}),te.current={x:D,y:V,time:de};const De=.005,Ke=ee.current.yaw-ae*De,He=Math.PI/2.3,qe=Math.max(-He,Math.min(He,ee.current.pitch-Y*De));ie({yaw:Ke,pitch:qe})},z=()=>{if(!Me.current)return;Me.current=!1;let D=-je.current.x*12,V=-je.current.y*12;const ae=()=>{Me.current||(D*=.95,V*=.95,!(Math.abs(D)<.01&&Math.abs(V)<.01)&&(ie(Y=>{const de=Math.PI/2.3;return{yaw:Y.yaw+D*.005,pitch:Math.max(-de,Math.min(de,Y.pitch+V*.005))}}),ye.current=requestAnimationFrame(ae)))};ye.current=requestAnimationFrame(ae)},[W,me]=M.useState(null),[X,Ce]=M.useState({x:0,y:0,shiftX:0}),fe=M.useRef(null);M.useEffect(()=>()=>{fe.current&&clearTimeout(fe.current)},[]),M.useEffect(()=>{if(!v||!ce.current)return;const D=V=>{V.preventDefault(),U(ae=>Math.max(.5,Math.min(3,ae-V.deltaY*.0025)))};return ce.current.addEventListener("wheel",D,{passive:!1}),()=>{var V;return(V=ce.current)==null?void 0:V.removeEventListener("wheel",D)}},[v]);const Ee=M.useMemo(()=>{const D=[];return C.forEach((V,ae)=>{(Array.isArray(V)?V:[]).forEach((Y,de)=>{Y&&D.push({key:Y.day||`${ae}-${de}`,col:ae,row:de,level:Y.level||0,value:Y.value||0,day:Y.day,models:Y.models||null})})}),D},[C]),nn=I-(v?1.8:1.5),_e=v?38:28,A=D=>Math.max(1.8,Number(D)/4*_e),Z=M.useMemo(()=>{if(Ee.length===0)return[];const D=C.length;return Ee.map(V=>{const ae=A(V.level),Y=Math.sqrt(Math.pow(V.col-D/2,2)+Math.pow(V.row-3.5,2)),de=Math.sqrt(Math.pow(D/2,2)+Math.pow(3.5,2)),ve=Y/de*.4,De=Math.min(1,Math.max(0,(Pe-ve)*(1/.6))),Ke=ae*De,He=(V.col-D/2)*I,qe=(V.row-3.5)*I,We=nn/2,rt=[{x:He-We,y:qe-We,z:0},{x:He+We,y:qe-We,z:0},{x:He+We,y:qe+We,z:0},{x:He-We,y:qe+We,z:0},{x:He-We,y:qe-We,z:Ke},{x:He+We,y:qe-We,z:Ke},{x:He+We,y:qe+We,z:Ke},{x:He-We,y:qe+We,z:Ke}].map(mt=>tn(mt.x,mt.y,mt.z,P.yaw,P.pitch)),At=tn(He,qe,Ke/2,P.yaw,P.pitch),Lt=[{name:"top",indices:[4,5,6,7],scale:1,normal:[0,0,1]},{name:"bottom",indices:[3,2,1,0],scale:.4,normal:[0,0,-1]},{name:"left",indices:[3,0,4,7],scale:.55,normal:[-1,0,0]},{name:"right",indices:[1,2,6,5],scale:.75,normal:[1,0,0]},{name:"front",indices:[0,1,5,4],scale:.85,normal:[0,-1,0]},{name:"back",indices:[2,3,7,6],scale:.65,normal:[0,1,0]}],yt=w[Math.min(4,Math.max(0,Number(V.level)||0))],Qt=[],Rt=.35,ao=-.4,so=.83;return Lt.forEach(mt=>{const An=Sp(mt.normal[0],mt.normal[1],mt.normal[2],P.yaw,P.pitch);if(An.z>.001){const kr=rt[mt.indices[0]],Zn=rt[mt.indices[1]],wr=rt[mt.indices[2]],fn=rt[mt.indices[3]],Sr=`M${kr.x},${kr.y} L${Zn.x},${Zn.y} L${wr.x},${wr.y} L${fn.x},${fn.y} Z`,Ln=An.x*Rt+An.y*ao+An.z*so,El=f?.18:0,Rn=mt.scale*(.82+.28*Math.max(0,Ln))+El;Qt.push({name:mt.name,d:Sr,fill:wp(yt,Rn)})}}),{...V,centerProj:At,renderedFaces:Qt}})},[Ee,P,w,C.length,Pe,I,nn,_e,f]),J=M.useMemo(()=>[...Z].sort((D,V)=>D.centerProj.z-V.centerProj.z),[Z]),ke=M.useMemo(()=>{if(J.length===0)return{minX:-100,minY:-100,maxX:100,maxY:100};let D=1/0,V=1/0,ae=-1/0,Y=-1/0;return J.forEach(de=>{const ve=I*2;de.centerProj.x-ve<D&&(D=de.centerProj.x-ve),de.centerProj.x+ve>ae&&(ae=de.centerProj.x+ve),de.centerProj.y-ve<V&&(V=de.centerProj.y-ve),de.centerProj.y+ve>Y&&(Y=de.centerProj.y+ve)}),{minX:D,minY:V,maxX:ae,maxY:Y}},[J,I]),pe=12,Te=ke.maxX-ke.minX+pe*2,Ae=ke.maxY-ke.minY+pe*2,Le=Te/Q,be=Ae/Q,Ye=ke.minX-pe+(Te-Le)/2,Re=ke.minY-pe+(Ae-be)/2,Ue=`${Ye} ${Re} ${Le} ${be}`;return Ee.length===0?s.jsx("div",{className:"py-8 text-center text-sm text-oai-gray-500",children:"No activity data yet."}):s.jsxs("div",{ref:ce,className:`relative select-none outline-none ${v?"cursor-grab active:cursor-grabbing w-full h-full flex items-center justify-center":"w-full h-full min-h-[220px] overflow-hidden flex items-center justify-center"}`,onMouseDown:D=>{if(!v)return;S(D.clientX,D.clientY);const V=Y=>_(Y.clientX,Y.clientY),ae=()=>{z(),window.removeEventListener("mousemove",V),window.removeEventListener("mouseup",ae)};window.addEventListener("mousemove",V),window.addEventListener("mouseup",ae)},onTouchStart:D=>{v&&D.touches.length&&S(D.touches[0].clientX,D.touches[0].clientY)},onTouchMove:D=>{v&&D.touches.length&&_(D.touches[0].clientX,D.touches[0].clientY)},onTouchEnd:()=>{v&&z()},children:[s.jsxs("svg",{ref:Se,viewBox:Ue,width:"100%",height:"100%",preserveAspectRatio:"xMidYMid meet",role:"img","aria-label":"Interactive activity heatmap",style:{display:"block",width:"100%",height:"100%",maxHeight:v?"78vh":"100%"},className:"transition-transform duration-300 ease-out",children:[v&&he.map(D=>s.jsx("path",{d:D.d,fill:"none",stroke:G,strokeWidth:.25,strokeDasharray:"1.5 2.5",strokeLinecap:"round"},D.key)),J.map(D=>{const V=W&&W.key===D.key;return s.jsxs("g",{onMouseEnter:ae=>{var Y;if(fe.current&&(clearTimeout(fe.current),fe.current=null),me(D),v&&Se.current){const de=tn((D.col-C.length/2)*I,(D.row-3.5)*I,A(D.level),P.yaw,P.pitch);let ve=0,De=0;const Ke=Se.current;if(ce.current&&typeof Ke.createSVGPoint=="function"&&typeof Ke.getScreenCTM=="function")try{const pt=Ke.createSVGPoint();pt.x=de.x,pt.y=de.y;const rt=Ke.getScreenCTM();if(rt){const At=pt.matrixTransform(rt),Lt=ce.current.getBoundingClientRect();ve=At.x-Lt.left,De=At.y-Lt.top}}catch{}const He=140,qe=((Y=ce.current)==null?void 0:Y.getBoundingClientRect().width)||Ke.getBoundingClientRect().width;let We=0;ve<He?We=He-ve:ve>qe-He&&(We=qe-He-ve),Ce({x:ve,y:De,shiftX:We})}},onMouseLeave:()=>{fe.current&&clearTimeout(fe.current),fe.current=setTimeout(()=>me(null),150)},className:"transition-all duration-200",style:{filter:V?"brightness(1.15) drop-shadow(0 4px 6px rgba(0,0,0,0.15))":"none",cursor:v?"pointer":"default"},children:[!v&&D.day&&s.jsx("title",{children:`${D.day}: ${Number(D.value).toLocaleString()} ${p.toLowerCase()}`}),D.renderedFaces.map((ae,Y)=>s.jsx("path",{d:ae.d,fill:ae.fill,stroke:ae.fill,strokeWidth:.25,strokeLinejoin:"round"},Y))]},D.key)})]}),v&&W&&s.jsxs("div",{onMouseEnter:()=>{fe.current&&(clearTimeout(fe.current),fe.current=null)},onMouseLeave:()=>{fe.current&&clearTimeout(fe.current),fe.current=setTimeout(()=>me(null),150)},className:"absolute z-[9999] w-0 h-0 transition-all duration-100 ease-out",style:{left:`${X.x}px`,top:`${X.y}px`},children:[s.jsxs("div",{className:"absolute left-0 bottom-[10px] backdrop-blur-md bg-white/90 dark:bg-oai-gray-900/90 border border-oai-gray-200/50 dark:border-oai-gray-800/50 shadow-xl rounded-xl p-3.5 max-w-[280px] min-w-[200px] flex flex-col gap-2 animate-in fade-in zoom-in-95 duration-100",style:{transform:`translateX(calc(-50% + ${X.shiftX}px))`},children:[s.jsxs("div",{className:"flex items-center justify-between border-b border-oai-gray-100 dark:border-oai-gray-800/80 pb-1.5",children:[s.jsx("span",{className:"text-[11px] font-semibold text-oai-gray-500 dark:text-oai-gray-400",children:W.day}),s.jsxs("span",{className:"text-[10px] px-2 py-0.5 rounded-full font-medium",style:{backgroundColor:(W.level===0?f?"#9ca3af":"#6b7280":w[W.level])+"22",color:W.level===0?f?"#9ca3af":"#6b7280":w[W.level],border:`1px solid ${W.level===0?f?"#9ca3af":"#6b7280":w[W.level]}44`},children:["Level ",W.level]})]}),s.jsxs("div",{className:"flex flex-col gap-2",children:[s.jsxs("div",{className:"flex items-baseline gap-1",children:[s.jsx("span",{className:"text-lg font-bold text-oai-gray-900 dark:text-white leading-none",children:Number(W.value).toLocaleString()}),s.jsx("span",{className:"text-[10px] text-oai-gray-400 uppercase tracking-wider font-semibold",children:p})]}),W.models&&Object.keys(W.models).length>0?s.jsxs("div",{className:"mt-1.5 border-t border-oai-gray-100 dark:border-oai-gray-800/60 pt-2 flex flex-col gap-1.5",children:[s.jsx("div",{className:"text-[10px] font-semibold text-oai-gray-400 dark:text-oai-gray-500 uppercase tracking-wider",children:"Source Breakdown"}),s.jsx("div",{className:"flex flex-col gap-2 max-h-[150px] overflow-y-auto pr-1.5",children:Object.entries(W.models).map(([D,V])=>({name:D,val:Number(V)||0})).sort((D,V)=>V.val-D.val).map(({name:D,val:V})=>{const ae=Number(W.value)||1,Y=Math.round(V/ae*100);return s.jsxs("div",{className:"flex flex-col gap-1",children:[s.jsxs("div",{className:"flex items-center justify-between text-[11px] gap-3",children:[s.jsx("span",{className:"font-medium text-oai-gray-700 dark:text-oai-gray-200 truncate max-w-[120px]",title:D,children:D}),s.jsxs("div",{className:"flex items-center gap-1.5 shrink-0",children:[s.jsx("span",{className:"font-mono text-oai-gray-900 dark:text-oai-gray-100 font-semibold",children:V.toLocaleString()}),s.jsxs("span",{className:"text-[9px] text-oai-gray-400 dark:text-oai-gray-500 min-w-[28px] text-right font-medium",children:[Y,"%"]})]})]}),s.jsx("div",{className:"w-full h-1 bg-oai-gray-100 dark:bg-oai-gray-800/85 rounded-full overflow-hidden",children:s.jsx("div",{className:"h-full rounded-full transition-all duration-300",style:{width:`${Y}%`,backgroundColor:w[4],boxShadow:`0 0 4px ${w[4]}55`}})})]},D)})})]}):s.jsx("p",{className:"text-[11px] text-oai-gray-600 dark:text-oai-gray-300 leading-relaxed font-normal mt-1 border-t border-dashed border-oai-gray-100 dark:border-oai-gray-800/60 pt-1.5",children:Cp(W.level,W.value)})]})]}),s.jsx("div",{className:"absolute bottom-[6px] left-0 -translate-x-1/2 w-2.5 h-2.5 rotate-45 bg-white dark:bg-oai-gray-900 border-r border-b border-oai-gray-200/50 dark:border-oai-gray-800/50 shadow-sm",style:{marginBottom:"1px"}})]})]})}const jp=["#ebedf0","#a7f3d0","#6ee7b7","#34d399","#10b981"],bp=["#121212","#065f46","#059669","#10b981","#34d399"],zn=11,ro=2,hs=26;function Np({prompts:a=[],dailyRows:c=null,weeks:u=26,dark:d=!1,compact:f=!1,dense:v=!1}){const{locale:m,t:g}=Xn(),p=M.useMemo(()=>Cs({prompts:a,dailyRows:c,weeks:u}),[a,c,u]),y=d?bp:jp,C=p.weeks||[],E=Math.max(C.length*(zn+ro)+hs,120),w=m==="zh"?["日","一","二","三","四","五","六"]:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],G=M.useMemo(()=>{const O=[];return C.forEach((T,P)=>{var F;const ie=(F=(T||[]).find(Q=>{var U;return(U=Q==null?void 0:Q.day)==null?void 0:U.endsWith("-01")}))==null?void 0:F.day;if(!ie)return;const ue=new Date(`${ie}T00:00:00Z`);O.push({index:P,text:new Intl.DateTimeFormat(m==="zh"?"zh-CN":"en-US",{month:"short",timeZone:"UTC"}).format(ue)})}),O},[C,m]);return s.jsxs("div",{className:"w-full",children:[s.jsx("div",{className:"activity-scroll overflow-x-auto overflow-y-hidden pb-1",children:s.jsxs("div",{style:{width:E},children:[s.jsx("div",{className:"relative mb-1 h-3 text-[10px] uppercase text-[#8b8680] dark:text-[#8f8f8f]",children:G.map(O=>s.jsx("span",{className:"absolute whitespace-nowrap",style:{left:hs+O.index*(zn+ro)},children:O.text},`${O.text}-${O.index}`))}),s.jsxs("div",{className:"flex",style:{gap:ro},children:[s.jsx("div",{className:"grid shrink-0 text-[10px] text-[#8b8680] dark:text-[#8f8f8f]",style:{width:hs,gridTemplateRows:`repeat(7, ${zn}px)`,rowGap:ro},children:w.map(O=>s.jsx("span",{className:"leading-none",children:O},O))}),s.jsx("div",{className:"grid",style:{gridAutoFlow:"column",gridTemplateRows:`repeat(7, ${zn}px)`,gap:ro},children:C.map((O,T)=>(O||[]).map((P,ie)=>P?s.jsx("span",{className:"activity-cell cursor-pointer rounded-[2px] transition-transform hover:z-10 hover:scale-125",style:{width:zn,height:zn,background:y[P.level]||y[0],"--motion-delay":`${Math.min(420,T*7+ie*5)}ms`},title:`${P.day}: ${Number(P.value||0).toLocaleString()}`},P.day||`${T}-${ie}`):s.jsx("span",{style:{width:zn,height:zn}},`${T}-${ie}`)))})]})]})}),s.jsxs("div",{className:"mt-3 flex items-center justify-center gap-2",children:[s.jsx("span",{className:"text-[10px] text-[#8b8680] dark:text-[#8f8f8f]",children:g("heatmap.less")}),s.jsx("span",{className:"flex gap-0.5",children:y.map((O,T)=>s.jsx("span",{className:"rounded-[1px]",style:{width:10,height:10,background:O},title:`Level ${T}`},O))}),s.jsx("span",{className:"text-[10px] text-[#8b8680] dark:text-[#8f8f8f]",children:g("heatmap.more")})]})]})}const yc={emerald:{rawColor:"#10b981"},ocean:{rawColor:"#3b82f6"},neon:{rawColor:"#a855f7"},amber:{rawColor:"#f59e0b"}};function kc(a){const c=Number(a)||0;return c<1e3?c.toLocaleString():c<1e6?`${(c/1e3).toFixed(c>=1e4?0:1)}K`:c<1e9?`${(c/1e6).toFixed(c>=1e7?0:2)}M`:`${(c/1e9).toFixed(c>=1e10?0:2)}B`}function Ep(a){const c=[];for(const p of a)for(const y of Array.isArray(p)?p:[])y!=null&&y.day&&c.push(y);c.sort((p,y)=>p.day.localeCompare(y.day));let u=0,d=0,f=0,v=0,m={day:"—",value:0};for(const p of c){const y=Number(p.value)||0;u+=y,y>0?(d+=1,v+=1,f=Math.max(f,v)):v=0,y>m.value&&(m={day:p.day,value:y})}const g=c.length?(d/c.length*100).toFixed(1):"0.0";return{totalValue:u,activeDays:d,activeRate:g,maxStreak:f,peakDay:m}}function Tp({prompts:a=[],activity:c=null,weeks:u=20,className:d="",forceLight:f=!1,defaultPalette:v="emerald",roastStyle:m=!1,showViewToggle:g=!1,defaultViewMode:p}){var me;const{theme:y}=Ic(),{t:C}=Xn(),E=f?!1:y==="dark"||y==="system"&&typeof window<"u"&&((me=window.matchMedia)==null?void 0:me.call(window,"(prefers-color-scheme: dark)").matches),w=Array.isArray(c==null?void 0:c.daily_rows)&&c.daily_rows.length>0,G=(c==null?void 0:c.metric)||"tokens",O=G==="tokens"?Array.isArray(c==null?void 0:c.daily_rows)?c.daily_rows:[]:w?c.daily_rows:null,T=G==="tokens"?Math.max(u,52):u,P=C(G==="tokens"?"heatmap.tokens":"heatmap.prompts"),ie=M.useMemo(()=>Cs({prompts:a,dailyRows:O,weeks:T}),[a,O,T]),ue=M.useMemo(()=>Ep(ie.weeks||[]),[ie.weeks]),[F,Q]=M.useState(!1),[U,I]=M.useState(!1),he=lo[v]?v:"emerald",[Se,ce]=M.useState(p??(g||m?"2d":"3d")),[Me,Fe]=M.useState(0),[ee,je]=M.useState("in"),te=M.useRef(null),ye=M.useRef(null),Pe=m||g,Ne=Pe?"min-h-[190px]":"min-h-[240px]",H=Pe?"max-h-[320px]":"",oe=yc[he]||yc.emerald,K=E?lo[he].dark:lo[he].light,S=M.useMemo(()=>{const X=-new Date().getTimezoneOffset(),Ce=X>=0?"+":"-",fe=String(Math.floor(Math.abs(X)/60)).padStart(2,"0"),Ee=String(Math.abs(X)%60).padStart(2,"0");return`UTC${Ce}${fe}:${Ee}`},[]),_=()=>I(!0),z=X=>{X!==Se&&(ye.current&&clearTimeout(ye.current),je("out"),ye.current=setTimeout(()=>{ce(X),Fe(Ce=>Ce+1),je("in")},160))};M.useEffect(()=>()=>{ye.current&&clearTimeout(ye.current)},[]),M.useEffect(()=>{if(!F||U)return;const X=Ce=>{Ce.key==="Escape"&&_()};return window.addEventListener("keydown",X),()=>window.removeEventListener("keydown",X)},[F,U]);const W=F&&typeof document<"u"?Wc.createPortal(s.jsx("div",{onAnimationEnd:X=>{X.target===X.currentTarget&&U&&(Q(!1),I(!1))},onClick:X=>{X.target===X.currentTarget&&_()},className:`fixed inset-0 z-50 flex items-center justify-center p-3 md:p-6 backdrop-blur-md bg-black/40 ${U?"animate-tt-fade-out":"animate-tt-fade-in"}`,children:s.jsxs("div",{className:`relative flex h-[88vh] w-full max-w-6xl flex-col overflow-hidden rounded-[22px] border border-black/[0.07] bg-[#fffcf7] shadow-[0_24px_70px_rgba(45,30,18,0.22)] dark:border-white/[0.08] dark:bg-[#171717] md:flex-row ${U?"animate-tt-modal-exit":"animate-tt-modal"}`,children:[s.jsxs("div",{className:"absolute right-4 top-4 z-50 flex items-center gap-1",children:[s.jsx("button",{type:"button",onClick:()=>{var X;return(X=te.current)==null?void 0:X.reset()},className:"inline-flex h-9 w-9 items-center justify-center rounded-full border border-black/[0.07] bg-[#fffcf7] text-[#8b8680] hover:text-[#1a1a1a] dark:border-white/[0.08] dark:bg-[#171717] dark:text-[#8f8f8f] dark:hover:text-white",title:C("heatmap.reset"),children:s.jsx(gp,{size:14})}),s.jsx("button",{type:"button",onClick:_,className:"inline-flex h-9 w-9 items-center justify-center rounded-full border border-black/[0.07] bg-[#fffcf7] text-[#8b8680] hover:text-[#1a1a1a] dark:border-white/[0.08] dark:bg-[#171717] dark:text-[#8f8f8f] dark:hover:text-white",title:C("heatmap.close"),children:s.jsx(Bc,{size:15})})]}),s.jsxs("aside",{className:"flex w-full flex-col gap-6 overflow-y-auto border-b border-black/[0.06] bg-[#f7f4ef] p-5 dark:border-white/[0.07] dark:bg-[#121212] md:w-[320px] md:border-b-0 md:border-r md:p-6",children:[s.jsxs("div",{children:[s.jsxs("div",{className:"flex items-center gap-1.5 select-none",children:[s.jsx("span",{className:"h-1.5 w-1.5 rounded-full",style:{backgroundColor:oe.rawColor}}),s.jsx("span",{className:"text-[10px] font-bold uppercase tracking-[0.16em] text-[#8b8680] dark:text-[#8f8f8f]",children:C("heatmap.insight")})]}),s.jsx("h4",{className:"mt-2 text-xl font-extrabold leading-none tracking-tight text-[#1a1a1a] dark:text-[#fafafa]",children:C(G==="tokens"?"heatmap.tokenTitle":"heatmap.promptTitle")}),s.jsx("p",{className:"mt-2 text-xs leading-5 text-[#716b65] dark:text-[#aaa49e]",children:C(G==="tokens"?"heatmap.tokenDesc":"heatmap.promptDesc")})]}),s.jsxs("div",{className:"grid grid-cols-2 gap-x-5 gap-y-5 border-y border-black/[0.07] py-5 dark:border-white/[0.08]",children:[s.jsx(kl,{label:C(G==="tokens"?"heatmap.totalTokens":"heatmap.totalPrompts"),value:kc(ue.totalValue),exact:`${ue.totalValue.toLocaleString()} ${P.toLowerCase()}`}),s.jsx(kl,{label:C(G==="tokens"?"heatmap.activeRateDays":"heatmap.activeDays"),value:`${ue.activeRate}%`,suffix:G==="tokens"?`(${ue.activeDays}D)`:void 0,exact:C("heatmap.activeDayCount",{count:ue.activeDays})}),s.jsx(kl,{label:C(G==="tokens"?"heatmap.longestStreak":"heatmap.maxStreak"),value:ue.maxStreak,suffix:C("heatmap.days")}),s.jsx(kl,{label:C("heatmap.peakDay"),value:ue.peakDay.value>0?kc(ue.peakDay.value):C("heatmap.noData"),suffix:ue.peakDay.day,exact:`${ue.peakDay.value.toLocaleString()} ${P.toLowerCase()}`})]}),s.jsx("div",{className:"mt-auto border-t border-black/[0.07] pt-4 dark:border-white/[0.08]",children:s.jsxs("div",{className:"flex flex-col gap-2",children:[s.jsx("span",{className:"text-[10px] font-bold uppercase tracking-[0.16em] text-[#8b8680] dark:text-[#8f8f8f]",children:C(G==="tokens"?"heatmap.activityLevels":"heatmap.legend")}),s.jsx("div",{className:"flex gap-1",children:K.map((X,Ce)=>s.jsx("div",{className:"flex-1 h-1 rounded-[2px]",style:{backgroundColor:X},title:`Level ${Ce}`},Ce))})]})})]}),s.jsxs("section",{className:"relative flex h-full flex-1 items-center justify-center overflow-hidden p-4",children:[s.jsx("div",{className:"absolute inset-0 pointer-events-none transition-colors duration-500",style:{background:`linear-gradient(135deg, ${oe.rawColor}0f, transparent 42%)`}}),s.jsx(vc,{prompts:a,dailyRows:O,weeks:T,isDark:E,interactive:!0,palette:he,autoRotateInit:!1,onResetViewRef:te,unitLabel:P}),s.jsxs("div",{className:"absolute bottom-4 right-4 flex items-center gap-1.5 text-[9px] font-bold text-oai-gray-400 bg-white/80 dark:bg-oai-gray-900/80 border border-oai-gray-200/50 dark:border-oai-gray-800/80 rounded-md px-2.5 py-1.5 select-none pointer-events-none backdrop-blur-md shadow-sm",children:[s.jsx(cp,{size:10,style:{color:oe.rawColor}}),s.jsx("span",{children:C("heatmap.footerTip")})]})]})]})}),document.body):null;return s.jsxs(s.Fragment,{children:[s.jsxs("div",{className:`relative w-full h-full ${Ne} ${H} ${d}`,children:[s.jsxs("div",{className:"mb-4 flex min-h-7 items-center justify-between gap-3",children:[s.jsx("h2",{className:"m-0 text-sm font-semibold uppercase tracking-[0.03em] text-[#393633] dark:text-[#d4d4d4]",children:C("profile.activity")}),s.jsxs("div",{className:"flex items-center gap-2",children:[g&&s.jsx("div",{role:"tablist","aria-label":C("heatmap.viewLabel"),className:"flex items-center rounded-lg border border-black/[0.07] bg-black/[0.02] p-0.5 text-[10px] font-medium text-[#8b8680] dark:border-white/[0.08] dark:bg-white/[0.02] dark:text-[#8f8f8f]",children:["2d","3d"].map(X=>s.jsx("button",{type:"button",role:"tab","aria-selected":Se===X,onClick:()=>z(X),className:`rounded-md px-2 py-0.5 uppercase transition-colors ${Se===X?"bg-white text-[#1a1a1a] shadow-sm dark:bg-[#2a2a2a] dark:text-white":"hover:text-[#1a1a1a] dark:hover:text-white"}`,children:C(X==="2d"?"heatmap.viewGrid":"heatmap.viewTerrain")},X))}),s.jsx("span",{className:"text-xs text-[#8b8680] dark:text-[#8f8f8f]",children:S})]})]}),s.jsx("div",{className:`h-full w-full ${Ne} ${H} ${ee==="out"?"heatmap-view-exit":"heatmap-view-enter"}`,children:Se==="2d"?s.jsx("div",{className:"flex w-full items-center justify-center overflow-hidden",children:s.jsx(Np,{prompts:a,dailyRows:O,weeks:T,dark:E,compact:!1,dense:!1})}):s.jsxs("button",{type:"button",onClick:()=>{I(!1),Q(!0)},className:`group relative w-full h-[170px] overflow-hidden rounded-lg border transition-all cursor-pointer ${m?"border-black/[0.04] bg-[#f7f4ef] hover:border-emerald-500/30 dark:border-white/[0.06] dark:bg-[#121212]":"border-transparent hover:border-oai-gray-700"}`,title:C("heatmap.openTitle"),children:[s.jsx(vc,{prompts:a,dailyRows:O,weeks:T,interactive:!1,autoRotateInit:!1,isDark:E,palette:he,unitLabel:P}),s.jsx("div",{className:`absolute inset-0 pointer-events-none opacity-0 group-hover:opacity-100 transition-opacity flex items-end justify-center pb-2 ${m?"bg-gradient-to-t from-[#f3f1ec]/70 to-transparent":"bg-gradient-to-t from-oai-gray-950/20 to-transparent"}`,children:s.jsxs("span",{className:`text-[10px] shadow px-2.5 py-1 rounded-full font-medium flex items-center gap-1 transform translate-y-2 group-hover:translate-y-0 transition-transform duration-200 ${m?"bg-[#fffcf7]/95 border border-black/5 text-[#6b6560]":"bg-white/95 dark:bg-oai-gray-900/95 border border-oai-gray-200/60 dark:border-oai-gray-800/80 text-oai-gray-500 dark:text-oai-gray-400"}`,children:[s.jsx(pp,{size:9}),C("heatmap.open")]})})]})},`${Se}-${Me}`)]}),W]})}function kl({label:a,value:c,suffix:u,exact:d}){return s.jsxs("div",{className:"flex flex-col gap-1 relative group cursor-default",children:[d&&s.jsx("div",{className:"absolute left-0 bottom-full mb-2 pointer-events-none opacity-0 translate-y-1 group-hover:opacity-100 group-hover:translate-y-0 transition-all duration-200 z-50",children:s.jsx("div",{className:"bg-white dark:bg-zinc-950 text-zinc-900 dark:text-zinc-50 text-[10px] font-semibold font-mono rounded-lg px-2.5 py-1.5 shadow-xl border border-zinc-200 dark:border-zinc-800/80 whitespace-nowrap",children:d})}),s.jsx("span",{className:"text-[10px] font-bold uppercase tracking-[0.12em] text-[#8b8680] dark:text-[#8f8f8f]",children:a}),s.jsxs("div",{className:"flex items-baseline gap-1.5",children:[s.jsx("span",{className:"font-[JetBrains_Mono,ui-monospace,monospace] text-xl font-bold tracking-tight text-[#1a1a1a] transition-transform duration-200 group-hover:-translate-y-[1px] dark:text-[#fafafa]",children:c}),u&&s.jsx("span",{className:"text-[10px] font-bold text-[#8b8680] dark:text-[#8f8f8f]",children:u})]})]})}const Vc={cursor:{label:"Cursor",glyph:"cursor",color:"#ffffff",background:"#171717"},codex:{label:"Codex",glyph:"codex",color:"#ffffff",background:"#111827"},claude:{label:"Claude Code",glyph:"claude",color:"#fff8f0",background:"#d97757"},gemini:{label:"Gemini CLI",glyph:"gemini",color:"#ffffff",background:"#4285f4"},copilot:{label:"GitHub Copilot",glyph:"copilot",color:"#ffffff",background:"#24292f"},antigravity:{label:"Antigravity",glyph:"antigravity",color:"#ffffff",background:"#1769ff"},cline:{label:"Cline",mark:"C",color:"#ffffff",background:"#2563eb"},roo:{label:"Roo Code",mark:"R",color:"#ffffff",background:"#ea580c"},continue:{label:"Continue",mark:"▶",color:"#ffffff",background:"#7c3aed"},aider:{label:"Aider",mark:"A",color:"#ffffff",background:"#15803d"},windsurf:{label:"Windsurf",mark:"≋",color:"#062a2e",background:"#5eead4"},amazonq:{label:"Amazon Q",mark:"Q",color:"#ffffff",background:"#ff9900"},opencode:{label:"OpenCode",glyph:"code",color:"#ffffff",background:"#334155"}};function js(a){const c=String(a||"").trim().toLowerCase().replace(/[\s_]+/g,"-");return{"claude-code":"claude","github-copilot":"copilot","amazon-q":"amazonq","gemini-cli":"gemini","roo-code":"roo"}[c]||c}function Nl(a){var u;const c=js(a);return((u=Vc[c])==null?void 0:u.label)||String(a||"Agent")}function _p({glyph:a,mark:c}){if(!a)return c;const u={width:"72%",height:"72%",viewBox:"0 0 24 24",fill:"none","aria-hidden":!0};return a==="cursor"?s.jsx("svg",{...u,children:s.jsx("path",{d:"M5.5 3.5 19 12l-6.1 1.35 3.25 5.7-2.6 1.45-3.2-5.7L6 19Z",fill:"currentColor"})}):a==="codex"?s.jsxs("svg",{...u,children:[s.jsx("path",{d:"M12 3.2 16 5.5l4 6.5-4 6.5-4 2.3-4-2.3L4 12l4-6.5Z",stroke:"currentColor",strokeWidth:"1.75"}),s.jsx("circle",{cx:"12",cy:"12",r:"3.25",stroke:"currentColor",strokeWidth:"1.75"})]}):a==="claude"?s.jsx("svg",{...u,children:s.jsx("path",{d:"M12 3v18M3 12h18M5.6 5.6l12.8 12.8M18.4 5.6 5.6 18.4M7.2 3.9l9.6 16.2M20.1 7.2 3.9 16.8",stroke:"currentColor",strokeWidth:"1.6",strokeLinecap:"round"})}):a==="gemini"?s.jsx("svg",{...u,children:s.jsx("path",{d:"M12 2.8c.5 5.55 3.65 8.7 9.2 9.2-5.55.5-8.7 3.65-9.2 9.2-.5-5.55-3.65-8.7-9.2-9.2 5.55-.5 8.7-3.65 9.2-9.2Z",fill:"currentColor"})}):a==="copilot"?s.jsxs("svg",{...u,children:[s.jsx("path",{d:"M5 10.5 7.2 6h9.6l2.2 4.5v6L16 19H8l-3-2.5Z",stroke:"currentColor",strokeWidth:"1.6",strokeLinejoin:"round"}),s.jsx("circle",{cx:"9",cy:"12",r:"1.25",fill:"currentColor"}),s.jsx("circle",{cx:"15",cy:"12",r:"1.25",fill:"currentColor"})]}):a==="antigravity"?s.jsxs("svg",{...u,children:[s.jsx("path",{d:"M5 17 17 5M9 5h8v8",stroke:"currentColor",strokeWidth:"2.2",strokeLinecap:"round",strokeLinejoin:"round"}),s.jsx("path",{d:"M5 8v9h9",stroke:"currentColor",strokeWidth:"1.4",strokeLinecap:"round",opacity:".7"})]}):a==="code"?s.jsx("svg",{...u,children:s.jsx("path",{d:"m9 5-4 7 4 7M15 5l4 7-4 7",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})}):c}function bs({agent:a,size:c=22,className:u=""}){const d=js(a),f=Vc[d]||{label:Nl(a),mark:String(d||"?").slice(0,1).toUpperCase(),color:"#ffffff",background:"#6b7280"};return s.jsx("span",{className:`inline-flex shrink-0 items-center justify-center rounded-[28%] font-black leading-none shadow-[inset_0_0_0_1px_rgba(255,255,255,0.18)] ${u}`,style:{width:c,height:c,color:f.color,background:f.background,fontSize:Math.max(9,Math.round(c*.48))},role:"img","aria-label":f.label,title:f.label,children:s.jsx(_p,{glyph:f.glyph,mark:f.mark})})}function Mp({open:a,previewUrl:c,accent:u,busy:d,nativeShareSupported:f,notice:v,onClose:m,onDownload:g,onNativeShare:p,onCopyCaption:y,t:C}){return M.useEffect(()=>{if(!a)return;const E=G=>{G.key==="Escape"&&m()};window.addEventListener("keydown",E);const w=document.body.style.overflow;return document.body.style.overflow="hidden",()=>{window.removeEventListener("keydown",E),document.body.style.overflow=w}},[a,m]),!a||typeof document>"u"?null:Wc.createPortal(s.jsx("div",{className:"fixed inset-0 z-[80] flex items-end justify-center bg-black/50 backdrop-blur-[3px] sm:items-center sm:p-5",onClick:E=>{E.target===E.currentTarget&&m()},role:"presentation",children:s.jsxs("div",{role:"dialog","aria-modal":"true","aria-label":C("profile.posterTitle"),className:"flex max-h-[96vh] w-full max-w-[820px] flex-col overflow-hidden rounded-t-[26px] bg-[#fffcf7] text-[#1a1a1a] shadow-[0_-16px_50px_rgba(20,14,8,0.2)] dark:bg-[#171717] dark:text-[#fafafa] sm:max-h-[92vh] sm:rounded-[26px] sm:shadow-[0_30px_80px_rgba(20,14,8,0.28)]",children:[s.jsxs("div",{className:"flex items-center justify-between border-b border-black/[0.06] px-5 py-3.5 dark:border-white/[0.08]",children:[s.jsx("div",{className:"text-[10px] font-extrabold uppercase tracking-[0.18em]",style:{color:u},children:C("profile.posterKicker")}),s.jsx("button",{type:"button",onClick:m,className:"motion-button inline-flex h-10 w-10 items-center justify-center rounded-xl text-[#6b6560] hover:bg-black/[0.05] hover:text-[#1a1a1a] dark:text-[#a3a3a3] dark:hover:bg-white/[0.06] dark:hover:text-white","aria-label":C("profile.posterClose"),children:s.jsx(Bc,{size:18})})]}),s.jsxs("div",{className:"grid min-h-0 flex-1 overflow-auto md:grid-cols-[minmax(280px,0.9fr)_minmax(320px,1.1fr)]",children:[s.jsx("div",{className:"flex items-center justify-center bg-[#ece8df] px-5 py-5 dark:bg-[#101010] sm:px-8 sm:py-7",children:s.jsx("div",{className:"aspect-[3/4] w-full max-w-[250px] overflow-hidden rounded-[16px] border border-black/[0.08] bg-[#f3f1ec] shadow-[0_20px_45px_rgba(40,28,12,0.18)] dark:border-white/[0.1] dark:bg-[#202020] sm:max-w-[320px]",children:c?s.jsx("img",{src:c,alt:C("profile.posterTitle"),className:"h-full w-full object-cover"}):s.jsxs("div",{className:"flex h-full flex-col items-center justify-center gap-3 text-sm font-semibold text-[#8b8680]",children:[s.jsx("span",{className:"h-8 w-8 animate-spin rounded-full border-2 border-current border-t-transparent"}),d?C("profile.posterBusy"):"…"]})})}),s.jsxs("div",{className:"flex min-h-0 flex-col px-5 py-6 sm:px-8 sm:py-8",children:[s.jsxs("div",{children:[s.jsx("h2",{className:"m-0 max-w-sm text-[30px] font-extrabold leading-[1.02] tracking-tight sm:text-[36px]",children:C("profile.posterTitle")}),s.jsx("p",{className:"mb-0 mt-3 max-w-sm text-[13px] leading-relaxed text-[#6b6560] dark:text-[#b0b0b0]",children:C("profile.posterHint")}),s.jsx("div",{className:"mt-4 inline-flex items-center rounded-full border border-black/[0.07] px-3 py-1.5 text-[10px] font-bold uppercase tracking-[0.12em] text-[#8b8680] dark:border-white/[0.09]",children:C("profile.posterFormat")})]}),s.jsxs("button",{type:"button",onClick:f?p:g,disabled:!c||d,className:"motion-button mt-7 inline-flex min-h-[54px] w-full items-center justify-center gap-2 rounded-2xl px-4 text-sm font-extrabold text-white shadow-[0_12px_26px_rgba(0,0,0,0.12)] disabled:opacity-50",style:{background:u},children:[f?s.jsx(xp,{size:18}):s.jsx(mc,{size:18}),C(f?"profile.posterNativeShare":"profile.posterDownload")]}),s.jsxs("div",{className:"mt-3 grid grid-cols-2 gap-2",children:[s.jsxs("button",{type:"button",onClick:y,disabled:!c||d,className:"motion-button inline-flex h-12 items-center justify-center gap-2 rounded-xl border border-black/[0.08] bg-white text-[13px] font-bold text-[#1a1a1a] disabled:opacity-50 dark:border-white/[0.08] dark:bg-[#242424] dark:text-white",children:[s.jsx(up,{size:16}),C("profile.posterCopyCaption")]}),s.jsxs("button",{type:"button",onClick:g,disabled:!c||d,className:"motion-button inline-flex h-12 items-center justify-center gap-2 rounded-xl border border-black/[0.08] bg-white text-[13px] font-bold text-[#1a1a1a] disabled:opacity-50 dark:border-white/[0.08] dark:bg-[#242424] dark:text-white",children:[s.jsx(mc,{size:16}),C("profile.posterDownload")]})]}),v&&s.jsxs("div",{className:"mt-4 flex items-start gap-2 rounded-xl bg-black/[0.035] px-3 py-2.5 text-[11px] font-semibold leading-relaxed text-[#6b6560] dark:bg-white/[0.05] dark:text-[#b0b0b0]",children:[s.jsx(Uc,{size:15,className:"mt-0.5 shrink-0",style:{color:u}}),s.jsx("span",{children:v})]}),s.jsx("p",{className:"mb-0 mt-auto pt-8 text-[10px] font-medium leading-relaxed text-[#8b8680] dark:text-[#8f8f8f]",children:C("profile.posterFootnote")})]})]})]})}),document.body)}var jl={exports:{}};/*!
|
|
161
161
|
* wordcloud2.js
|
|
162
162
|
* http://timdream.org/wordcloud2.js/
|
|
163
163
|
*
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
html { background: #f3f1ec; }
|
|
24
24
|
html.dark { background: #0a0a0a; }
|
|
25
25
|
</style>
|
|
26
|
-
<script type="module" crossorigin src="/assets/index-
|
|
26
|
+
<script type="module" crossorigin src="/assets/index-BU-4n-Cw.js"></script>
|
|
27
27
|
<link rel="stylesheet" crossorigin href="/assets/index-DlBycTcO.css">
|
|
28
28
|
</head>
|
|
29
29
|
<body>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vibe-roast",
|
|
3
|
-
"version": "0.98.
|
|
3
|
+
"version": "0.98.4",
|
|
4
4
|
"description": "Local-first AI coding personality profiler, usage dashboard, and evidence-grounded roast.",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"bin": {
|
|
@@ -32,7 +32,10 @@
|
|
|
32
32
|
"worker/wrangler.jsonc",
|
|
33
33
|
"worker/src/",
|
|
34
34
|
"dashboard/dist/",
|
|
35
|
-
"assests/",
|
|
35
|
+
"assests/characters/",
|
|
36
|
+
"assests/characters-vibe-types/",
|
|
37
|
+
"assests/readme/",
|
|
38
|
+
"assests/screenshots/",
|
|
36
39
|
"README.md"
|
|
37
40
|
],
|
|
38
41
|
"scripts": {
|
|
@@ -53,5 +56,8 @@
|
|
|
53
56
|
},
|
|
54
57
|
"publishConfig": {
|
|
55
58
|
"access": "public"
|
|
59
|
+
},
|
|
60
|
+
"dependencies": {
|
|
61
|
+
"tokentracker-cli": "^0.84.9"
|
|
56
62
|
}
|
|
57
63
|
}
|
package/src/inspect.js
CHANGED
|
@@ -90,41 +90,18 @@ function buildActivity(tokenTrackerActivity, prompts = [], sourceReports = {}) {
|
|
|
90
90
|
};
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
const day = String(prompt.timestamp).slice(0, 10);
|
|
97
|
-
if (!/^\d{4}-\d{2}-\d{2}$/.test(day)) continue;
|
|
98
|
-
const row = byDay.get(day) || { day, value: 0, conversation_count: 0, models: {}, sources: {} };
|
|
99
|
-
row.value += 1;
|
|
100
|
-
row.conversation_count += 1;
|
|
101
|
-
const source = prompt.source || "unknown";
|
|
102
|
-
row.sources[source] = (row.sources[source] || 0) + 1;
|
|
103
|
-
row.models[source] = (row.models[source] || 0) + 1;
|
|
104
|
-
byDay.set(day, row);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
const daily_rows = [...byDay.values()]
|
|
108
|
-
.sort((a, b) => a.day.localeCompare(b.day))
|
|
109
|
-
.map((row) => ({
|
|
110
|
-
day: row.day,
|
|
111
|
-
value: row.value,
|
|
112
|
-
total_tokens: row.value,
|
|
113
|
-
billable_total_tokens: row.value,
|
|
114
|
-
conversation_count: row.conversation_count,
|
|
115
|
-
models: row.models,
|
|
116
|
-
sources: row.sources,
|
|
117
|
-
}));
|
|
118
|
-
|
|
93
|
+
// TokenTracker is a runtime dependency and is initialized before inspection.
|
|
94
|
+
// If a platform or permission blocks collection, stay honest: show an empty
|
|
95
|
+
// token metric instead of relabeling prompt counts as usage.
|
|
119
96
|
return {
|
|
120
|
-
source: "
|
|
121
|
-
metric: "
|
|
122
|
-
daily_rows,
|
|
97
|
+
source: "token-tracker",
|
|
98
|
+
metric: "tokens",
|
|
99
|
+
daily_rows: [],
|
|
123
100
|
total_tokens: 0,
|
|
124
|
-
active_day_count:
|
|
101
|
+
active_day_count: 0,
|
|
125
102
|
bucket_count: 0,
|
|
126
|
-
daily_row_count:
|
|
127
|
-
root: null,
|
|
103
|
+
daily_row_count: 0,
|
|
104
|
+
root: tokenTrackerActivity?.root || null,
|
|
128
105
|
estimated_cost_usd: null,
|
|
129
106
|
};
|
|
130
107
|
}
|
|
@@ -166,7 +166,7 @@ function buildActivitySignals({ activity = {}, summary = {}, categories = {} } =
|
|
|
166
166
|
.filter(([, count]) => count > 0)
|
|
167
167
|
.sort((a, b) => b[1] - a[1])[0];
|
|
168
168
|
|
|
169
|
-
if (stats.metric === "tokens"
|
|
169
|
+
if (stats.metric === "tokens") {
|
|
170
170
|
const signals = [
|
|
171
171
|
{ label: "Total tokens", labelZh: "总 Tokens", value: compactNumber(stats.totalValue) },
|
|
172
172
|
{
|
|
@@ -200,6 +200,13 @@ function buildActivitySignals({ activity = {}, summary = {}, categories = {} } =
|
|
|
200
200
|
value: formatModelName(stats.topModel),
|
|
201
201
|
});
|
|
202
202
|
}
|
|
203
|
+
if (!stats.topAgent && (summary.active_source_count ?? summary.source_count ?? 0) > 0) {
|
|
204
|
+
signals.push({
|
|
205
|
+
label: "Agents found",
|
|
206
|
+
labelZh: "检测到 Agent",
|
|
207
|
+
value: String(summary.active_source_count ?? summary.source_count ?? 0),
|
|
208
|
+
});
|
|
209
|
+
}
|
|
203
210
|
if (signals.length === 2) {
|
|
204
211
|
signals.push({
|
|
205
212
|
label: "Peak day",
|
package/src/lib/ai-roast.js
CHANGED
|
@@ -57,7 +57,8 @@ COMEDY ENGINE
|
|
|
57
57
|
- Use a three-beat escalation: (1) a sharp cold open that casts the personality as a character, (2) a receipts paragraph with 2-4 evidence-backed details, and (3) an absurd-but-grounded escalation ending on the strongest punchline.
|
|
58
58
|
- Sustain one concrete metaphor world—courtroom, kitchen, airport, laboratory, reality show, religion, heist, sports commentary, etc.—chosen to fit the evidence. Do not mix five unrelated metaphors.
|
|
59
59
|
- Prefer specific nouns, active verbs, varied sentence rhythm, callbacks, contrast, and comic misdirection. One sentence may be dry; the next should twist the knife.
|
|
60
|
-
-
|
|
60
|
+
- When recurring_domain_clusters is non-empty, choose the most semantically distinctive recognizable cluster as the preferred theme evidence. Do not mechanically choose the first or highest-salience row: salience measures repetition, not comic or semantic quality. Ignore identifier fragments, generic UI words, status prose, and operational boilerplate.
|
|
61
|
+
- Otherwise mention at least one distinctive recurring domain concept when recurring_domain_concepts is non-empty. Treat it as a prompt mention, not proof of a project.
|
|
61
62
|
- Use exact numbers selectively as "receipts"; never turn every sentence into a dashboard caption.
|
|
62
63
|
- The final sentence must be a quotable punchline, not advice, diagnosis, or a generic summary.
|
|
63
64
|
- English and Chinese should be locally funny adaptations using the same evidence beats, not stiff line-by-line translations.
|
|
@@ -66,14 +67,20 @@ COMEDY ENGINE
|
|
|
66
67
|
|
|
67
68
|
HASHTAG ENGINE
|
|
68
69
|
- Hashtags are interpretations, not a frequency table. Never copy a recurring concept merely because it ranks highly.
|
|
69
|
-
- Read coherent concept clusters and infer the recognizable domain, community, scene, or
|
|
70
|
-
-
|
|
71
|
-
-
|
|
70
|
+
- Read coherent concept clusters and infer the recognizable domain, community, scene, or playful fictional role behind them. For example, preflop + folds + raises + river can become "HoldemPlayer"; 前庭 + HIT + nystagmus can become "VestibularLab" or "前庭实验室"; Delta Force + bullet + price + market can become "AmmoBroker"/"弹药盘商" or the sharper "ArmsDealer"/"武器贩子". Examples demonstrate reasoning only; never copy an example unless the supplied evidence supports that exact scene.
|
|
71
|
+
- Treat hashtags as stage names from a comedy writer's room, not cautious analytics labels. Bold exaggeration, slang, puns, subculture references, mock job titles, and slightly unhinged fictional roles are welcome.
|
|
72
|
+
- A distinctive standalone recurring concept may inspire a fictional role even when it does not form a large cluster. Prefer a funny, recognizable interpretation over a technically exhaustive label.
|
|
73
|
+
- Produce a varied set: usually include a domain/scene alter ego, a coding-behavior joke, the immutable personality title, and one or two wildcards tied to the roast metaphor or a memorable prop. Change the mix when the evidence offers a better joke.
|
|
72
74
|
- Do not emit isolated raw keywords such as "preflop", "browser", "implementation", "debugging", or "UI" as tags. A proper name or acronym may remain literal only when it is already a meaningful identity label.
|
|
73
|
-
- Generate every tag as one bilingual pair with a shared semantic gloss. The Chinese tag must localize the intended joke, not translate the English surface form word by word.
|
|
75
|
+
- Generate every tag as one bilingual pair with a shared semantic gloss. The Chinese tag must localize the intended joke, not translate the English surface form word by word.
|
|
74
76
|
- When kind is "personality_character", reuse immutable_profile.personality and immutable_profile.personality_zh instead of inventing a new translation.
|
|
75
77
|
- Use kind "proper_noun" only for names or acronyms that should remain unchanged in both languages, such as GitHub, HIT, or ONNX.
|
|
76
|
-
-
|
|
78
|
+
- A hashtag may cast a cluster or distinctive recurring concept as an obviously fictional scene role, but it must not assert the user's real occupation, credential, project ownership, or offline conduct. "ArmsDealer" is a comic handle; "the user sells weapons" is a forbidden factual claim.
|
|
79
|
+
- Never fuse unrelated concepts. Combine concepts only when recurring_domain_clusters explicitly shows that they repeatedly co-occurred.
|
|
80
|
+
- Every tag needs a different job. Generic stems such as Prompt, Code, Context, Build, Architect, Guru, Master, Minimalist, Ninja, or Wizard are allowed when they complete a specific punchline (for example "CodeCult"); reject them only as bland filler such as "CodeMaster".
|
|
81
|
+
- The best domain tag should be difficult to write without the supplied topic evidence. The behavior tag should turn a measured contradiction into a concrete prop, scene role, or consequence—not a workflow label.
|
|
82
|
+
- Only the immutable personality tag may be a plain title. The other tags must contain a concrete scene, prop, social role, tension, or punchline.
|
|
83
|
+
- Before returning, silently run a writer's-room test: if a tag could describe almost any developer, if two tags are synonyms, or if nobody would want to screenshot it, replace it with a stranger and more evidence-specific joke.
|
|
77
84
|
|
|
78
85
|
ANTI-BLANDNESS
|
|
79
86
|
- Avoid report voice and filler such as "You're a builder", "all about", "minor signal", "faint echo", "verification pending", "context is optional", "X master", or "the data suggests".
|
|
@@ -91,7 +98,8 @@ EVIDENCE RULES
|
|
|
91
98
|
- A low testing/debugging signal means verification is under-observed in these prompts. It does not prove the code is wrong, untested elsewhere, or delegated to other people.
|
|
92
99
|
- Treat category counts as observed prompt behavior, not objective engineering quality or completed work.
|
|
93
100
|
- Concept occurrence_count means text mentions, never completed commits, pushes, tests, features, or other real-world actions. Call it a mention when citing it.
|
|
94
|
-
-
|
|
101
|
+
- recurring_domain_clusters are aggregate same-prompt co-occurrence evidence, so their concepts may be interpreted together as a comic prompt-world.
|
|
102
|
+
- Standalone aggregated concepts do not prove they belong to the same project. Never combine separate concepts unless recurring_domain_clusters links them; never turn either form into an invented app, bot, product, stack, real occupation, or ownership claim. Say the prompts "orbit", "mention", or "cluster around" those concepts.
|
|
95
103
|
- Category ratios do not reveal execution order. Never say code shipped before verification, entered production, broke, contained bugs, or failed to run.
|
|
96
104
|
- Do not turn implementation/testing/debugging prompt categories into completed implementation, shipping, testing, or debugging actions. Say "implementation-classified prompts", "testing signal", or "debugging mentions".
|
|
97
105
|
- Do not quote or reconstruct raw prompts.
|
|
@@ -119,8 +127,9 @@ Before writing, silently select:
|
|
|
119
127
|
2. the metaphor world;
|
|
120
128
|
3. three evidence receipts;
|
|
121
129
|
4. the closing callback.
|
|
130
|
+
Then silently verify that every non-personality hashtag is specific, distinct, and entertaining.
|
|
122
131
|
|
|
123
|
-
Return
|
|
132
|
+
Return exactly 5 hashtagPairs. Do not force a rigid order. Lead with the most shareable tag. When recurring_domain_clusters is non-empty, at least one tag should transform its most distinctive semantically credible cluster into a recognizable scene character or clearly fictional role rather than repeat one of its terms. When only recurring_domain_concepts are available, a distinctive recurring concept may still inspire a playful alter ego.
|
|
124
133
|
Each pair must express the same meaning in both languages. Tags must be compact semantic labels, not copied high-frequency words. English tags must be English except proper names/acronyms. Chinese tags must be a culturally natural localization of the meaning, not a dictionary translation of the English word shape.`;
|
|
125
134
|
|
|
126
135
|
function endpoint(baseUrl) {
|
|
@@ -274,8 +283,8 @@ function cleanHashtagPairs(value) {
|
|
|
274
283
|
const seenEn = new Set();
|
|
275
284
|
const seenZh = new Set();
|
|
276
285
|
for (const raw of value) {
|
|
277
|
-
const en = cleanTags([raw?.en],
|
|
278
|
-
const zh = cleanTags([raw?.zh],
|
|
286
|
+
const en = cleanTags([raw?.en], 32)[0];
|
|
287
|
+
const zh = cleanTags([raw?.zh], 16)[0];
|
|
279
288
|
if (!en || !zh) continue;
|
|
280
289
|
const enKey = en.toLowerCase();
|
|
281
290
|
const zhKey = zh.toLowerCase();
|
|
@@ -291,7 +300,7 @@ function cleanHashtagPairs(value) {
|
|
|
291
300
|
kind,
|
|
292
301
|
meaning: cleanText(raw?.meaning, 80, { short: true }),
|
|
293
302
|
});
|
|
294
|
-
if (pairs.length >=
|
|
303
|
+
if (pairs.length >= 6) break;
|
|
295
304
|
}
|
|
296
305
|
return pairs;
|
|
297
306
|
}
|
|
@@ -349,8 +358,8 @@ function validateRoastPayload(raw) {
|
|
|
349
358
|
const paired = hashtagPairs.length >= 3;
|
|
350
359
|
const result = {
|
|
351
360
|
...(paired ? { hashtagPairs } : {}),
|
|
352
|
-
hashtags: paired ? hashtagPairs.map((pair) => pair.en) : cleanTags(parsed?.hashtags,
|
|
353
|
-
hashtagsZh: paired ? hashtagPairs.map((pair) => pair.zh) : cleanTags(parsed?.hashtagsZh,
|
|
361
|
+
hashtags: paired ? hashtagPairs.map((pair) => pair.en) : cleanTags(parsed?.hashtags, 32),
|
|
362
|
+
hashtagsZh: paired ? hashtagPairs.map((pair) => pair.zh) : cleanTags(parsed?.hashtagsZh, 16),
|
|
354
363
|
roast: paragraphize(cleanText(parsed?.roast, 1100)),
|
|
355
364
|
roastZh: paragraphize(cleanText(parsed?.roastZh, 700)),
|
|
356
365
|
tldr: cleanText(parsed?.tldr, 150, { short: true }),
|
|
@@ -392,7 +401,7 @@ async function generateAiRoast(evidence, {
|
|
|
392
401
|
const request = requestForProvider(config, {
|
|
393
402
|
apiKey,
|
|
394
403
|
messages,
|
|
395
|
-
temperature:
|
|
404
|
+
temperature: 1.05,
|
|
396
405
|
maxTokens: 1800,
|
|
397
406
|
});
|
|
398
407
|
const response = await fetchImpl(request.url, {
|