Commit 5a7d06f
refactor(buddy): align companion system with official CLI (#82)
* refactor(buddy): align companion system with official CLI
## Summary
Reverse-engineered the official Claude Code CLI (v2.1.91) buddy/companion
system and aligned our implementation to match.
## Changes (7 files)
### Added
- `src/buddy/CompanionCard.tsx` (+109)
JSX bordered card matching official vc8: rarity header, colored sprite,
name, personality, 10-bar stats, last reaction in nested border.
- `src/buddy/companionReact.ts` (+156)
Reaction system matching official ZUK+Dc8: 45s rate limiting, @-mention
detection, transcript builder (12 msgs, 5000 chars), POST buddy_react API.
### Modified
- `src/commands/buddy/index.ts`
type: local -> local-jsx, description/argumentHint/immediate/isHidden.
- `src/commands/buddy/buddy.ts`
LocalCommandCall -> LocalJSXCommandCall signature (onDone, context, args).
Removed mute/unmute/rehatch (official uses off/on only).
/buddy show returns CompanionCard JSX instead of plain text.
Pet auto-unmutes. companionMuted writes globalConfig (matches UI read source).
- `src/screens/REPL.tsx` (line 2808)
globalThis.fireCompanionObserver -> import triggerCompanionReaction.
- `src/state/AppStateStore.ts` — comment fix.
- `src/types/global.d.ts` — removed fireCompanionObserver declaration.
## Data flow (verified consistent)
- companionMuted: saveGlobalConfig() <-> getGlobalConfig() (6 read sites)
- companionReaction: setAppState() <-> useAppState() (4 sites)
- companionPetAt: setAppState() <-> useAppState() (2 sites)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(buddy): address CodeRabbit review findings
- buddy.ts: return type Promise<null> → Promise<React.ReactNode>
to match LocalJSXCommandCall interface (CompanionCard path returns
ReactElement, not null).
- CompanionCard.tsx: clamp stat value to 0..100 before .repeat()
to prevent negative count runtime error on out-of-range values.
Import path alias suggestions (src/ vs ../) dismissed — project
convention uses relative paths (verified against color.ts, help.ts).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(buddy): address second round CodeRabbit findings
- buddy.ts:105: remove unsafe (context as any).messages cast.
ToolUseContext already declares messages: Message[] at Tool.ts:250,
so context.messages is properly typed. Other commands (feedback,
copy, export) access it the same way without cast.
- companionReact.ts:154: wrap resp.json() in try/catch for defensive
JSON parsing. Malformed 200 responses now return null instead of
propagating to the outer catch.
Rate-limit timing (set before API call) kept as-is — matches official
ZUK pattern: prevents retry-storm on transient failures.
src/ path alias suggestions dismissed — project uses relative paths.
Auto-unmute on /buddy view kept — matches official behavior.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: unraid <local@unraid.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>2 files changed
Lines changed: 7 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
151 | 151 | | |
152 | 152 | | |
153 | 153 | | |
154 | | - | |
155 | | - | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
156 | 160 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
102 | 102 | | |
103 | 103 | | |
104 | 104 | | |
105 | | - | |
| 105 | + | |
106 | 106 | | |
107 | 107 | | |
108 | 108 | | |
| |||
0 commit comments