Commit graph

23 commits

Author SHA1 Message Date
pyr0ball
85af20b6f1 feat: 6 control-flow bug monsters
InfiniteWisp  — while/until loops that never exit (KeyboardInterrupt, hung process)
BoundsHound   — off-by-one, IndexError, ArrayIndexOutOfBounds
BranchGhost   — wrong branch taken, unreachable/dead code, fallthrough
SwitchTrap    — unhandled case/switch arms, non-exhaustive match, missing default
RecurseWraith — missing base case, RecursionError, StackOverflow
CatchAll      — broad exception handlers; rare, defeat=false (catch only)

Total bug_monsters: 18
2026-04-02 22:40:38 -07:00
pyr0ball
6632d67da4 nerf: probability gates on wound and flee transitions
Healthy → wounded: 50% per clean run (avg ~2 runs, was instant)
Wounded → fled: 35% per clean run (avg ~3 runs, was instant)

Combined expected clean runs before auto-resolve: ~5, giving the user
a realistic window to type /buddymon catch between tool calls.
2026-04-02 22:39:07 -07:00
pyr0ball
85f53b1e83 feat: catch-pending flag + wounded state for encounter resolution
catch_pending: set immediately when /buddymon catch is invoked, suppresses
auto-resolve while weakening Q&A is in progress. Cleared before catch roll
(success clears encounter, failure leaves it without the flag so auto-resolve
resumes naturally on the next clean Bash run).

wounded: first clean Bash run without catch_pending drops the encounter to 5%
strength and re-announces via UserPromptSubmit with a fleeing message. Second
clean run auto-resolves it (it fled). UserPromptSubmit now shows distinct
announcement text for wounded vs fresh encounters.
2026-04-02 22:37:35 -07:00
pyr0ball
55747068e1 feat: expand MemoryLeech patterns + add CudaCrash bug_monster
MemoryLeech now catches: malloc failures, std::bad_alloc, Java OOM,
GC overhead limit, JavaScript heap OOM, OOMKilled, oom-killer,
macOS malloc region failures.

CudaCrash is a new uncommon bug_monster (strength 65, 130 XP) for
GPU/VRAM OOM: torch.cuda.OutOfMemoryError, CUDA error: out of memory,
cuDNN/CUBLAS allocation failures, device-side assert triggered.
2026-04-02 22:33:52 -07:00
pyr0ball
0c311b099b feat: buddymon statusline widget
Adds lib/statusline.sh — a fast bash+jq status bar widget showing
active buddy, level, session XP, and any active encounter in red.

install.sh now copies the script to ~/.claude/buddymon/statusline.sh
and wires it into settings.json automatically during install.

/buddymon statusline subcommand documented in SKILL.md for manual install.
2026-04-02 22:31:37 -07:00
pyr0ball
a9c5610914 feat: language affinity system — persistent XP + tier progression
Adds LANGUAGE_TIERS with 6 tiers: discovering → familiar → comfortable
→ proficient → expert → master (thresholds: 0/50/150/350/700/1200 XP).

add_language_affinity() writes to roster.json['language_affinities'],
accumulating across sessions. Returns (leveled_up, old_tier, new_tier)
so the Edit/Write branch can fire a level-up message immediately (Edit
PostToolUse additionalContext surfaces fine).

Session-level languages_seen remains for the one-time Explorer bonus.
Roster skill view updated to show language affinity section.
2026-04-02 22:23:31 -07:00
pyr0ball
d2006727a1 feat: add LayerLurker and DiskDemon event encounters
LayerLurker triggers on docker/podman build commands.
DiskDemon triggers on ENOSPC and disk-full output patterns.
2026-04-02 22:21:31 -07:00
pyr0ball
75f3d9e179 feat: add ReviewHawk, TicketGremlin, PermWraith, SudoSprite encounters
ReviewHawk  — gh pr create / push -u (catch-only, opens PR)
TicketGremlin — jira/linear CLI, curl to issue tracker APIs
PermWraith  — Permission denied / EACCES / EPERM output
SudoSprite  — chmod / chown / chgrp commands (catch-only)

Also switch command_patterns matching to re.search so patterns
with .* work correctly (e.g. git push.*--set-upstream).
2026-04-02 22:16:00 -07:00
pyr0ball
6a81392074 feat: expand encounter triggers — git ops, installs, test events, test files
New event_encounters catalog section:
  🔀 MergeMaw     — git merge / rebase
  🌿 BranchSprite — git checkout -b / switch -c (catch-only)
  📦 DepGolem     — pip/npm/cargo/yarn/brew install
  🎲 FlakeDemon   — test failure output (FAILED, AssertionError, etc.)
   PhantomPass  — tests pass after session errors (rare, catch-only)
  🧪 TestSpecter  — editing a test file (50% chance)

Detection logic:
  - Bash hook now checks tool_input.command for command-pattern triggers
  - Event encounters run when no bug monster matched (priority: bugs first)
  - Edit/Write hook adds TestSpecter check on test file paths
