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.
This commit is contained in:
parent
a9c5610914
commit
0c311b099b
3 changed files with 98 additions and 0 deletions
18
install.sh
18
install.sh
|
|
@ -278,6 +278,24 @@ if not os.path.exists(log_path):
|
|||
print(" Created hook_debug.log")
|
||||
PYEOF
|
||||
|
||||
# Copy statusline script to stable user-local path
|
||||
cp "${REPO_DIR}/lib/statusline.sh" "${BUDDYMON_DIR}/statusline.sh"
|
||||
chmod +x "${BUDDYMON_DIR}/statusline.sh"
|
||||
ok "Installed statusline.sh → ${BUDDYMON_DIR}/statusline.sh"
|
||||
|
||||
# Install statusline into settings.json if not already configured
|
||||
python3 << PYEOF
|
||||
import json
|
||||
f = '${SETTINGS_FILE}'
|
||||
d = json.load(open(f))
|
||||
if 'statusLine' not in d:
|
||||
d['statusLine'] = {"type": "command", "command": "bash ${BUDDYMON_DIR}/statusline.sh"}
|
||||
json.dump(d, open(f, 'w'), indent=2)
|
||||
print(" Installed Buddymon statusline in settings.json")
|
||||
else:
|
||||
print(" statusLine already configured — skipped (run /buddymon statusline to install manually)")
|
||||
PYEOF
|
||||
|
||||
echo ""
|
||||
echo "✓ ${PLUGIN_KEY} installed!"
|
||||
echo ""
|
||||
|
|
|
|||
38
lib/statusline.sh
Normal file
38
lib/statusline.sh
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
#!/usr/bin/env bash
|
||||
# Buddymon statusline — displays active buddy + encounter in the CC status bar.
|
||||
# Install: add to ~/.claude/settings.json → "statusLine" → "command"
|
||||
# Or run: /buddymon statusline (installs automatically)
|
||||
|
||||
B="$HOME/.claude/buddymon"
|
||||
|
||||
# Bail fast if no state directory or no starter chosen
|
||||
[[ -d "$B" ]] || exit 0
|
||||
STARTER=$(jq -r '.starter_chosen // false' "$B/roster.json" 2>/dev/null)
|
||||
[[ "$STARTER" == "true" ]] || exit 0
|
||||
|
||||
# Read state
|
||||
ID=$(jq -r '.buddymon_id // ""' "$B/active.json" 2>/dev/null)
|
||||
[[ -n "$ID" ]] || exit 0
|
||||
|
||||
LVL=$(jq -r ".owned[\"$ID\"].level // 1" "$B/roster.json" 2>/dev/null)
|
||||
XP=$(jq -r '.session_xp // 0' "$B/active.json" 2>/dev/null)
|
||||
|
||||
ENC_JSON=$(jq -c '.active_encounter // null' "$B/encounters.json" 2>/dev/null)
|
||||
ENC_DISPLAY=$(echo "$ENC_JSON" | jq -r '.display // ""' 2>/dev/null)
|
||||
ENC_STRENGTH=$(echo "$ENC_JSON" | jq -r '.current_strength // 0' 2>/dev/null)
|
||||
|
||||
# ANSI colors
|
||||
CY='\033[38;2;23;146;153m' # cyan — buddy
|
||||
GR='\033[38;2;64;160;43m' # green — xp
|
||||
RD='\033[38;2;203;60;51m' # red — encounter
|
||||
DM='\033[38;2;120;120;120m' # dim — separators
|
||||
RS='\033[0m'
|
||||
|
||||
printf "${CY}🐾 ${ID} Lv.${LVL}${RS}"
|
||||
printf " ${DM}·${RS} ${GR}+${XP}xp${RS}"
|
||||
|
||||
if [[ "$ENC_JSON" != "null" ]] && [[ -n "$ENC_DISPLAY" ]]; then
|
||||
printf " ${RD}⚔ ${ENC_DISPLAY} [${ENC_STRENGTH}%%]${RS}"
|
||||
fi
|
||||
|
||||
echo
|
||||
|
|
@ -25,6 +25,7 @@ Parse `$ARGUMENTS` (trim whitespace, lowercase the first word) and dispatch:
|
|||
| `fight` | Fight active encounter |
|
||||
| `catch` | Catch active encounter |
|
||||
| `roster` | Full roster view |
|
||||
| `statusline` | Install Buddymon statusline into settings.json |
|
||||
| `help` | Show command list |
|
||||
|
||||
---
|
||||
|
|
@ -279,6 +280,46 @@ Read `roster.json` → `language_affinities`. Skip this section if empty.
|
|||
|
||||
---
|
||||
|
||||
## `statusline` — Install Buddymon Statusline
|
||||
|
||||
Installs the Buddymon statusline into `~/.claude/settings.json`.
|
||||
|
||||
The statusline shows active buddy + level + session XP, and highlights any
|
||||
active encounter in red:
|
||||
|
||||
```
|
||||
🐾 Debuglin Lv.90 · +45xp ⚔ 💀 NullWraith [60%]
|
||||
```
|
||||
|
||||
Run this Python to install:
|
||||
|
||||
```python
|
||||
import json, os, shutil
|
||||
|
||||
SETTINGS = os.path.expanduser("~/.claude/settings.json")
|
||||
PLUGIN_ROOT = os.environ.get("CLAUDE_PLUGIN_ROOT", "")
|
||||
SCRIPT = os.path.join(PLUGIN_ROOT, "lib", "statusline.sh")
|
||||
|
||||
settings = json.load(open(SETTINGS))
|
||||
|
||||
if settings.get("statusLine"):
|
||||
print("⚠️ A statusLine is already configured. Replace it? (y/n)")
|
||||
# ask user — if no, abort
|
||||
# if yes, proceed
|
||||
pass
|
||||
|
||||
settings["statusLine"] = {
|
||||
"type": "command",
|
||||
"command": f"bash {SCRIPT}",
|
||||
}
|
||||
json.dump(settings, open(SETTINGS, "w"), indent=2)
|
||||
print(f"✅ Buddymon statusline installed. Reload Claude Code to activate.")
|
||||
```
|
||||
|
||||
If a `statusLine` is already set, show the existing command and ask before replacing.
|
||||
|
||||
---
|
||||
|
||||
## `help`
|
||||
|
||||
```
|
||||
|
|
@ -288,4 +329,5 @@ Read `roster.json` → `language_affinities`. Skip this section if empty.
|
|||
/buddymon fight — fight active encounter
|
||||
/buddymon catch — catch active encounter
|
||||
/buddymon roster — view full roster
|
||||
/buddymon statusline — install statusline widget
|
||||
```
|
||||
|
|
|
|||
Loading…
Reference in a new issue