feat(bad): auto-detect and chain existing statusLine during setup

Setup now scans settings files highest→lowest precedence, finds the
effective statusLine command, chains it stdin-safely into bad-statusline.sh,
and writes only to settings.local.json — no other files touched.
Detailed logic extracted to references/coordinator/setup-statusline-hook.md.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
stephenleo
2026-04-12 10:17:07 +08:00
parent b0d09a3454
commit 13133d685e
2 changed files with 75 additions and 24 deletions

View File

@@ -51,30 +51,7 @@ Ask: **"Install BAD session-state capture (writes rate-limit / context data to a
Default: **yes** (or auto-accept if `--headless` / `accept all defaults`).
If **yes**:
1. Copy `./assets/bad-statusline.sh` to `{project-root}/.claude/bad-statusline.sh`.
Make it executable: `chmod +x {project-root}/.claude/bad-statusline.sh`.
2. Read `{project-root}/.claude/settings.json` (create `{}` if absent).
3. Check if a `statusLine` key already exists:
- **If absent:** set it to:
```json
"statusLine": {
"type": "command",
"command": ".claude/bad-statusline.sh"
}
```
- **If already set:** do not overwrite. Instead, print:
```
⚠️ A statusLine is already configured in .claude/settings.json.
To enable BAD's session-state capture, chain it manually:
1. Open .claude/bad-statusline.sh — it shows how to pipe to an existing script.
2. Add .claude/bad-statusline.sh as the last step in your existing statusline pipeline.
```
4. Write the updated `settings.json` back (only if you modified it).
If **yes**, read and follow `references/coordinator/setup-statusline-hook.md`.
---

View File

@@ -0,0 +1,74 @@
# BAD Session-State Hook Setup
Executed during `/bad setup` (Step 2b). Installs `bad-statusline.sh` as the Claude Code
`statusLine` script, automatically chaining any pre-existing statusLine command so the user
loses no existing functionality.
---
## Step 1: Find the Effective Existing Command
Claude Code applies `statusLine` using this precedence (highest to lowest). Scan in order and
stop at the first file that has a `statusLine.command`. Skip any command already equal to
`.claude/bad-statusline.sh` (re-run guard).
| Priority | File | Writable by setup |
|----------|------|-------------------|
| 1 (highest) | `/Library/Application Support/ClaudeCode/managed-settings.json` | No |
| 2 | `{project-root}/.claude/settings.local.json` | Yes |
| 3 | `{project-root}/.claude/settings.json` | No — local.json takes precedence |
| 4 (lowest) | `~/.claude/settings.json` | No — outside project scope |
- If found at priority 1 (managed): set `MANAGED_CONFLICT=true` — go directly to the managed
warning below and stop. Writing to `settings.local.json` would have no effect since managed
settings override all user-writable files.
- If found at priority 24: save the value as `CHAIN_COMMAND`.
- If not found anywhere: `CHAIN_COMMAND` is empty.
---
## Step 2: Write `bad-statusline.sh`
Copy `./assets/bad-statusline.sh` to `{project-root}/.claude/bad-statusline.sh`.
Make it executable: `chmod +x {project-root}/.claude/bad-statusline.sh`.
If `CHAIN_COMMAND` is non-empty, rewrite the script body:
```bash
#!/bin/bash
# BAD session-state capture — auto-generated by /bad setup.
# Chains pre-existing statusLine command then writes Claude Code session JSON
# to a temp file for BAD Pre-Continuation Checks.
SESSION_JSON=$(cat)
echo "$SESSION_JSON" | <CHAIN_COMMAND>
echo "$SESSION_JSON" > "${TMPDIR:-/tmp}/bad-session-state.json"
```
If `CHAIN_COMMAND` is empty, keep the script body as-is.
---
## Step 3: Write `statusLine` to Project-Local Settings
Read `{project-root}/.claude/settings.local.json` (create `{}` if absent). Set:
```json
"statusLine": {
"type": "command",
"command": ".claude/bad-statusline.sh"
}
```
Write the file back. No other settings files are modified.
---
## Managed Settings Conflict
If `MANAGED_CONFLICT=true`, skip Steps 23 and print:
```
⚠️ A managed statusLine is configured and takes precedence over all user settings.
BAD session-state capture (rate-limit pausing, context compaction) will not function.
Ask your admin to chain .claude/bad-statusline.sh into the managed statusLine script.
```