Buddy Identity & Generation
Relevant source files
The following files were used as context for generating this wiki page:
Buddy Identity & Generation is a core system in Buddi that creates a unique, deterministic companion for each user based on their system identity and Claude Code configuration. These "Buddies" serve as visual indicators of Claude Code's state, animating through different tasks while maintaining a persistent identity defined by species, rarity, and physical traits.
The system ensures that every user receives a unique "roll" upon first launch, while also providing mechanisms for manual overrides and customization through the application settings. The generation logic relies on hashing user identifiers to seed a pseudo-random number generator, ensuring consistency across app restarts.
Architecture & Components
The Buddy system is composed of several key modules that handle detection, generation, management, and persistence.
Component Overview
- BuddyDetector: Responsible for locating Claude Code configurations and performing the initial identity "roll" using hashing and PRNG algorithms.
- BuddyManager: A singleton service that maintains both the original base identity and the "effective" identity (applying user overrides).
- BuddyIdentity: The core data structure defining a buddy's traits.
- ASCIISpriteView: The rendering layer that converts identity traits into visual ASCII art.
Data Flow for Buddy Generation
The following diagram illustrates how a Buddy's identity is derived from system configurations.
Identity Data Structures
The identity of a Buddy is defined by four primary attributes that determine its appearance and rarity.
Buddy Traits
| Attribute | Type | Description |
|---|---|---|
| Species | BuddySpecies | 18 distinct types (e.g., duck, cat, dragon, chonk). |
| Rarity | BuddyRarity | Determines color and stat floors (Common to Legendary). |
| Eye | BuddyEye | The character representing the buddy's eyes (e.g., dot, spark, cross). |
| Hat | BuddyHat | Accessory rendered on top of the buddy (e.g., crown, tophat). |
| Name | String? | Optional custom name, often pulled from Claude's "Companion Soul" config. |
Sources: buddi/Buddi/Buddy/BuddyIdentity.swift:3-100, buddi/Buddi/Buddy/BuddyDetector.swift:101-118
Rarity Tiers
Rarity is determined by a weighted roll, affecting the visual color rendering in the UI.
| Tier | Weight | Color (NSColor) | Stars |
|---|---|---|---|
| Common | 60 | labelColor | ★ |
| Uncommon | 25 | systemGreen | ★★ |
| Rare | 10 | systemBlue | ★★★ |
| Epic | 4 | systemPurple | ★★★★ |
| Legendary | 1 | systemYellow | ★★★★★ |
Sources: buddi/Buddi/Buddy/BuddyIdentity.swift:25-72
Generation Logic
Buddy generation is deterministic. It uses a specific salt (friend-2026-401) and the detected User ID to seed the random number generator.
Deterministic Rolling Process
- Hash Generation: The User ID and salt are passed through
Wyhashto create a 64-bit hash, truncated to aUInt32seed. - PRNG Initialization: A
Mulberry32generator is initialized with the seed. - Attribute Selection:
- Rarity is rolled first based on cumulative weights.
- Species and Eyes are picked from all available cases.
- Hats are only assigned if the rarity is greater than
Common.
Sources: buddi/Buddi/Buddy/BuddyDetector.swift:12-32, buddi/Buddi/Buddy/BuddyDetector.swift:42-53
Claude Config Detection
The system searches for Claude Code configuration files in multiple locations to extract a persistent userId:
$CLAUDE_CONFIG_DIR(Environment Variable)~/.claude.json~/.claude/.config.json
Sources: buddi/Buddi/Buddy/BuddyDetector.swift:70-98
Management & Customization
The BuddyManager handles the lifecycle of the identity and integrates user preferences.
Effective Identity Logic
The effectiveIdentity is a computed version of the original roll with user-defined overrides applied via UserDefaults. If a user resets their settings, the system falls back to the original deterministic identity.
private static func applyOverrides(to base: BuddyIdentity) -> BuddyIdentity {
var result = base
if let raw = Defaults[.buddySpeciesOverride], let species = BuddySpecies(rawValue: raw) {
result.species = species
}
// ... similarly for eyes, hats, and rarity
return result
}
Sources: buddi/Buddi/Buddy/BuddyManager.swift:33-65, buddi/Buddi/Settings/ClaudeCodeSettings.swift:101-135
Visual Representation
Buddies are rendered as ASCII art. The ASCIISpriteView and ASCIIFullSpriteView use the BuddyIdentity to determine which characters to draw.
- Coloration: The
rarity.nsColordetermines the foreground color of the ASCII text. - State-Based Eyes: While the identity defines a default eye, certain states override it (e.g.,
crosseyes for errors,doteyes for sleeping). - Animation:
TimelineViewis used to cycle through animation frames every 0.8 seconds, with the specific frame content determined by the species and traits.
Sources: buddi/Buddi/Buddy/ASCIISpriteView.swift:5-52
Summary
Buddy Identity & Generation provides a personalized experience for Buddi users by deriving a unique companion from their existing Claude Code environment. By combining deterministic hashing with a flexible override system, Buddi maintains a balance between a "signature" identity and user expressibility. The identity system is deeply integrated into the UI, influencing everything from the notch's small status display to the expanded onboarding and settings views.