2026-04-02 22:11:31 -07:00
pyr0ball
1930bd29bd fix: rotate challenge each session
Stop hook clears active.challenge after reporting it.
Start hook assigns a random challenge from the buddy's pool if none is set.
Result: fresh challenge every session, no stale repeat.
2026-04-02 12:20:19 -07:00
pyr0ball
95ffc92e7d docs: companion widget note is user-configured, not Anthropic-shipped 2026-04-02 11:22:50 -07:00
pyr0ball
39b14f27be fix: correct Bash output extraction + README Thrumble relationship note
- CC Bash tool_response uses stdout/stderr keys (not output/content/text)
- Encounter detection now works — confirmed TypeGreml match via stderr
- README: clarify Thrumble is Anthropic's widget, not driveable by plugins
2026-04-02 11:22:16 -07:00
pyr0ball
b0deb21d3a fix: use stdout/stderr fields for Bash tool_response output extraction
CC sends Bash results as {stdout, stderr, interrupted, isImage, noOutputExpected}.
Previous code guessed output/content/text — all wrong, so encounter detection
never matched. Confirmed via active.json relay debug.
2026-04-02 11:20:00 -07:00
pyr0ball
7b9e78a501 fix: add matcher field to UserPromptSubmit hook (semgrep pattern) 2026-04-01 23:13:27 -07:00
pyr0ball
9b13150d1b feat: UserPromptSubmit hook for encounter announcements
Bash PostToolUse additionalContext is silently dropped by CC — encounters
are written to state but never surfaced. Fix with a two-phase approach:

- PostToolUse (Bash): detects error, writes encounter with announced:false
- UserPromptSubmit: fires on next user message, checks for unannounced
  encounter, surfaces it once, marks announced:true so dedup loop breaks

Removes debug scaffolding and the format_encounter_message call from the
Bash hook (announcement is now fully owned by user-prompt-submit.py).
2026-04-01 23:08:57 -07:00
pyr0ball
e2a4b66267 fix: stop hook schema, uninstall cleanup, and README architecture note
- Fix session-stop.sh in 0.1.0 cache to use systemMessage instead of
  hookSpecificOutput (Stop hook schema doesn't support hookSpecificOutput)
- Remove debug scaffolding from post-tool-use.py
- Installer: pre-create hook_debug.log so sandbox can write to it;
  uninstall now removes marketplace plugin symlink
- README: clarify extension vs mod architecture, fix cache path in
  install description
2026-04-01 22:49:12 -07:00
pyr0ball
507a2fc4a9 fix: correct hook output schemas and marketplace registration
Stop hook was emitting hookSpecificOutput with hookEventName=Stop,
which is not a valid hookSpecificOutput type (only PreToolUse,
PostToolUse, UserPromptSubmit are). Changed to systemMessage.

SessionStart still uses additionalContext (confirmed working).

Stale /buddymon-fight and /buddymon-catch references in session-start.sh
updated to /buddymon fight and /buddymon catch.

install.sh now creates a full circuitforge marketplace with marketplace.json
so CC can validate the plugin name against the index before loading.
Removed invalid extraKnownMarketplaces local source (only github/git valid).
2026-04-01 21:45:59 -07:00
pyr0ball
9440c8c0b2 fix: installPath must be cache symlink path, not realpath
CC requires installPath to be inside ~/.claude/plugins/cache/ — resolved
real path breaks plugin loading. Version bump to 0.1.1 in install.sh.
2026-04-01 17:05:31 -07:00
pyr0ball
b81f39bfcd fix: plugin registration and reload survival
- plugin.json: flatten repository to string, remove extra fields that
  failed CC schema validation (caused 'Unknown skill' on reload)
- hooks.json: remove escaped quotes from command paths (matched hookify
  reference implementation)
- install.sh: register 'local' marketplace in known_marketplaces.json
  so CC doesn't GC the cache symlink on /reload-plugins
2026-04-01 16:52:09 -07:00
pyr0ball
804d1f3887 docs: rewrite install section for v0.1.0 release
Full install instructions with clone URLs for all three remotes,
install.sh walkthrough, update/uninstall notes.
2026-04-01 15:21:40 -07:00
pyr0ball
e9b04070f3 feat: install script + smoke test fixes
- install.sh: symlink-based dev install, registers in installed_plugins.json
  and settings.json, initializes ~/.claude/buddymon/ state files
- install.sh --uninstall to cleanly remove
- Fix stale /buddymon-start and /buddymon-assign references in session-start.sh
  to use unified /buddymon start and /buddymon assign subcommands
2026-04-01 15:20:29 -07:00
pyr0ball
46734e79c8 feat: auto-resolve encounters on clean Bash runs
When an active encounter exists and the next Bash tool call produces
output with no matching error patterns, the monster is automatically
defeated and XP is awarded — no manual /buddymon fight needed.

/buddymon fight is kept as a manual fallback for fixes that happen
outside Bash (config edits, etc.).
2026-04-01 15:15:02 -07:00
pyr0ball
f3d1f45253 feat: initial Buddymon plugin
Claude Code plugin — collectible creatures discovered through coding.

- Bug monsters spawn from error output (NullWraith, RacePhantom, ShadowBit, 11 total)
- 5 Buddymon with affinities, challenges, and evolution chains
- SessionStart hook injects active buddy + challenge into system context
- PostToolUse hook detects error patterns, new languages, and commit events
- Stop hook tallies XP and checks challenge completion
- Single /buddymon command with start/assign/fight/catch/roster subcommands
- Local state in ~/.claude/buddymon/ (roster, encounters, active, session)
2026-04-01 15:11:46 -07:00