source dump of claude code
1export const RARITIES = [
2 'common',
3 'uncommon',
4 'rare',
5 'epic',
6 'legendary',
7] as const
8export type Rarity = (typeof RARITIES)[number]
9
10// One species name collides with a model-codename canary in excluded-strings.txt.
11// The check greps build output (not source), so runtime-constructing the value keeps
12// the literal out of the bundle while the check stays armed for the actual codename.
13// All species encoded uniformly; `as` casts are type-position only (erased pre-bundle).
14const c = String.fromCharCode
15// biome-ignore format: keep the species list compact
16
17export const duck = c(0x64,0x75,0x63,0x6b) as 'duck'
18export const goose = c(0x67, 0x6f, 0x6f, 0x73, 0x65) as 'goose'
19export const blob = c(0x62, 0x6c, 0x6f, 0x62) as 'blob'
20export const cat = c(0x63, 0x61, 0x74) as 'cat'
21export const dragon = c(0x64, 0x72, 0x61, 0x67, 0x6f, 0x6e) as 'dragon'
22export const octopus = c(0x6f, 0x63, 0x74, 0x6f, 0x70, 0x75, 0x73) as 'octopus'
23export const owl = c(0x6f, 0x77, 0x6c) as 'owl'
24export const penguin = c(0x70, 0x65, 0x6e, 0x67, 0x75, 0x69, 0x6e) as 'penguin'
25export const turtle = c(0x74, 0x75, 0x72, 0x74, 0x6c, 0x65) as 'turtle'
26export const snail = c(0x73, 0x6e, 0x61, 0x69, 0x6c) as 'snail'
27export const ghost = c(0x67, 0x68, 0x6f, 0x73, 0x74) as 'ghost'
28export const axolotl = c(0x61, 0x78, 0x6f, 0x6c, 0x6f, 0x74, 0x6c) as 'axolotl'
29export const capybara = c(
30 0x63,
31 0x61,
32 0x70,
33 0x79,
34 0x62,
35 0x61,
36 0x72,
37 0x61,
38) as 'capybara'
39export const cactus = c(0x63, 0x61, 0x63, 0x74, 0x75, 0x73) as 'cactus'
40export const robot = c(0x72, 0x6f, 0x62, 0x6f, 0x74) as 'robot'
41export const rabbit = c(0x72, 0x61, 0x62, 0x62, 0x69, 0x74) as 'rabbit'
42export const mushroom = c(
43 0x6d,
44 0x75,
45 0x73,
46 0x68,
47 0x72,
48 0x6f,
49 0x6f,
50 0x6d,
51) as 'mushroom'
52export const chonk = c(0x63, 0x68, 0x6f, 0x6e, 0x6b) as 'chonk'
53
54export const SPECIES = [
55 duck,
56 goose,
57 blob,
58 cat,
59 dragon,
60 octopus,
61 owl,
62 penguin,
63 turtle,
64 snail,
65 ghost,
66 axolotl,
67 capybara,
68 cactus,
69 robot,
70 rabbit,
71 mushroom,
72 chonk,
73] as const
74export type Species = (typeof SPECIES)[number] // biome-ignore format: keep compact
75
76export const EYES = ['·', '✦', '×', '◉', '@', '°'] as const
77export type Eye = (typeof EYES)[number]
78
79export const HATS = [
80 'none',
81 'crown',
82 'tophat',
83 'propeller',
84 'halo',
85 'wizard',
86 'beanie',
87 'tinyduck',
88] as const
89export type Hat = (typeof HATS)[number]
90
91export const STAT_NAMES = [
92 'DEBUGGING',
93 'PATIENCE',
94 'CHAOS',
95 'WISDOM',
96 'SNARK',
97] as const
98export type StatName = (typeof STAT_NAMES)[number]
99
100// Deterministic parts — derived from hash(userId)
101export type CompanionBones = {
102 rarity: Rarity
103 species: Species
104 eye: Eye
105 hat: Hat
106 shiny: boolean
107 stats: Record<StatName, number>
108}
109
110// Model-generated soul — stored in config after first hatch
111export type CompanionSoul = {
112 name: string
113 personality: string
114}
115
116export type Companion = CompanionBones &
117 CompanionSoul & {
118 hatchedAt: number
119 }
120
121// What actually persists in config. Bones are regenerated from hash(userId)
122// on every read so species renames don't break stored companions and users
123// can't edit their way to a legendary.
124export type StoredCompanion = CompanionSoul & { hatchedAt: number }
125
126export const RARITY_WEIGHTS = {
127 common: 60,
128 uncommon: 25,
129 rare: 10,
130 epic: 4,
131 legendary: 1,
132} as const satisfies Record<Rarity, number>
133
134export const RARITY_STARS = {
135 common: '★',
136 uncommon: '★★',
137 rare: '★★★',
138 epic: '★★★★',
139 legendary: '★★★★★',
140} as const satisfies Record<Rarity, string>
141
142export const RARITY_COLORS = {
143 common: 'inactive',
144 uncommon: 'success',
145 rare: 'permission',
146 epic: 'autoAccept',
147 legendary: 'warning',
148} as const satisfies Record<Rarity, keyof import('../utils/theme.js').Theme>