Skip to content

refactor(tui): remove hard-coded personal familiars#93

Merged
BunsDev merged 1 commit into
mainfrom
fix/remove-hardcoded-familiars
Jun 15, 2026
Merged

refactor(tui): remove hard-coded personal familiars#93
BunsDev merged 1 commit into
mainfrom
fix/remove-hardcoded-familiars

Conversation

@BunsDev

@BunsDev BunsDev commented Jun 15, 2026

Copy link
Copy Markdown
Member

What & why

The TUI shipped a hard-coded roster of seven named personal familiarskitty, nova, cody, charm, sage, astra, echo — each with a baked-in display name, emoji, bespoke pixel-art glyph, and a name-based default tool-access tier. Anyone installing coven-code inherited these:

  • a fresh user with no ~/.coven/familiars.toml silently got "kitty" as the default familiar,
  • unknown ids fell back to kitty, and
  • cody/nova/kitty were auto-granted full (write/exec) access by name (a security-relevant inheritance).

This removes every aspect of the TUI/CLI that hard-codes those personas, so other users cannot accidentally inherit them in any capacity — while keeping the procedural rendering engine so each user's own familiars.toml entries still render with first-class visual identity.

Changes

  • familiar_theme.rs — deleted BUILTIN_PALETTES, builtin(), and builtin_access() (the name-based full-access grants); reduced Archetype to the four procedural sigils; rewrote resolve() so roster entries use the user's own definition and any other id is derived procedurally from the id itself — no named fallback.
  • mascot.rs — gutted to just CompanionPose; removed all seven bespoke art builders, archetype_lines, and mascot_lines_for.
  • familiar_card.rs — every familiar now renders through the procedural sigil path; added a pose-driven pulse_accent so all cards animate generically (no per-persona art).
  • app.rs — removed the unwrap_or("kitty") switcher fallback.
  • Test fixtures (app.rs, render.rs, agents_view.rs, handoff.rs, cli/main.rs) scrubbed of persona names → neutral wisp/ember/onyx.
  • docs/familiars.md — replaced the example roster, access-tier role names, opt-in roster example, and example config with generic ids; removed the now-false "Built-in glyphs" table and static-glyph claim.

Note: the app-level selection paths (default_familiar_switcher_list, infer_familiar_from_env, visible_familiar) were already roster-only, and familiar_image.rs already loaded images at runtime from the user's own dirs — those needed no change.

Verification

  • cargo build -p claurst -p claurst-tui — clean.
  • cargo clippy — no new warnings.
  • cargo test -p claurst-tui (632 + suites) and -p claurstall pass, 0 failures, including the new familiar_theme procedural tests.
  • Residual-reference sweep: no personal-familiar references remain in TUI/CLI or docs (only the unrelated Kitty terminal graphics protocol).

🤖 Generated with Claude Code

The TUI shipped a roster of seven named built-in familiars (kitty, nova,
cody, charm, sage, astra, echo) with baked-in names, emoji, bespoke
pixel-art, and name-based access grants. A fresh install with no
~/.coven/familiars.toml silently inherited "kitty" as the default, unknown
ids fell back to "kitty", and cody/nova/kitty were auto-granted full
(write/exec) access by name. Other users should never inherit these.

- familiar_theme: drop BUILTIN_PALETTES, builtin(), builtin_access();
  reduce Archetype to the four procedural sigils; resolve() now derives
  every familiar (roster or unknown) procedurally from its id with no
  named fallback.
- mascot: gut to just CompanionPose; remove the seven bespoke art builders,
  archetype_lines, and mascot_lines_for.
- familiar_card: route every familiar through the sigil path; add a
  pose-driven palette pulse so all cards animate generically.
- app: drop the unwrap_or("kitty") switcher fallback.
- Scrub persona names from test fixtures and update docs/familiars.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 15, 2026 13:45
@vercel

vercel Bot commented Jun 15, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
docs Ready Ready Preview Jun 15, 2026 1:45pm

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Removes hard-coded “personal familiar” personas from the TUI/CLI and shifts rendering entirely to procedurally-derived familiars so fresh installs and unknown IDs no longer inherit named defaults or access tiers.

Changes:

  • Deleted built-in familiar palettes/archetypes and bespoke mascot pixel art; rendering is now procedural across the board.
  • Updated familiar resolution so unknown IDs derive a theme from the ID itself (no named fallback).
  • Scrubbed tests and docs to use neutral example familiar IDs.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src-rust/crates/tui/src/render.rs Updates tests to use neutral familiar IDs.
src-rust/crates/tui/src/mascot.rs Removes bespoke mascot rendering; retains only pose state used for card animation.
src-rust/crates/tui/src/handoff.rs Updates tests to use neutral familiar IDs/strings.
src-rust/crates/tui/src/familiar_theme.rs Removes built-in roster resolution; resolves themes procedurally and updates tests.
src-rust/crates/tui/src/familiar_card.rs Routes all rendering through procedural sigils; adds pose-driven accent pulsing.
src-rust/crates/tui/src/app.rs Removes kitty fallback in switcher highlighting; updates tests.
src-rust/crates/tui/src/agents_view.rs Updates test fixtures to neutral familiar IDs.
src-rust/crates/cli/src/main.rs Updates tests and fixtures to neutral familiar IDs/branch names.
docs/familiars.md Updates documentation to reflect no built-in roster and procedural glyph behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +216 to 224
fn unknown_id_is_stable() {
let a = resolve("solo", &[]);
let b = resolve("solo", &[]);
assert_eq!(format!("{:?}", a.archetype), format!("{:?}", b.archetype));
assert_eq!(
format!("{:?}", a.palette.primary),
format!("{:?}", b.palette.primary)
);
}
Comment on lines +241 to 252
// The eye socket follows each familiar's palette rather than one
// shared hardcoded violet, so across a spread of ids more than one
// distinct eye socket shows up.
let ids = ["alpha", "beta", "gamma", "delta", "epsilon", "zeta"];
let sockets: std::collections::HashSet<String> = ids
.iter()
.map(|id| format!("{:?}", resolve(id, &[]).palette.eye_socket))
.collect();
assert!(
sockets.len() > 1,
"eye sockets should follow each familiar's palette, got {sockets:?}"
);
Comment on lines +249 to +262
/// Accent color for a sigil's decorative row, pulsed by the companion pose.
///
/// The glyph text never changes width — only the accent row's color shifts
/// between the bright accent and the dimmer primary — so an `Idle` card
/// breathes softly and a stalled `Loading` card pulses faster, while a
/// `Static` card stays bright. This is the only animation; it is identical for
/// every familiar and tied to no named persona.
fn pulse_accent(p: &FamiliarPalette, pose: &CompanionPose) -> Color {
match pose {
CompanionPose::Idle { frame } if matches!(frame % 120, 90..=95) => p.primary,
CompanionPose::Loading { frame } if (frame / 5) % 2 == 1 => p.primary,
_ => p.accent,
}
}
@BunsDev BunsDev merged commit 9723baa into main Jun 15, 2026
2 checks passed
@BunsDev BunsDev deleted the fix/remove-hardcoded-familiars branch June 15, 2026 13:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants