prompt-profile 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +25 -9
  2. package/dist/bin.js +236 -150
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -5,14 +5,27 @@ personal profile.
5
5
 
6
6
  ![Synthetic sample share card](docs/sample-card.png)
7
7
 
8
- [Sample HTML report](https://htmlpreview.github.io/?https://github.com/EricTsai83/prompt-profile/blob/main/docs/sample-report.html)
8
+ [Sample HTML report](https://erictsai83.github.io/prompt-profile/sample-report.html)
9
9
  · [Sample profile JSON](docs/sample-profile.json) (all sample data is hand-written and fictional).
10
10
 
11
- The same profile in the other looks (`--look signal`, `afterhours`, `studio`):
11
+ ### A real report
12
12
 
13
- | Signal | Afterhours | Studio |
14
- | ------------------------------------------- | --------------------------------------------------- | ------------------------------------------- |
15
- | ![Signal look](docs/sample-card-signal.png) | ![Afterhours look](docs/sample-card-afterhours.png) | ![Studio look](docs/sample-card-studio.png) |
13
+ The author's own report, from about 1,700 real prompts over six months, published as written:
14
+
15
+ - [Full report](https://erictsai83.github.io/prompt-profile/demo/full/report.html): what you see on your own machine, with quotes from
16
+ real prompts, suggested rewrites, project names, exact dates and fun facts.
17
+ - [Shareable report](https://erictsai83.github.io/prompt-profile/demo/without-personal/report.html): the same profile rendered with
18
+ `--exclude personal`: no quotes, rewrites or fun facts, projects shown as "Project A, B…",
19
+ dates by month. This is what you would post publicly.
20
+
21
+ The share card is the same for both: it never contains quotes or project names. The full report
22
+ in every look (`--look`; render only, no new analysis):
23
+
24
+ | [Classic](https://erictsai83.github.io/prompt-profile/demo/full/report.html) (default) | [Signal](https://erictsai83.github.io/prompt-profile/demo/signal/report.html) |
25
+ | -------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- |
26
+ | ![Classic card](docs/demo/card.png) | ![Signal card](docs/demo/signal/card.png) |
27
+ | [Afterhours](https://erictsai83.github.io/prompt-profile/demo/afterhours/report.html) | [Studio](https://erictsai83.github.io/prompt-profile/demo/studio/report.html) |
28
+ | ![Afterhours card](docs/demo/afterhours/card.png) | ![Studio card](docs/demo/studio/card.png) |
16
29
 
17
30
  ## Quick start
18
31
 
@@ -22,24 +35,27 @@ The same profile in the other looks (`--look signal`, `afterhours`, `studio`):
22
35
  2. Run it (Node.js ≥ 22):
23
36
 
24
37
  ```bash
25
- npx prompt-profile
38
+ npx prompt-profile@latest
26
39
  ```
27
40
 
41
+ `@latest` makes npx fetch the newest version instead of reusing one it cached earlier.
42
+
28
43
  3. It reads your local history, shows how many prompts it found and how many CLI calls the
29
44
  analysis will take, and asks `Continue?`. The calls use your Claude / ChatGPT subscription
30
- quota. To see what would be sent first, run `npx prompt-profile --dry-run` (calls nothing).
45
+ quota. To see what would be sent first, run `npx prompt-profile@latest --dry-run` (calls nothing).
31
46
  4. When it is done, the report opens in your browser. Everything is written to
32
47
  `./prompt-profile-report/`.
33
48
 
34
- Want to look around for free first? `npx prompt-profile stats` shows statistics without any LLM
49
+ Want to look around for free first? `npx prompt-profile@latest stats` shows statistics without any LLM
35
50
  call.
36
51
 
37
52
  ## Install
38
53
 
39
54
  ```bash
40
- npx prompt-profile # run without installing
55
+ npx prompt-profile@latest # run without installing (always the newest version)
41
56
  npm i -g prompt-profile # or install the `prompt-profile` command
42
57
  prompt-profile --help
58
+ npm i -g prompt-profile@latest # update the installed command
43
59
  ```
44
60
 
45
61
  No Node.js? Every [GitHub Release](https://github.com/EricTsai83/prompt-profile/releases) has a
package/dist/bin.js CHANGED
@@ -1302,7 +1302,7 @@ const fileCacheLayer = (dir) => Layer.effect(AnalysisCache, Effect.gen(function*
1302
1302
  * Package version. Injected by tsdown at build time; during development and tests
1303
1303
  * (tsx / vitest) it falls back to reading package.json.
1304
1304
  */
1305
- const VERSION = "0.1.1";
1305
+ const VERSION = "0.1.3";
1306
1306
  // src/cli/errors.ts
1307
1307
  /** No prompts found at all, or none in the selected range. */
1308
1308
  var NoData = class extends Data.TaggedError("NoData") {};
@@ -2401,7 +2401,94 @@ const withRetry = (runner, options = {}) => {
2401
2401
  generate
2402
2402
  };
2403
2403
  };
2404
- // src/report/graphic.ts
2404
+ // src/report/derive.ts
2405
+ /** The busiest four consecutive hours (wrapping past midnight); `end` is exclusive. */
2406
+ const chronotype = (s) => {
2407
+ const total = s.hourHistogram.reduce((a, b) => a + b, 0);
2408
+ if (total === 0) return null;
2409
+ let best = {
2410
+ start: 0,
2411
+ sum: -1
2412
+ };
2413
+ for (let start = 0; start < 24; start++) {
2414
+ let sum = 0;
2415
+ for (let i = 0; i < 4; i++) sum += s.hourHistogram[(start + i) % 24];
2416
+ if (sum > best.sum) best = {
2417
+ start,
2418
+ sum
2419
+ };
2420
+ }
2421
+ return {
2422
+ start: best.start,
2423
+ end: (best.start + 4) % 24,
2424
+ share: best.sum / total
2425
+ };
2426
+ };
2427
+ /** Mean prompts per session, one decimal; null without sessions. */
2428
+ const promptsPerSession = (s) => s.totalSessions === 0 ? null : Math.round(10 * s.totalPrompts / s.totalSessions) / 10;
2429
+ /** "1 in N prompts corrects the AI"; null without corrections. */
2430
+ const correctionEvery = (s) => s.correctionRate <= 0 ? null : Math.round(1 / s.correctionRate);
2431
+ /**
2432
+ * The dominant project per month, with consecutive months of the same project merged. "Other
2433
+ * folders" only names a month when no named project has prompts in it.
2434
+ */
2435
+ const chapters = (s) => {
2436
+ const slots = s.activity.projects.length + 1;
2437
+ const months = /* @__PURE__ */ new Map();
2438
+ for (const d of s.activity.days) {
2439
+ const key = d.date.slice(0, 7);
2440
+ const counts = months.get(key) ?? Array.from({ length: slots }, () => 0);
2441
+ d.byProject.forEach((n, i) => counts[i] += n);
2442
+ months.set(key, counts);
2443
+ }
2444
+ const out = [];
2445
+ for (const [month, counts] of [...months.entries()].toSorted(([a], [b]) => a.localeCompare(b))) {
2446
+ const named = counts.slice(0, slots - 1);
2447
+ const pool = named.some((n) => n > 0) ? named : counts;
2448
+ const slot = pool.indexOf(Math.max(...pool));
2449
+ const prompts = counts.reduce((a, b) => a + b, 0);
2450
+ const last = out.at(-1);
2451
+ if (last && last.slot === slot) out[out.length - 1] = {
2452
+ ...last,
2453
+ to: month,
2454
+ prompts: last.prompts + prompts
2455
+ };
2456
+ else out.push({
2457
+ from: month,
2458
+ to: month,
2459
+ slot,
2460
+ prompts
2461
+ });
2462
+ }
2463
+ return out;
2464
+ };
2465
+ /**
2466
+ * The 24 radial bars of the hour clock (260 × 260, centre 130): length by prompts in that hour,
2467
+ * `on` for the busiest window. Shared by the report's hero and the classic card.
2468
+ */
2469
+ const clockBars = (hours, window) => {
2470
+ const max = Math.max(1, ...hours);
2471
+ const inWindow = (h) => window !== null && (h - window.start + 24) % 24 < (window.end - window.start + 24) % 24;
2472
+ return hours.map((n, h) => {
2473
+ const a = h / 24 * Math.PI * 2 - Math.PI / 2;
2474
+ const r0 = 62;
2475
+ const r1 = 66 + 54 * n / max;
2476
+ const p = (r) => `${(130 + Math.cos(a) * r).toFixed(1)} ${(130 + Math.sin(a) * r).toFixed(1)}`;
2477
+ return {
2478
+ from: p(r0),
2479
+ to: p(r1),
2480
+ on: inWindow(h)
2481
+ };
2482
+ });
2483
+ };
2484
+ /** The report's hour clock as a standalone SVG (no hour labels: the card has no SVG fonts). */
2485
+ const clockSvg = (hours, color) => {
2486
+ return {
2487
+ svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 260 260"><circle cx="130" cy="130" r="60" fill="none" stroke="${color}" stroke-opacity="0.25"/>${clockBars(hours, chronotype({ hourHistogram: hours })).map((b) => `<path d="M${b.from}L${b.to}" stroke="${color}" stroke-width="7" stroke-linecap="round" stroke-opacity="${b.on ? 1 : .35}"/>`).join("")}</svg>`,
2488
+ width: 260,
2489
+ height: 260
2490
+ };
2491
+ };
2405
2492
  /** A look's signature graphic as a standalone SVG, drawn from the 24-hour histogram only. */
2406
2493
  const graphicSvg = (kind, hours, identity) => {
2407
2494
  const max = Math.max(1, ...hours);
@@ -2603,6 +2690,31 @@ const LOOKS = [
2603
2690
  ];
2604
2691
  /** The look's data, or null for `classic`. */
2605
2692
  const lookOf = (id) => LOOKS.find((l) => l.id === id) ?? null;
2693
+ /** Colors of the classic report (no look); the classic card uses the dark ones. */
2694
+ const CLASSIC_TOKENS = {
2695
+ light: {
2696
+ bg: "#f6f6f3",
2697
+ fg: "#1d1d1f",
2698
+ muted: "#6b6b70",
2699
+ card: "#ffffff",
2700
+ border: "#e6e6e1",
2701
+ accent: "#5b5bd6",
2702
+ accentSoft: "#ececfb",
2703
+ warn: "#9a5800",
2704
+ empty: "#ececea"
2705
+ },
2706
+ dark: {
2707
+ bg: "#121214",
2708
+ fg: "#ececee",
2709
+ muted: "#9a9aa2",
2710
+ card: "#1c1c20",
2711
+ border: "#2c2c33",
2712
+ accent: "#9d9dff",
2713
+ accentSoft: "#25254a",
2714
+ warn: "#f0b35a",
2715
+ empty: "#26262c"
2716
+ }
2717
+ };
2606
2718
  // src/report/content.ts
2607
2719
  const contentIn = (p, lang) => {
2608
2720
  const t = lang === "en" ? void 0 : p.translations[lang];
@@ -2618,67 +2730,6 @@ const contentIn = (p, lang) => {
2618
2730
  improvement: (i) => t?.improvements[i] ?? p.improvements[i]
2619
2731
  };
2620
2732
  };
2621
- // src/report/derive.ts
2622
- /** The busiest four consecutive hours (wrapping past midnight); `end` is exclusive. */
2623
- const chronotype = (s) => {
2624
- const total = s.hourHistogram.reduce((a, b) => a + b, 0);
2625
- if (total === 0) return null;
2626
- let best = {
2627
- start: 0,
2628
- sum: -1
2629
- };
2630
- for (let start = 0; start < 24; start++) {
2631
- let sum = 0;
2632
- for (let i = 0; i < 4; i++) sum += s.hourHistogram[(start + i) % 24];
2633
- if (sum > best.sum) best = {
2634
- start,
2635
- sum
2636
- };
2637
- }
2638
- return {
2639
- start: best.start,
2640
- end: (best.start + 4) % 24,
2641
- share: best.sum / total
2642
- };
2643
- };
2644
- /** Mean prompts per session, one decimal; null without sessions. */
2645
- const promptsPerSession = (s) => s.totalSessions === 0 ? null : Math.round(10 * s.totalPrompts / s.totalSessions) / 10;
2646
- /** "1 in N prompts corrects the AI"; null without corrections. */
2647
- const correctionEvery = (s) => s.correctionRate <= 0 ? null : Math.round(1 / s.correctionRate);
2648
- /**
2649
- * The dominant project per month, with consecutive months of the same project merged. "Other
2650
- * folders" only names a month when no named project has prompts in it.
2651
- */
2652
- const chapters = (s) => {
2653
- const slots = s.activity.projects.length + 1;
2654
- const months = /* @__PURE__ */ new Map();
2655
- for (const d of s.activity.days) {
2656
- const key = d.date.slice(0, 7);
2657
- const counts = months.get(key) ?? Array.from({ length: slots }, () => 0);
2658
- d.byProject.forEach((n, i) => counts[i] += n);
2659
- months.set(key, counts);
2660
- }
2661
- const out = [];
2662
- for (const [month, counts] of [...months.entries()].toSorted(([a], [b]) => a.localeCompare(b))) {
2663
- const named = counts.slice(0, slots - 1);
2664
- const pool = named.some((n) => n > 0) ? named : counts;
2665
- const slot = pool.indexOf(Math.max(...pool));
2666
- const prompts = counts.reduce((a, b) => a + b, 0);
2667
- const last = out.at(-1);
2668
- if (last && last.slot === slot) out[out.length - 1] = {
2669
- ...last,
2670
- to: month,
2671
- prompts: last.prompts + prompts
2672
- };
2673
- else out.push({
2674
- from: month,
2675
- to: month,
2676
- slot,
2677
- prompts
2678
- });
2679
- }
2680
- return out;
2681
- };
2682
2733
  // src/report/messages.ts
2683
2734
  const plural = (n, one, many) => `${n.toLocaleString("en")} ${n === 1 ? one : many}`;
2684
2735
  /** Every text of the report and the card, per language. */
@@ -3192,76 +3243,143 @@ const cardMetrics = (profile, lang, n) => {
3192
3243
  [t.cardStreak, t.days(s.longestStreakDays)]
3193
3244
  ].slice(0, n);
3194
3245
  };
3195
- /** Today's card. `hide` can only remove the trait or number rows. */
3246
+ /** Clock size on the classic card; the report's 260 × 260 drawing is scaled to it. */
3247
+ const CARD_CLOCK = 300;
3248
+ /**
3249
+ * The classic card: the classic report's hero on its page, in its dark colors, with the same
3250
+ * hour clock. The hour labels are text nodes over the drawing (SVG images get no fonts).
3251
+ */
3196
3252
  const classicTree = (profile, hide, lang) => {
3197
3253
  const t = MESSAGES[lang];
3198
3254
  const c = contentIn(profile, lang);
3199
- const numbers = cardMetrics(profile, lang, 3);
3255
+ const k = CLASSIC_TOKENS.dark;
3256
+ const name = clip(c.archetype.name, 56);
3257
+ const showGraphic = !hide.includes("graphic");
3258
+ const clock = clockSvg(profile.stats.hourHistogram, k.accent);
3259
+ const left = 808;
3260
+ const top = 165;
3261
+ const scale = CARD_CLOCK / clock.width;
3262
+ const ticks = [
3263
+ 0,
3264
+ 6,
3265
+ 12,
3266
+ 18
3267
+ ].map((hour) => {
3268
+ const a = hour / 24 * Math.PI * 2 - Math.PI / 2;
3269
+ return h("div", {
3270
+ position: "absolute",
3271
+ left: left + (130 + Math.cos(a) * 46) * scale - 20,
3272
+ top: top + (130 + Math.sin(a) * 46) * scale - 10,
3273
+ width: 40,
3274
+ display: "flex",
3275
+ justifyContent: "center",
3276
+ fontSize: 14,
3277
+ color: k.muted
3278
+ }, String(hour).padStart(2, "0"));
3279
+ });
3200
3280
  return h("div", {
3201
3281
  width: CARD_WIDTH,
3202
3282
  height: 630,
3203
3283
  boxSizing: "border-box",
3204
3284
  display: "flex",
3205
- flexDirection: "column",
3206
- justifyContent: "space-between",
3207
- padding: "56px 64px",
3208
- backgroundImage: "linear-gradient(135deg, #17172b 0%, #2b2b6b 60%, #5b5bd6 100%)",
3209
- color: "#f4f4ff",
3285
+ position: "relative",
3286
+ backgroundColor: k.bg,
3287
+ color: k.fg,
3210
3288
  fontFamily: "Inter"
3211
3289
  }, [
3290
+ h("div", {
3291
+ position: "absolute",
3292
+ left: 36,
3293
+ top: 36,
3294
+ width: 1128,
3295
+ height: 558,
3296
+ backgroundColor: k.card,
3297
+ border: `1.5px solid ${k.border}`,
3298
+ borderRadius: 32
3299
+ }),
3300
+ ...showGraphic ? [{
3301
+ type: "img",
3302
+ props: {
3303
+ src: svgDataUrl(clock.svg),
3304
+ width: CARD_CLOCK,
3305
+ height: CARD_CLOCK,
3306
+ style: {
3307
+ position: "absolute",
3308
+ left,
3309
+ top
3310
+ }
3311
+ }
3312
+ }, ...ticks] : [],
3212
3313
  h("div", {
3213
3314
  display: "flex",
3214
- flexDirection: "column"
3315
+ flexDirection: "column",
3316
+ justifyContent: "space-between",
3317
+ position: "absolute",
3318
+ left: 36,
3319
+ top: 36,
3320
+ width: 1128,
3321
+ height: 558,
3322
+ padding: "40px 56px",
3323
+ boxSizing: "border-box"
3215
3324
  }, [
3216
3325
  h("div", {
3217
- fontSize: 22,
3218
- color: "#b9b9ff",
3219
- letterSpacing: 1
3326
+ fontSize: 20,
3327
+ fontWeight: 700
3220
3328
  }, t.project),
3221
3329
  h("div", {
3222
- fontSize: 56,
3223
- fontWeight: 700,
3224
- marginTop: 14,
3225
- lineHeight: 1.15
3226
- }, clip(c.archetype.name, 56)),
3330
+ display: "flex",
3331
+ flexDirection: "column",
3332
+ maxWidth: showGraphic ? 700 : 1e3
3333
+ }, [
3334
+ h("div", {
3335
+ fontFamily: DISPLAY_FONT,
3336
+ fontWeight: 800,
3337
+ fontSize: titleSize(name),
3338
+ lineHeight: .98,
3339
+ letterSpacing: -2
3340
+ }, name),
3341
+ h("div", {
3342
+ fontSize: 24,
3343
+ lineHeight: 1.4,
3344
+ marginTop: 18,
3345
+ color: k.muted
3346
+ }, clip(c.headline, 120)),
3347
+ hide.includes("traits") ? null : h("div", {
3348
+ display: "flex",
3349
+ gap: 10,
3350
+ flexWrap: "wrap",
3351
+ marginTop: 20
3352
+ }, profile.traits.slice(0, 3).map((_tr, i) => h("div", {
3353
+ display: "flex",
3354
+ fontSize: 18,
3355
+ padding: "6px 16px",
3356
+ borderRadius: 999,
3357
+ color: k.accent,
3358
+ backgroundColor: k.accentSoft
3359
+ }, clip(c.trait(i).name, 32))))
3360
+ ]),
3227
3361
  h("div", {
3228
- fontSize: 26,
3229
- marginTop: 16,
3230
- lineHeight: 1.4,
3231
- color: "#dcdcf5"
3232
- }, clip(c.headline, 150))
3233
- ]),
3234
- h("div", {
3235
- display: "flex",
3236
- gap: 12,
3237
- flexWrap: "wrap"
3238
- }, (hide.includes("traits") ? [] : profile.traits.slice(0, 3)).map((_tr, i) => h("div", {
3239
- display: "flex",
3240
- fontSize: 24,
3241
- padding: "8px 18px",
3242
- borderRadius: 999,
3243
- backgroundColor: "rgba(255,255,255,0.14)"
3244
- }, clip(c.trait(i).name, 32)))),
3245
- h("div", {
3246
- display: "flex",
3247
- justifyContent: "space-between",
3248
- alignItems: "flex-end"
3249
- }, [h("div", {
3250
- display: "flex",
3251
- gap: 48
3252
- }, (hide.includes("stats") ? [] : numbers).map(([label, value]) => h("div", {
3253
- display: "flex",
3254
- flexDirection: "column"
3255
- }, [h("div", {
3256
- fontSize: 40,
3257
- fontWeight: 700
3258
- }, value), h("div", {
3259
- fontSize: 18,
3260
- color: "#b9b9ff"
3261
- }, label)]))), h("div", {
3262
- fontSize: 20,
3263
- color: "#b9b9ff"
3264
- }, "npx prompt-profile")])
3362
+ display: "flex",
3363
+ justifyContent: "space-between",
3364
+ alignItems: "flex-end"
3365
+ }, [h("div", {
3366
+ display: "flex",
3367
+ gap: 44
3368
+ }, (hide.includes("stats") ? [] : cardMetrics(profile, lang, 3)).map(([label, value]) => h("div", {
3369
+ display: "flex",
3370
+ flexDirection: "column"
3371
+ }, [h("div", {
3372
+ fontFamily: DISPLAY_FONT,
3373
+ fontWeight: 800,
3374
+ fontSize: 36
3375
+ }, value), h("div", {
3376
+ fontSize: 16,
3377
+ color: k.muted
3378
+ }, label)]))), h("div", {
3379
+ fontSize: 18,
3380
+ color: k.muted
3381
+ }, "npx prompt-profile")])
3382
+ ])
3265
3383
  ]);
3266
3384
  };
3267
3385
  /** Archetype size steps: long names get smaller type instead of overflowing. */
@@ -3543,15 +3661,7 @@ const heatmap = (s, loc, view = PRIVATE_VIEW) => {
3543
3661
  };
3544
3662
  /** 24 radial bars around a dial; the busiest four hours are drawn in full colour. */
3545
3663
  const radialClock = (s, window, label) => {
3546
- const max = Math.max(1, ...s.hourHistogram);
3547
- const inWindow = (h) => window !== null && (h - window.start + 24) % 24 < (window.end - window.start + 24) % 24;
3548
- const bars = s.hourHistogram.map((n, h) => {
3549
- const a = h / 24 * Math.PI * 2 - Math.PI / 2;
3550
- const r0 = 62;
3551
- const r1 = 66 + 54 * n / max;
3552
- const p = (r) => `${(130 + Math.cos(a) * r).toFixed(1)} ${(130 + Math.sin(a) * r).toFixed(1)}`;
3553
- return html`<path d="M${p(r0)}L${p(r1)}" class="${inWindow(h) ? "clock-bar on" : "clock-bar"}" />`;
3554
- });
3664
+ const bars = clockBars(s.hourHistogram, window).map((b) => html`<path d="M${b.from}L${b.to}" class="${b.on ? "clock-bar on" : "clock-bar"}" />`);
3555
3665
  const ticks = [
3556
3666
  0,
3557
3667
  6,
@@ -3569,7 +3679,7 @@ const radialClock = (s, window, label) => {
3569
3679
  });
3570
3680
  return html`<figure class="clock">
3571
3681
  <svg viewBox="0 0 260 260" aria-hidden="true">
3572
- <circle cx="130" cy="130" r="60" class="clock-dial" />
3682
+ <circle cx="130" cy="130" r="${60}" class="clock-dial" />
3573
3683
  ${bars}${ticks}
3574
3684
  </svg>
3575
3685
  <figcaption>${label}</figcaption>
@@ -4305,30 +4415,6 @@ const progressBlock = (p, loc, v, scrub) => {
4305
4415
  const signatureTile = (value, label, tip, i) => html`<div class="sig tip ${i === 0 ? "tip-l" : i === 3 ? "tip-r" : ""}" ${tip} tabindex="-1">
4306
4416
  <b>${value}</b><span>${label}</span>
4307
4417
  </div>`;
4308
- const CLASSIC_TOKENS = {
4309
- light: {
4310
- bg: "#f6f6f3",
4311
- fg: "#1d1d1f",
4312
- muted: "#6b6b70",
4313
- card: "#ffffff",
4314
- border: "#e6e6e1",
4315
- accent: "#5b5bd6",
4316
- accentSoft: "#ececfb",
4317
- warn: "#9a5800",
4318
- empty: "#ececea"
4319
- },
4320
- dark: {
4321
- bg: "#121214",
4322
- fg: "#ececee",
4323
- muted: "#9a9aa2",
4324
- card: "#1c1c20",
4325
- border: "#2c2c33",
4326
- accent: "#9d9dff",
4327
- accentSoft: "#25254a",
4328
- warn: "#f0b35a",
4329
- empty: "#26262c"
4330
- }
4331
- };
4332
4418
  /** The classic hero: today's colors on a card, with the hour graphic. */
4333
4419
  const CLASSIC_IDENTITY = {
4334
4420
  background: "var(--card)",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prompt-profile",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Analyze your past prompts from AI coding agents (Claude Code, Codex) locally and generate a personal profile.",
5
5
  "keywords": [
6
6
  "ai",