My Claude Code has a custom status bar: model, git branch, context percentage, cost. Then I installed kickbacks, an extension that pays you for showing ads in your dev tools, and it took over my status bar. I wanted both. Here is the whole rabbit hole, and the fix that finally held.
Discovery one: it was designed to coexist
kickbacks (internally called "vibe-ads", a VS Code extension) writes its own statusLine into settings.json. But reading its code showed it was designed for coexistence: its script prints the ad, then runs your previous status line and places it underneath, reading it from vibe-ads/cli-prev-statusline.json.
So why the takeover? The chaining file was empty. kickbacks had no "previous bar" of mine to place under the ad, so I saw only the ad.
Fix number 1: feed the chaining file with my bar. Both appeared, ad on top, my bar underneath. Victory! Well, no.
Why did fix 1 die?
I lost my status bar again, because kickbacks flaps between "inject" and "restore", and its auth was returning 401 errors, so it circled endlessly. Its restore deletes the chaining file every cycle, and it captured null as my "previous" bar. The result: a degenerate, empty state.
Fix number 2: stop fighting it, feed it. I fed kickbacks' own restore source, settings.json.vibe-ads-backup, with my bar, and re-fed the chain file. Now every inject means ad plus my bar, and every restore means my bar comes back. Self-healing across the whole flap cycle. Victory! No, not yet.
Why did fix 2 die too?
Two things killed it as a final solution: kickbacks auto-updates (0.3.174 to .176 to .177 while I watched), and the breakage is continuous, mid-session. It syncs roughly every 90 seconds and deletes the chain. My manual feeding survived neither.
I tried a SessionStart hook that re-feeds on every launch. Not enough: it runs once per session, and a fix that runs once per session does not beat an extension that deletes your files every few minutes. I needed something that recovers the moment kickbacks touches the config.
The fix that held: watch the file, not the session
Fix number 3: a macOS launchd LaunchAgent that monitors settings.json. A kernel-level file event triggers a re-feed within about 2 seconds, roughly 50ms per run, no polling, with a hard cap of once per 10 seconds. The bar can no longer stay dead.
Now kickbacks can flap as much as it wants. Worst case the ad flickers, and my status bar stays.
The takeaways for any config-touching, auto-updating tool
- Read its code. It may already support chaining your config.
- Feed its durable restore path, not just the live config.
- Recover reactively (file-watch), not once at startup.
Beyond the specific fight, this is the debugging posture that matters when tools share state they do not coordinate on: assume the other side will win any one-shot battle, and build the thing that recovers automatically. It is the same principle I apply to production agent systems: self-healing beats manual repair every time the failure repeats.
FAQ
How do I keep my settings when another tool overwrites them?
Three lessons from this fight. First, read the other tool's code; it may already support chaining your config. Second, feed its durable restore path, not just the live config file. Third, recover reactively with a file watcher, because a fix that runs once at session start loses to a tool that rewrites files every few minutes.
What finally survived the auto-updates?
A macOS launchd LaunchAgent watching settings.json. A kernel-level file event triggers a re-feed within about two seconds, roughly 50 milliseconds per run, no polling, hard-capped at once per ten seconds. The extension can flap as much as it wants; the status bar cannot stay dead.