@mauricode/token-derby 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin.js CHANGED
@@ -320,6 +320,7 @@ function HorseCreator({ onSubmit, onCancel, initialColors, initialName, lockName
320
320
 
321
321
  // src/stable/stable.ts
322
322
  import * as fs from "fs/promises";
323
+ import { randomUUID } from "crypto";
323
324
 
324
325
  // src/paths.ts
325
326
  import * as os from "os";
@@ -344,12 +345,26 @@ function claudeProjectsDir() {
344
345
  }
345
346
 
346
347
  // src/stable/stable.ts
348
+ function newStableHorseId() {
349
+ return randomUUID();
350
+ }
347
351
  async function loadStable() {
348
352
  try {
349
353
  const raw = await fs.readFile(stableFile(), "utf8");
350
354
  const parsed = JSON.parse(raw);
351
355
  if (!parsed || !Array.isArray(parsed.horses)) return { horses: [] };
352
- return parsed;
356
+ const stable = parsed;
357
+ let mutated = false;
358
+ const horses = stable.horses.map((h) => {
359
+ if (typeof h.stable_horse_id === "string" && h.stable_horse_id.length > 0) {
360
+ return h;
361
+ }
362
+ mutated = true;
363
+ return { ...h, stable_horse_id: newStableHorseId() };
364
+ });
365
+ const result = { horses };
366
+ if (mutated) await saveStable(result);
367
+ return result;
353
368
  } catch (e) {
354
369
  if (e?.code === "ENOENT") return { horses: [] };
355
370
  if (e instanceof SyntaxError) return { horses: [] };
@@ -397,7 +412,8 @@ async function stableCreateCommand() {
397
412
  return;
398
413
  }
399
414
  }
400
- await upsertHorse({ name, colors, created_at: (/* @__PURE__ */ new Date()).toISOString() });
415
+ const stable_horse_id = existing?.stable_horse_id ?? newStableHorseId();
416
+ await upsertHorse({ stable_horse_id, name, colors, created_at: (/* @__PURE__ */ new Date()).toISOString() });
401
417
  app.unmount();
402
418
  console.log(`\u2713 Saved "${name}" to your stable.`);
403
419
  },
@@ -535,7 +551,12 @@ async function stableEditCommand(name) {
535
551
  initialName: existing.name,
536
552
  lockName: true,
537
553
  onSubmit: async (_name, colors) => {
538
- await upsertHorse({ name: existing.name, colors, created_at: existing.created_at });
554
+ await upsertHorse({
555
+ stable_horse_id: existing.stable_horse_id,
556
+ name: existing.name,
557
+ colors,
558
+ created_at: existing.created_at
559
+ });
539
560
  app.unmount();
540
561
  console.log(`\u2713 Updated "${existing.name}".`);
541
562
  },
@@ -566,8 +587,8 @@ var HEARTBEAT_RETRY_DELAYS_MS = [1e3, 2e3, 4e3, 8e3, 15e3];
566
587
  // src/version.ts
567
588
  import { createRequire } from "module";
568
589
  function readVersion() {
569
- if ("1.0.0".length > 0) {
570
- return "1.0.0";
590
+ if ("1.1.0".length > 0) {
591
+ return "1.1.0";
571
592
  }
572
593
  try {
573
594
  const req = createRequire(import.meta.url);
@@ -1200,10 +1221,12 @@ async function joinCommand(joinCode) {
1200
1221
  return 1;
1201
1222
  }
1202
1223
  const ownHorse = race.horses.find((h) => h.user_id === identity.user_id) ?? null;
1224
+ let chosenStableHorseId;
1203
1225
  let chosenName;
1204
1226
  let chosenColors;
1205
1227
  let isResume;
1206
1228
  if (ownHorse) {
1229
+ chosenStableHorseId = ownHorse.stable_horse_id;
1207
1230
  chosenName = ownHorse.name;
1208
1231
  chosenColors = ownHorse.colors;
1209
1232
  isResume = true;
@@ -1218,13 +1241,16 @@ async function joinCommand(joinCode) {
1218
1241
  console.log("Cancelled.");
1219
1242
  return 1;
1220
1243
  }
1244
+ chosenStableHorseId = picked.stable_horse_id;
1221
1245
  chosenName = picked.name;
1222
1246
  chosenColors = picked.colors;
1223
1247
  isResume = false;
1224
1248
  }
1225
1249
  let joinResp;
1226
1250
  try {
1227
- joinResp = await joinRace(code, { horse: { name: chosenName, colors: chosenColors } });
1251
+ joinResp = await joinRace(code, {
1252
+ horse: { stable_horse_id: chosenStableHorseId, name: chosenName, colors: chosenColors }
1253
+ });
1228
1254
  } catch (e) {
1229
1255
  if (e instanceof ApiError) {
1230
1256
  if (e.code === "RACE_FULL") console.error("This race is full.");
package/dist/bin.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/commands/stable-create.ts","../src/ui/HorseCreator.tsx","../src/ui/HorseSprite.tsx","../src/ui/sprite.ts","../src/ui/sprite-render.ts","../src/ui/palette.ts","../src/stable/stable.ts","../src/paths.ts","../src/commands/stable-list.tsx","../src/commands/stable-delete.ts","../src/stable/active-race.ts","../src/commands/stable-edit.ts","../src/commands/create.ts","../src/config.ts","../src/version.ts","../../shared/src/constants.ts","../src/identity/identity.ts","../src/api/client.ts","../src/api/endpoints.ts","../src/commands/join.ts","../src/ui/HorsePicker.tsx","../src/runtime/run-race.tsx","../src/ui/StatusScreen.tsx","../src/runtime/heartbeat-loop.ts","../src/runtime/poll-loop.ts","../src/tokens/transcripts.ts","../src/tokens/baseline.ts","../src/commands/end.ts","../src/commands/init.ts","../src/bin.ts"],"sourcesContent":["import React from 'react';\nimport { render } from 'ink';\nimport { HorseCreator } from '../ui/HorseCreator.js';\nimport { upsertHorse, loadStable, findHorse } from '../stable/stable.js';\nimport * as readline from 'node:readline/promises';\nimport { stdin, stdout } from 'node:process';\n\nexport async function stableCreateCommand(): Promise<number> {\n let exitCode = 0;\n const app = render(\n React.createElement(HorseCreator, {\n onSubmit: async (name, colors) => {\n const stable = await loadStable();\n const existing = findHorse(stable, name);\n if (existing) {\n app.unmount();\n const rl = readline.createInterface({ input: stdin, output: stdout });\n const answer = (await rl.question(`Horse \"${name}\" already exists. Overwrite? [y/N] `)).trim().toLowerCase();\n rl.close();\n if (answer !== 'y' && answer !== 'yes') {\n console.log('Cancelled.');\n exitCode = 1;\n return;\n }\n }\n await upsertHorse({ name, colors, created_at: new Date().toISOString() });\n app.unmount();\n console.log(`✓ Saved \"${name}\" to your stable.`);\n },\n onCancel: () => {\n app.unmount();\n console.log('Cancelled.');\n exitCode = 1;\n },\n }),\n );\n await app.waitUntilExit();\n return exitCode;\n}\n","import React, { useState } from 'react';\nimport { Box, Text, useInput } from 'ink';\nimport TextInput from 'ink-text-input';\nimport type { HorseColors } from '@token-derby/shared';\nimport { HorseSprite } from './HorseSprite.js';\nimport { MAIN_SPRITE } from './sprite.js';\nimport { SLOTS, PALETTES, nextColor, prevColor, defaultColors, type Slot } from './palette.js';\n\ntype Props = {\n onSubmit: (name: string, colors: HorseColors) => void;\n onCancel: () => void;\n initialColors?: HorseColors;\n initialName?: string;\n lockName?: boolean;\n};\n\nexport function HorseCreator({ onSubmit, onCancel, initialColors, initialName, lockName }: Props) {\n const [colors, setColors] = useState<HorseColors>(initialColors ?? defaultColors());\n const [slotIdx, setSlotIdx] = useState(0);\n const [namingMode, setNamingMode] = useState(false);\n const [name, setName] = useState(initialName ?? '');\n const [error, setError] = useState<string | null>(null);\n\n const slot: Slot = SLOTS[slotIdx]!;\n\n useInput((input, key) => {\n if (namingMode) return;\n if (key.escape) { onCancel(); return; }\n if (key.upArrow) { setSlotIdx((slotIdx - 1 + SLOTS.length) % SLOTS.length); return; }\n if (key.downArrow) { setSlotIdx((slotIdx + 1) % SLOTS.length); return; }\n if (key.leftArrow) { setColors({ ...colors, [slot]: prevColor(slot, colors[slot]) }); return; }\n if (key.rightArrow) { setColors({ ...colors, [slot]: nextColor(slot, colors[slot]) }); return; }\n if (key.return) {\n if (lockName) { onSubmit(initialName ?? '', colors); return; }\n setNamingMode(true);\n return;\n }\n });\n\n const handleNameSubmit = (value: string) => {\n if (!value.trim()) {\n setError('Name required');\n return;\n }\n onSubmit(value.trim(), colors);\n };\n\n return (\n <Box flexDirection=\"column\">\n <Box marginBottom={1}>\n <HorseSprite sprite={MAIN_SPRITE} colors={colors} />\n </Box>\n\n <Box flexDirection=\"column\">\n {SLOTS.map((s, i) => (\n <Text key={s}>\n {i === slotIdx ? '►' : ' '} {s.padEnd(7)} <Text color={colors[s]}>██</Text> {colors[s]}\n </Text>\n ))}\n </Box>\n\n {!namingMode && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text dimColor>↑/↓ select slot · ←/→ cycle color · Enter accept · Esc cancel</Text>\n </Box>\n )}\n\n {namingMode && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text>Name your horse: </Text>\n <TextInput value={name} onChange={(v) => { setName(v); setError(null); }} onSubmit={handleNameSubmit} />\n {error && <Text color=\"red\">{error}</Text>}\n </Box>\n )}\n </Box>\n );\n}\n","import React from 'react';\nimport { Box, Text } from 'ink';\nimport type { HorseColors } from '@token-derby/shared';\nimport { renderSprite, type Cell } from './sprite-render.js';\nimport type { SlotTag } from './sprite.js';\n\ntype Props = {\n sprite: readonly (readonly SlotTag[])[];\n colors: HorseColors;\n};\n\nexport function HorseSprite({ sprite, colors }: Props) {\n const grid = renderSprite(sprite, colors);\n return (\n <Box flexDirection=\"column\">\n {grid.map((row, y) => (\n <Text key={y}>{rowToAnsi(row)}</Text>\n ))}\n </Box>\n );\n}\n\nfunction rowToAnsi(row: Cell[]): string {\n let out = '';\n for (const cell of row) {\n if (cell.top === null && cell.bottom === null) {\n out += ' ';\n } else if (cell.top !== null && cell.bottom !== null) {\n out += ansiFg(cell.top) + ansiBg(cell.bottom) + '▀' + RESET;\n } else if (cell.top !== null) {\n out += ansiFg(cell.top) + '▀' + RESET;\n } else {\n out += ansiFg(cell.bottom!) + '▄' + RESET;\n }\n }\n return out;\n}\n\nconst RESET = '\\x1b[0m';\n\nfunction hexToRgb(hex: string): [number, number, number] {\n const h = hex.replace('#', '');\n return [\n parseInt(h.slice(0, 2), 16),\n parseInt(h.slice(2, 4), 16),\n parseInt(h.slice(4, 6), 16),\n ];\n}\n\nfunction ansiFg(hex: string): string {\n const [r, g, b] = hexToRgb(hex);\n return `\\x1b[38;2;${r};${g};${b}m`;\n}\n\nfunction ansiBg(hex: string): string {\n const [r, g, b] = hexToRgb(hex);\n return `\\x1b[48;2;${r};${g};${b}m`;\n}\n","// Pixel slot tags. `null` = transparent.\n// B = body, M = mane, T = tail, S = saddle, E = eye (fixed black), H = hoof (fixed dark)\nexport type SlotTag = 'B' | 'M' | 'T' | 'S' | 'E' | 'H' | null;\n\nexport const FIXED_COLORS = {\n E: '#000000',\n H: '#1F1108',\n} as const;\n\n// Each pair of adjacent rows is intentionally identical so every half-block\n// cell renders as a solid color. The only intentional split is the last row\n// (legs/hooves transition).\nconst MAIN_ROWS: readonly string[] = [\n '................................',\n '................................',\n '..........................MMM...',\n '..........................MMM...',\n '.........................MBBEBB.',\n '.........................MBBEBB.',\n '........................MBBBBBBB',\n '........................MBBBBBBB',\n '..................MMMMMMMBBB....',\n '..................MMMMMMMBBB....',\n '....BBBBBBBBSSSSSSMMBBBBBB......',\n '...BBBBBBBBBSSSSSSMMBBBBBB......',\n '.TTBBBBBBBBBSSSSSSBBBBBBBB......',\n '.TTBBBBBBBBBSSSSSSBBBBBBBB......',\n 'TTTBBBBBBBBBBBBBBBBBBBBBBB......',\n 'TTTBBBBBBBBBBBBBBBBBBBBB........',\n '...BBB.BBB.....BBB.BBB..........',\n '...BBB.BBB.....BBB.BBB..........',\n '....BB..BB......BB..BB..........',\n '....BB..BB......BB..BB..........',\n '....BB..BB......BB..BB..........',\n '....BB..BB......BB..BB..........',\n '....BB..BB......BB..BB..........',\n '...HHH.HHH.....HHH.HHH..........',\n];\n\nconst MINI_ROWS: readonly string[] = [\n '.BBSSMBB',\n '.BBSSMBB',\n 'TBBBBBB.',\n 'THH..HH.',\n];\n\nexport const MAIN_SPRITE: readonly (readonly SlotTag[])[] = parse(MAIN_ROWS, 32, 24);\nexport const MINI_SPRITE: readonly (readonly SlotTag[])[] = parse(MINI_ROWS, 8, 4);\n\nfunction parse(rows: readonly string[], width: number, height: number): SlotTag[][] {\n if (rows.length !== height) {\n throw new Error(`sprite has ${rows.length} rows, expected ${height}`);\n }\n return rows.map((row, y) => {\n if (row.length !== width) {\n throw new Error(`sprite row ${y} has length ${row.length}, expected ${width}`);\n }\n return [...row].map(c => toTag(c));\n });\n}\n\nfunction toTag(c: string): SlotTag {\n switch (c) {\n case 'B': return 'B';\n case 'M': return 'M';\n case 'T': return 'T';\n case 'S': return 'S';\n case 'E': return 'E';\n case 'H': return 'H';\n case '.': return null;\n default: throw new Error(`unknown sprite char: ${c}`);\n }\n}\n","import type { HorseColors } from '@token-derby/shared';\nimport { FIXED_COLORS, type SlotTag } from './sprite.js';\n\nexport type Cell = {\n top: string | null;\n bottom: string | null;\n};\n\nexport function renderSprite(\n sprite: readonly (readonly SlotTag[])[],\n colors: HorseColors,\n): Cell[][] {\n const out: Cell[][] = [];\n for (let y = 0; y + 1 < sprite.length || y < sprite.length; y += 2) {\n const topRow = sprite[y];\n const bottomRow = sprite[y + 1];\n if (!topRow) break;\n const row: Cell[] = [];\n for (let x = 0; x < topRow.length; x++) {\n row.push({\n top: tagColor(topRow[x] ?? null, colors),\n bottom: tagColor(bottomRow?.[x] ?? null, colors),\n });\n }\n out.push(row);\n if (!bottomRow) break;\n }\n return out;\n}\n\nfunction tagColor(tag: SlotTag, colors: HorseColors): string | null {\n if (tag === null) return null;\n if (tag === 'E') return FIXED_COLORS.E;\n if (tag === 'H') return FIXED_COLORS.H;\n if (tag === 'B') return colors.body;\n if (tag === 'M') return colors.mane;\n if (tag === 'T') return colors.tail;\n if (tag === 'S') return colors.saddle;\n return null;\n}\n","import type { HorseColors } from '@token-derby/shared';\n\nexport type Slot = keyof HorseColors;\n\nexport const SLOTS: readonly Slot[] = ['body', 'mane', 'tail', 'saddle'] as const;\n\nexport const PALETTES: Record<Slot, readonly string[]> = {\n body: [\n '#8B4513', '#A0522D', '#D2691E', '#CD853F', '#DEB887', '#F5DEB3',\n '#FFFFFF', '#000000', '#4A2C2A', '#5D3A1A', '#704214', '#9C5919',\n '#B87333', '#E5B783', '#F0E1C9', '#2F1B0C',\n ],\n mane: [\n '#000000', '#1C1C1C', '#2F1B0C', '#4A2C2A', '#5D3A1A', '#8B4513',\n '#FFFFFF', '#F5F5DC', '#DEB887', '#CD853F', '#FF4500', '#B22222',\n '#191970', '#4B0082', '#2E8B57', '#FFD700',\n ],\n tail: [\n '#000000', '#1C1C1C', '#2F1B0C', '#4A2C2A', '#5D3A1A', '#8B4513',\n '#FFFFFF', '#F5F5DC', '#DEB887', '#CD853F', '#FF4500', '#B22222',\n '#191970', '#4B0082', '#2E8B57', '#FFD700',\n ],\n saddle: [\n '#C0392B', '#922B21', '#7B241C', '#641E16', '#1F618D', '#21618C',\n '#1B4F72', '#0E6655', '#117A65', '#196F3D', '#7D6608', '#9A7D0A',\n '#6E2C00', '#4D5656', '#212F3D', '#000000',\n ],\n};\n\nexport function nextColor(slot: Slot, current: string): string {\n const palette = PALETTES[slot];\n const idx = palette.indexOf(current);\n return palette[(idx + 1 + palette.length) % palette.length] ?? palette[0]!;\n}\n\nexport function prevColor(slot: Slot, current: string): string {\n const palette = PALETTES[slot];\n const idx = palette.indexOf(current);\n if (idx < 0) return palette[0]!;\n return palette[(idx - 1 + palette.length) % palette.length]!;\n}\n\nexport function defaultColors(): HorseColors {\n return {\n body: PALETTES.body[0]!,\n mane: PALETTES.mane[0]!,\n tail: PALETTES.tail[0]!,\n saddle: PALETTES.saddle[0]!,\n };\n}\n","import * as fs from 'node:fs/promises';\nimport type { HorseColors } from '@token-derby/shared';\nimport { homeDir, stableFile } from '../paths.js';\n\nexport type StableHorse = {\n name: string;\n colors: HorseColors;\n created_at: string;\n};\n\nexport type Stable = {\n horses: StableHorse[];\n};\n\nexport async function loadStable(): Promise<Stable> {\n try {\n const raw = await fs.readFile(stableFile(), 'utf8');\n const parsed = JSON.parse(raw);\n if (!parsed || !Array.isArray(parsed.horses)) return { horses: [] };\n return parsed as Stable;\n } catch (e: any) {\n if (e?.code === 'ENOENT') return { horses: [] };\n if (e instanceof SyntaxError) return { horses: [] };\n throw e;\n }\n}\n\nexport async function saveStable(stable: Stable): Promise<void> {\n await fs.mkdir(homeDir(), { recursive: true });\n await fs.writeFile(stableFile(), JSON.stringify(stable, null, 2) + '\\n', 'utf8');\n}\n\nexport async function upsertHorse(horse: StableHorse): Promise<void> {\n const stable = await loadStable();\n const idx = stable.horses.findIndex(h => h.name === horse.name);\n if (idx >= 0) stable.horses[idx] = horse;\n else stable.horses.push(horse);\n await saveStable(stable);\n}\n\nexport async function removeHorse(name: string): Promise<void> {\n const stable = await loadStable();\n stable.horses = stable.horses.filter(h => h.name !== name);\n await saveStable(stable);\n}\n\nexport function findHorse(stable: Stable, name: string): StableHorse | undefined {\n return stable.horses.find(h => h.name === name);\n}\n","import * as os from 'node:os';\nimport * as path from 'node:path';\n\nexport function homeDir(): string {\n return process.env.TOKEN_DERBY_HOME ?? path.join(os.homedir(), '.token-derby');\n}\n\nexport function stableFile(): string {\n return path.join(homeDir(), 'stable.json');\n}\n\nexport function identityFile(): string {\n return path.join(homeDir(), 'identity.json');\n}\n\nexport function activeRaceFile(joinCode: string): string {\n return path.join(homeDir(), 'active-races', `${joinCode}.json`);\n}\n\nexport function activeRacesDir(): string {\n return path.join(homeDir(), 'active-races');\n}\n\nexport function claudeProjectsDir(): string {\n return process.env.TOKEN_DERBY_CLAUDE_DIR ?? path.join(os.homedir(), '.claude', 'projects');\n}\n","import React from 'react';\nimport { render, Box, Text } from 'ink';\nimport { loadStable } from '../stable/stable.js';\nimport { HorseSprite } from '../ui/HorseSprite.js';\nimport { MINI_SPRITE } from '../ui/sprite.js';\n\nexport async function stableListCommand(): Promise<number> {\n const stable = await loadStable();\n if (stable.horses.length === 0) {\n console.log('Your stable is empty. Run `token-derby stable create` to add a horse.');\n return 0;\n }\n const app = render(\n React.createElement(StableList, { horses: stable.horses }),\n );\n await app.waitUntilExit();\n return 0;\n}\n\nfunction StableList({ horses }: { horses: { name: string; colors: any; created_at: string }[] }) {\n React.useEffect(() => {\n setImmediate(() => process.exit(0));\n }, []);\n return (\n <Box flexDirection=\"column\">\n <Text bold>Your stable ({horses.length}):</Text>\n {horses.map(h => (\n <Box key={h.name} flexDirection=\"row\" marginTop={1}>\n <HorseSprite sprite={MINI_SPRITE} colors={h.colors} />\n <Text> {h.name}</Text>\n </Box>\n ))}\n </Box>\n );\n}\n","import * as readline from 'node:readline/promises';\nimport { stdin, stdout } from 'node:process';\nimport { loadStable, findHorse, removeHorse } from '../stable/stable.js';\nimport { listActiveRaces, loadActiveRace } from '../stable/active-race.js';\n\nexport async function stableDeleteCommand(name: string | undefined): Promise<number> {\n if (!name) {\n console.error('Usage: token-derby stable delete <name>');\n return 2;\n }\n const stable = await loadStable();\n const horse = findHorse(stable, name);\n if (!horse) {\n console.error(`No horse named \"${name}\" in your stable.`);\n return 1;\n }\n\n const codes = await listActiveRaces();\n for (const code of codes) {\n const active = await loadActiveRace(code);\n if (active?.horse_name === name) {\n console.error(`\"${name}\" is currently running in race ${code}. Close that terminal first.`);\n return 1;\n }\n }\n\n const rl = readline.createInterface({ input: stdin, output: stdout });\n const answer = (await rl.question(`Delete \"${name}\" from your stable? [y/N] `)).trim().toLowerCase();\n rl.close();\n if (answer !== 'y' && answer !== 'yes') {\n console.log('Cancelled.');\n return 1;\n }\n await removeHorse(name);\n console.log(`✓ Deleted \"${name}\".`);\n return 0;\n}\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { HorseColors } from '@token-derby/shared';\nimport { activeRaceFile, activeRacesDir } from '../paths.js';\n\nexport type ActiveRace = {\n join_code: string;\n race_id: string;\n horse_id: string;\n heartbeat_token: string;\n horse_name: string;\n horse_colors: HorseColors;\n joined_at: string;\n last_race_tokens: number;\n last_heartbeat_at: string;\n};\n\nexport async function loadActiveRace(joinCode: string): Promise<ActiveRace | null> {\n try {\n const raw = await fs.readFile(activeRaceFile(joinCode), 'utf8');\n return JSON.parse(raw) as ActiveRace;\n } catch (e: any) {\n if (e?.code === 'ENOENT') return null;\n throw e;\n }\n}\n\nexport async function saveActiveRace(active: ActiveRace): Promise<void> {\n await fs.mkdir(activeRacesDir(), { recursive: true });\n await fs.writeFile(\n activeRaceFile(active.join_code),\n JSON.stringify(active, null, 2) + '\\n',\n 'utf8',\n );\n}\n\nexport async function deleteActiveRace(joinCode: string): Promise<void> {\n try {\n await fs.unlink(activeRaceFile(joinCode));\n } catch (e: any) {\n if (e?.code !== 'ENOENT') throw e;\n }\n}\n\nexport async function listActiveRaces(): Promise<string[]> {\n try {\n const entries = await fs.readdir(activeRacesDir());\n return entries\n .filter(f => f.endsWith('.json'))\n .map(f => path.basename(f, '.json'));\n } catch (e: any) {\n if (e?.code === 'ENOENT') return [];\n throw e;\n }\n}\n","import React from 'react';\nimport { render } from 'ink';\nimport { HorseCreator } from '../ui/HorseCreator.js';\nimport { upsertHorse, loadStable, findHorse } from '../stable/stable.js';\n\nexport async function stableEditCommand(name: string | undefined): Promise<number> {\n if (!name) {\n console.error('Usage: token-derby stable edit <name>');\n return 2;\n }\n const stable = await loadStable();\n const existing = findHorse(stable, name);\n if (!existing) {\n console.error(`No horse named \"${name}\" in your stable.`);\n return 1;\n }\n\n let exitCode = 0;\n const app = render(\n React.createElement(HorseCreator, {\n initialColors: existing.colors,\n initialName: existing.name,\n lockName: true,\n onSubmit: async (_name, colors) => {\n await upsertHorse({ name: existing.name, colors, created_at: existing.created_at });\n app.unmount();\n console.log(`✓ Updated \"${existing.name}\".`);\n },\n onCancel: () => {\n app.unmount();\n console.log('Cancelled.');\n exitCode = 1;\n },\n }),\n );\n await app.waitUntilExit();\n return exitCode;\n}\n","import * as readline from 'node:readline/promises';\nimport { stdin, stdout } from 'node:process';\nimport { createRace } from '../api/endpoints.js';\nimport { ApiError } from '../api/client.js';\n\nconst DEFAULT_TZ = Intl.DateTimeFormat().resolvedOptions().timeZone || 'UTC';\n\nexport async function createRaceCommand(): Promise<number> {\n const rl = readline.createInterface({ input: stdin, output: stdout });\n try {\n const name = (await rl.question('Race name: ')).trim();\n if (!name) { console.error('Name required.'); return 1; }\n\n const startRaw = (await rl.question('Start time (ISO 8601, blank = now): ')).trim();\n const start = startRaw ? startRaw : new Date().toISOString();\n if (!isIso(start)) { console.error('Invalid start time.'); return 1; }\n\n const durationRaw = (await rl.question('Race duration (hours): ')).trim();\n const durationHours = parseFloat(durationRaw);\n if (!Number.isFinite(durationHours) || durationHours <= 0) {\n console.error('Duration must be a positive number of hours.'); return 1;\n }\n const end = new Date(new Date(start).getTime() + durationHours * 3600_000).toISOString();\n\n const tz = (await rl.question(`Time zone [${DEFAULT_TZ}]: `)).trim() || DEFAULT_TZ;\n const maxRaw = (await rl.question('Max participants [30]: ')).trim();\n const max = maxRaw ? parseInt(maxRaw, 10) : undefined;\n if (max !== undefined && (!Number.isFinite(max) || max < 1)) {\n console.error('Max participants must be a positive number.'); return 1;\n }\n\n const resp = await createRace({\n name, start_time: start, end_time: end, tz,\n ...(max !== undefined ? { max_participants: max } : {}),\n });\n\n console.log('');\n console.log(' ╔══════════════════════════════════════╗');\n console.log(` ║ JOIN CODE: ${resp.join_code.padEnd(23)}║`);\n console.log(' ╚══════════════════════════════════════╝');\n console.log('');\n console.log(` Admin code: ${resp.admin_code}`);\n console.log(' ⚠ Save the admin code — you need it to end the race early.');\n console.log('');\n console.log(` Share with participants: token-derby join ${resp.join_code}`);\n return 0;\n } catch (e) {\n if (e instanceof ApiError) {\n console.error(`Error: ${e.code} ${e.message}`);\n return 1;\n }\n throw e;\n } finally {\n rl.close();\n }\n}\n\nfunction isIso(s: string): boolean {\n if (!s) return false;\n const d = new Date(s);\n return !Number.isNaN(d.getTime());\n}\n","export const DEFAULT_API_BASE = 'https://token-derby.mauricode.co.uk/api';\n\nexport function apiBase(): string {\n return process.env.TOKEN_DERBY_API_BASE ?? DEFAULT_API_BASE;\n}\n\nexport const HEARTBEAT_INTERVAL_MS = 60_000;\nexport const POLL_INTERVAL_MS = 3_000;\nexport const HEARTBEAT_RETRY_DELAYS_MS = [1_000, 2_000, 4_000, 8_000, 15_000];\n","import { createRequire } from 'node:module';\n\ndeclare const __CLI_VERSION__: string | undefined;\n\nfunction readVersion(): string {\n if (typeof __CLI_VERSION__ === 'string' && __CLI_VERSION__.length > 0) {\n return __CLI_VERSION__;\n }\n try {\n const req = createRequire(import.meta.url);\n const pkg = req('../package.json') as { version?: string };\n if (typeof pkg.version === 'string') return pkg.version;\n } catch {\n // fall through\n }\n return '0.0.0-dev';\n}\n\nexport const CLI_VERSION: string = readVersion();\n","export const DEFAULT_MAX_PARTICIPANTS = 30;\nexport const JOIN_CODE_LENGTH = 6;\nexport const JOIN_CODE_ALPHABET = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';\nexport const CLI_VERSION_HEADER = 'x-cli-version';\nexport const USER_ID_HEADER = 'x-user-id';\nexport const USER_NAME_HEADER = 'x-user-name';\nexport const USER_NAME_MAX_LENGTH = 40;\n","import { promises as fs } from 'node:fs';\nimport * as path from 'node:path';\nimport * as crypto from 'node:crypto';\nimport { USER_NAME_MAX_LENGTH } from '@token-derby/shared';\nimport { identityFile, homeDir } from '../paths.js';\n\nexport type Identity = {\n user_id: string;\n display_name: string;\n created_at: string;\n};\n\nexport async function loadIdentity(): Promise<Identity | null> {\n try {\n const raw = await fs.readFile(identityFile(), 'utf8');\n const parsed = JSON.parse(raw) as Partial<Identity>;\n if (\n typeof parsed.user_id === 'string' &&\n typeof parsed.display_name === 'string' &&\n typeof parsed.created_at === 'string'\n ) {\n return parsed as Identity;\n }\n return null;\n } catch (e: any) {\n if (e?.code === 'ENOENT') return null;\n return null;\n }\n}\n\nexport async function saveIdentity(identity: Identity): Promise<void> {\n await fs.mkdir(homeDir(), { recursive: true });\n await fs.writeFile(identityFile(), JSON.stringify(identity, null, 2) + '\\n', 'utf8');\n}\n\nexport function generateUserId(): string {\n return crypto.randomUUID();\n}\n\nexport function validateDisplayName(name: string): { ok: true; name: string } | { ok: false; error: string } {\n const trimmed = name.trim();\n if (trimmed.length < 1) return { ok: false, error: 'Name cannot be empty.' };\n if (trimmed.length > USER_NAME_MAX_LENGTH) {\n return { ok: false, error: `Name must be ${USER_NAME_MAX_LENGTH} characters or fewer.` };\n }\n return { ok: true, name: trimmed };\n}\n\nexport function identityFilePath(): string {\n return identityFile();\n}\n\nexport function identityFileDir(): string {\n return path.dirname(identityFile());\n}\n","import { apiBase } from '../config.js';\nimport { CLI_VERSION } from '../version.js';\nimport { CLI_VERSION_HEADER, USER_ID_HEADER, USER_NAME_HEADER } from '@token-derby/shared';\nimport { loadIdentity, type Identity } from '../identity/identity.js';\n\nexport type ApiErrorCode =\n | 'RACE_NOT_FOUND'\n | 'RACE_FULL'\n | 'RACE_FINISHED'\n | 'INVALID_TOKEN'\n | 'RATE_LIMITED'\n | 'BAD_REQUEST'\n | 'VERSION_MISMATCH'\n | 'IDENTITY_REQUIRED'\n | 'DUPLICATE_HORSE'\n | 'NETWORK_ERROR';\n\nexport class ApiError extends Error {\n constructor(\n readonly code: ApiErrorCode,\n message: string,\n readonly status: number,\n ) {\n super(message);\n this.name = 'ApiError';\n }\n}\n\ntype FetchFn = typeof fetch;\n\nlet identityCache: Promise<Identity | null> | null = null;\nfunction getIdentity(): Promise<Identity | null> {\n if (!identityCache) identityCache = loadIdentity();\n return identityCache;\n}\n\n// Tests can reset the cached identity.\nexport function _resetIdentityCacheForTests(): void {\n identityCache = null;\n}\n\nexport async function request<T>(\n method: string,\n path: string,\n body: unknown,\n authToken: string | undefined,\n fetchImpl: FetchFn = fetch,\n): Promise<T> {\n const url = path.startsWith('http') ? path : `${apiBase()}${path}`;\n const headers: Record<string, string> = {};\n headers[CLI_VERSION_HEADER] = CLI_VERSION;\n const identity = await getIdentity();\n if (identity) {\n headers[USER_ID_HEADER] = identity.user_id;\n headers[USER_NAME_HEADER] = identity.display_name;\n }\n if (authToken) headers['authorization'] = `Bearer ${authToken}`;\n if (body !== undefined) headers['content-type'] = 'application/json';\n\n let res: Awaited<ReturnType<FetchFn>>;\n try {\n res = await fetchImpl(url, {\n method,\n headers,\n body: body !== undefined ? JSON.stringify(body) : undefined,\n });\n } catch (e: any) {\n throw new ApiError('NETWORK_ERROR', e?.message ?? 'fetch failed', 0);\n }\n\n const text = await res.text();\n const contentType = res.headers.get('content-type') ?? '';\n let parsed: any = null;\n if (contentType.includes('application/json') && text.length > 0) {\n try {\n parsed = JSON.parse(text);\n } catch {\n parsed = null;\n }\n }\n\n if (!res.ok) {\n if (parsed && typeof parsed.code === 'string') {\n throw new ApiError(parsed.code as ApiErrorCode, parsed.message ?? 'API error', res.status);\n }\n throw new ApiError('NETWORK_ERROR', `HTTP ${res.status}`, res.status);\n }\n\n return parsed as T;\n}\n","import type {\n CreateRaceRequest, CreateRaceResponse,\n GetRaceResponse, JoinRaceRequest, JoinRaceResponse,\n HeartbeatRequest, HeartbeatResponse, EndRaceResponse,\n} from '@token-derby/shared';\nimport { request } from './client.js';\n\nexport function createRace(body: CreateRaceRequest) {\n return request<CreateRaceResponse>('POST', '/races', body, undefined);\n}\n\nexport function getRace(joinCode: string) {\n return request<GetRaceResponse>('GET', `/races/${encodeURIComponent(joinCode)}`, undefined, undefined);\n}\n\nexport function joinRace(joinCode: string, body: JoinRaceRequest) {\n return request<JoinRaceResponse>('POST', `/races/${encodeURIComponent(joinCode)}/join`, body, undefined);\n}\n\nexport function heartbeat(joinCode: string, horseId: string, token: string, body: HeartbeatRequest) {\n return request<HeartbeatResponse>(\n 'POST',\n `/races/${encodeURIComponent(joinCode)}/horses/${encodeURIComponent(horseId)}/heartbeat`,\n body,\n token,\n );\n}\n\nexport function endRace(adminCode: string) {\n return request<EndRaceResponse>('DELETE', `/races/admin/${encodeURIComponent(adminCode)}`, undefined, undefined);\n}\n","import React from 'react';\nimport { render } from 'ink';\nimport type { HorseColors, HorseView } from '@token-derby/shared';\nimport { loadStable } from '../stable/stable.js';\nimport { HorsePicker } from '../ui/HorsePicker.js';\nimport { joinRace, getRace } from '../api/endpoints.js';\nimport { ApiError } from '../api/client.js';\nimport { saveActiveRace, loadActiveRace, type ActiveRace } from '../stable/active-race.js';\nimport { RunRace, buildInitialState } from '../runtime/run-race.js';\nimport { loadIdentity } from '../identity/identity.js';\nimport type { StableHorse } from '../stable/stable.js';\n\nexport async function joinCommand(joinCode: string | undefined): Promise<number> {\n if (!joinCode) {\n console.error('Usage: token-derby join <join-code>');\n return 2;\n }\n const code = joinCode.toUpperCase();\n\n const identity = await loadIdentity();\n if (!identity) {\n // Defensive — bin.ts already checks. Kept so this command is self-contained.\n console.error('Run `token-derby init` to set up your identity.');\n return 1;\n }\n\n // Pre-flight: fetch the race view to detect whether this user is already in it.\n let race;\n try {\n race = await getRace(code);\n } catch (e) {\n if (e instanceof ApiError) {\n if (e.code === 'RACE_NOT_FOUND') console.error(`No race with join code ${code}.`);\n else console.error(`Error: ${e.code} ${e.message}`);\n return 1;\n }\n throw e;\n }\n if (race.status === 'finished') {\n console.error('This race has already ended.');\n return 1;\n }\n\n const ownHorse = race.horses.find(h => h.user_id === identity.user_id) ?? null;\n\n let chosenName: string;\n let chosenColors: HorseColors;\n let isResume: boolean;\n\n if (ownHorse) {\n // Auto-resume: use server's snapshot of the horse, no picker.\n chosenName = ownHorse.name;\n chosenColors = ownHorse.colors;\n isResume = true;\n } else {\n const stable = await loadStable();\n if (stable.horses.length === 0) {\n console.error('Your stable is empty. Run `token-derby stable create` first.');\n return 1;\n }\n const picked = await pickHorse(stable.horses);\n if (!picked) { console.log('Cancelled.'); return 1; }\n chosenName = picked.name;\n chosenColors = picked.colors;\n isResume = false;\n }\n\n let joinResp;\n try {\n joinResp = await joinRace(code, { horse: { name: chosenName, colors: chosenColors } });\n } catch (e) {\n if (e instanceof ApiError) {\n if (e.code === 'RACE_FULL') console.error('This race is full.');\n else if (e.code === 'RACE_FINISHED') console.error('This race has ended.');\n else if (e.code === 'RACE_NOT_FOUND') console.error(`No race with join code ${code}.`);\n else if (e.code === 'VERSION_MISMATCH') console.error(e.message);\n else if (e.code === 'DUPLICATE_HORSE') console.error(e.message);\n else if (e.code === 'IDENTITY_REQUIRED') console.error(`Error: ${e.message}`);\n else console.error(`Error: ${e.code} ${e.message}`);\n return 1;\n }\n throw e;\n }\n\n // For resume, try to carry forward our last token total from active-races state.\n const prior = await loadActiveRace(code);\n const lastTokens = isResume && prior?.horse_id === joinResp.horse_id ? prior.last_race_tokens : (ownHorse?.current_tokens ?? 0);\n\n const status: 'pending' | 'live' = race.status;\n const active: ActiveRace = {\n join_code: code,\n race_id: race.race_id,\n horse_id: joinResp.horse_id,\n heartbeat_token: joinResp.heartbeat_token,\n horse_name: chosenName,\n horse_colors: chosenColors,\n joined_at: ownHorse?.joined_at ?? new Date().toISOString(),\n last_race_tokens: lastTokens,\n last_heartbeat_at: new Date(0).toISOString(),\n };\n await saveActiveRace(active);\n\n const initial = await buildInitialState({ active, raceStatus: status, rejoin: isResume });\n const app = render(React.createElement(RunRace, { active, ...initial, ownUserName: identity.display_name }));\n await app.waitUntilExit();\n return 0;\n}\n\nasync function pickHorse(horses: StableHorse[]): Promise<StableHorse | null> {\n return new Promise(resolve => {\n const app = render(\n React.createElement(HorsePicker, {\n horses,\n onPick: (h: StableHorse) => { app.unmount(); resolve(h); },\n onCancel: () => { app.unmount(); resolve(null); },\n }),\n );\n });\n}\n","import React, { useState } from 'react';\nimport { Box, Text, useInput } from 'ink';\nimport { HorseSprite } from './HorseSprite.js';\nimport { MINI_SPRITE } from './sprite.js';\nimport type { StableHorse } from '../stable/stable.js';\n\ntype Props = {\n horses: StableHorse[];\n onPick: (horse: StableHorse) => void;\n onCancel: () => void;\n};\n\nexport function HorsePicker({ horses, onPick, onCancel }: Props) {\n const [idx, setIdx] = useState(0);\n\n useInput((input, key) => {\n if (key.escape) { onCancel(); return; }\n if (horses.length === 0) return;\n if (key.upArrow) { setIdx((idx - 1 + horses.length) % horses.length); return; }\n if (key.downArrow) { setIdx((idx + 1) % horses.length); return; }\n if (key.return) { onPick(horses[idx]!); return; }\n });\n\n if (horses.length === 0) {\n return (\n <Box flexDirection=\"column\">\n <Text>No horses in your stable.</Text>\n <Text dimColor>Run `token-derby stable create` to make one.</Text>\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"column\">\n <Text>Pick a horse to race:</Text>\n {horses.map((h, i) => (\n <Box key={h.name} flexDirection=\"column\">\n <Box flexDirection=\"row\">\n <Text>{i === idx ? '►' : ' '} {h.name}</Text>\n </Box>\n <Box flexDirection=\"row\">\n <Text> </Text>\n <HorseSprite sprite={MINI_SPRITE} colors={h.colors} />\n </Box>\n </Box>\n ))}\n <Box marginTop={1}>\n <Text dimColor>↑/↓ choose · Enter pick · Esc cancel</Text>\n </Box>\n </Box>\n );\n}\n","import React, { useEffect, useRef, useState } from 'react';\nimport { Box, Text, useApp } from 'ink';\nimport type { GetRaceResponse, HeartbeatResponse } from '@token-derby/shared';\nimport { StatusScreen } from '../ui/StatusScreen.js';\nimport { runHeartbeatLoop } from './heartbeat-loop.js';\nimport { runPollLoop } from './poll-loop.js';\nimport { sumOutputTokens } from '../tokens/transcripts.js';\nimport { initialBaseline } from '../tokens/baseline.js';\nimport * as endpoints from '../api/endpoints.js';\nimport { ApiError } from '../api/client.js';\nimport { saveActiveRace, type ActiveRace } from '../stable/active-race.js';\nimport { HEARTBEAT_INTERVAL_MS, POLL_INTERVAL_MS, HEARTBEAT_RETRY_DELAYS_MS } from '../config.js';\n\nexport type RunRaceProps = {\n active: ActiveRace;\n startingBaseline: number;\n pendingMode: boolean;\n ownUserName: string;\n};\n\nexport function RunRace({ active, startingBaseline, pendingMode, ownUserName }: RunRaceProps) {\n const { exit } = useApp();\n const [race, setRace] = useState<GetRaceResponse | null>(null);\n const [lastHbAt, setLastHbAt] = useState<Date | null>(null);\n const [lastHbOk, setLastHbOk] = useState<boolean>(true);\n const [tickNow, setTickNow] = useState<Date>(new Date());\n const [fatalError, setFatalError] = useState<string | null>(null);\n\n const baselineRef = useRef(startingBaseline);\n const pendingRef = useRef(pendingMode);\n const lastTokenSampleRef = useRef<number>(startingBaseline);\n const ctrl = useRef(new AbortController());\n\n // Re-render every second so the \"Ns ago\" counter updates.\n useEffect(() => {\n const t = setInterval(() => setTickNow(new Date()), 1_000);\n return () => clearInterval(t);\n }, []);\n\n // Re-snapshot baseline when race transitions pending → live.\n useEffect(() => {\n if (pendingRef.current && race?.status === 'live') {\n sumOutputTokens().then(total => {\n baselineRef.current = total;\n pendingRef.current = false;\n });\n }\n }, [race?.status]);\n\n useEffect(() => {\n runPollLoop({\n fetchRace: () => endpoints.getRace(active.join_code),\n intervalMs: POLL_INTERVAL_MS,\n onSnapshot: (r) => setRace(r),\n onError: () => {/* silently keep last-known state */},\n abortSignal: ctrl.current.signal,\n });\n\n runHeartbeatLoop({\n sendHeartbeat: async (currentTokens) => {\n const resp = await endpoints.heartbeat(\n active.join_code, active.horse_id, active.heartbeat_token, { current_tokens: currentTokens },\n );\n const updated: ActiveRace = {\n ...active,\n last_race_tokens: currentTokens,\n last_heartbeat_at: new Date().toISOString(),\n };\n await saveActiveRace(updated);\n return resp;\n },\n getCurrentTokens: () => {\n if (pendingRef.current) return 0;\n return Math.max(0, lastTokenSampleRef.current - baselineRef.current);\n },\n intervalMs: HEARTBEAT_INTERVAL_MS,\n retryDelaysMs: HEARTBEAT_RETRY_DELAYS_MS,\n onSuccess: (resp: HeartbeatResponse) => {\n setLastHbAt(new Date());\n setLastHbOk(true);\n if (resp.race_status === 'finished') exit();\n },\n onError: (err) => {\n if (err instanceof ApiError && err.code === 'VERSION_MISMATCH') {\n setFatalError(err.message);\n ctrl.current.abort();\n exit();\n return;\n }\n setLastHbOk(false);\n },\n onFinished: () => exit(),\n abortSignal: ctrl.current.signal,\n });\n\n // Token sampler — refresh the running token total every 5s so the heartbeat sees fresh data.\n const sampler = setInterval(async () => {\n try {\n lastTokenSampleRef.current = await sumOutputTokens();\n } catch {/* keep last sample */}\n }, 5_000);\n // Prime it once at startup.\n sumOutputTokens().then(t => { lastTokenSampleRef.current = t; }).catch(() => {});\n\n const controller = ctrl.current;\n return () => {\n clearInterval(sampler);\n controller.abort();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const lastHeartbeatAgoSec = lastHbAt\n ? Math.max(0, Math.floor((tickNow.getTime() - lastHbAt.getTime()) / 1000))\n : null;\n\n if (fatalError) {\n return (\n <Box flexDirection=\"column\" padding={1}>\n <Text color=\"red\" bold>CLI version mismatch — disconnected</Text>\n <Text>{fatalError}</Text>\n </Box>\n );\n }\n\n return (\n <StatusScreen\n race={race}\n ownHorseId={active.horse_id}\n ownHorseName={active.horse_name}\n ownColors={active.horse_colors}\n ownUserName={ownUserName}\n lastHeartbeatAgoSec={lastHeartbeatAgoSec}\n lastHeartbeatOk={lastHbOk}\n />\n );\n}\n\nexport async function buildInitialState(args: {\n active: ActiveRace;\n raceStatus: 'pending' | 'live';\n rejoin: boolean;\n}): Promise<{ startingBaseline: number; pendingMode: boolean }> {\n const runningTotal = await sumOutputTokens();\n if (args.rejoin) {\n return {\n startingBaseline: Math.max(0, runningTotal - args.active.last_race_tokens),\n pendingMode: args.raceStatus === 'pending',\n };\n }\n return {\n startingBaseline: initialBaseline({ runningTotal, status: args.raceStatus }),\n pendingMode: args.raceStatus === 'pending',\n };\n}\n","import React from 'react';\nimport { Box, Text } from 'ink';\nimport type { GetRaceResponse, HorseColors, HorseView } from '@token-derby/shared';\nimport { HorseSprite } from './HorseSprite.js';\nimport { MINI_SPRITE } from './sprite.js';\n\ntype Props = {\n race: GetRaceResponse | null;\n ownHorseId: string;\n ownHorseName: string;\n ownColors: HorseColors;\n ownUserName: string;\n lastHeartbeatAgoSec: number | null;\n lastHeartbeatOk: boolean;\n};\n\nexport function StatusScreen(props: Props) {\n const { race, ownHorseId, ownHorseName, ownColors, ownUserName, lastHeartbeatAgoSec, lastHeartbeatOk } = props;\n\n if (!race) {\n return (\n <Box flexDirection=\"column\">\n <Text>Joining race…</Text>\n </Box>\n );\n }\n\n const own: HorseView | undefined = race.horses.find(h => h.horse_id === ownHorseId);\n const leader: HorseView | undefined = race.horses[0];\n const elapsedPct = elapsed(race);\n const timeLeft = formatDuration(race.time_left_seconds);\n\n return (\n <Box flexDirection=\"column\" borderStyle=\"round\" paddingX={1}>\n <Text>\n 🏇 TOKEN DERBY ─── <Text bold>{race.name}</Text> ─── status: <Text color={statusColor(race.status)}>{race.status}</Text>\n </Text>\n\n <Box marginTop={1} flexDirection=\"row\">\n <HorseSprite sprite={MINI_SPRITE} colors={ownColors} />\n <Box flexDirection=\"column\">\n <Text> {ownHorseName}</Text>\n <Text> <Text dimColor>({ownUserName})</Text></Text>\n </Box>\n </Box>\n\n <Box flexDirection=\"column\" marginTop={1}>\n <Text>Tokens (race): {own?.current_tokens ?? 0}</Text>\n <Text>Position: {own?.rank ?? '—'} of {race.horses.length}</Text>\n <Text>\n Leader: {leader ? `${leader.name}${leader.user_name ? ` (${leader.user_name})` : ''} — ${leader.current_tokens}` : '—'}\n </Text>\n <Text>Race elapsed: {(elapsedPct * 100).toFixed(0)}% {bar(elapsedPct, 20)}</Text>\n <Text>Time left: {timeLeft}</Text>\n <Text>\n Last heartbeat: {lastHeartbeatAgoSec === null ? '—' : `${lastHeartbeatAgoSec}s ago`}\n {' '}\n <Text color={lastHeartbeatOk ? 'green' : 'yellow'}>\n {lastHeartbeatOk ? '✓' : '⚠'}\n </Text>\n </Text>\n </Box>\n\n <Box marginTop={1}>\n <Text dimColor>Press Ctrl+C to crash out of the race.</Text>\n </Box>\n </Box>\n );\n}\n\nfunction elapsed(race: GetRaceResponse): number {\n const start = new Date(race.start_time).getTime();\n const end = new Date(race.end_time).getTime();\n const now = new Date(race.server_time).getTime();\n if (end <= start) return 0;\n const v = (now - start) / (end - start);\n return Math.max(0, Math.min(1, v));\n}\n\nfunction bar(pct: number, width: number): string {\n const filled = Math.round(pct * width);\n return '▓'.repeat(filled) + '░'.repeat(width - filled);\n}\n\nfunction statusColor(status: GetRaceResponse['status']): string {\n if (status === 'live') return 'green';\n if (status === 'pending') return 'yellow';\n return 'gray';\n}\n\nfunction formatDuration(seconds: number): string {\n const s = Math.max(0, Math.floor(seconds));\n const h = Math.floor(s / 3600);\n const m = Math.floor((s % 3600) / 60);\n const ss = s % 60;\n return `${h.toString().padStart(2, '0')}:${m.toString().padStart(2, '0')}:${ss.toString().padStart(2, '0')}`;\n}\n","import type { HeartbeatResponse } from '@token-derby/shared';\n\nexport type HeartbeatLoopOptions = {\n sendHeartbeat: (currentTokens: number) => Promise<HeartbeatResponse>;\n getCurrentTokens: () => number;\n intervalMs: number;\n retryDelaysMs: readonly number[];\n onSuccess: (resp: HeartbeatResponse) => void;\n onError: (err: unknown) => void;\n onFinished: () => void;\n abortSignal: AbortSignal;\n};\n\nexport function runHeartbeatLoop(opts: HeartbeatLoopOptions): void {\n let timer: ReturnType<typeof setTimeout> | null = null;\n let retryIndex = 0;\n let stopped = false;\n\n const stop = () => {\n stopped = true;\n if (timer) clearTimeout(timer);\n timer = null;\n };\n\n opts.abortSignal.addEventListener('abort', stop, { once: true });\n\n const schedule = (delay: number) => {\n if (stopped) return;\n timer = setTimeout(tick, delay);\n };\n\n const tick = async () => {\n if (stopped) return;\n try {\n const tokens = opts.getCurrentTokens();\n const resp = await opts.sendHeartbeat(tokens);\n retryIndex = 0;\n opts.onSuccess(resp);\n if (resp.race_status === 'finished') {\n opts.onFinished();\n stop();\n return;\n }\n schedule(opts.intervalMs);\n } catch (err) {\n opts.onError(err);\n const delay = opts.retryDelaysMs[Math.min(retryIndex, opts.retryDelaysMs.length - 1)] ?? 1_000;\n retryIndex += 1;\n schedule(delay);\n }\n };\n\n schedule(0);\n}\n","import type { GetRaceResponse } from '@token-derby/shared';\n\nexport type PollLoopOptions = {\n fetchRace: () => Promise<GetRaceResponse>;\n intervalMs: number;\n onSnapshot: (race: GetRaceResponse) => void;\n onError: (err: unknown) => void;\n abortSignal: AbortSignal;\n};\n\nexport function runPollLoop(opts: PollLoopOptions): void {\n let timer: ReturnType<typeof setTimeout> | null = null;\n let stopped = false;\n\n const stop = () => {\n stopped = true;\n if (timer) clearTimeout(timer);\n timer = null;\n };\n\n opts.abortSignal.addEventListener('abort', stop, { once: true });\n\n const tick = async () => {\n if (stopped) return;\n try {\n const race = await opts.fetchRace();\n if (!stopped) opts.onSnapshot(race);\n } catch (err) {\n if (!stopped) opts.onError(err);\n }\n if (!stopped) timer = setTimeout(tick, opts.intervalMs);\n };\n\n timer = setTimeout(tick, 0);\n}\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { claudeProjectsDir } from '../paths.js';\n\nexport type TokenTotals = { input: number; output: number };\n\nexport async function sumTokens(): Promise<TokenTotals> {\n const root = claudeProjectsDir();\n const files = await listJsonlFiles(root);\n let input = 0;\n let output = 0;\n for (const file of files) {\n const t = await sumFile(file);\n input += t.input;\n output += t.output;\n }\n return { input, output };\n}\n\n/** @deprecated Use sumTokens() instead */\nexport async function sumOutputTokens(): Promise<number> {\n const { input, output } = await sumTokens();\n return input + output;\n}\n\nasync function listJsonlFiles(root: string): Promise<string[]> {\n let projects: string[];\n try {\n projects = await fs.readdir(root);\n } catch (e: any) {\n if (e?.code === 'ENOENT') return [];\n throw e;\n }\n const out: string[] = [];\n for (const project of projects) {\n const projectDir = path.join(root, project);\n let stat;\n try {\n stat = await fs.stat(projectDir);\n } catch {\n continue;\n }\n if (!stat.isDirectory()) continue;\n const entries = await fs.readdir(projectDir);\n for (const entry of entries) {\n if (entry.endsWith('.jsonl')) out.push(path.join(projectDir, entry));\n }\n }\n return out;\n}\n\nfunction addNum(value: unknown): number {\n return typeof value === 'number' && Number.isFinite(value) ? value : 0;\n}\n\nasync function sumFile(file: string): Promise<TokenTotals> {\n let raw: string;\n try {\n raw = await fs.readFile(file, 'utf8');\n } catch {\n return { input: 0, output: 0 };\n }\n let input = 0;\n let output = 0;\n for (const line of raw.split('\\n')) {\n if (!line.trim()) continue;\n let parsed: any;\n try {\n parsed = JSON.parse(line);\n } catch {\n continue;\n }\n const usage = parsed?.message?.usage;\n if (!usage) continue;\n input += addNum(usage.input_tokens)\n + addNum(usage.cache_creation_input_tokens)\n + addNum(usage.cache_read_input_tokens);\n output += addNum(usage.output_tokens);\n }\n return { input, output };\n}\n","import type { RaceStatus } from '@token-derby/shared';\n\nexport function initialBaseline(args: { runningTotal: number; status: RaceStatus }): number {\n return args.runningTotal;\n}\n\nexport function rejoinBaseline(args: { runningTotal: number; lastRaceTokens: number }): number {\n return Math.max(0, args.runningTotal - args.lastRaceTokens);\n}\n\nexport function currentRaceTokens(runningTotal: number, baseline: number): number {\n return Math.max(0, runningTotal - baseline);\n}\n","import * as readline from 'node:readline/promises';\nimport { stdin, stdout } from 'node:process';\nimport { endRace } from '../api/endpoints.js';\nimport { ApiError } from '../api/client.js';\n\nexport async function endCommand(adminCode: string | undefined): Promise<number> {\n if (!adminCode) {\n console.error('Usage: token-derby end <admin-code>');\n return 2;\n }\n const rl = readline.createInterface({ input: stdin, output: stdout });\n const answer = (await rl.question('End the race now and freeze final tokens? [y/N] ')).trim().toLowerCase();\n rl.close();\n if (answer !== 'y' && answer !== 'yes') {\n console.log('Cancelled.');\n return 1;\n }\n try {\n await endRace(adminCode);\n console.log('✓ Race ended.');\n return 0;\n } catch (e) {\n if (e instanceof ApiError) {\n if (e.code === 'RACE_NOT_FOUND') console.error('No race with that admin code.');\n else console.error(`Error: ${e.code} ${e.message}`);\n return 1;\n }\n throw e;\n }\n}\n","import * as readline from 'node:readline/promises';\nimport { stdin, stdout } from 'node:process';\nimport {\n loadIdentity,\n saveIdentity,\n generateUserId,\n validateDisplayName,\n type Identity,\n} from '../identity/identity.js';\n\nexport async function initCommand(): Promise<number> {\n const existing = await loadIdentity();\n const rl = readline.createInterface({ input: stdin, output: stdout });\n try {\n if (existing) {\n console.log(`Current jockey name: ${existing.display_name}`);\n const raw = (await rl.question('New jockey name (use your real name please) [keep]: ')).trim();\n if (!raw) {\n console.log('Kept existing name.');\n return 0;\n }\n const v = validateDisplayName(raw);\n if (!v.ok) { console.error(v.error); return 1; }\n const updated: Identity = { ...existing, display_name: v.name };\n await saveIdentity(updated);\n console.log(`Updated jockey name to: ${updated.display_name}`);\n return 0;\n }\n\n const raw = (await rl.question('Jockey Name (use your real name please): ')).trim();\n const v = validateDisplayName(raw);\n if (!v.ok) { console.error(v.error); return 1; }\n\n const identity: Identity = {\n user_id: generateUserId(),\n display_name: v.name,\n created_at: new Date().toISOString(),\n };\n await saveIdentity(identity);\n console.log('');\n console.log(`Welcome, ${identity.display_name}!`);\n console.log(`Your identity is saved. You can now create a stable and join races.`);\n return 0;\n } finally {\n rl.close();\n }\n}\n","import { stableCreateCommand } from './commands/stable-create.js';\nimport { stableListCommand } from './commands/stable-list.js';\nimport { stableDeleteCommand } from './commands/stable-delete.js';\nimport { stableEditCommand } from './commands/stable-edit.js';\nimport { createRaceCommand } from './commands/create.js';\nimport { joinCommand } from './commands/join.js';\nimport { endCommand } from './commands/end.js';\nimport { initCommand } from './commands/init.js';\nimport { CLI_VERSION } from './version.js';\nimport { loadIdentity } from './identity/identity.js';\n\nconst HELP = `token-derby v${CLI_VERSION}\n\nIdentity:\n token-derby init Set up your jockey identity (run this first)\n\nStable management:\n token-derby stable create Make a new horse (interactive)\n token-derby stable list Show your saved horses\n token-derby stable edit <name> Edit an existing horse's colors\n token-derby stable delete <name> Remove a horse from your stable\n\nRaces:\n token-derby create Create a new race (interactive)\n token-derby join <join-code> Join (or resume) a race\n token-derby end <admin-code> End a race early\n\nEnvironment:\n TOKEN_DERBY_API_BASE Override API base URL (default: production)\n TOKEN_DERBY_HOME Override identity/stable directory\n`;\n\nasync function main(): Promise<number> {\n const argv = process.argv.slice(2);\n const cmd = argv[0];\n\n if (!cmd || cmd === '--help' || cmd === '-h') { console.log(HELP); return 0; }\n if (cmd === '--version' || cmd === '-v') { console.log(CLI_VERSION); return 0; }\n\n if (cmd === 'init') return initCommand();\n\n // Every other command requires an identity. `init` is the only escape hatch.\n const identity = await loadIdentity();\n if (!identity) {\n console.error('Run `token-derby init` to set up your identity before using any other command.');\n return 1;\n }\n\n if (cmd === 'stable') {\n const sub = argv[1];\n if (sub === 'create') return stableCreateCommand();\n if (sub === 'list') return stableListCommand();\n if (sub === 'edit') return stableEditCommand(argv[2]);\n if (sub === 'delete') return stableDeleteCommand(argv[2]);\n console.error(`Unknown stable subcommand: ${sub ?? '(none)'}`);\n console.error('Try: stable create | stable list | stable edit <name> | stable delete <name>');\n return 2;\n }\n\n if (cmd === 'create') return createRaceCommand();\n if (cmd === 'join') return joinCommand(argv[1]);\n if (cmd === 'end') return endCommand(argv[1]);\n\n console.error(`Unknown command: ${cmd}`);\n console.error(HELP);\n return 2;\n}\n\nmain().then(\n code => process.exit(code),\n err => {\n console.error(err?.stack ?? err);\n process.exit(1);\n },\n);\n"],"mappings":"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","names":["React","Box","Text","jsx","Box","Text","React","React","render","Box","Text","jsx","jsxs","render","React","Box","Text","readline","stdin","stdout","fs","path","stdin","stdout","React","render","render","React","readline","stdin","stdout","fs","path","fs","path","stdin","stdout","React","render","useState","Box","Text","useInput","jsx","jsxs","useState","useInput","Box","Text","useState","Box","Text","Box","Text","jsx","jsxs","Box","Text","fs","path","stat","jsx","jsxs","useState","Box","Text","render","React","readline","stdin","stdout","stdin","stdout","readline","stdin","stdout","stdin","stdout","raw","v"]}
1
+ {"version":3,"sources":["../src/commands/stable-create.ts","../src/ui/HorseCreator.tsx","../src/ui/HorseSprite.tsx","../src/ui/sprite.ts","../src/ui/sprite-render.ts","../src/ui/palette.ts","../src/stable/stable.ts","../src/paths.ts","../src/commands/stable-list.tsx","../src/commands/stable-delete.ts","../src/stable/active-race.ts","../src/commands/stable-edit.ts","../src/commands/create.ts","../src/config.ts","../src/version.ts","../../shared/src/constants.ts","../src/identity/identity.ts","../src/api/client.ts","../src/api/endpoints.ts","../src/commands/join.ts","../src/ui/HorsePicker.tsx","../src/runtime/run-race.tsx","../src/ui/StatusScreen.tsx","../src/runtime/heartbeat-loop.ts","../src/runtime/poll-loop.ts","../src/tokens/transcripts.ts","../src/tokens/baseline.ts","../src/commands/end.ts","../src/commands/init.ts","../src/bin.ts"],"sourcesContent":["import React from 'react';\nimport { render } from 'ink';\nimport { HorseCreator } from '../ui/HorseCreator.js';\nimport { upsertHorse, loadStable, findHorse, newStableHorseId } from '../stable/stable.js';\nimport * as readline from 'node:readline/promises';\nimport { stdin, stdout } from 'node:process';\n\nexport async function stableCreateCommand(): Promise<number> {\n let exitCode = 0;\n const app = render(\n React.createElement(HorseCreator, {\n onSubmit: async (name, colors) => {\n const stable = await loadStable();\n const existing = findHorse(stable, name);\n if (existing) {\n app.unmount();\n const rl = readline.createInterface({ input: stdin, output: stdout });\n const answer = (await rl.question(`Horse \"${name}\" already exists. Overwrite? [y/N] `)).trim().toLowerCase();\n rl.close();\n if (answer !== 'y' && answer !== 'yes') {\n console.log('Cancelled.');\n exitCode = 1;\n return;\n }\n }\n const stable_horse_id = existing?.stable_horse_id ?? newStableHorseId();\n await upsertHorse({ stable_horse_id, name, colors, created_at: new Date().toISOString() });\n app.unmount();\n console.log(`✓ Saved \"${name}\" to your stable.`);\n },\n onCancel: () => {\n app.unmount();\n console.log('Cancelled.');\n exitCode = 1;\n },\n }),\n );\n await app.waitUntilExit();\n return exitCode;\n}\n","import React, { useState } from 'react';\nimport { Box, Text, useInput } from 'ink';\nimport TextInput from 'ink-text-input';\nimport type { HorseColors } from '@token-derby/shared';\nimport { HorseSprite } from './HorseSprite.js';\nimport { MAIN_SPRITE } from './sprite.js';\nimport { SLOTS, PALETTES, nextColor, prevColor, defaultColors, type Slot } from './palette.js';\n\ntype Props = {\n onSubmit: (name: string, colors: HorseColors) => void;\n onCancel: () => void;\n initialColors?: HorseColors;\n initialName?: string;\n lockName?: boolean;\n};\n\nexport function HorseCreator({ onSubmit, onCancel, initialColors, initialName, lockName }: Props) {\n const [colors, setColors] = useState<HorseColors>(initialColors ?? defaultColors());\n const [slotIdx, setSlotIdx] = useState(0);\n const [namingMode, setNamingMode] = useState(false);\n const [name, setName] = useState(initialName ?? '');\n const [error, setError] = useState<string | null>(null);\n\n const slot: Slot = SLOTS[slotIdx]!;\n\n useInput((input, key) => {\n if (namingMode) return;\n if (key.escape) { onCancel(); return; }\n if (key.upArrow) { setSlotIdx((slotIdx - 1 + SLOTS.length) % SLOTS.length); return; }\n if (key.downArrow) { setSlotIdx((slotIdx + 1) % SLOTS.length); return; }\n if (key.leftArrow) { setColors({ ...colors, [slot]: prevColor(slot, colors[slot]) }); return; }\n if (key.rightArrow) { setColors({ ...colors, [slot]: nextColor(slot, colors[slot]) }); return; }\n if (key.return) {\n if (lockName) { onSubmit(initialName ?? '', colors); return; }\n setNamingMode(true);\n return;\n }\n });\n\n const handleNameSubmit = (value: string) => {\n if (!value.trim()) {\n setError('Name required');\n return;\n }\n onSubmit(value.trim(), colors);\n };\n\n return (\n <Box flexDirection=\"column\">\n <Box marginBottom={1}>\n <HorseSprite sprite={MAIN_SPRITE} colors={colors} />\n </Box>\n\n <Box flexDirection=\"column\">\n {SLOTS.map((s, i) => (\n <Text key={s}>\n {i === slotIdx ? '►' : ' '} {s.padEnd(7)} <Text color={colors[s]}>██</Text> {colors[s]}\n </Text>\n ))}\n </Box>\n\n {!namingMode && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text dimColor>↑/↓ select slot · ←/→ cycle color · Enter accept · Esc cancel</Text>\n </Box>\n )}\n\n {namingMode && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text>Name your horse: </Text>\n <TextInput value={name} onChange={(v) => { setName(v); setError(null); }} onSubmit={handleNameSubmit} />\n {error && <Text color=\"red\">{error}</Text>}\n </Box>\n )}\n </Box>\n );\n}\n","import React from 'react';\nimport { Box, Text } from 'ink';\nimport type { HorseColors } from '@token-derby/shared';\nimport { renderSprite, type Cell } from './sprite-render.js';\nimport type { SlotTag } from './sprite.js';\n\ntype Props = {\n sprite: readonly (readonly SlotTag[])[];\n colors: HorseColors;\n};\n\nexport function HorseSprite({ sprite, colors }: Props) {\n const grid = renderSprite(sprite, colors);\n return (\n <Box flexDirection=\"column\">\n {grid.map((row, y) => (\n <Text key={y}>{rowToAnsi(row)}</Text>\n ))}\n </Box>\n );\n}\n\nfunction rowToAnsi(row: Cell[]): string {\n let out = '';\n for (const cell of row) {\n if (cell.top === null && cell.bottom === null) {\n out += ' ';\n } else if (cell.top !== null && cell.bottom !== null) {\n out += ansiFg(cell.top) + ansiBg(cell.bottom) + '▀' + RESET;\n } else if (cell.top !== null) {\n out += ansiFg(cell.top) + '▀' + RESET;\n } else {\n out += ansiFg(cell.bottom!) + '▄' + RESET;\n }\n }\n return out;\n}\n\nconst RESET = '\\x1b[0m';\n\nfunction hexToRgb(hex: string): [number, number, number] {\n const h = hex.replace('#', '');\n return [\n parseInt(h.slice(0, 2), 16),\n parseInt(h.slice(2, 4), 16),\n parseInt(h.slice(4, 6), 16),\n ];\n}\n\nfunction ansiFg(hex: string): string {\n const [r, g, b] = hexToRgb(hex);\n return `\\x1b[38;2;${r};${g};${b}m`;\n}\n\nfunction ansiBg(hex: string): string {\n const [r, g, b] = hexToRgb(hex);\n return `\\x1b[48;2;${r};${g};${b}m`;\n}\n","// Pixel slot tags. `null` = transparent.\n// B = body, M = mane, T = tail, S = saddle, E = eye (fixed black), H = hoof (fixed dark)\nexport type SlotTag = 'B' | 'M' | 'T' | 'S' | 'E' | 'H' | null;\n\nexport const FIXED_COLORS = {\n E: '#000000',\n H: '#1F1108',\n} as const;\n\n// Each pair of adjacent rows is intentionally identical so every half-block\n// cell renders as a solid color. The only intentional split is the last row\n// (legs/hooves transition).\nconst MAIN_ROWS: readonly string[] = [\n '................................',\n '................................',\n '..........................MMM...',\n '..........................MMM...',\n '.........................MBBEBB.',\n '.........................MBBEBB.',\n '........................MBBBBBBB',\n '........................MBBBBBBB',\n '..................MMMMMMMBBB....',\n '..................MMMMMMMBBB....',\n '....BBBBBBBBSSSSSSMMBBBBBB......',\n '...BBBBBBBBBSSSSSSMMBBBBBB......',\n '.TTBBBBBBBBBSSSSSSBBBBBBBB......',\n '.TTBBBBBBBBBSSSSSSBBBBBBBB......',\n 'TTTBBBBBBBBBBBBBBBBBBBBBBB......',\n 'TTTBBBBBBBBBBBBBBBBBBBBB........',\n '...BBB.BBB.....BBB.BBB..........',\n '...BBB.BBB.....BBB.BBB..........',\n '....BB..BB......BB..BB..........',\n '....BB..BB......BB..BB..........',\n '....BB..BB......BB..BB..........',\n '....BB..BB......BB..BB..........',\n '....BB..BB......BB..BB..........',\n '...HHH.HHH.....HHH.HHH..........',\n];\n\nconst MINI_ROWS: readonly string[] = [\n '.BBSSMBB',\n '.BBSSMBB',\n 'TBBBBBB.',\n 'THH..HH.',\n];\n\nexport const MAIN_SPRITE: readonly (readonly SlotTag[])[] = parse(MAIN_ROWS, 32, 24);\nexport const MINI_SPRITE: readonly (readonly SlotTag[])[] = parse(MINI_ROWS, 8, 4);\n\nfunction parse(rows: readonly string[], width: number, height: number): SlotTag[][] {\n if (rows.length !== height) {\n throw new Error(`sprite has ${rows.length} rows, expected ${height}`);\n }\n return rows.map((row, y) => {\n if (row.length !== width) {\n throw new Error(`sprite row ${y} has length ${row.length}, expected ${width}`);\n }\n return [...row].map(c => toTag(c));\n });\n}\n\nfunction toTag(c: string): SlotTag {\n switch (c) {\n case 'B': return 'B';\n case 'M': return 'M';\n case 'T': return 'T';\n case 'S': return 'S';\n case 'E': return 'E';\n case 'H': return 'H';\n case '.': return null;\n default: throw new Error(`unknown sprite char: ${c}`);\n }\n}\n","import type { HorseColors } from '@token-derby/shared';\nimport { FIXED_COLORS, type SlotTag } from './sprite.js';\n\nexport type Cell = {\n top: string | null;\n bottom: string | null;\n};\n\nexport function renderSprite(\n sprite: readonly (readonly SlotTag[])[],\n colors: HorseColors,\n): Cell[][] {\n const out: Cell[][] = [];\n for (let y = 0; y + 1 < sprite.length || y < sprite.length; y += 2) {\n const topRow = sprite[y];\n const bottomRow = sprite[y + 1];\n if (!topRow) break;\n const row: Cell[] = [];\n for (let x = 0; x < topRow.length; x++) {\n row.push({\n top: tagColor(topRow[x] ?? null, colors),\n bottom: tagColor(bottomRow?.[x] ?? null, colors),\n });\n }\n out.push(row);\n if (!bottomRow) break;\n }\n return out;\n}\n\nfunction tagColor(tag: SlotTag, colors: HorseColors): string | null {\n if (tag === null) return null;\n if (tag === 'E') return FIXED_COLORS.E;\n if (tag === 'H') return FIXED_COLORS.H;\n if (tag === 'B') return colors.body;\n if (tag === 'M') return colors.mane;\n if (tag === 'T') return colors.tail;\n if (tag === 'S') return colors.saddle;\n return null;\n}\n","import type { HorseColors } from '@token-derby/shared';\n\nexport type Slot = keyof HorseColors;\n\nexport const SLOTS: readonly Slot[] = ['body', 'mane', 'tail', 'saddle'] as const;\n\nexport const PALETTES: Record<Slot, readonly string[]> = {\n body: [\n '#8B4513', '#A0522D', '#D2691E', '#CD853F', '#DEB887', '#F5DEB3',\n '#FFFFFF', '#000000', '#4A2C2A', '#5D3A1A', '#704214', '#9C5919',\n '#B87333', '#E5B783', '#F0E1C9', '#2F1B0C',\n ],\n mane: [\n '#000000', '#1C1C1C', '#2F1B0C', '#4A2C2A', '#5D3A1A', '#8B4513',\n '#FFFFFF', '#F5F5DC', '#DEB887', '#CD853F', '#FF4500', '#B22222',\n '#191970', '#4B0082', '#2E8B57', '#FFD700',\n ],\n tail: [\n '#000000', '#1C1C1C', '#2F1B0C', '#4A2C2A', '#5D3A1A', '#8B4513',\n '#FFFFFF', '#F5F5DC', '#DEB887', '#CD853F', '#FF4500', '#B22222',\n '#191970', '#4B0082', '#2E8B57', '#FFD700',\n ],\n saddle: [\n '#C0392B', '#922B21', '#7B241C', '#641E16', '#1F618D', '#21618C',\n '#1B4F72', '#0E6655', '#117A65', '#196F3D', '#7D6608', '#9A7D0A',\n '#6E2C00', '#4D5656', '#212F3D', '#000000',\n ],\n};\n\nexport function nextColor(slot: Slot, current: string): string {\n const palette = PALETTES[slot];\n const idx = palette.indexOf(current);\n return palette[(idx + 1 + palette.length) % palette.length] ?? palette[0]!;\n}\n\nexport function prevColor(slot: Slot, current: string): string {\n const palette = PALETTES[slot];\n const idx = palette.indexOf(current);\n if (idx < 0) return palette[0]!;\n return palette[(idx - 1 + palette.length) % palette.length]!;\n}\n\nexport function defaultColors(): HorseColors {\n return {\n body: PALETTES.body[0]!,\n mane: PALETTES.mane[0]!,\n tail: PALETTES.tail[0]!,\n saddle: PALETTES.saddle[0]!,\n };\n}\n","import * as fs from 'node:fs/promises';\nimport { randomUUID } from 'node:crypto';\nimport type { HorseColors } from '@token-derby/shared';\nimport { homeDir, stableFile } from '../paths.js';\n\nexport type StableHorse = {\n stable_horse_id: string;\n name: string;\n colors: HorseColors;\n created_at: string;\n};\n\nexport type Stable = {\n horses: StableHorse[];\n};\n\nexport function newStableHorseId(): string {\n return randomUUID();\n}\n\nexport async function loadStable(): Promise<Stable> {\n try {\n const raw = await fs.readFile(stableFile(), 'utf8');\n const parsed = JSON.parse(raw);\n if (!parsed || !Array.isArray(parsed.horses)) return { horses: [] };\n const stable = parsed as { horses: Array<Partial<StableHorse> & { name: string; colors: HorseColors; created_at: string }> };\n let mutated = false;\n const horses: StableHorse[] = stable.horses.map(h => {\n if (typeof h.stable_horse_id === 'string' && h.stable_horse_id.length > 0) {\n return h as StableHorse;\n }\n mutated = true;\n return { ...h, stable_horse_id: newStableHorseId() } as StableHorse;\n });\n const result: Stable = { horses };\n if (mutated) await saveStable(result);\n return result;\n } catch (e: any) {\n if (e?.code === 'ENOENT') return { horses: [] };\n if (e instanceof SyntaxError) return { horses: [] };\n throw e;\n }\n}\n\nexport async function saveStable(stable: Stable): Promise<void> {\n await fs.mkdir(homeDir(), { recursive: true });\n await fs.writeFile(stableFile(), JSON.stringify(stable, null, 2) + '\\n', 'utf8');\n}\n\nexport async function upsertHorse(horse: StableHorse): Promise<void> {\n const stable = await loadStable();\n const idx = stable.horses.findIndex(h => h.name === horse.name);\n if (idx >= 0) stable.horses[idx] = horse;\n else stable.horses.push(horse);\n await saveStable(stable);\n}\n\nexport async function removeHorse(name: string): Promise<void> {\n const stable = await loadStable();\n stable.horses = stable.horses.filter(h => h.name !== name);\n await saveStable(stable);\n}\n\nexport function findHorse(stable: Stable, name: string): StableHorse | undefined {\n return stable.horses.find(h => h.name === name);\n}\n","import * as os from 'node:os';\nimport * as path from 'node:path';\n\nexport function homeDir(): string {\n return process.env.TOKEN_DERBY_HOME ?? path.join(os.homedir(), '.token-derby');\n}\n\nexport function stableFile(): string {\n return path.join(homeDir(), 'stable.json');\n}\n\nexport function identityFile(): string {\n return path.join(homeDir(), 'identity.json');\n}\n\nexport function activeRaceFile(joinCode: string): string {\n return path.join(homeDir(), 'active-races', `${joinCode}.json`);\n}\n\nexport function activeRacesDir(): string {\n return path.join(homeDir(), 'active-races');\n}\n\nexport function claudeProjectsDir(): string {\n return process.env.TOKEN_DERBY_CLAUDE_DIR ?? path.join(os.homedir(), '.claude', 'projects');\n}\n","import React from 'react';\nimport { render, Box, Text } from 'ink';\nimport { loadStable } from '../stable/stable.js';\nimport { HorseSprite } from '../ui/HorseSprite.js';\nimport { MINI_SPRITE } from '../ui/sprite.js';\n\nexport async function stableListCommand(): Promise<number> {\n const stable = await loadStable();\n if (stable.horses.length === 0) {\n console.log('Your stable is empty. Run `token-derby stable create` to add a horse.');\n return 0;\n }\n const app = render(\n React.createElement(StableList, { horses: stable.horses }),\n );\n await app.waitUntilExit();\n return 0;\n}\n\nfunction StableList({ horses }: { horses: { name: string; colors: any; created_at: string }[] }) {\n React.useEffect(() => {\n setImmediate(() => process.exit(0));\n }, []);\n return (\n <Box flexDirection=\"column\">\n <Text bold>Your stable ({horses.length}):</Text>\n {horses.map(h => (\n <Box key={h.name} flexDirection=\"row\" marginTop={1}>\n <HorseSprite sprite={MINI_SPRITE} colors={h.colors} />\n <Text> {h.name}</Text>\n </Box>\n ))}\n </Box>\n );\n}\n","import * as readline from 'node:readline/promises';\nimport { stdin, stdout } from 'node:process';\nimport { loadStable, findHorse, removeHorse } from '../stable/stable.js';\nimport { listActiveRaces, loadActiveRace } from '../stable/active-race.js';\n\nexport async function stableDeleteCommand(name: string | undefined): Promise<number> {\n if (!name) {\n console.error('Usage: token-derby stable delete <name>');\n return 2;\n }\n const stable = await loadStable();\n const horse = findHorse(stable, name);\n if (!horse) {\n console.error(`No horse named \"${name}\" in your stable.`);\n return 1;\n }\n\n const codes = await listActiveRaces();\n for (const code of codes) {\n const active = await loadActiveRace(code);\n if (active?.horse_name === name) {\n console.error(`\"${name}\" is currently running in race ${code}. Close that terminal first.`);\n return 1;\n }\n }\n\n const rl = readline.createInterface({ input: stdin, output: stdout });\n const answer = (await rl.question(`Delete \"${name}\" from your stable? [y/N] `)).trim().toLowerCase();\n rl.close();\n if (answer !== 'y' && answer !== 'yes') {\n console.log('Cancelled.');\n return 1;\n }\n await removeHorse(name);\n console.log(`✓ Deleted \"${name}\".`);\n return 0;\n}\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { HorseColors } from '@token-derby/shared';\nimport { activeRaceFile, activeRacesDir } from '../paths.js';\n\nexport type ActiveRace = {\n join_code: string;\n race_id: string;\n horse_id: string;\n heartbeat_token: string;\n horse_name: string;\n horse_colors: HorseColors;\n joined_at: string;\n last_race_tokens: number;\n last_heartbeat_at: string;\n};\n\nexport async function loadActiveRace(joinCode: string): Promise<ActiveRace | null> {\n try {\n const raw = await fs.readFile(activeRaceFile(joinCode), 'utf8');\n return JSON.parse(raw) as ActiveRace;\n } catch (e: any) {\n if (e?.code === 'ENOENT') return null;\n throw e;\n }\n}\n\nexport async function saveActiveRace(active: ActiveRace): Promise<void> {\n await fs.mkdir(activeRacesDir(), { recursive: true });\n await fs.writeFile(\n activeRaceFile(active.join_code),\n JSON.stringify(active, null, 2) + '\\n',\n 'utf8',\n );\n}\n\nexport async function deleteActiveRace(joinCode: string): Promise<void> {\n try {\n await fs.unlink(activeRaceFile(joinCode));\n } catch (e: any) {\n if (e?.code !== 'ENOENT') throw e;\n }\n}\n\nexport async function listActiveRaces(): Promise<string[]> {\n try {\n const entries = await fs.readdir(activeRacesDir());\n return entries\n .filter(f => f.endsWith('.json'))\n .map(f => path.basename(f, '.json'));\n } catch (e: any) {\n if (e?.code === 'ENOENT') return [];\n throw e;\n }\n}\n","import React from 'react';\nimport { render } from 'ink';\nimport { HorseCreator } from '../ui/HorseCreator.js';\nimport { upsertHorse, loadStable, findHorse } from '../stable/stable.js';\n\nexport async function stableEditCommand(name: string | undefined): Promise<number> {\n if (!name) {\n console.error('Usage: token-derby stable edit <name>');\n return 2;\n }\n const stable = await loadStable();\n const existing = findHorse(stable, name);\n if (!existing) {\n console.error(`No horse named \"${name}\" in your stable.`);\n return 1;\n }\n\n let exitCode = 0;\n const app = render(\n React.createElement(HorseCreator, {\n initialColors: existing.colors,\n initialName: existing.name,\n lockName: true,\n onSubmit: async (_name, colors) => {\n await upsertHorse({\n stable_horse_id: existing.stable_horse_id,\n name: existing.name,\n colors,\n created_at: existing.created_at,\n });\n app.unmount();\n console.log(`✓ Updated \"${existing.name}\".`);\n },\n onCancel: () => {\n app.unmount();\n console.log('Cancelled.');\n exitCode = 1;\n },\n }),\n );\n await app.waitUntilExit();\n return exitCode;\n}\n","import * as readline from 'node:readline/promises';\nimport { stdin, stdout } from 'node:process';\nimport { createRace } from '../api/endpoints.js';\nimport { ApiError } from '../api/client.js';\n\nconst DEFAULT_TZ = Intl.DateTimeFormat().resolvedOptions().timeZone || 'UTC';\n\nexport async function createRaceCommand(): Promise<number> {\n const rl = readline.createInterface({ input: stdin, output: stdout });\n try {\n const name = (await rl.question('Race name: ')).trim();\n if (!name) { console.error('Name required.'); return 1; }\n\n const startRaw = (await rl.question('Start time (ISO 8601, blank = now): ')).trim();\n const start = startRaw ? startRaw : new Date().toISOString();\n if (!isIso(start)) { console.error('Invalid start time.'); return 1; }\n\n const durationRaw = (await rl.question('Race duration (hours): ')).trim();\n const durationHours = parseFloat(durationRaw);\n if (!Number.isFinite(durationHours) || durationHours <= 0) {\n console.error('Duration must be a positive number of hours.'); return 1;\n }\n const end = new Date(new Date(start).getTime() + durationHours * 3600_000).toISOString();\n\n const tz = (await rl.question(`Time zone [${DEFAULT_TZ}]: `)).trim() || DEFAULT_TZ;\n const maxRaw = (await rl.question('Max participants [30]: ')).trim();\n const max = maxRaw ? parseInt(maxRaw, 10) : undefined;\n if (max !== undefined && (!Number.isFinite(max) || max < 1)) {\n console.error('Max participants must be a positive number.'); return 1;\n }\n\n const resp = await createRace({\n name, start_time: start, end_time: end, tz,\n ...(max !== undefined ? { max_participants: max } : {}),\n });\n\n console.log('');\n console.log(' ╔══════════════════════════════════════╗');\n console.log(` ║ JOIN CODE: ${resp.join_code.padEnd(23)}║`);\n console.log(' ╚══════════════════════════════════════╝');\n console.log('');\n console.log(` Admin code: ${resp.admin_code}`);\n console.log(' ⚠ Save the admin code — you need it to end the race early.');\n console.log('');\n console.log(` Share with participants: token-derby join ${resp.join_code}`);\n return 0;\n } catch (e) {\n if (e instanceof ApiError) {\n console.error(`Error: ${e.code} ${e.message}`);\n return 1;\n }\n throw e;\n } finally {\n rl.close();\n }\n}\n\nfunction isIso(s: string): boolean {\n if (!s) return false;\n const d = new Date(s);\n return !Number.isNaN(d.getTime());\n}\n","export const DEFAULT_API_BASE = 'https://token-derby.mauricode.co.uk/api';\n\nexport function apiBase(): string {\n return process.env.TOKEN_DERBY_API_BASE ?? DEFAULT_API_BASE;\n}\n\nexport const HEARTBEAT_INTERVAL_MS = 60_000;\nexport const POLL_INTERVAL_MS = 3_000;\nexport const HEARTBEAT_RETRY_DELAYS_MS = [1_000, 2_000, 4_000, 8_000, 15_000];\n","import { createRequire } from 'node:module';\n\ndeclare const __CLI_VERSION__: string | undefined;\n\nfunction readVersion(): string {\n if (typeof __CLI_VERSION__ === 'string' && __CLI_VERSION__.length > 0) {\n return __CLI_VERSION__;\n }\n try {\n const req = createRequire(import.meta.url);\n const pkg = req('../package.json') as { version?: string };\n if (typeof pkg.version === 'string') return pkg.version;\n } catch {\n // fall through\n }\n return '0.0.0-dev';\n}\n\nexport const CLI_VERSION: string = readVersion();\n","export const DEFAULT_MAX_PARTICIPANTS = 30;\nexport const JOIN_CODE_LENGTH = 6;\nexport const JOIN_CODE_ALPHABET = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';\nexport const CLI_VERSION_HEADER = 'x-cli-version';\nexport const USER_ID_HEADER = 'x-user-id';\nexport const USER_NAME_HEADER = 'x-user-name';\nexport const USER_NAME_MAX_LENGTH = 40;\n","import { promises as fs } from 'node:fs';\nimport * as path from 'node:path';\nimport * as crypto from 'node:crypto';\nimport { USER_NAME_MAX_LENGTH } from '@token-derby/shared';\nimport { identityFile, homeDir } from '../paths.js';\n\nexport type Identity = {\n user_id: string;\n display_name: string;\n created_at: string;\n};\n\nexport async function loadIdentity(): Promise<Identity | null> {\n try {\n const raw = await fs.readFile(identityFile(), 'utf8');\n const parsed = JSON.parse(raw) as Partial<Identity>;\n if (\n typeof parsed.user_id === 'string' &&\n typeof parsed.display_name === 'string' &&\n typeof parsed.created_at === 'string'\n ) {\n return parsed as Identity;\n }\n return null;\n } catch (e: any) {\n if (e?.code === 'ENOENT') return null;\n return null;\n }\n}\n\nexport async function saveIdentity(identity: Identity): Promise<void> {\n await fs.mkdir(homeDir(), { recursive: true });\n await fs.writeFile(identityFile(), JSON.stringify(identity, null, 2) + '\\n', 'utf8');\n}\n\nexport function generateUserId(): string {\n return crypto.randomUUID();\n}\n\nexport function validateDisplayName(name: string): { ok: true; name: string } | { ok: false; error: string } {\n const trimmed = name.trim();\n if (trimmed.length < 1) return { ok: false, error: 'Name cannot be empty.' };\n if (trimmed.length > USER_NAME_MAX_LENGTH) {\n return { ok: false, error: `Name must be ${USER_NAME_MAX_LENGTH} characters or fewer.` };\n }\n return { ok: true, name: trimmed };\n}\n\nexport function identityFilePath(): string {\n return identityFile();\n}\n\nexport function identityFileDir(): string {\n return path.dirname(identityFile());\n}\n","import { apiBase } from '../config.js';\nimport { CLI_VERSION } from '../version.js';\nimport { CLI_VERSION_HEADER, USER_ID_HEADER, USER_NAME_HEADER } from '@token-derby/shared';\nimport { loadIdentity, type Identity } from '../identity/identity.js';\n\nexport type ApiErrorCode =\n | 'RACE_NOT_FOUND'\n | 'RACE_FULL'\n | 'RACE_FINISHED'\n | 'INVALID_TOKEN'\n | 'RATE_LIMITED'\n | 'BAD_REQUEST'\n | 'VERSION_MISMATCH'\n | 'IDENTITY_REQUIRED'\n | 'DUPLICATE_HORSE'\n | 'NETWORK_ERROR';\n\nexport class ApiError extends Error {\n constructor(\n readonly code: ApiErrorCode,\n message: string,\n readonly status: number,\n ) {\n super(message);\n this.name = 'ApiError';\n }\n}\n\ntype FetchFn = typeof fetch;\n\nlet identityCache: Promise<Identity | null> | null = null;\nfunction getIdentity(): Promise<Identity | null> {\n if (!identityCache) identityCache = loadIdentity();\n return identityCache;\n}\n\n// Tests can reset the cached identity.\nexport function _resetIdentityCacheForTests(): void {\n identityCache = null;\n}\n\nexport async function request<T>(\n method: string,\n path: string,\n body: unknown,\n authToken: string | undefined,\n fetchImpl: FetchFn = fetch,\n): Promise<T> {\n const url = path.startsWith('http') ? path : `${apiBase()}${path}`;\n const headers: Record<string, string> = {};\n headers[CLI_VERSION_HEADER] = CLI_VERSION;\n const identity = await getIdentity();\n if (identity) {\n headers[USER_ID_HEADER] = identity.user_id;\n headers[USER_NAME_HEADER] = identity.display_name;\n }\n if (authToken) headers['authorization'] = `Bearer ${authToken}`;\n if (body !== undefined) headers['content-type'] = 'application/json';\n\n let res: Awaited<ReturnType<FetchFn>>;\n try {\n res = await fetchImpl(url, {\n method,\n headers,\n body: body !== undefined ? JSON.stringify(body) : undefined,\n });\n } catch (e: any) {\n throw new ApiError('NETWORK_ERROR', e?.message ?? 'fetch failed', 0);\n }\n\n const text = await res.text();\n const contentType = res.headers.get('content-type') ?? '';\n let parsed: any = null;\n if (contentType.includes('application/json') && text.length > 0) {\n try {\n parsed = JSON.parse(text);\n } catch {\n parsed = null;\n }\n }\n\n if (!res.ok) {\n if (parsed && typeof parsed.code === 'string') {\n throw new ApiError(parsed.code as ApiErrorCode, parsed.message ?? 'API error', res.status);\n }\n throw new ApiError('NETWORK_ERROR', `HTTP ${res.status}`, res.status);\n }\n\n return parsed as T;\n}\n","import type {\n CreateRaceRequest, CreateRaceResponse,\n GetRaceResponse, JoinRaceRequest, JoinRaceResponse,\n HeartbeatRequest, HeartbeatResponse, EndRaceResponse,\n} from '@token-derby/shared';\nimport { request } from './client.js';\n\nexport function createRace(body: CreateRaceRequest) {\n return request<CreateRaceResponse>('POST', '/races', body, undefined);\n}\n\nexport function getRace(joinCode: string) {\n return request<GetRaceResponse>('GET', `/races/${encodeURIComponent(joinCode)}`, undefined, undefined);\n}\n\nexport function joinRace(joinCode: string, body: JoinRaceRequest) {\n return request<JoinRaceResponse>('POST', `/races/${encodeURIComponent(joinCode)}/join`, body, undefined);\n}\n\nexport function heartbeat(joinCode: string, horseId: string, token: string, body: HeartbeatRequest) {\n return request<HeartbeatResponse>(\n 'POST',\n `/races/${encodeURIComponent(joinCode)}/horses/${encodeURIComponent(horseId)}/heartbeat`,\n body,\n token,\n );\n}\n\nexport function endRace(adminCode: string) {\n return request<EndRaceResponse>('DELETE', `/races/admin/${encodeURIComponent(adminCode)}`, undefined, undefined);\n}\n","import React from 'react';\nimport { render } from 'ink';\nimport type { HorseColors, HorseView } from '@token-derby/shared';\nimport { loadStable } from '../stable/stable.js';\nimport { HorsePicker } from '../ui/HorsePicker.js';\nimport { joinRace, getRace } from '../api/endpoints.js';\nimport { ApiError } from '../api/client.js';\nimport { saveActiveRace, loadActiveRace, type ActiveRace } from '../stable/active-race.js';\nimport { RunRace, buildInitialState } from '../runtime/run-race.js';\nimport { loadIdentity } from '../identity/identity.js';\nimport type { StableHorse } from '../stable/stable.js';\n\nexport async function joinCommand(joinCode: string | undefined): Promise<number> {\n if (!joinCode) {\n console.error('Usage: token-derby join <join-code>');\n return 2;\n }\n const code = joinCode.toUpperCase();\n\n const identity = await loadIdentity();\n if (!identity) {\n // Defensive — bin.ts already checks. Kept so this command is self-contained.\n console.error('Run `token-derby init` to set up your identity.');\n return 1;\n }\n\n // Pre-flight: fetch the race view to detect whether this user is already in it.\n let race;\n try {\n race = await getRace(code);\n } catch (e) {\n if (e instanceof ApiError) {\n if (e.code === 'RACE_NOT_FOUND') console.error(`No race with join code ${code}.`);\n else console.error(`Error: ${e.code} ${e.message}`);\n return 1;\n }\n throw e;\n }\n if (race.status === 'finished') {\n console.error('This race has already ended.');\n return 1;\n }\n\n const ownHorse = race.horses.find(h => h.user_id === identity.user_id) ?? null;\n\n let chosenStableHorseId: string;\n let chosenName: string;\n let chosenColors: HorseColors;\n let isResume: boolean;\n\n if (ownHorse) {\n // Auto-resume: use server's snapshot of the horse, no picker.\n chosenStableHorseId = ownHorse.stable_horse_id;\n chosenName = ownHorse.name;\n chosenColors = ownHorse.colors;\n isResume = true;\n } else {\n const stable = await loadStable();\n if (stable.horses.length === 0) {\n console.error('Your stable is empty. Run `token-derby stable create` first.');\n return 1;\n }\n const picked = await pickHorse(stable.horses);\n if (!picked) { console.log('Cancelled.'); return 1; }\n chosenStableHorseId = picked.stable_horse_id;\n chosenName = picked.name;\n chosenColors = picked.colors;\n isResume = false;\n }\n\n let joinResp;\n try {\n joinResp = await joinRace(code, {\n horse: { stable_horse_id: chosenStableHorseId, name: chosenName, colors: chosenColors },\n });\n } catch (e) {\n if (e instanceof ApiError) {\n if (e.code === 'RACE_FULL') console.error('This race is full.');\n else if (e.code === 'RACE_FINISHED') console.error('This race has ended.');\n else if (e.code === 'RACE_NOT_FOUND') console.error(`No race with join code ${code}.`);\n else if (e.code === 'VERSION_MISMATCH') console.error(e.message);\n else if (e.code === 'DUPLICATE_HORSE') console.error(e.message);\n else if (e.code === 'IDENTITY_REQUIRED') console.error(`Error: ${e.message}`);\n else console.error(`Error: ${e.code} ${e.message}`);\n return 1;\n }\n throw e;\n }\n\n // For resume, try to carry forward our last token total from active-races state.\n const prior = await loadActiveRace(code);\n const lastTokens = isResume && prior?.horse_id === joinResp.horse_id ? prior.last_race_tokens : (ownHorse?.current_tokens ?? 0);\n\n const status: 'pending' | 'live' = race.status;\n const active: ActiveRace = {\n join_code: code,\n race_id: race.race_id,\n horse_id: joinResp.horse_id,\n heartbeat_token: joinResp.heartbeat_token,\n horse_name: chosenName,\n horse_colors: chosenColors,\n joined_at: ownHorse?.joined_at ?? new Date().toISOString(),\n last_race_tokens: lastTokens,\n last_heartbeat_at: new Date(0).toISOString(),\n };\n await saveActiveRace(active);\n\n const initial = await buildInitialState({ active, raceStatus: status, rejoin: isResume });\n const app = render(React.createElement(RunRace, { active, ...initial, ownUserName: identity.display_name }));\n await app.waitUntilExit();\n return 0;\n}\n\nasync function pickHorse(horses: StableHorse[]): Promise<StableHorse | null> {\n return new Promise(resolve => {\n const app = render(\n React.createElement(HorsePicker, {\n horses,\n onPick: (h: StableHorse) => { app.unmount(); resolve(h); },\n onCancel: () => { app.unmount(); resolve(null); },\n }),\n );\n });\n}\n","import React, { useState } from 'react';\nimport { Box, Text, useInput } from 'ink';\nimport { HorseSprite } from './HorseSprite.js';\nimport { MINI_SPRITE } from './sprite.js';\nimport type { StableHorse } from '../stable/stable.js';\n\ntype Props = {\n horses: StableHorse[];\n onPick: (horse: StableHorse) => void;\n onCancel: () => void;\n};\n\nexport function HorsePicker({ horses, onPick, onCancel }: Props) {\n const [idx, setIdx] = useState(0);\n\n useInput((input, key) => {\n if (key.escape) { onCancel(); return; }\n if (horses.length === 0) return;\n if (key.upArrow) { setIdx((idx - 1 + horses.length) % horses.length); return; }\n if (key.downArrow) { setIdx((idx + 1) % horses.length); return; }\n if (key.return) { onPick(horses[idx]!); return; }\n });\n\n if (horses.length === 0) {\n return (\n <Box flexDirection=\"column\">\n <Text>No horses in your stable.</Text>\n <Text dimColor>Run `token-derby stable create` to make one.</Text>\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"column\">\n <Text>Pick a horse to race:</Text>\n {horses.map((h, i) => (\n <Box key={h.name} flexDirection=\"column\">\n <Box flexDirection=\"row\">\n <Text>{i === idx ? '►' : ' '} {h.name}</Text>\n </Box>\n <Box flexDirection=\"row\">\n <Text> </Text>\n <HorseSprite sprite={MINI_SPRITE} colors={h.colors} />\n </Box>\n </Box>\n ))}\n <Box marginTop={1}>\n <Text dimColor>↑/↓ choose · Enter pick · Esc cancel</Text>\n </Box>\n </Box>\n );\n}\n","import React, { useEffect, useRef, useState } from 'react';\nimport { Box, Text, useApp } from 'ink';\nimport type { GetRaceResponse, HeartbeatResponse } from '@token-derby/shared';\nimport { StatusScreen } from '../ui/StatusScreen.js';\nimport { runHeartbeatLoop } from './heartbeat-loop.js';\nimport { runPollLoop } from './poll-loop.js';\nimport { sumOutputTokens } from '../tokens/transcripts.js';\nimport { initialBaseline } from '../tokens/baseline.js';\nimport * as endpoints from '../api/endpoints.js';\nimport { ApiError } from '../api/client.js';\nimport { saveActiveRace, type ActiveRace } from '../stable/active-race.js';\nimport { HEARTBEAT_INTERVAL_MS, POLL_INTERVAL_MS, HEARTBEAT_RETRY_DELAYS_MS } from '../config.js';\n\nexport type RunRaceProps = {\n active: ActiveRace;\n startingBaseline: number;\n pendingMode: boolean;\n ownUserName: string;\n};\n\nexport function RunRace({ active, startingBaseline, pendingMode, ownUserName }: RunRaceProps) {\n const { exit } = useApp();\n const [race, setRace] = useState<GetRaceResponse | null>(null);\n const [lastHbAt, setLastHbAt] = useState<Date | null>(null);\n const [lastHbOk, setLastHbOk] = useState<boolean>(true);\n const [tickNow, setTickNow] = useState<Date>(new Date());\n const [fatalError, setFatalError] = useState<string | null>(null);\n\n const baselineRef = useRef(startingBaseline);\n const pendingRef = useRef(pendingMode);\n const lastTokenSampleRef = useRef<number>(startingBaseline);\n const ctrl = useRef(new AbortController());\n\n // Re-render every second so the \"Ns ago\" counter updates.\n useEffect(() => {\n const t = setInterval(() => setTickNow(new Date()), 1_000);\n return () => clearInterval(t);\n }, []);\n\n // Re-snapshot baseline when race transitions pending → live.\n useEffect(() => {\n if (pendingRef.current && race?.status === 'live') {\n sumOutputTokens().then(total => {\n baselineRef.current = total;\n pendingRef.current = false;\n });\n }\n }, [race?.status]);\n\n useEffect(() => {\n runPollLoop({\n fetchRace: () => endpoints.getRace(active.join_code),\n intervalMs: POLL_INTERVAL_MS,\n onSnapshot: (r) => setRace(r),\n onError: () => {/* silently keep last-known state */},\n abortSignal: ctrl.current.signal,\n });\n\n runHeartbeatLoop({\n sendHeartbeat: async (currentTokens) => {\n const resp = await endpoints.heartbeat(\n active.join_code, active.horse_id, active.heartbeat_token, { current_tokens: currentTokens },\n );\n const updated: ActiveRace = {\n ...active,\n last_race_tokens: currentTokens,\n last_heartbeat_at: new Date().toISOString(),\n };\n await saveActiveRace(updated);\n return resp;\n },\n getCurrentTokens: () => {\n if (pendingRef.current) return 0;\n return Math.max(0, lastTokenSampleRef.current - baselineRef.current);\n },\n intervalMs: HEARTBEAT_INTERVAL_MS,\n retryDelaysMs: HEARTBEAT_RETRY_DELAYS_MS,\n onSuccess: (resp: HeartbeatResponse) => {\n setLastHbAt(new Date());\n setLastHbOk(true);\n if (resp.race_status === 'finished') exit();\n },\n onError: (err) => {\n if (err instanceof ApiError && err.code === 'VERSION_MISMATCH') {\n setFatalError(err.message);\n ctrl.current.abort();\n exit();\n return;\n }\n setLastHbOk(false);\n },\n onFinished: () => exit(),\n abortSignal: ctrl.current.signal,\n });\n\n // Token sampler — refresh the running token total every 5s so the heartbeat sees fresh data.\n const sampler = setInterval(async () => {\n try {\n lastTokenSampleRef.current = await sumOutputTokens();\n } catch {/* keep last sample */}\n }, 5_000);\n // Prime it once at startup.\n sumOutputTokens().then(t => { lastTokenSampleRef.current = t; }).catch(() => {});\n\n const controller = ctrl.current;\n return () => {\n clearInterval(sampler);\n controller.abort();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const lastHeartbeatAgoSec = lastHbAt\n ? Math.max(0, Math.floor((tickNow.getTime() - lastHbAt.getTime()) / 1000))\n : null;\n\n if (fatalError) {\n return (\n <Box flexDirection=\"column\" padding={1}>\n <Text color=\"red\" bold>CLI version mismatch — disconnected</Text>\n <Text>{fatalError}</Text>\n </Box>\n );\n }\n\n return (\n <StatusScreen\n race={race}\n ownHorseId={active.horse_id}\n ownHorseName={active.horse_name}\n ownColors={active.horse_colors}\n ownUserName={ownUserName}\n lastHeartbeatAgoSec={lastHeartbeatAgoSec}\n lastHeartbeatOk={lastHbOk}\n />\n );\n}\n\nexport async function buildInitialState(args: {\n active: ActiveRace;\n raceStatus: 'pending' | 'live';\n rejoin: boolean;\n}): Promise<{ startingBaseline: number; pendingMode: boolean }> {\n const runningTotal = await sumOutputTokens();\n if (args.rejoin) {\n return {\n startingBaseline: Math.max(0, runningTotal - args.active.last_race_tokens),\n pendingMode: args.raceStatus === 'pending',\n };\n }\n return {\n startingBaseline: initialBaseline({ runningTotal, status: args.raceStatus }),\n pendingMode: args.raceStatus === 'pending',\n };\n}\n","import React from 'react';\nimport { Box, Text } from 'ink';\nimport type { GetRaceResponse, HorseColors, HorseView } from '@token-derby/shared';\nimport { HorseSprite } from './HorseSprite.js';\nimport { MINI_SPRITE } from './sprite.js';\n\ntype Props = {\n race: GetRaceResponse | null;\n ownHorseId: string;\n ownHorseName: string;\n ownColors: HorseColors;\n ownUserName: string;\n lastHeartbeatAgoSec: number | null;\n lastHeartbeatOk: boolean;\n};\n\nexport function StatusScreen(props: Props) {\n const { race, ownHorseId, ownHorseName, ownColors, ownUserName, lastHeartbeatAgoSec, lastHeartbeatOk } = props;\n\n if (!race) {\n return (\n <Box flexDirection=\"column\">\n <Text>Joining race…</Text>\n </Box>\n );\n }\n\n const own: HorseView | undefined = race.horses.find(h => h.horse_id === ownHorseId);\n const leader: HorseView | undefined = race.horses[0];\n const elapsedPct = elapsed(race);\n const timeLeft = formatDuration(race.time_left_seconds);\n\n return (\n <Box flexDirection=\"column\" borderStyle=\"round\" paddingX={1}>\n <Text>\n 🏇 TOKEN DERBY ─── <Text bold>{race.name}</Text> ─── status: <Text color={statusColor(race.status)}>{race.status}</Text>\n </Text>\n\n <Box marginTop={1} flexDirection=\"row\">\n <HorseSprite sprite={MINI_SPRITE} colors={ownColors} />\n <Box flexDirection=\"column\">\n <Text> {ownHorseName}</Text>\n <Text> <Text dimColor>({ownUserName})</Text></Text>\n </Box>\n </Box>\n\n <Box flexDirection=\"column\" marginTop={1}>\n <Text>Tokens (race): {own?.current_tokens ?? 0}</Text>\n <Text>Position: {own?.rank ?? '—'} of {race.horses.length}</Text>\n <Text>\n Leader: {leader ? `${leader.name}${leader.user_name ? ` (${leader.user_name})` : ''} — ${leader.current_tokens}` : '—'}\n </Text>\n <Text>Race elapsed: {(elapsedPct * 100).toFixed(0)}% {bar(elapsedPct, 20)}</Text>\n <Text>Time left: {timeLeft}</Text>\n <Text>\n Last heartbeat: {lastHeartbeatAgoSec === null ? '—' : `${lastHeartbeatAgoSec}s ago`}\n {' '}\n <Text color={lastHeartbeatOk ? 'green' : 'yellow'}>\n {lastHeartbeatOk ? '✓' : '⚠'}\n </Text>\n </Text>\n </Box>\n\n <Box marginTop={1}>\n <Text dimColor>Press Ctrl+C to crash out of the race.</Text>\n </Box>\n </Box>\n );\n}\n\nfunction elapsed(race: GetRaceResponse): number {\n const start = new Date(race.start_time).getTime();\n const end = new Date(race.end_time).getTime();\n const now = new Date(race.server_time).getTime();\n if (end <= start) return 0;\n const v = (now - start) / (end - start);\n return Math.max(0, Math.min(1, v));\n}\n\nfunction bar(pct: number, width: number): string {\n const filled = Math.round(pct * width);\n return '▓'.repeat(filled) + '░'.repeat(width - filled);\n}\n\nfunction statusColor(status: GetRaceResponse['status']): string {\n if (status === 'live') return 'green';\n if (status === 'pending') return 'yellow';\n return 'gray';\n}\n\nfunction formatDuration(seconds: number): string {\n const s = Math.max(0, Math.floor(seconds));\n const h = Math.floor(s / 3600);\n const m = Math.floor((s % 3600) / 60);\n const ss = s % 60;\n return `${h.toString().padStart(2, '0')}:${m.toString().padStart(2, '0')}:${ss.toString().padStart(2, '0')}`;\n}\n","import type { HeartbeatResponse } from '@token-derby/shared';\n\nexport type HeartbeatLoopOptions = {\n sendHeartbeat: (currentTokens: number) => Promise<HeartbeatResponse>;\n getCurrentTokens: () => number;\n intervalMs: number;\n retryDelaysMs: readonly number[];\n onSuccess: (resp: HeartbeatResponse) => void;\n onError: (err: unknown) => void;\n onFinished: () => void;\n abortSignal: AbortSignal;\n};\n\nexport function runHeartbeatLoop(opts: HeartbeatLoopOptions): void {\n let timer: ReturnType<typeof setTimeout> | null = null;\n let retryIndex = 0;\n let stopped = false;\n\n const stop = () => {\n stopped = true;\n if (timer) clearTimeout(timer);\n timer = null;\n };\n\n opts.abortSignal.addEventListener('abort', stop, { once: true });\n\n const schedule = (delay: number) => {\n if (stopped) return;\n timer = setTimeout(tick, delay);\n };\n\n const tick = async () => {\n if (stopped) return;\n try {\n const tokens = opts.getCurrentTokens();\n const resp = await opts.sendHeartbeat(tokens);\n retryIndex = 0;\n opts.onSuccess(resp);\n if (resp.race_status === 'finished') {\n opts.onFinished();\n stop();\n return;\n }\n schedule(opts.intervalMs);\n } catch (err) {\n opts.onError(err);\n const delay = opts.retryDelaysMs[Math.min(retryIndex, opts.retryDelaysMs.length - 1)] ?? 1_000;\n retryIndex += 1;\n schedule(delay);\n }\n };\n\n schedule(0);\n}\n","import type { GetRaceResponse } from '@token-derby/shared';\n\nexport type PollLoopOptions = {\n fetchRace: () => Promise<GetRaceResponse>;\n intervalMs: number;\n onSnapshot: (race: GetRaceResponse) => void;\n onError: (err: unknown) => void;\n abortSignal: AbortSignal;\n};\n\nexport function runPollLoop(opts: PollLoopOptions): void {\n let timer: ReturnType<typeof setTimeout> | null = null;\n let stopped = false;\n\n const stop = () => {\n stopped = true;\n if (timer) clearTimeout(timer);\n timer = null;\n };\n\n opts.abortSignal.addEventListener('abort', stop, { once: true });\n\n const tick = async () => {\n if (stopped) return;\n try {\n const race = await opts.fetchRace();\n if (!stopped) opts.onSnapshot(race);\n } catch (err) {\n if (!stopped) opts.onError(err);\n }\n if (!stopped) timer = setTimeout(tick, opts.intervalMs);\n };\n\n timer = setTimeout(tick, 0);\n}\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { claudeProjectsDir } from '../paths.js';\n\nexport type TokenTotals = { input: number; output: number };\n\nexport async function sumTokens(): Promise<TokenTotals> {\n const root = claudeProjectsDir();\n const files = await listJsonlFiles(root);\n let input = 0;\n let output = 0;\n for (const file of files) {\n const t = await sumFile(file);\n input += t.input;\n output += t.output;\n }\n return { input, output };\n}\n\n/** @deprecated Use sumTokens() instead */\nexport async function sumOutputTokens(): Promise<number> {\n const { input, output } = await sumTokens();\n return input + output;\n}\n\nasync function listJsonlFiles(root: string): Promise<string[]> {\n let projects: string[];\n try {\n projects = await fs.readdir(root);\n } catch (e: any) {\n if (e?.code === 'ENOENT') return [];\n throw e;\n }\n const out: string[] = [];\n for (const project of projects) {\n const projectDir = path.join(root, project);\n let stat;\n try {\n stat = await fs.stat(projectDir);\n } catch {\n continue;\n }\n if (!stat.isDirectory()) continue;\n const entries = await fs.readdir(projectDir);\n for (const entry of entries) {\n if (entry.endsWith('.jsonl')) out.push(path.join(projectDir, entry));\n }\n }\n return out;\n}\n\nfunction addNum(value: unknown): number {\n return typeof value === 'number' && Number.isFinite(value) ? value : 0;\n}\n\nasync function sumFile(file: string): Promise<TokenTotals> {\n let raw: string;\n try {\n raw = await fs.readFile(file, 'utf8');\n } catch {\n return { input: 0, output: 0 };\n }\n let input = 0;\n let output = 0;\n for (const line of raw.split('\\n')) {\n if (!line.trim()) continue;\n let parsed: any;\n try {\n parsed = JSON.parse(line);\n } catch {\n continue;\n }\n const usage = parsed?.message?.usage;\n if (!usage) continue;\n input += addNum(usage.input_tokens)\n + addNum(usage.cache_creation_input_tokens)\n + addNum(usage.cache_read_input_tokens);\n output += addNum(usage.output_tokens);\n }\n return { input, output };\n}\n","import type { RaceStatus } from '@token-derby/shared';\n\nexport function initialBaseline(args: { runningTotal: number; status: RaceStatus }): number {\n return args.runningTotal;\n}\n\nexport function rejoinBaseline(args: { runningTotal: number; lastRaceTokens: number }): number {\n return Math.max(0, args.runningTotal - args.lastRaceTokens);\n}\n\nexport function currentRaceTokens(runningTotal: number, baseline: number): number {\n return Math.max(0, runningTotal - baseline);\n}\n","import * as readline from 'node:readline/promises';\nimport { stdin, stdout } from 'node:process';\nimport { endRace } from '../api/endpoints.js';\nimport { ApiError } from '../api/client.js';\n\nexport async function endCommand(adminCode: string | undefined): Promise<number> {\n if (!adminCode) {\n console.error('Usage: token-derby end <admin-code>');\n return 2;\n }\n const rl = readline.createInterface({ input: stdin, output: stdout });\n const answer = (await rl.question('End the race now and freeze final tokens? [y/N] ')).trim().toLowerCase();\n rl.close();\n if (answer !== 'y' && answer !== 'yes') {\n console.log('Cancelled.');\n return 1;\n }\n try {\n await endRace(adminCode);\n console.log('✓ Race ended.');\n return 0;\n } catch (e) {\n if (e instanceof ApiError) {\n if (e.code === 'RACE_NOT_FOUND') console.error('No race with that admin code.');\n else console.error(`Error: ${e.code} ${e.message}`);\n return 1;\n }\n throw e;\n }\n}\n","import * as readline from 'node:readline/promises';\nimport { stdin, stdout } from 'node:process';\nimport {\n loadIdentity,\n saveIdentity,\n generateUserId,\n validateDisplayName,\n type Identity,\n} from '../identity/identity.js';\n\nexport async function initCommand(): Promise<number> {\n const existing = await loadIdentity();\n const rl = readline.createInterface({ input: stdin, output: stdout });\n try {\n if (existing) {\n console.log(`Current jockey name: ${existing.display_name}`);\n const raw = (await rl.question('New jockey name (use your real name please) [keep]: ')).trim();\n if (!raw) {\n console.log('Kept existing name.');\n return 0;\n }\n const v = validateDisplayName(raw);\n if (!v.ok) { console.error(v.error); return 1; }\n const updated: Identity = { ...existing, display_name: v.name };\n await saveIdentity(updated);\n console.log(`Updated jockey name to: ${updated.display_name}`);\n return 0;\n }\n\n const raw = (await rl.question('Jockey Name (use your real name please): ')).trim();\n const v = validateDisplayName(raw);\n if (!v.ok) { console.error(v.error); return 1; }\n\n const identity: Identity = {\n user_id: generateUserId(),\n display_name: v.name,\n created_at: new Date().toISOString(),\n };\n await saveIdentity(identity);\n console.log('');\n console.log(`Welcome, ${identity.display_name}!`);\n console.log(`Your identity is saved. You can now create a stable and join races.`);\n return 0;\n } finally {\n rl.close();\n }\n}\n","import { stableCreateCommand } from './commands/stable-create.js';\nimport { stableListCommand } from './commands/stable-list.js';\nimport { stableDeleteCommand } from './commands/stable-delete.js';\nimport { stableEditCommand } from './commands/stable-edit.js';\nimport { createRaceCommand } from './commands/create.js';\nimport { joinCommand } from './commands/join.js';\nimport { endCommand } from './commands/end.js';\nimport { initCommand } from './commands/init.js';\nimport { CLI_VERSION } from './version.js';\nimport { loadIdentity } from './identity/identity.js';\n\nconst HELP = `token-derby v${CLI_VERSION}\n\nIdentity:\n token-derby init Set up your jockey identity (run this first)\n\nStable management:\n token-derby stable create Make a new horse (interactive)\n token-derby stable list Show your saved horses\n token-derby stable edit <name> Edit an existing horse's colors\n token-derby stable delete <name> Remove a horse from your stable\n\nRaces:\n token-derby create Create a new race (interactive)\n token-derby join <join-code> Join (or resume) a race\n token-derby end <admin-code> End a race early\n\nEnvironment:\n TOKEN_DERBY_API_BASE Override API base URL (default: production)\n TOKEN_DERBY_HOME Override identity/stable directory\n`;\n\nasync function main(): Promise<number> {\n const argv = process.argv.slice(2);\n const cmd = argv[0];\n\n if (!cmd || cmd === '--help' || cmd === '-h') { console.log(HELP); return 0; }\n if (cmd === '--version' || cmd === '-v') { console.log(CLI_VERSION); return 0; }\n\n if (cmd === 'init') return initCommand();\n\n // Every other command requires an identity. `init` is the only escape hatch.\n const identity = await loadIdentity();\n if (!identity) {\n console.error('Run `token-derby init` to set up your identity before using any other command.');\n return 1;\n }\n\n if (cmd === 'stable') {\n const sub = argv[1];\n if (sub === 'create') return stableCreateCommand();\n if (sub === 'list') return stableListCommand();\n if (sub === 'edit') return stableEditCommand(argv[2]);\n if (sub === 'delete') return stableDeleteCommand(argv[2]);\n console.error(`Unknown stable subcommand: ${sub ?? '(none)'}`);\n console.error('Try: stable create | stable list | stable edit <name> | stable delete <name>');\n return 2;\n }\n\n if (cmd === 'create') return createRaceCommand();\n if (cmd === 'join') return joinCommand(argv[1]);\n if (cmd === 'end') return endCommand(argv[1]);\n\n console.error(`Unknown command: ${cmd}`);\n console.error(HELP);\n return 2;\n}\n\nmain().then(\n code => process.exit(code),\n err => {\n console.error(err?.stack ?? err);\n process.exit(1);\n },\n);\n"],"mappings":"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","names":["React","Box","Text","jsx","Box","Text","React","React","render","Box","Text","jsx","jsxs","render","React","Box","Text","readline","stdin","stdout","fs","path","stdin","stdout","React","render","render","React","readline","stdin","stdout","fs","path","fs","path","stdin","stdout","React","render","useState","Box","Text","useInput","jsx","jsxs","useState","useInput","Box","Text","useState","Box","Text","Box","Text","jsx","jsxs","Box","Text","fs","path","stat","jsx","jsxs","useState","Box","Text","render","React","readline","stdin","stdout","stdin","stdout","readline","stdin","stdout","stdin","stdout","raw","v"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mauricode/token-derby",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Token Derby CLI — manage your stable, run horses in token races driven by Claude Code output.",
5
5
  "type": "module",
6
6
  "bin": {