InkdownInkdown
Start writing

Claude-Code

62 filesยท4 subfolders

Shared Workspace

Claude-Code
codex

14-buddy-companion

Shared from "Claude-Code" on Inkdown

Buddy (Companion Pet)

The animated ASCII companion pet that sits beside your input box.


Overview

Buddy is a feature-gated companion pet system that displays an animated ASCII creature next to the user's input area. Gated behind feature('BUDDY') with a teaser window (April 1-7, 2026).


Species

20 species with multi-frame idle fidget animations:

SpeciesRarity
0000_start_here_index_and_recommended_reading_order.md
0100_project_overview_tech_stack_runtime_modes_and_folder_map.md
0200_startup_flow_entry_points_and_cold_start_sequence.md
0300_codebase_modules_layers_state_models_and_schemas.md
0400_system_architecture_and_design_rationale.md
0500_interactive_repl_request_flow_end_to_end.md
0600_headless_sdk_and_print_mode_request_flow_end_to_end.md
0700_mcp_integration_connection_and_tool_call_flow.md
0800_external_services_sdks_storage_and_local_dependencies.md
0900_environment_variables_settings_feature_flags_and_failure_modes.md
1000_non_obvious_patterns_gotchas_and_debugging_traps.md
1100_full_codebase_file_inventory_grouped_by_directory.md
kimi
00-overview.md
01-entrypoints.md
02-state-management.md
03-query-system.md
04-tools-system.md
05-tasks-system.md
06-ui-components.md
07-bridge-remote.md
08-services.md
09-skills-plugins.md
10-commands.md
11-testing-architecture.md
12-permission-system.md
13-build-system.md
14-ink-internals.md
15-git-internals.md
16-context-compaction.md
17-vim-mode.md
18-mailbox-notifications.md
19-session-persistence.md
20-hooks-system.md
21-error-recovery.md
README.md
qwen
00-overview.md
01-entry-points.md
02-query-engine.md
03-tools-and-tasks.md
04-commands-and-skills.md
05-state-management.md
06-ink-rendering.md
07-bridge-remote.md
08-mcp-services.md
09-services-overview.md
10-multi-agent.md
11-system-prompt-constants.md
12-tool-interface.md
13-memory-system.md
14-buddy-companion.md
15-keybindings.md
16-stop-hooks.md
17-vim-mode.md
18-upstreamproxy.md
19-cost-tracking-history.md
20-contexts-styles-onboarding.md
21-hooks.md
22-screens.md
tweets-explain
claude-code-memory-analysis.md
compact
memory-system
agentic-architecture
DuckCommon
GooseCommon
BlobCommon
CatCommon
RabbitCommon
CactusUncommon
PenguinUncommon
TurtleUncommon
SnailUncommon
MushroomUncommon
OwlRare
DragonRare
GhostRare
AxolotlRare
CapybaraEpic
ChonkEpic
RobotEpic
OctopusLegendary
Rarity System

Weighted rolling based on rarity:

TypeScript
const weights = {
  common: 40,
  uncommon: 25,
  rare: 20,
  epic: 10,
  legendary: 5,
}
Deterministic Generation

The species is determined by hashing the user's ID:

TypeScript
const species = hashToSpecies(userId)

This means:

  • You can't fake a rare species by editing config
  • Same user always gets the same species
  • Different users get different species

Sprite Rendering

Two Modes

Full sprite (wide terminals, >80 chars):

Plain text
  โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
  โ”‚  Think about    โ”‚  โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
  โ”‚  this code...   โ”‚  โ”‚ โ—•   โ—• โ”‚
  โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ  โ”‚  โ”€โ”€โ”€  โ”‚
                       โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

Collapsed one-liner (narrow terminals):

Plain text
[โ—•โ€ฟโ—•] Think about this code...
Animation Frames

Each species has multiple idle animation frames:

TypeScript
const duckFrames = [
  ` โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
   โ”‚ โ—•   โ—• โ”‚
   โ”‚  โ”€โ”€โ”€  โ”‚
   โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ`,
  ` โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
   โ”‚ โ—•   โ—• โ”‚
   โ”‚  โ–ฝ    โ”‚
   โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ`,
  // ... more frames
]

Frames cycle on a timer to create a fidgeting effect.


Speech Bubble

The buddy reacts to model responses with speech bubbles:

TypeScript
interface CompanionReaction {
  text: string       // What the buddy says
  sprite?: number    // Optional sprite override
}

Reactions are triggered by:

  • Model completing a response
  • Tool execution
  • Errors
  • User petting

Bubbles fade out after ~10 seconds.


Pet Mechanic

Users can pet their buddy with /buddy pet:

Plain text
User: /buddy pet
    โ”‚
    โ–ผ
Floating heart animation:
  โ™ฅ
    โ™ฅ
      โ™ฅ

Triggers a happy reaction from the buddy.


System Prompt Integration

A companion_intro attachment is injected into the system prompt:

Plain text
You have a companion pet (a <species>) that sits beside the user's input.
The pet can react to your responses. Use the companion_reaction field
to trigger reactions.

State in AppState

TypeScript
// In AppState
companionReaction: CompanionReaction | null
companionPetAt: number | null  // Timestamp of last pet

Notification Hook

useBuddyNotification.tsx manages buddy notifications:

TypeScript
// Shows notification when buddy has something to say
const notification = useBuddyNotification()

Files

FilePurpose
src/buddy/companion.tsCore companion logic
src/buddy/CompanionSprite.tsxSprite rendering component
src/buddy/sprites.tsAll 20 species sprite frames
src/buddy/prompt.tsSystem prompt injection
src/buddy/types.tsType definitions
src/buddy/useBuddyNotification.tsxNotification hook