standout 0.6.1 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +23 -2
  2. package/dist/cli.js +641 -287
  3. package/package.json +2 -1
package/dist/cli.js CHANGED
@@ -3,7 +3,7 @@ var __toBinaryNode = Uint8Array.fromBase64 || ((base64) => new Uint8Array(Buffer
3
3
 
4
4
  // src/cli.ts
5
5
  import Anthropic from "@anthropic-ai/sdk";
6
- import chalk3 from "chalk";
6
+ import chalk4 from "chalk";
7
7
  import { writeFileSync as writeFileSync2 } from "node:fs";
8
8
  import { tmpdir as tmpdir2 } from "node:os";
9
9
  import { join as join7 } from "node:path";
@@ -1608,6 +1608,449 @@ async function renderWrappedCardLocally(prefetched, theme = "dark") {
1608
1608
  return Buffer.from(png);
1609
1609
  }
1610
1610
 
1611
+ // src/endgame.ts
1612
+ import chalk from "chalk";
1613
+
1614
+ // src/wrapped/tiers.ts
1615
+ var UNICORN2 = ` ,.. /
1616
+ ,' ';
1617
+ ,,.__ _,' /'; .
1618
+ :',' ~~~~ '. '~
1619
+ ' ( ) )::,
1620
+ '. '..=----=..-~ .;'
1621
+ ' ;' :: ':. '"
1622
+ (: ': ;)
1623
+ \\\\ '" ./
1624
+ '" '"`;
1625
+ var ROCKETSHIP2 = ` .
1626
+ .'.
1627
+ |o|
1628
+ .'o'.
1629
+ |.-.|
1630
+ ' '
1631
+ ( )
1632
+ )
1633
+ ( )`;
1634
+ var WIZARD2 = ` (\\. \\ ,/)
1635
+ \\( |\\ )/
1636
+ //\\ | \\ /\\\\
1637
+ (/ /\\_#oo#_/\\ \\)
1638
+ \\/\\ #### /\\/
1639
+ \`##'`;
1640
+ var RISING_STAR2 = ` .
1641
+ ,O,
1642
+ ,OOO,
1643
+ 'oooooOOOOOooooo'
1644
+ \`OOOOOOOOOOO\`
1645
+ \`OOOOOOO\`
1646
+ OOOO'OOOO
1647
+ OOO' 'OOO
1648
+ O' 'O`;
1649
+ var CURIOUS_CAT2 = ` |\\__/,| (\`\\
1650
+ |_ _ |.--.) )
1651
+ ( T ) /
1652
+ (((^_(((/(((_/`;
1653
+ var GINGERBREAD2 = ` ,--.
1654
+ _(*_*)_
1655
+ (_ o _)
1656
+ / o \\
1657
+ (_/ \\_)`;
1658
+ var TIERS2 = [
1659
+ {
1660
+ key: "still_figuring",
1661
+ label: "STILL FIGURING IT OUT",
1662
+ min: 1,
1663
+ art: GINGERBREAD2
1664
+ },
1665
+ { key: "curious_cat", label: "CURIOUS CAT", min: 35, art: CURIOUS_CAT2 },
1666
+ { key: "rising_star", label: "RISING STAR", min: 60, art: RISING_STAR2 },
1667
+ { key: "prompt_wizard", label: "PROMPT WIZARD", min: 77, art: WIZARD2 },
1668
+ {
1669
+ key: "escape_velocity",
1670
+ label: "ESCAPE VELOCITY",
1671
+ min: 86,
1672
+ art: ROCKETSHIP2
1673
+ },
1674
+ { key: "unicorn", label: "UNICORN", min: 95, art: UNICORN2 }
1675
+ ];
1676
+ function tierForScore2(score) {
1677
+ const s = Number.isFinite(score) ? score : 0;
1678
+ for (let i = TIERS2.length - 1; i >= 0; i--) {
1679
+ if (s >= TIERS2[i].min) return TIERS2[i];
1680
+ }
1681
+ return TIERS2[0];
1682
+ }
1683
+
1684
+ // src/share-block.ts
1685
+ var TIER_EMOJI = {
1686
+ still_figuring: "\u{1F331}",
1687
+ curious_cat: "\u{1F408}",
1688
+ rising_star: "\u2B50",
1689
+ prompt_wizard: "\u{1F9D9}",
1690
+ escape_velocity: "\u{1F680}",
1691
+ unicorn: "\u{1F984}"
1692
+ };
1693
+ var SPARK_CHARS = "\u2581\u2582\u2583\u2584\u2585\u2586\u2587\u2588";
1694
+ function sparkline2(buckets) {
1695
+ const recent = buckets.slice(-6).map((b) => Math.max(0, b.duration_hours));
1696
+ if (recent.filter((h) => h > 0).length < 2) return "";
1697
+ const max = Math.max(...recent);
1698
+ if (max <= 0) return "";
1699
+ return recent.map((h) => {
1700
+ const idx = Math.min(
1701
+ SPARK_CHARS.length - 1,
1702
+ Math.round(h / max * (SPARK_CHARS.length - 1))
1703
+ );
1704
+ return SPARK_CHARS[idx];
1705
+ }).join("");
1706
+ }
1707
+ function compactCount(n) {
1708
+ if (n >= 1e9) {
1709
+ const b = n / 1e9;
1710
+ return `${b >= 10 ? Math.round(b) : b.toFixed(1).replace(/\.0$/, "")}B`;
1711
+ }
1712
+ if (n >= 1e6) {
1713
+ const m = n / 1e6;
1714
+ return `${m >= 10 ? Math.round(m) : m.toFixed(1).replace(/\.0$/, "")}M`;
1715
+ }
1716
+ if (n >= 1e3) {
1717
+ const k = n / 1e3;
1718
+ return `${k >= 10 ? Math.round(k) : k.toFixed(1).replace(/\.0$/, "")}K`;
1719
+ }
1720
+ return `${Math.round(n)}`;
1721
+ }
1722
+ function monthLabel(month) {
1723
+ const names = [
1724
+ "Jan",
1725
+ "Feb",
1726
+ "Mar",
1727
+ "Apr",
1728
+ "May",
1729
+ "Jun",
1730
+ "Jul",
1731
+ "Aug",
1732
+ "Sep",
1733
+ "Oct",
1734
+ "Nov",
1735
+ "Dec"
1736
+ ];
1737
+ const idx = Number(month.split("-")[1]) - 1;
1738
+ return names[idx] ?? month;
1739
+ }
1740
+ function firstName(name) {
1741
+ return name.trim().split(/\s+/)[0] || name;
1742
+ }
1743
+ function identityLine(ctx) {
1744
+ const p = ctx.view.proficiency;
1745
+ if (ctx.versus && p && ctx.versus.score !== null && p.score > ctx.versus.score) {
1746
+ return `I beat ${firstName(ctx.versus.name)}'s AI Wrapped \u2694\uFE0F ${p.score} vs ${ctx.versus.score}`;
1747
+ }
1748
+ if (!p) return `My AI Wrapped \xB7 ${ctx.view.archetype_label}`;
1749
+ const tier = tierForScore2(p.score);
1750
+ const emoji = TIER_EMOJI[tier.key] ?? "";
1751
+ const top = p.score_percentile != null ? ` (top ${Math.max(1, Math.round(100 - p.score_percentile))}%)` : "";
1752
+ return `My AI Wrapped \xB7 ${titleCase(tier.label)} ${emoji} \xB7 ${p.score}/100${top}`.trim();
1753
+ }
1754
+ function titleCase(label) {
1755
+ return label.toLowerCase().split(/\s+/).map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
1756
+ }
1757
+ function proofLine(ctx) {
1758
+ const parts = [];
1759
+ const spark = sparkline2(ctx.view.all_time.monthly_buckets);
1760
+ if (spark) parts.push(spark);
1761
+ const hours = Math.round(ctx.view.all_time.total_hours);
1762
+ if (hours > 0) parts.push(`${hours.toLocaleString("en-US")}h`);
1763
+ if (ctx.view.streak_days >= 3) {
1764
+ parts.push(`${ctx.view.streak_days}-day streak`);
1765
+ }
1766
+ const tokens = ctx.view.tokens.work_tokens + ctx.view.tokens.cache_tokens;
1767
+ if (tokens > 0) parts.push(`${compactCount(tokens)} tokens`);
1768
+ const current = ctx.view.proficiency?.score;
1769
+ if (ctx.previous && current != null && current > ctx.previous.score) {
1770
+ parts.push(
1771
+ `+${current - ctx.previous.score} vs ${monthLabel(ctx.previous.month)}`
1772
+ );
1773
+ }
1774
+ return parts.join(" \xB7 ");
1775
+ }
1776
+ function buildShareBlock(ctx) {
1777
+ const lines = [identityLine(ctx)];
1778
+ const proof = proofLine(ctx);
1779
+ if (proof) lines.push(proof);
1780
+ lines.push(
1781
+ ctx.challengeCode ? `beat me \u2192 npx standout beat-${ctx.challengeCode}` : `get yours \u2192 npx standout`
1782
+ );
1783
+ if (ctx.shortUrl) lines.push(ctx.shortUrl);
1784
+ return lines.join("\n");
1785
+ }
1786
+
1787
+ // src/clipboard.ts
1788
+ import { spawnSync } from "child_process";
1789
+ import { platform } from "os";
1790
+ function clipboardCandidates(osPlatform = platform(), env = process.env) {
1791
+ if (osPlatform === "darwin") return [{ cmd: "pbcopy", args: [] }];
1792
+ if (osPlatform === "win32") return [{ cmd: "clip", args: [] }];
1793
+ const tools = [];
1794
+ if (env.WAYLAND_DISPLAY) tools.push({ cmd: "wl-copy", args: [] });
1795
+ tools.push(
1796
+ { cmd: "xclip", args: ["-selection", "clipboard"] },
1797
+ { cmd: "xsel", args: ["-ib"] }
1798
+ );
1799
+ if (env.WSL_DISTRO_NAME || env.WSL_INTEROP) {
1800
+ tools.push({ cmd: "clip.exe", args: [] });
1801
+ }
1802
+ return tools;
1803
+ }
1804
+ function osc52Sequence(text) {
1805
+ const b64 = Buffer.from(text, "utf8").toString("base64");
1806
+ return `\x1B]52;c;${b64}\x07`;
1807
+ }
1808
+ function copyToClipboard(text) {
1809
+ for (const tool of clipboardCandidates()) {
1810
+ try {
1811
+ const res = spawnSync(tool.cmd, tool.args, {
1812
+ input: text,
1813
+ timeout: 3e3,
1814
+ stdio: ["pipe", "ignore", "ignore"]
1815
+ });
1816
+ if (res.status === 0) return true;
1817
+ } catch {
1818
+ }
1819
+ }
1820
+ if (process.stdout.isTTY) {
1821
+ process.stdout.write(osc52Sequence(text));
1822
+ return true;
1823
+ }
1824
+ return false;
1825
+ }
1826
+
1827
+ // src/qr.ts
1828
+ import qrcodeGenerator from "qrcode-generator";
1829
+ var QUIET_ZONE = 2;
1830
+ function qrMatrix(text) {
1831
+ const qr = qrcodeGenerator(0, "M");
1832
+ qr.addData(text);
1833
+ qr.make();
1834
+ const count = qr.getModuleCount();
1835
+ const size = count + QUIET_ZONE * 2;
1836
+ const rows = [];
1837
+ for (let y = 0; y < size; y++) {
1838
+ const row = [];
1839
+ for (let x = 0; x < size; x++) {
1840
+ const my = y - QUIET_ZONE;
1841
+ const mx = x - QUIET_ZONE;
1842
+ row.push(
1843
+ my >= 0 && my < count && mx >= 0 && mx < count ? qr.isDark(my, mx) : false
1844
+ );
1845
+ }
1846
+ rows.push(row);
1847
+ }
1848
+ return rows;
1849
+ }
1850
+ function renderQrHalfBlocks(matrix, indent = " ") {
1851
+ const lines = [];
1852
+ for (let y = 0; y < matrix.length; y += 2) {
1853
+ const top = matrix[y];
1854
+ const bottom = matrix[y + 1] ?? top.map(() => false);
1855
+ let line = indent;
1856
+ for (let x = 0; x < top.length; x++) {
1857
+ const t = !top[x];
1858
+ const b = !bottom[x];
1859
+ line += t && b ? "\u2588" : t ? "\u2580" : b ? "\u2584" : " ";
1860
+ }
1861
+ lines.push(line);
1862
+ }
1863
+ return lines.join("\n");
1864
+ }
1865
+ function qrForTerminal(url, opts = {}) {
1866
+ const isTTY = opts.isTTY ?? process.stdout.isTTY ?? false;
1867
+ if (!isTTY) return null;
1868
+ const rows = opts.rows ?? process.stdout.rows ?? 0;
1869
+ const matrix = qrMatrix(url);
1870
+ const neededRows = Math.ceil(matrix.length / 2) + 4;
1871
+ if (rows > 0 && rows < (opts.minRows ?? neededRows)) return null;
1872
+ return renderQrHalfBlocks(matrix);
1873
+ }
1874
+
1875
+ // src/wrapped-share.ts
1876
+ import open from "open";
1877
+ async function openWrapped(shareUrl) {
1878
+ await open(shareUrl);
1879
+ }
1880
+
1881
+ // src/endgame.ts
1882
+ var ACCENT = "#ad5cff";
1883
+ function firstName2(name) {
1884
+ return name.trim().split(/\s+/)[0] || name;
1885
+ }
1886
+ function buildVersusCard(view, versus) {
1887
+ const mine = view.proficiency?.score ?? null;
1888
+ const theirs = versus.score;
1889
+ const them = firstName2(versus.name);
1890
+ const myTier = mine != null ? TIER_EMOJI[tierForScore2(mine).key] ?? "" : "";
1891
+ const theirTier = versus.tier_key ? TIER_EMOJI[versus.tier_key] ?? "" : "";
1892
+ const lines = ["", chalk.bold.white(" \u2694\uFE0F THE CHALLENGE"), ""];
1893
+ if (mine != null && theirs != null) {
1894
+ const you = `you ${myTier}`.trim();
1895
+ const other = `${them} ${theirTier}`.trim();
1896
+ lines.push(
1897
+ ` ${chalk.white(you)} ${chalk.hex(ACCENT)(String(mine))} vs ${chalk.hex(ACCENT)(String(theirs))} ${chalk.white(other)}`
1898
+ );
1899
+ lines.push("");
1900
+ if (mine > theirs) {
1901
+ lines.push(
1902
+ chalk.white(` you took it. ${them} has been notified. (kidding.)`)
1903
+ );
1904
+ } else if (mine < theirs) {
1905
+ lines.push(
1906
+ chalk.white(
1907
+ ` ${theirs - mine} point${theirs - mine === 1 ? "" : "s"} behind. run it again next month \u2014 scores move.`
1908
+ )
1909
+ );
1910
+ } else {
1911
+ lines.push(chalk.white(` dead even. this demands a rematch.`));
1912
+ }
1913
+ } else {
1914
+ lines.push(chalk.white(` ${them} challenged you \u2014 challenge accepted.`));
1915
+ }
1916
+ lines.push("");
1917
+ return lines.join("\n");
1918
+ }
1919
+ function shareBlockContext(ctx) {
1920
+ return {
1921
+ view: ctx.view,
1922
+ challengeCode: ctx.challengeCode,
1923
+ shortUrl: ctx.shortUrl,
1924
+ versus: ctx.versus,
1925
+ previous: ctx.previous
1926
+ };
1927
+ }
1928
+ function xIntentUrl(block) {
1929
+ return `https://x.com/intent/post?text=${encodeURIComponent(block)}`;
1930
+ }
1931
+ function linkedInIntentUrl(block) {
1932
+ return `https://www.linkedin.com/feed/?shareActive=true&text=${encodeURIComponent(block)}`;
1933
+ }
1934
+ async function markShared(ctx) {
1935
+ if (ctx.wrappedId) {
1936
+ try {
1937
+ await markWrappedShared(ctx.wrappedId);
1938
+ } catch {
1939
+ }
1940
+ }
1941
+ }
1942
+ function waitForAction() {
1943
+ return new Promise((resolve) => {
1944
+ const stdin = process.stdin;
1945
+ stdin.setRawMode(true);
1946
+ stdin.resume();
1947
+ stdin.setEncoding("utf8");
1948
+ const onData = (data) => {
1949
+ stdin.setRawMode(false);
1950
+ stdin.pause();
1951
+ stdin.removeListener("data", onData);
1952
+ resolve(data);
1953
+ };
1954
+ stdin.on("data", onData);
1955
+ });
1956
+ }
1957
+ async function runEndgame(ctx) {
1958
+ const block = buildShareBlock(shareBlockContext(ctx));
1959
+ if (ctx.versus) {
1960
+ process.stdout.write(buildVersusCard(ctx.view, ctx.versus));
1961
+ }
1962
+ const framed = block.split("\n").map((l) => ` ${chalk.white(l)}`).join("\n");
1963
+ process.stdout.write(`
1964
+ ${framed}
1965
+
1966
+ `);
1967
+ const copied = copyToClipboard(block);
1968
+ if (copied) {
1969
+ process.stderr.write(
1970
+ chalk.hex(ACCENT)(" \u2713 copied to your clipboard \u2014 paste anywhere\n\n")
1971
+ );
1972
+ }
1973
+ if (!process.stdin.isTTY) {
1974
+ if (ctx.shareUrl) {
1975
+ process.stderr.write(
1976
+ ` your wrapped: ${ctx.shortUrl ?? ctx.shareUrl}
1977
+
1978
+ `
1979
+ );
1980
+ }
1981
+ return;
1982
+ }
1983
+ if (ctx.shortUrl) {
1984
+ const qr = qrForTerminal(`${ctx.shortUrl}?src=qr`);
1985
+ if (qr) {
1986
+ process.stdout.write(qr + "\n");
1987
+ process.stderr.write(chalk.dim(" scan to share from your phone\n\n"));
1988
+ }
1989
+ }
1990
+ const actions = [];
1991
+ if (ctx.shareUrl)
1992
+ actions.push(`${chalk.bold.white("[enter]")} open in browser`);
1993
+ actions.push(`${chalk.bold.white("[x]")} post to X`);
1994
+ actions.push(`${chalk.bold.white("[l]")} post to LinkedIn`);
1995
+ actions.push(`${chalk.bold.white("[q]")} done`);
1996
+ process.stderr.write(` ${actions.join(chalk.dim(" \xB7 "))}
1997
+ `);
1998
+ for (; ; ) {
1999
+ const key = await waitForAction();
2000
+ if (key === "" || key === "q" || key === "Q") {
2001
+ if (ctx.shortUrl) {
2002
+ process.stderr.write(`
2003
+ your wrapped: ${ctx.shortUrl}
2004
+
2005
+ `);
2006
+ }
2007
+ return;
2008
+ }
2009
+ if (key === "x" || key === "X" || key === "l" || key === "L") {
2010
+ const linkedin = key === "l" || key === "L";
2011
+ try {
2012
+ await openWrapped(
2013
+ linkedin ? linkedInIntentUrl(block) : xIntentUrl(block)
2014
+ );
2015
+ await markShared(ctx);
2016
+ process.stderr.write(
2017
+ chalk.dim(
2018
+ `
2019
+ opened ${linkedin ? "LinkedIn" : "X"} \u2014 your post is pre-filled
2020
+ `
2021
+ )
2022
+ );
2023
+ } catch {
2024
+ process.stderr.write(
2025
+ chalk.dim(
2026
+ "\n couldn't open a browser \u2014 the block is in your clipboard\n"
2027
+ )
2028
+ );
2029
+ }
2030
+ continue;
2031
+ }
2032
+ if ((key === "\r" || key === "\n") && ctx.shareUrl) {
2033
+ try {
2034
+ await openWrapped(ctx.shareUrl);
2035
+ await markShared(ctx);
2036
+ process.stderr.write(`
2037
+ opened: ${ctx.shareUrl}
2038
+
2039
+ `);
2040
+ } catch (err) {
2041
+ process.stderr.write(
2042
+ `
2043
+ couldn't open browser. open it manually: ${ctx.shareUrl}
2044
+ (${err instanceof Error ? err.message : err})
2045
+
2046
+ `
2047
+ );
2048
+ }
2049
+ return;
2050
+ }
2051
+ }
2052
+ }
2053
+
1611
2054
  // src/gather.ts
1612
2055
  import { execSync as execSync2 } from "child_process";
1613
2056
  import { existsSync as existsSync5, readFileSync as readFileSync5, statSync as statSync4 } from "fs";
@@ -1629,7 +2072,7 @@ import { createInterface } from "readline";
1629
2072
 
1630
2073
  // src/cursor.ts
1631
2074
  import { existsSync } from "fs";
1632
- import { homedir, platform } from "os";
2075
+ import { homedir, platform as platform2 } from "os";
1633
2076
  import { join } from "path";
1634
2077
 
1635
2078
  // src/redact.ts
@@ -1750,7 +2193,7 @@ var EXT_TO_LANG = {
1750
2193
  };
1751
2194
  function findCursorDb() {
1752
2195
  const home = homedir();
1753
- const os = platform();
2196
+ const os = platform2();
1754
2197
  const candidates = os === "darwin" ? [
1755
2198
  join(
1756
2199
  home,
@@ -3674,7 +4117,7 @@ import {
3674
4117
  rmSync,
3675
4118
  readFileSync as readFileSync4
3676
4119
  } from "fs";
3677
- import { homedir as homedir4, platform as platform2, tmpdir } from "os";
4120
+ import { homedir as homedir4, platform as platform3, tmpdir } from "os";
3678
4121
  import { join as join4 } from "path";
3679
4122
  import { spawn } from "child_process";
3680
4123
  var DEBUG_PORT_WAIT_MS = 1e4;
@@ -3684,7 +4127,7 @@ function wait(ms) {
3684
4127
  return new Promise((r) => setTimeout(r, ms));
3685
4128
  }
3686
4129
  function findChromeExecutable() {
3687
- const os = platform2();
4130
+ const os = platform3();
3688
4131
  const candidates = os === "darwin" ? [
3689
4132
  "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
3690
4133
  "/Applications/Google Chrome Beta.app/Contents/MacOS/Google Chrome Beta",
@@ -3706,7 +4149,7 @@ function findChromeExecutable() {
3706
4149
  return null;
3707
4150
  }
3708
4151
  function findChromeProfileRoot() {
3709
- const os = platform2();
4152
+ const os = platform3();
3710
4153
  const home = homedir4();
3711
4154
  const candidates = os === "darwin" ? [
3712
4155
  join4(home, "Library", "Application Support", "Google", "Chrome"),
@@ -3766,7 +4209,7 @@ async function waitForDebugPort(userDataDir, timeoutMs) {
3766
4209
  return null;
3767
4210
  }
3768
4211
  async function spawnChrome(executablePath, userDataDir) {
3769
- const os = platform2();
4212
+ const os = platform3();
3770
4213
  const args = [
3771
4214
  "--headless=new",
3772
4215
  `--user-data-dir=${userDataDir}`,
@@ -4828,7 +5271,7 @@ async function gather(options = {}) {
4828
5271
  }
4829
5272
 
4830
5273
  // src/heap.ts
4831
- import { spawnSync } from "child_process";
5274
+ import { spawnSync as spawnSync2 } from "child_process";
4832
5275
  import { totalmem } from "os";
4833
5276
  function ensureHeapHeadroom() {
4834
5277
  if (process.env.STANDOUT_HEAP_BOOSTED === "1") return;
@@ -4839,7 +5282,7 @@ function ensureHeapHeadroom() {
4839
5282
  if (desiredMb <= 4096) return;
4840
5283
  const entry = process.argv[1];
4841
5284
  if (!entry) return;
4842
- const res = spawnSync(
5285
+ const res = spawnSync2(
4843
5286
  process.execPath,
4844
5287
  [`--max-old-space-size=${desiredMb}`, entry, ...process.argv.slice(2)],
4845
5288
  {
@@ -5149,8 +5592,8 @@ The JSON should follow this structure:
5149
5592
  - If you receive a pause_turn stop reason, your turn will be continued automatically \u2014 just keep going.`;
5150
5593
 
5151
5594
  // src/schedule.ts
5152
- import chalk from "chalk";
5153
- import { spawnSync as spawnSync2 } from "node:child_process";
5595
+ import chalk2 from "chalk";
5596
+ import { spawnSync as spawnSync3 } from "node:child_process";
5154
5597
  import {
5155
5598
  existsSync as existsSync6,
5156
5599
  mkdirSync as mkdirSync2,
@@ -5163,7 +5606,7 @@ import { homedir as homedir6 } from "node:os";
5163
5606
  import { join as join6 } from "node:path";
5164
5607
  var LAUNCHD_LABEL = "work.standout.monthly";
5165
5608
  var CRON_MARKER = "# standout-monthly";
5166
- var ACCENT = "#ad5cff";
5609
+ var ACCENT2 = "#ad5cff";
5167
5610
  var SLUG_RE = /^[a-z0-9][a-z0-9_-]*$/i;
5168
5611
  var FLAG_ALLOWLIST = ["--local", "--no-upload", "--terminal"];
5169
5612
  function parseScheduleArgs(args) {
@@ -5282,7 +5725,7 @@ function writeRefreshStamp() {
5282
5725
  `);
5283
5726
  }
5284
5727
  function launchctl(args) {
5285
- const res = spawnSync2("launchctl", args, { encoding: "utf8" });
5728
+ const res = spawnSync3("launchctl", args, { encoding: "utf8" });
5286
5729
  return {
5287
5730
  status: res.status,
5288
5731
  stdout: res.stdout ?? "",
@@ -5293,11 +5736,11 @@ function uid() {
5293
5736
  return process.getuid?.() ?? 0;
5294
5737
  }
5295
5738
  function readCrontab() {
5296
- const res = spawnSync2("crontab", ["-l"], { encoding: "utf8" });
5739
+ const res = spawnSync3("crontab", ["-l"], { encoding: "utf8" });
5297
5740
  return res.status === 0 ? res.stdout ?? "" : "";
5298
5741
  }
5299
5742
  function writeCrontab(content) {
5300
- const res = spawnSync2("crontab", ["-"], {
5743
+ const res = spawnSync3("crontab", ["-"], {
5301
5744
  input: content,
5302
5745
  encoding: "utf8"
5303
5746
  });
@@ -5352,10 +5795,10 @@ async function installSchedule(slug, flags) {
5352
5795
  installJob(command);
5353
5796
  process.stderr.write(
5354
5797
  `
5355
- ${chalk.hex(ACCENT)("\u2713")} ${chalk.white("monthly refresh scheduled")} ${chalk.dim("(first awake hour of each month)")}
5356
- ` + chalk.dim(` runs: ${command}
5357
- `) + chalk.dim(` log: ${schedLogPath()}
5358
- `) + chalk.dim(" disable anytime with `npx standout schedule off`\n\n")
5798
+ ${chalk2.hex(ACCENT2)("\u2713")} ${chalk2.white("monthly refresh scheduled")} ${chalk2.dim("(first awake hour of each month)")}
5799
+ ` + chalk2.dim(` runs: ${command}
5800
+ `) + chalk2.dim(` log: ${schedLogPath()}
5801
+ `) + chalk2.dim(" disable anytime with `npx standout schedule off`\n\n")
5359
5802
  );
5360
5803
  }
5361
5804
  async function removeSchedule() {
@@ -5383,11 +5826,11 @@ async function removeSchedule() {
5383
5826
  }
5384
5827
  process.stderr.write(
5385
5828
  removed ? `
5386
- ${chalk.hex(ACCENT)("\u2713")} ${chalk.white("monthly refresh disabled")}
5387
- ` + chalk.dim(
5829
+ ${chalk2.hex(ACCENT2)("\u2713")} ${chalk2.white("monthly refresh disabled")}
5830
+ ` + chalk2.dim(
5388
5831
  " it won't be scheduled again \u2014 re-enable with `npx standout schedule`\n\n"
5389
5832
  ) : `
5390
- ${chalk.dim("no monthly schedule installed \u2014 future runs won't add one (re-enable with `npx standout schedule`)")}
5833
+ ${chalk2.dim("no monthly schedule installed \u2014 future runs won't add one (re-enable with `npx standout schedule`)")}
5391
5834
 
5392
5835
  `
5393
5836
  );
@@ -5403,17 +5846,17 @@ async function scheduleStatus() {
5403
5846
  if (!shell) {
5404
5847
  process.stderr.write(
5405
5848
  `
5406
- ${chalk.white("no monthly schedule installed")}` + (isOptedOut() ? chalk.dim(" (opted out)") : "") + "\n" + chalk.dim(" enable with `npx standout schedule`\n\n")
5849
+ ${chalk2.white("no monthly schedule installed")}` + (isOptedOut() ? chalk2.dim(" (opted out)") : "") + "\n" + chalk2.dim(" enable with `npx standout schedule`\n\n")
5407
5850
  );
5408
5851
  return;
5409
5852
  }
5410
5853
  const stamp = readRefreshStamp();
5411
5854
  process.stderr.write(
5412
5855
  `
5413
- ${chalk.hex(ACCENT)("\u2713")} ${chalk.white("monthly refresh is on")} ${chalk.dim("(first awake hour of each month)")}
5414
- ` + chalk.dim(` runs: ${extractRunCommand(shell) ?? shell}
5415
- `) + chalk.dim(` log: ${schedLogPath()}
5416
- `) + chalk.dim(` last refreshed month: ${stamp ?? "never"}
5856
+ ${chalk2.hex(ACCENT2)("\u2713")} ${chalk2.white("monthly refresh is on")} ${chalk2.dim("(first awake hour of each month)")}
5857
+ ` + chalk2.dim(` runs: ${extractRunCommand(shell) ?? shell}
5858
+ `) + chalk2.dim(` log: ${schedLogPath()}
5859
+ `) + chalk2.dim(` last refreshed month: ${stamp ?? "never"}
5417
5860
  `)
5418
5861
  );
5419
5862
  if (process.platform === "darwin") {
@@ -5421,12 +5864,12 @@ async function scheduleStatus() {
5421
5864
  const exitLine = res.stdout.split("\n").find((l) => l.includes("last exit code"));
5422
5865
  if (res.status !== 0) {
5423
5866
  process.stderr.write(
5424
- chalk.dim(
5867
+ chalk2.dim(
5425
5868
  " warning: job not loaded in launchd \u2014 re-run `npx standout schedule`\n"
5426
5869
  )
5427
5870
  );
5428
5871
  } else if (exitLine) {
5429
- process.stderr.write(chalk.dim(` ${exitLine.trim()}
5872
+ process.stderr.write(chalk2.dim(` ${exitLine.trim()}
5430
5873
  `));
5431
5874
  }
5432
5875
  }
@@ -5434,9 +5877,9 @@ async function scheduleStatus() {
5434
5877
  const mtime = statSync5(schedLogPath()).mtime;
5435
5878
  const tail = readFileSync6(schedLogPath(), "utf8").trimEnd().split("\n").slice(-10);
5436
5879
  process.stderr.write(
5437
- chalk.dim(` last log activity: ${mtime.toLocaleString()}
5880
+ chalk2.dim(` last log activity: ${mtime.toLocaleString()}
5438
5881
 
5439
- `) + tail.map((l) => chalk.dim(` \u2502 ${l}
5882
+ `) + tail.map((l) => chalk2.dim(` \u2502 ${l}
5440
5883
  `)).join("")
5441
5884
  );
5442
5885
  }
@@ -5445,10 +5888,10 @@ async function scheduleStatus() {
5445
5888
  function autoRefreshNotice(headline) {
5446
5889
  const optOut = "npx standout schedule off";
5447
5890
  return `
5448
- ${chalk.hex(ACCENT)("\u27F3")} ${chalk.bold.white(headline)}
5449
- ${chalk.white("standout re-runs once a month so your wrapped keeps building")}
5450
- ${chalk.white("(because local logs only keep ~30 days of history).")}
5451
- ${chalk.white("opt out anytime:")} ${chalk.hex(ACCENT)(optOut)}
5891
+ ${chalk2.hex(ACCENT2)("\u27F3")} ${chalk2.bold.white(headline)}
5892
+ ${chalk2.white("standout re-runs once a month so your wrapped keeps building")}
5893
+ ${chalk2.white("(because local logs only keep ~30 days of history).")}
5894
+ ${chalk2.white("opt out anytime:")} ${chalk2.hex(ACCENT2)(optOut)}
5452
5895
 
5453
5896
  `;
5454
5897
  }
@@ -5466,7 +5909,7 @@ async function maybeAutoInstallSchedule(slug) {
5466
5909
  process.stderr.write(autoRefreshNotice("auto-refresh scheduled"));
5467
5910
  } catch (error) {
5468
5911
  process.stderr.write(
5469
- chalk.dim(
5912
+ chalk2.dim(
5470
5913
  ` (couldn't schedule the monthly refresh: ${error instanceof Error ? error.message : String(error)})
5471
5914
 
5472
5915
  `
@@ -6345,7 +6788,7 @@ function computeConversation(aiUsage, line, themes) {
6345
6788
 
6346
6789
  // src/wrapped/render.ts
6347
6790
  import boxen from "boxen";
6348
- import chalk2 from "chalk";
6791
+ import chalk3 from "chalk";
6349
6792
  import gradient from "gradient-string";
6350
6793
 
6351
6794
  // src/wrapped/chrono-critters.ts
@@ -6411,76 +6854,6 @@ var MASCOTS = {
6411
6854
  / | \\ \u25BC`
6412
6855
  };
6413
6856
 
6414
- // src/wrapped/tiers.ts
6415
- var UNICORN2 = ` ,.. /
6416
- ,' ';
6417
- ,,.__ _,' /'; .
6418
- :',' ~~~~ '. '~
6419
- ' ( ) )::,
6420
- '. '..=----=..-~ .;'
6421
- ' ;' :: ':. '"
6422
- (: ': ;)
6423
- \\\\ '" ./
6424
- '" '"`;
6425
- var ROCKETSHIP2 = ` .
6426
- .'.
6427
- |o|
6428
- .'o'.
6429
- |.-.|
6430
- ' '
6431
- ( )
6432
- )
6433
- ( )`;
6434
- var WIZARD2 = ` (\\. \\ ,/)
6435
- \\( |\\ )/
6436
- //\\ | \\ /\\\\
6437
- (/ /\\_#oo#_/\\ \\)
6438
- \\/\\ #### /\\/
6439
- \`##'`;
6440
- var RISING_STAR2 = ` .
6441
- ,O,
6442
- ,OOO,
6443
- 'oooooOOOOOooooo'
6444
- \`OOOOOOOOOOO\`
6445
- \`OOOOOOO\`
6446
- OOOO'OOOO
6447
- OOO' 'OOO
6448
- O' 'O`;
6449
- var CURIOUS_CAT2 = ` |\\__/,| (\`\\
6450
- |_ _ |.--.) )
6451
- ( T ) /
6452
- (((^_(((/(((_/`;
6453
- var GINGERBREAD2 = ` ,--.
6454
- _(*_*)_
6455
- (_ o _)
6456
- / o \\
6457
- (_/ \\_)`;
6458
- var TIERS2 = [
6459
- {
6460
- key: "still_figuring",
6461
- label: "STILL FIGURING IT OUT",
6462
- min: 1,
6463
- art: GINGERBREAD2
6464
- },
6465
- { key: "curious_cat", label: "CURIOUS CAT", min: 35, art: CURIOUS_CAT2 },
6466
- { key: "rising_star", label: "RISING STAR", min: 60, art: RISING_STAR2 },
6467
- { key: "prompt_wizard", label: "PROMPT WIZARD", min: 77, art: WIZARD2 },
6468
- {
6469
- key: "escape_velocity",
6470
- label: "ESCAPE VELOCITY",
6471
- min: 86,
6472
- art: ROCKETSHIP2
6473
- },
6474
- { key: "unicorn", label: "UNICORN", min: 95, art: UNICORN2 }
6475
- ];
6476
- function tierForScore2(score) {
6477
- const s = Number.isFinite(score) ? score : 0;
6478
- for (let i = TIERS2.length - 1; i >= 0; i--) {
6479
- if (s >= TIERS2[i].min) return TIERS2[i];
6480
- }
6481
- return TIERS2[0];
6482
- }
6483
-
6484
6857
  // src/wrapped/render.ts
6485
6858
  var BOX_WIDTH = 56;
6486
6859
  var SPARK_BARS = ["\u2581", "\u2582", "\u2583", "\u2584", "\u2585", "\u2586", "\u2587", "\u2588"];
@@ -6522,8 +6895,8 @@ function hasHistogramData(view) {
6522
6895
  return view.hour_histogram.some((v) => v > 0);
6523
6896
  }
6524
6897
  function divider(label) {
6525
- return chalk2.dim(`
6526
- ${label.padEnd(48, " ")} ${chalk2.dim("[press \u21B5]")}
6898
+ return chalk3.dim(`
6899
+ ${label.padEnd(48, " ")} ${chalk3.dim("[press \u21B5]")}
6527
6900
  `);
6528
6901
  }
6529
6902
  function wrapWords(text, width) {
@@ -6561,7 +6934,7 @@ function centerBlock(art, color) {
6561
6934
  function bar2(value, max, width) {
6562
6935
  if (max === 0) return " ".repeat(width);
6563
6936
  const filled = Math.round(value / max * width);
6564
- return chalk2.hex("#ff8a00")("\u2588".repeat(filled)) + chalk2.gray("\u2591".repeat(width - filled));
6937
+ return chalk3.hex("#ff8a00")("\u2588".repeat(filled)) + chalk3.gray("\u2591".repeat(width - filled));
6565
6938
  }
6566
6939
  function compactNum(n) {
6567
6940
  const sign = n < 0 ? "-" : "";
@@ -6571,14 +6944,14 @@ function compactNum(n) {
6571
6944
  return `${sign}${abs}`;
6572
6945
  }
6573
6946
  function coloredBar(value, max, width, hex) {
6574
- if (max <= 0) return chalk2.gray("\u2591".repeat(width));
6947
+ if (max <= 0) return chalk3.gray("\u2591".repeat(width));
6575
6948
  const filled = Math.max(
6576
6949
  0,
6577
6950
  Math.min(width, Math.round(value / max * width))
6578
6951
  );
6579
- return chalk2.hex(hex)("\u2588".repeat(filled)) + chalk2.gray("\u2591".repeat(width - filled));
6952
+ return chalk3.hex(hex)("\u2588".repeat(filled)) + chalk3.gray("\u2591".repeat(width - filled));
6580
6953
  }
6581
- function sparkline2(buckets) {
6954
+ function sparkline3(buckets) {
6582
6955
  if (!buckets.length) return "";
6583
6956
  const max = Math.max(...buckets, 1);
6584
6957
  return buckets.map(
@@ -6589,7 +6962,7 @@ function sparkline2(buckets) {
6589
6962
  ).join("");
6590
6963
  }
6591
6964
  function hourlyChart(buckets, critter = null) {
6592
- const spark = sparkline2(buckets);
6965
+ const spark = sparkline3(buckets);
6593
6966
  const width = 24;
6594
6967
  const axis = new Array(width).fill(" ");
6595
6968
  for (const label of [
@@ -6604,8 +6977,8 @@ function hourlyChart(buckets, critter = null) {
6604
6977
  }
6605
6978
  }
6606
6979
  const left = [
6607
- chalk2.hex("#ad5cff")(spark.padEnd(width, " ")),
6608
- chalk2.dim(axis.join(""))
6980
+ chalk3.hex("#ad5cff")(spark.padEnd(width, " ")),
6981
+ chalk3.dim(axis.join(""))
6609
6982
  ];
6610
6983
  if (!critter) return left.map((l) => ` ${l}`);
6611
6984
  const critterLines = critter.art.split("\n");
@@ -6647,12 +7020,12 @@ function card1Open(view) {
6647
7020
  const verdict = perDay >= 6 ? "that's a second full-time job. 996 who?" : perDay >= 3 ? "basically a part-time gig with the machines." : perDay >= 1 ? "a daily habit at this point." : "just getting warmed up.";
6648
7021
  const bench = benchmarkInline(view, view.rank_summary.hours_percentile);
6649
7022
  const lines = [
6650
- chalk2.dim("YOU MANAGED"),
7023
+ chalk3.dim("YOU MANAGED"),
6651
7024
  "",
6652
7025
  bigNumber(` ${hours} session-hours`) + (bench ? ` ${bench}` : ""),
6653
7026
  "",
6654
- chalk2.white(` ${verdict}`),
6655
- chalk2.dim(" across parallel agent sessions, last 30 days")
7027
+ chalk3.white(` ${verdict}`),
7028
+ chalk3.dim(" across parallel agent sessions, last 30 days")
6656
7029
  ].join("\n");
6657
7030
  return box(lines, { borderColor: "yellow" });
6658
7031
  }
@@ -6662,7 +7035,7 @@ function cardAllTime(view) {
6662
7035
  const max = Math.max(...months.map((m) => m.duration_hours), 1);
6663
7036
  const rows = months.map((m) => {
6664
7037
  const label = monthYearShort(m.month).padEnd(6);
6665
- return ` ${chalk2.dim(label)} ${bar2(m.duration_hours, max, 20)} ${chalk2.dim(`${Math.round(m.duration_hours)}h`)}`;
7038
+ return ` ${chalk3.dim(label)} ${bar2(m.duration_hours, max, 20)} ${chalk3.dim(`${Math.round(m.duration_hours)}h`)}`;
6666
7039
  });
6667
7040
  const since = view.all_time.first_session ? new Date(view.all_time.first_session).toISOString().slice(0, 7) : "your first local log";
6668
7041
  const latest = months[months.length - 1];
@@ -6672,14 +7045,14 @@ function cardAllTime(view) {
6672
7045
  )[0];
6673
7046
  const trend = latest && prior && prior.duration_hours > 0 ? `${monthShort(latest.month)}: ${latest.duration_hours >= prior.duration_hours ? "+" : ""}${Math.round((latest.duration_hours - prior.duration_hours) / prior.duration_hours * 100)}% vs previous month` : latest && prior && latest.duration_hours > 0 ? `${monthShort(latest.month)}: active after a quiet month` : null;
6674
7047
  const lines = [
6675
- chalk2.dim("YOUR AI CODING YEAR"),
7048
+ chalk3.dim("YOUR AI CODING YEAR"),
6676
7049
  "",
6677
7050
  ` ${bigNumber(`~${Math.round(view.all_time.total_hours).toLocaleString()} hours`)} from local logs`,
6678
- ` ${chalk2.white(view.all_time.total_sessions.toLocaleString())} sessions detected since ${since}`,
6679
- ...trend ? [` ${chalk2.dim(trend)}`] : [],
7051
+ ` ${chalk3.white(view.all_time.total_sessions.toLocaleString())} sessions detected since ${since}`,
7052
+ ...trend ? [` ${chalk3.dim(trend)}`] : [],
6680
7053
  "",
6681
7054
  ...rows,
6682
- best ? ` ${chalk2.dim(`best local-log month: ${monthShort(best.month)} \xB7 ~${Math.round(best.duration_hours)}h`)}` : ""
7055
+ best ? ` ${chalk3.dim(`best local-log month: ${monthShort(best.month)} \xB7 ~${Math.round(best.duration_hours)}h`)}` : ""
6683
7056
  ].join("\n");
6684
7057
  return box(lines, { borderColor: "cyan" });
6685
7058
  }
@@ -6698,25 +7071,25 @@ function cardRhythm(view) {
6698
7071
  const isNightOwl = critter?.key === "night_owl";
6699
7072
  const subhead = isNightOwl ? "while the 9-5ers sleep, you ship." : weekendPct < 10 ? "locked in on weekdays, weekends are yours." : weekendPct >= 35 ? "weekends are just more reps for you." : peak !== null && peak < 9 ? "up before standup. menace." : "you keep your own hours.";
6700
7073
  const lines = [
6701
- chalk2.dim("WHEN YOU CODE"),
7074
+ chalk3.dim("WHEN YOU CODE"),
6702
7075
  "",
6703
7076
  ...hourlyChart(
6704
7077
  view.hour_histogram,
6705
- critter ? { art: critter.art, color: chalk2.magenta } : null
7078
+ critter ? { art: critter.art, color: chalk3.magenta } : null
6706
7079
  ),
6707
7080
  "",
6708
- ` ${chalk2.white(caption)}`,
7081
+ ` ${chalk3.white(caption)}`,
6709
7082
  "",
6710
- ` ${chalk2.white("weekdays".padEnd(9))} ${bar2(weekdayPct, 100, 20)} ${chalk2.dim(weekdayPct + "%")}`,
6711
- ` ${chalk2.white("weekends".padEnd(9))} ${bar2(weekendPct, 100, 20)} ${chalk2.dim(weekendPct + "%")}`,
7083
+ ` ${chalk3.white("weekdays".padEnd(9))} ${bar2(weekdayPct, 100, 20)} ${chalk3.dim(weekdayPct + "%")}`,
7084
+ ` ${chalk3.white("weekends".padEnd(9))} ${bar2(weekendPct, 100, 20)} ${chalk3.dim(weekendPct + "%")}`,
6712
7085
  ...weekendBench ? ["", ` ${weekendBench}`] : [],
6713
7086
  ""
6714
7087
  ];
6715
7088
  if (view.rhythm_comment) {
6716
7089
  for (const l of wrapWords(view.rhythm_comment, 47))
6717
- lines.push(chalk2.italic.white(" " + l));
7090
+ lines.push(chalk3.italic.white(" " + l));
6718
7091
  } else {
6719
- lines.push(chalk2.dim(" " + subhead));
7092
+ lines.push(chalk3.dim(" " + subhead));
6720
7093
  }
6721
7094
  return box(lines.join("\n"), { borderColor });
6722
7095
  }
@@ -6729,10 +7102,10 @@ function cardProjects(view) {
6729
7102
  if (!usageReady(view)) return "";
6730
7103
  const projects = view.top_projects.filter((p) => p.commits > 0 || p.sessions > 0).slice(0, 3);
6731
7104
  if (projects.length === 0) return "";
6732
- const lines = [chalk2.dim("YOUR TOP PROJECTS"), ""];
7105
+ const lines = [chalk3.dim("YOUR TOP PROJECTS"), ""];
6733
7106
  const c = view.contributions;
6734
7107
  if (c && c.one_liner) {
6735
- for (const l of wrapWords(c.one_liner, 50)) lines.push(chalk2.dim(l));
7108
+ for (const l of wrapWords(c.one_liner, 50)) lines.push(chalk3.dim(l));
6736
7109
  lines.push("");
6737
7110
  }
6738
7111
  projects.forEach((p, i) => {
@@ -6742,14 +7115,14 @@ function cardProjects(view) {
6742
7115
  lines.push(` ${bigNumber(`\u25B8 ${name}`)} ${TITLE_GRADIENT(count)}`);
6743
7116
  if (p.blurb)
6744
7117
  for (const l of wrapWords(p.blurb, 44))
6745
- lines.push(` ${chalk2.white(l)}`);
7118
+ lines.push(` ${chalk3.white(l)}`);
6746
7119
  } else {
6747
7120
  const namePart = `\u25B8 ${name}`;
6748
7121
  const pad = " ".repeat(Math.max(2, 24 - namePart.length));
6749
- lines.push(` ${chalk2.white(namePart)}${pad}${chalk2.dim(count)}`);
7122
+ lines.push(` ${chalk3.white(namePart)}${pad}${chalk3.dim(count)}`);
6750
7123
  if (p.blurb)
6751
7124
  for (const l of wrapWords(p.blurb, 44))
6752
- lines.push(` ${chalk2.dim(l)}`);
7125
+ lines.push(` ${chalk3.dim(l)}`);
6753
7126
  }
6754
7127
  lines.push("");
6755
7128
  });
@@ -6765,17 +7138,17 @@ function card7AINative(view) {
6765
7138
  );
6766
7139
  const streak = view.streak_days;
6767
7140
  const lines = [
6768
- chalk2.dim("YOU'RE AI-NATIVE"),
7141
+ chalk3.dim("YOU'RE AI-NATIVE"),
6769
7142
  "",
6770
- ` commits since 2024: ${chalk2.white(view.total_commits.toLocaleString())}`,
6771
- ` AI co-authored: ${chalk2.white(view.ai_assisted_commits.toLocaleString())}`,
7143
+ ` commits since 2024: ${chalk3.white(view.total_commits.toLocaleString())}`,
7144
+ ` AI co-authored: ${chalk3.white(view.ai_assisted_commits.toLocaleString())}`,
6772
7145
  "",
6773
- ` ${bar2(pct, 100, 22)} ${chalk2.white(pct + "%")}${bench ? ` ${bench}` : ""}`,
7146
+ ` ${bar2(pct, 100, 22)} ${chalk3.white(pct + "%")}${bench ? ` ${bench}` : ""}`,
6774
7147
  ...streak >= 2 ? [
6775
- ` ${chalk2.white(`${streak}-day streak`)}${chalk2.dim(", coding without missing a day.")}`
7148
+ ` ${chalk3.white(`${streak}-day streak`)}${chalk3.dim(", coding without missing a day.")}`
6776
7149
  ] : [],
6777
7150
  "",
6778
- chalk2.dim(subhead)
7151
+ chalk3.dim(subhead)
6779
7152
  ].join("\n");
6780
7153
  return box(lines, { borderColor: "yellow" });
6781
7154
  }
@@ -6788,7 +7161,7 @@ function benchmarkInline(view, percentile) {
6788
7161
  const top = topPercentNumber(percentile);
6789
7162
  if (top === null) return "";
6790
7163
  const pct = `${top}%`;
6791
- return top < 10 ? chalk2.dim("(top ") + TITLE_GRADIENT(pct) + chalk2.dim(" of users)") : chalk2.dim(`(top ${pct} of users)`);
7164
+ return top < 10 ? chalk3.dim("(top ") + TITLE_GRADIENT(pct) + chalk3.dim(" of users)") : chalk3.dim(`(top ${pct} of users)`);
6792
7165
  }
6793
7166
  function formatTokens(n) {
6794
7167
  if (n >= 1e9) return (n / 1e9).toFixed(1) + "B";
@@ -6808,24 +7181,24 @@ function cardTokens(view) {
6808
7181
  const max = Math.max(...t.by_tool.map((x) => x.tokens), 1);
6809
7182
  const toolRows = t.by_tool.length > 0 ? t.by_tool.slice(0, 3).map((x) => {
6810
7183
  const padTool = x.tool.padEnd(13, " ");
6811
- return ` ${chalk2.white(padTool)} ${bar2(x.tokens, max, 16)} ${chalk2.dim(formatTokens(x.tokens))}`;
6812
- }).join("\n") : chalk2.dim(" (no tool breakdown available)");
6813
- const deltaLine = t.multiplier_vs_prior !== null && t.multiplier_vs_prior >= 1.05 ? chalk2.hex("#ff8a00")(
7184
+ return ` ${chalk3.white(padTool)} ${bar2(x.tokens, max, 16)} ${chalk3.dim(formatTokens(x.tokens))}`;
7185
+ }).join("\n") : chalk3.dim(" (no tool breakdown available)");
7186
+ const deltaLine = t.multiplier_vs_prior !== null && t.multiplier_vs_prior >= 1.05 ? chalk3.hex("#ff8a00")(
6814
7187
  ` \u2191 ${t.multiplier_vs_prior.toFixed(1)}\xD7 vs last period`
6815
- ) : t.multiplier_vs_prior !== null && t.multiplier_vs_prior < 0.95 ? chalk2.dim(
7188
+ ) : t.multiplier_vs_prior !== null && t.multiplier_vs_prior < 0.95 ? chalk3.dim(
6816
7189
  ` \u2193 ${(1 / t.multiplier_vs_prior).toFixed(1)}\xD7 less than last period`
6817
- ) : t.total_prior_30d > 0 ? chalk2.dim(` \u2248 same as last period`) : chalk2.dim(` rolling 30-day window`);
7190
+ ) : t.total_prior_30d > 0 ? chalk3.dim(` \u2248 same as last period`) : chalk3.dim(` rolling 30-day window`);
6818
7191
  const cost = t.estimated_retail_cost_usd;
6819
- const costLine = cost > 0 ? ` ${chalk2.dim("would have cost")} ${TITLE_GRADIENT(`~$${cost.toLocaleString()}`)} ${chalk2.dim("at retail API rates")}` : "";
6820
- const cursorNote = t.cursor_estimated ? t.cursor_token_share >= 0.9 ? chalk2.dim(
7192
+ const costLine = cost > 0 ? ` ${chalk3.dim("would have cost")} ${TITLE_GRADIENT(`~$${cost.toLocaleString()}`)} ${chalk3.dim("at retail API rates")}` : "";
7193
+ const cursorNote = t.cursor_estimated ? t.cursor_token_share >= 0.9 ? chalk3.dim(
6821
7194
  " \u2248 estimated from time spent in Cursor (no local token data)"
6822
- ) : chalk2.dim(
7195
+ ) : chalk3.dim(
6823
7196
  " includes Cursor (tokens + cost estimated from active time)"
6824
7197
  ) : "";
6825
- const cachedNote = t.cache_tokens > t.work_tokens ? chalk2.dim(" thankfully, most of them were cached :)") : t.cache_tokens > 0 ? chalk2.dim(" (includes cached context, re-read each turn)") : "";
6826
- const generatedLine = t.work_tokens > 0 ? ` ${chalk2.white(formatTokens(t.work_tokens))} ${chalk2.dim("were actually generated fresh")}` : "";
7198
+ const cachedNote = t.cache_tokens > t.work_tokens ? chalk3.dim(" thankfully, most of them were cached :)") : t.cache_tokens > 0 ? chalk3.dim(" (includes cached context, re-read each turn)") : "";
7199
+ const generatedLine = t.work_tokens > 0 ? ` ${chalk3.white(formatTokens(t.work_tokens))} ${chalk3.dim("were actually generated fresh")}` : "";
6827
7200
  const lines = [
6828
- chalk2.dim("YOU BURNED THIS MANY TOKENS"),
7201
+ chalk3.dim("YOU BURNED THIS MANY TOKENS"),
6829
7202
  "",
6830
7203
  ` ${totalLine}${tokensBench ? ` ${tokensBench}` : ""}`,
6831
7204
  "",
@@ -6847,23 +7220,23 @@ function cardToolRelationship(view) {
6847
7220
  if (r.kind === "insufficient") {
6848
7221
  return "";
6849
7222
  }
6850
- const streakLine = view.streak_days >= 2 ? ` ${chalk2.white(`${view.streak_days}-day streak, coding without missing a day.`)}` : null;
7223
+ const streakLine = view.streak_days >= 2 ? ` ${chalk3.white(`${view.streak_days}-day streak, coding without missing a day.`)}` : null;
6851
7224
  if (r.kind === "switch") {
6852
7225
  const rows = r.timeline.slice(-6).map((t) => {
6853
7226
  const monthShort2 = t.month.slice(2).replace("-", "/");
6854
7227
  const filled = Math.round(t.share * 10);
6855
- const bar3 = chalk2.hex("#ff8a00")("\u2588".repeat(filled)) + chalk2.gray("\u2591".repeat(10 - filled));
6856
- const label = t.dominant === r.from_tool ? chalk2.dim(t.dominant) : chalk2.white(t.dominant);
6857
- return ` ${chalk2.dim(monthShort2)} ${bar3} ${label}`;
7228
+ const bar3 = chalk3.hex("#ff8a00")("\u2588".repeat(filled)) + chalk3.gray("\u2591".repeat(10 - filled));
7229
+ const label = t.dominant === r.from_tool ? chalk3.dim(t.dominant) : chalk3.white(t.dominant);
7230
+ return ` ${chalk3.dim(monthShort2)} ${bar3} ${label}`;
6858
7231
  });
6859
7232
  return box(
6860
7233
  [
6861
- chalk2.dim("YOU SWITCHED TOOLS"),
7234
+ chalk3.dim("YOU SWITCHED TOOLS"),
6862
7235
  "",
6863
7236
  ...rows,
6864
7237
  "",
6865
- chalk2.dim(` joined the "${r.from_tool} \u2192 ${r.to_tool}" club`),
6866
- chalk2.dim(` in ${r.switch_month}.`),
7238
+ chalk3.dim(` joined the "${r.from_tool} \u2192 ${r.to_tool}" club`),
7239
+ chalk3.dim(` in ${r.switch_month}.`),
6867
7240
  ...streakLine ? ["", streakLine] : []
6868
7241
  ].join("\n"),
6869
7242
  { borderColor: "cyan" }
@@ -6872,14 +7245,14 @@ function cardToolRelationship(view) {
6872
7245
  if (r.kind === "loyalist") {
6873
7246
  return box(
6874
7247
  [
6875
- chalk2.dim("YOU'RE A LOYALIST"),
7248
+ chalk3.dim("YOU'RE A LOYALIST"),
6876
7249
  "",
6877
7250
  ` ${bigNumber(r.tool.toUpperCase())}`,
6878
7251
  "",
6879
- chalk2.dim(
7252
+ chalk3.dim(
6880
7253
  ` ${r.sessions_count} sessions across ${r.months_count} month${r.months_count === 1 ? "" : "s"}.`
6881
7254
  ),
6882
- chalk2.dim(" no second-guessing. you knew what you wanted."),
7255
+ chalk3.dim(" no second-guessing. you knew what you wanted."),
6883
7256
  ...streakLine ? ["", streakLine] : []
6884
7257
  ].join("\n"),
6885
7258
  { borderColor: "cyan" }
@@ -6888,16 +7261,16 @@ function cardToolRelationship(view) {
6888
7261
  if (r.kind === "polyglot") {
6889
7262
  const rows = r.tools.slice(0, 4).map((t) => {
6890
7263
  const filled = Math.round(t.share * 22);
6891
- const bar3 = chalk2.hex("#ff8a00")("\u2588".repeat(filled)) + chalk2.gray("\u2591".repeat(22 - filled));
6892
- return ` ${chalk2.white(t.tool.padEnd(12, " "))} ${bar3} ${chalk2.dim(Math.round(t.share * 100) + "%")}`;
7264
+ const bar3 = chalk3.hex("#ff8a00")("\u2588".repeat(filled)) + chalk3.gray("\u2591".repeat(22 - filled));
7265
+ return ` ${chalk3.white(t.tool.padEnd(12, " "))} ${bar3} ${chalk3.dim(Math.round(t.share * 100) + "%")}`;
6893
7266
  });
6894
7267
  return box(
6895
7268
  [
6896
- chalk2.dim("YOU'RE A POLYGLOT"),
7269
+ chalk3.dim("YOU'RE A POLYGLOT"),
6897
7270
  "",
6898
7271
  ...rows,
6899
7272
  "",
6900
- chalk2.dim(" you don't pick favorites. respect."),
7273
+ chalk3.dim(" you don't pick favorites. respect."),
6901
7274
  ...streakLine ? ["", streakLine] : []
6902
7275
  ].join("\n"),
6903
7276
  { borderColor: "cyan" }
@@ -6959,17 +7332,17 @@ function cardModelsStack(view) {
6959
7332
  const column = (mm) => {
6960
7333
  if (!mm) return [];
6961
7334
  const c = modelProviderColor(mm.prov);
6962
- const hex = (s) => chalk2.hex(c)(s);
7335
+ const hex = (s) => chalk3.hex(c)(s);
6963
7336
  const cap = " " + hex("\u256D" + "\u2500".repeat(8) + "\u256E") + " ";
6964
7337
  const base = " " + hex("\u2570" + "\u2500".repeat(8) + "\u256F") + " ";
6965
7338
  const side = " " + hex("\u2502") + " ".repeat(8) + hex("\u2502") + " ";
6966
- const num3 = " " + hex("\u2502") + chalk2.bold.white(center("#" + mm.rank, 8)) + hex("\u2502") + " ";
7339
+ const num3 = " " + hex("\u2502") + chalk3.bold.white(center("#" + mm.rank, 8)) + hex("\u2502") + " ";
6967
7340
  const h = heights[mm.rank];
6968
7341
  const mid = Math.floor((h - 1) / 2);
6969
7342
  const body = [];
6970
7343
  for (let i = 0; i < h; i++) body.push(i === mid ? num3 : side);
6971
- const label = mm.rank === 1 ? bigNumber(center(mm.name)) : chalk2.white(center(mm.name));
6972
- return [label, chalk2.dim(center(mm.pct + "%")), cap, ...body, base];
7344
+ const label = mm.rank === 1 ? bigNumber(center(mm.name)) : chalk3.white(center(mm.name));
7345
+ return [label, chalk3.dim(center(mm.pct + "%")), cap, ...body, base];
6973
7346
  };
6974
7347
  const cols = [column(second), column(first), column(third)];
6975
7348
  const maxH = Math.max(...cols.map((col) => col.length));
@@ -6977,20 +7350,20 @@ function cardModelsStack(view) {
6977
7350
  (col) => Array(maxH - col.length).fill(blankCol).concat(col)
6978
7351
  );
6979
7352
  const header = ranked.length === 1 ? "YOUR MODEL & STACK" : "YOUR MODELS & STACK";
6980
- const lines = [chalk2.dim(header), ""];
7353
+ const lines = [chalk3.dim(header), ""];
6981
7354
  lines.push(
6982
- " " + [blankCol, chalk2.hex("#ffd700")(center("\u265B")), blankCol].join(" ")
7355
+ " " + [blankCol, chalk3.hex("#ffd700")(center("\u265B")), blankCol].join(" ")
6983
7356
  );
6984
7357
  for (let r = 0; r < maxH; r++)
6985
7358
  lines.push(" " + [padded[0][r], padded[1][r], padded[2][r]].join(" "));
6986
7359
  lines.push("");
6987
7360
  lines.push(
6988
- ` top pick: ${chalk2.white(first.name)} ${chalk2.dim(`\u2014 ${first.pct}% of sessions`)}`
7361
+ ` top pick: ${chalk3.white(first.name)} ${chalk3.dim(`\u2014 ${first.pct}% of sessions`)}`
6989
7362
  );
6990
7363
  if (view.stack_comment) {
6991
7364
  lines.push("");
6992
7365
  for (const l of wrapWords(view.stack_comment, 46))
6993
- lines.push(chalk2.italic.white(" " + l));
7366
+ lines.push(chalk3.italic.white(" " + l));
6994
7367
  }
6995
7368
  return box(lines.join("\n"), { borderColor: "magenta" });
6996
7369
  }
@@ -7001,25 +7374,25 @@ function cardCodeFootprint(view) {
7001
7374
  const netLabel = `${f.net >= 0 ? "+" : ""}${compactNum(f.net)}`;
7002
7375
  const subhead = f.label === "Cleaner" ? "you delete more than you add. the slop stops with you." : f.label === "Shipper" ? `${f.additive_ratio >= 0 ? Math.round(f.additive_ratio * 100) : 0}% of your churn is brand-new code.` : "you rework as much as you write. nothing ships half-baked.";
7003
7376
  const lines = [
7004
- chalk2.dim("YOUR CODE FOOTPRINT"),
7377
+ chalk3.dim("YOUR CODE FOOTPRINT"),
7005
7378
  "",
7006
7379
  ` ${bigNumber(f.label.toUpperCase())}`,
7007
7380
  "",
7008
- ` ${chalk2.green("+ " + compactNum(f.lines_added).padEnd(7))} ${coloredBar(f.lines_added, max, 22, "#22c55e")} ${chalk2.dim("added")}`,
7009
- ` ${chalk2.red("- " + compactNum(f.lines_deleted).padEnd(7))} ${coloredBar(f.lines_deleted, max, 22, "#ef4444")} ${chalk2.dim("deleted")}`,
7381
+ ` ${chalk3.green("+ " + compactNum(f.lines_added).padEnd(7))} ${coloredBar(f.lines_added, max, 22, "#22c55e")} ${chalk3.dim("added")}`,
7382
+ ` ${chalk3.red("- " + compactNum(f.lines_deleted).padEnd(7))} ${coloredBar(f.lines_deleted, max, 22, "#ef4444")} ${chalk3.dim("deleted")}`,
7010
7383
  "",
7011
- ` ${chalk2.white("net " + netLabel)} ${chalk2.dim("lines since 2024")}`
7384
+ ` ${chalk3.white("net " + netLabel)} ${chalk3.dim("lines since 2024")}`
7012
7385
  ];
7013
7386
  if (f.median_commit_size > 0)
7014
7387
  lines.push(
7015
- ` ${chalk2.dim(`typical commit ~${compactNum(f.median_commit_size)} lines \xB7 biggest ${compactNum(f.biggest_commit_size)}`)}`
7388
+ ` ${chalk3.dim(`typical commit ~${compactNum(f.median_commit_size)} lines \xB7 biggest ${compactNum(f.biggest_commit_size)}`)}`
7016
7389
  );
7017
7390
  lines.push("");
7018
7391
  if (f.line) {
7019
7392
  for (const l of wrapWords(f.line, 47))
7020
- lines.push(chalk2.italic.white(" " + l));
7393
+ lines.push(chalk3.italic.white(" " + l));
7021
7394
  } else {
7022
- lines.push(chalk2.dim(" " + subhead));
7395
+ lines.push(chalk3.dim(" " + subhead));
7023
7396
  }
7024
7397
  return box(lines.join("\n"), { borderColor: "green" });
7025
7398
  }
@@ -7030,20 +7403,20 @@ function cardConcurrency(view) {
7030
7403
  const longest = days >= 1.5 ? `${days.toFixed(0)} days` : `${Math.round(c.longest_session_hours)}h`;
7031
7404
  const bench = benchmarkInline(view, view.rank_summary.avg_agents_percentile);
7032
7405
  const lines = [
7033
- chalk2.dim("HOW MANY AGENTS YOU JUGGLE"),
7406
+ chalk3.dim("HOW MANY AGENTS YOU JUGGLE"),
7034
7407
  "",
7035
- ` ${bigNumber(`~${c.open_tab_avg}`)} ${chalk2.white("agents open at once")}${bench ? ` ${bench}` : ""}`,
7408
+ ` ${bigNumber(`~${c.open_tab_avg}`)} ${chalk3.white("agents open at once")}${bench ? ` ${bench}` : ""}`,
7036
7409
  "",
7037
- ` ${chalk2.white("peak".padEnd(14))} ${chalk2.dim(`${c.open_tab_peak} at once`)}`,
7038
- ` ${chalk2.white("longest tab".padEnd(14))} ${chalk2.dim(`${longest} open`)}`,
7039
- ` ${chalk2.white("2+ active".padEnd(14))} ${chalk2.dim(`${Math.round(c.active_juggle_pct * 100)}% of your coding time`)}`,
7410
+ ` ${chalk3.white("peak".padEnd(14))} ${chalk3.dim(`${c.open_tab_peak} at once`)}`,
7411
+ ` ${chalk3.white("longest tab".padEnd(14))} ${chalk3.dim(`${longest} open`)}`,
7412
+ ` ${chalk3.white("2+ active".padEnd(14))} ${chalk3.dim(`${Math.round(c.active_juggle_pct * 100)}% of your coding time`)}`,
7040
7413
  ""
7041
7414
  ];
7042
7415
  if (c.line) {
7043
7416
  for (const l of wrapWords(c.line, 47))
7044
- lines.push(chalk2.italic.white(" " + l));
7417
+ lines.push(chalk3.italic.white(" " + l));
7045
7418
  } else {
7046
- lines.push(chalk2.dim(" a one-agent setup could never."));
7419
+ lines.push(chalk3.dim(" a one-agent setup could never."));
7047
7420
  }
7048
7421
  return box(lines.join("\n"), { borderColor: "blue" });
7049
7422
  }
@@ -7060,22 +7433,22 @@ function cardTalk(view) {
7060
7433
  const c = view.conversation;
7061
7434
  const v = view.collaboration;
7062
7435
  if ((!c || c.total_prompts < 10) && !v) return "";
7063
- const lines = [chalk2.dim("HOW YOU TALK"), ""];
7436
+ const lines = [chalk3.dim("HOW YOU TALK"), ""];
7064
7437
  if (c?.line) {
7065
7438
  for (const l of wrapWords(c.line, 47))
7066
- lines.push(chalk2.italic.white(" " + l));
7439
+ lines.push(chalk3.italic.white(" " + l));
7067
7440
  lines.push("");
7068
7441
  }
7069
7442
  if (v) {
7070
7443
  lines.push(` ${bigNumber(v.style_label)}`);
7071
7444
  if (v.summary)
7072
7445
  for (const l of wrapWords(v.summary, 47))
7073
- lines.push(chalk2.white(" " + l));
7446
+ lines.push(chalk3.white(" " + l));
7074
7447
  const sigs = [
7075
7448
  ["reads", v.signals.fact_checking],
7076
7449
  ["drives", v.signals.autonomy]
7077
7450
  ].filter(([, t]) => t).map(
7078
- ([label, t]) => ` ${chalk2.dim(label.padEnd(8))} ${chalk2.white(briefSignal(t))}`
7451
+ ([label, t]) => ` ${chalk3.dim(label.padEnd(8))} ${chalk3.white(briefSignal(t))}`
7079
7452
  );
7080
7453
  if (sigs.length > 0) {
7081
7454
  lines.push("");
@@ -7085,11 +7458,11 @@ function cardTalk(view) {
7085
7458
  if (c) {
7086
7459
  lines.push("");
7087
7460
  lines.push(
7088
- ` ${chalk2.white(c.total_prompts.toLocaleString())} ${chalk2.dim("prompts")} \xB7 ${chalk2.white(Math.round(c.question_ratio * 100) + "%")} ${chalk2.dim("questions")} \xB7 ${chalk2.white("~" + c.avg_prompt_chars)} ${chalk2.dim("chars")}`
7461
+ ` ${chalk3.white(c.total_prompts.toLocaleString())} ${chalk3.dim("prompts")} \xB7 ${chalk3.white(Math.round(c.question_ratio * 100) + "%")} ${chalk3.dim("questions")} \xB7 ${chalk3.white("~" + c.avg_prompt_chars)} ${chalk3.dim("chars")}`
7089
7462
  );
7090
7463
  if (c.themes.length > 0)
7091
7464
  lines.push(
7092
- ` ${chalk2.dim("recurring: " + c.themes.slice(0, 4).join(", "))}`
7465
+ ` ${chalk3.dim("recurring: " + c.themes.slice(0, 4).join(", "))}`
7093
7466
  );
7094
7467
  }
7095
7468
  return box(lines.join("\n"), { borderColor: "magenta" });
@@ -7101,13 +7474,13 @@ function cardProficiency(view) {
7101
7474
  if (!p) {
7102
7475
  return box(
7103
7476
  [
7104
- chalk2.dim(" you are\u2026"),
7477
+ chalk3.dim(" you are\u2026"),
7105
7478
  "",
7106
- chalk2.hex("#ff8a00")(mascot),
7479
+ chalk3.hex("#ff8a00")(mascot),
7107
7480
  "",
7108
7481
  ` ${archetype}`,
7109
7482
  "",
7110
- ` ${chalk2.italic.white(`"${view.zinger}"`)}`
7483
+ ` ${chalk3.italic.white(`"${view.zinger}"`)}`
7111
7484
  ].join("\n"),
7112
7485
  { borderColor: "yellow" }
7113
7486
  );
@@ -7115,27 +7488,33 @@ function cardProficiency(view) {
7115
7488
  const scoreTop = topPercentNumber(p.score_percentile ?? null);
7116
7489
  const sampleSize = view.rank_summary.sample_size;
7117
7490
  const cohort = scoreTop != null && sampleSize > 0 ? `top ${scoreTop}% of ${sampleSize.toLocaleString()} users` : view.cohort_size > 0 ? `among ${view.cohort_size.toLocaleString()} users so far` : "";
7118
- const metricRow = (label, value) => value === null ? null : ` ${chalk2.white(label.padEnd(12))} ${bar2(value, 100, 10)} ${chalk2.dim(String(value))}`;
7491
+ const metricRow = (label, value) => value === null ? null : ` ${chalk3.white(label.padEnd(12))} ${bar2(value, 100, 10)} ${chalk3.dim(String(value))}`;
7119
7492
  const bars = [
7120
7493
  metricRow("intensity", p.intensity),
7121
7494
  metricRow("consistency", p.consistency),
7122
- p.craft_bonus > 0 ? ` ${chalk2.white("craft".padEnd(12))} ${chalk2.hex("#ff8a00")(`+${p.craft_bonus}`)} ${chalk2.dim("clean prompting")}` : null
7495
+ p.craft_bonus > 0 ? ` ${chalk3.white("craft".padEnd(12))} ${chalk3.hex("#ff8a00")(`+${p.craft_bonus}`)} ${chalk3.dim("clean prompting")}` : null
7123
7496
  ].filter((r) => r !== null);
7124
7497
  const zingerLines = wrapWords(`"${view.zinger}"`, INNER_WIDTH).map(
7125
- (l) => centerText(l, chalk2.italic.white)
7498
+ (l) => centerText(l, chalk3.italic.white)
7126
7499
  );
7127
7500
  const commentLines = p.comment ? wrapWords(p.comment, INNER_WIDTH - 4).map(
7128
- (l, i) => i === 0 ? ` ${chalk2.hex("#ff8a00")(">")} ${chalk2.white(l)}` : ` ${chalk2.white(l)}`
7501
+ (l, i) => i === 0 ? ` ${chalk3.hex("#ff8a00")(">")} ${chalk3.white(l)}` : ` ${chalk3.white(l)}`
7129
7502
  ) : [];
7130
7503
  const tier = tierForScore2(p.score);
7504
+ const nextTier = TIERS2[TIERS2.findIndex((t) => t.key === tier.key) + 1];
7505
+ const nextTierLine = nextTier ? centerText(
7506
+ `${nextTier.min - p.score} pts to ${nextTier.label.toLowerCase()}`,
7507
+ chalk3.hex("#ad5cff")
7508
+ ) : null;
7131
7509
  const lines = [
7132
- centerBlock(tier.art, chalk2.hex("#ff8a00")),
7510
+ centerBlock(tier.art, chalk3.hex("#ff8a00")),
7133
7511
  "",
7134
7512
  centerText(`\u2500\u2500 ${tier.label} \u2500\u2500`, bigNumber),
7135
7513
  centerText(`${p.score} / 100`, bigNumber),
7136
- cohort ? centerText(cohort, chalk2.dim) : null,
7514
+ cohort ? centerText(cohort, chalk3.dim) : null,
7515
+ nextTierLine,
7137
7516
  "",
7138
- centerText(view.archetype_label, chalk2.bold.hex("#ad5cff")),
7517
+ centerText(view.archetype_label, chalk3.bold.hex("#ad5cff")),
7139
7518
  ...zingerLines,
7140
7519
  "",
7141
7520
  ...bars,
@@ -7173,7 +7552,7 @@ async function renderWrappedAll(view) {
7173
7552
  " " + TITLE_GRADIENT.multiline("\u2591\u2592\u2593 YOUR AI WRAPPED \u2593\u2592\u2591") + "\n"
7174
7553
  );
7175
7554
  process.stdout.write(
7176
- chalk2.dim(` ${view.name.toLowerCase()} \xB7 last 30 days
7555
+ chalk3.dim(` ${view.name.toLowerCase()} \xB7 last 30 days
7177
7556
 
7178
7557
  `)
7179
7558
  );
@@ -7275,7 +7654,8 @@ async function createWrapped(args) {
7275
7654
  const body = JSON.stringify({
7276
7655
  profile,
7277
7656
  submission_id: args.submissionId ?? void 0,
7278
- group: args.group ?? void 0
7657
+ group: args.group ?? void 0,
7658
+ challenge: args.challenge ?? void 0
7279
7659
  });
7280
7660
  const bodyKb = Math.round(bytesAfter / 1024);
7281
7661
  let created = null;
@@ -7344,16 +7724,14 @@ async function createWrapped(args) {
7344
7724
  id: created.id,
7345
7725
  share_url: created.share_url,
7346
7726
  view,
7347
- group: created.group ?? null
7727
+ group: created.group ?? null,
7728
+ challenge_code: created.challenge_code ?? null,
7729
+ short_url: created.short_url ?? null,
7730
+ versus: created.versus ?? null,
7731
+ previous: created.previous ?? null
7348
7732
  };
7349
7733
  }
7350
7734
 
7351
- // src/wrapped-share.ts
7352
- import open from "open";
7353
- async function openWrapped(shareUrl) {
7354
- await open(shareUrl);
7355
- }
7356
-
7357
7735
  // src/cli.ts
7358
7736
  var MAX_TURNS = 40;
7359
7737
  function profileChatEnabled() {
@@ -7396,18 +7774,18 @@ var MODE_OPTIONS = [
7396
7774
  function renderModeMenu(selected) {
7397
7775
  const out = [
7398
7776
  "",
7399
- chalk3.white(" How do you want to run Standout?"),
7777
+ chalk4.white(" How do you want to run Standout?"),
7400
7778
  ""
7401
7779
  ];
7402
7780
  MODE_OPTIONS.forEach((opt, i) => {
7403
7781
  const active = i === selected;
7404
- const pointer = active ? chalk3.hex("#ad5cff")("\u276F ") : " ";
7405
- const title = active ? chalk3.bold.white(opt.title) + chalk3.dim(opt.tag) : chalk3.dim(opt.title + opt.tag);
7782
+ const pointer = active ? chalk4.hex("#ad5cff")("\u276F ") : " ";
7783
+ const title = active ? chalk4.bold.white(opt.title) + chalk4.dim(opt.tag) : chalk4.dim(opt.title + opt.tag);
7406
7784
  out.push(`${pointer}${title}`);
7407
- for (const line of opt.lines) out.push(chalk3.dim(` ${line}`));
7785
+ for (const line of opt.lines) out.push(chalk4.dim(` ${line}`));
7408
7786
  out.push("");
7409
7787
  });
7410
- out.push(chalk3.dim(" \u2191/\u2193 to move \xB7 enter to select"));
7788
+ out.push(chalk4.dim(" \u2191/\u2193 to move \xB7 enter to select"));
7411
7789
  return out.join("\n");
7412
7790
  }
7413
7791
  async function chooseMode() {
@@ -7510,8 +7888,8 @@ function startLoadingLine(label) {
7510
7888
  let frame = 0;
7511
7889
  const render = () => {
7512
7890
  const dots = frames[frame % frames.length];
7513
- const accent = chalk3.hex("#ad5cff")(dots);
7514
- const text = chalk3.white(label);
7891
+ const accent = chalk4.hex("#ad5cff")(dots);
7892
+ const text = chalk4.white(label);
7515
7893
  process.stderr.write(`\r\x1B[2K ${accent} ${text}`);
7516
7894
  frame += 1;
7517
7895
  };
@@ -7522,54 +7900,6 @@ function startLoadingLine(label) {
7522
7900
  process.stderr.write("\r\x1B[2K");
7523
7901
  };
7524
7902
  }
7525
- async function askLine(prompt) {
7526
- if (!process.stdin.isTTY) return "y";
7527
- return new Promise((resolve) => {
7528
- const iface = createInterface3({
7529
- input: process.stdin,
7530
- output: process.stderr
7531
- });
7532
- iface.question(prompt, (ans) => {
7533
- iface.close();
7534
- resolve(ans.trim());
7535
- });
7536
- });
7537
- }
7538
- async function maybeShareWrapped(wrapped) {
7539
- if (!process.stdin.isTTY) {
7540
- process.stderr.write(` your wrapped: ${wrapped.share_url}
7541
-
7542
- `);
7543
- return;
7544
- }
7545
- const ans = await askLine(
7546
- chalk3.white(" press enter to see your ai wrapped ")
7547
- );
7548
- process.stderr.write("\n");
7549
- const shared = !ans || ans.toLowerCase() !== "n";
7550
- if (!shared) {
7551
- process.stderr.write(` your wrapped: ${wrapped.share_url}
7552
-
7553
- `);
7554
- return;
7555
- }
7556
- process.stderr.write(" opening your wrapped...\n");
7557
- try {
7558
- await openWrapped(wrapped.share_url);
7559
- await markWrappedShared(wrapped.id);
7560
- process.stderr.write(` opened: ${wrapped.share_url}
7561
-
7562
- `);
7563
- } catch (err) {
7564
- process.stderr.write(
7565
- ` couldn't open browser. open it manually: ${wrapped.share_url}
7566
- `
7567
- );
7568
- process.stderr.write(` (${err instanceof Error ? err.message : err})
7569
-
7570
- `);
7571
- }
7572
- }
7573
7903
  async function renderLocalTerminal(prefetched) {
7574
7904
  const view = aggregateView({
7575
7905
  profile: prefetched,
@@ -7648,23 +7978,30 @@ async function runLocal() {
7648
7978
  " (Your terminal can't show inline images \u2014 open the saved card below.)\n"
7649
7979
  );
7650
7980
  }
7651
- const post = encodeURIComponent(
7652
- "Check out my AI Wrapped \u{1F916} \u2014 get yours: npx standout"
7653
- );
7654
- process.stderr.write(
7655
- `
7981
+ process.stderr.write(`
7656
7982
  Saved card: ${file}
7657
-
7658
- Share it:
7659
- X: https://x.com/intent/post?text=${post}
7660
- LinkedIn: https://www.linkedin.com/feed/?shareActive=true&text=${post}
7661
-
7662
- (Rendered on your machine \u2014 nothing left your computer.)
7983
+ `);
7984
+ await runEndgame({
7985
+ view: aggregateView({
7986
+ profile: prefetched,
7987
+ computed: {},
7988
+ share_url: ""
7989
+ }),
7990
+ wrappedId: null,
7991
+ shareUrl: null,
7992
+ shortUrl: null,
7993
+ challengeCode: null,
7994
+ versus: null,
7995
+ previous: null,
7996
+ localOnly: true
7997
+ });
7998
+ process.stderr.write(
7999
+ ` (Rendered on your machine \u2014 nothing left your computer.)
7663
8000
 
7664
8001
  `
7665
8002
  );
7666
8003
  }
7667
- async function runAgent(jobId) {
8004
+ async function runAgent(jobId, challengeCode) {
7668
8005
  if (profileChatEnabled()) {
7669
8006
  ensureInteractive("The interactive profile chat");
7670
8007
  }
@@ -7704,7 +8041,8 @@ async function runAgent(jobId) {
7704
8041
  const wrapped2 = await createWrapped({
7705
8042
  profile: prefetched2,
7706
8043
  submissionId: null,
7707
- group: jobId ?? null
8044
+ group: jobId ?? null,
8045
+ challenge: challengeCode ?? null
7708
8046
  });
7709
8047
  return { wrapped: wrapped2, prefetched: prefetched2 };
7710
8048
  } catch {
@@ -7732,7 +8070,16 @@ async function runAgent(jobId) {
7732
8070
  );
7733
8071
  }
7734
8072
  await maybeAutoInstallSchedule(jobId);
7735
- await maybeShareWrapped(wrapped);
8073
+ await runEndgame({
8074
+ view: wrapped.view,
8075
+ wrappedId: wrapped.id,
8076
+ shareUrl: wrapped.share_url,
8077
+ shortUrl: wrapped.short_url,
8078
+ challengeCode: wrapped.challenge_code,
8079
+ versus: wrapped.versus,
8080
+ previous: wrapped.previous,
8081
+ localOnly: false
8082
+ });
7736
8083
  } else {
7737
8084
  process.stderr.write(
7738
8085
  " (couldn't generate wrapped right now. continuing profile setup.)\n\n"
@@ -7890,17 +8237,24 @@ async function main() {
7890
8237
  await startMcpServer();
7891
8238
  return;
7892
8239
  }
7893
- const jobId = args.find((a) => !a.startsWith("-"));
8240
+ const positional = args.filter((a) => !a.startsWith("-"));
8241
+ const challengeCode = positional.find((a) => a.startsWith("beat-"));
8242
+ const jobId = positional.find((a) => !a.startsWith("beat-"));
7894
8243
  printBanner();
7895
8244
  let mode;
7896
8245
  if (localOnly) mode = "local";
7897
- else if (jobId) mode = "full";
8246
+ else if (jobId || challengeCode) mode = "full";
7898
8247
  else mode = await chooseMode();
7899
8248
  if (mode === "local") {
8249
+ if (challengeCode) {
8250
+ process.stderr.write(
8251
+ " (challenges need the full run to rank you \u2014 skipping the versus in local mode)\n"
8252
+ );
8253
+ }
7900
8254
  await runLocal();
7901
8255
  } else {
7902
8256
  if (jobId) process.env.STANDOUT_JOB_ID = jobId;
7903
- await runAgent(jobId);
8257
+ await runAgent(jobId, challengeCode);
7904
8258
  }
7905
8259
  }
7906
8260
  main().catch((error) => {