Live hot-reload so external changes to a server's sidecar (ssh-mcp's config.toml) or to BCC's own loaded config surface without a restart. Detection (#91/#93) previously ran only at profile load / server selection.
Core (pure, unit-tested — CI has no PySide6)
sidecar_watch_paths() — the external paths worth watching for a server: the resolved sidecar file, its directory (so create/delete and atomic-rename replaces register), and the wrong-path/doc file. Order-stable, de-duplicated.
sidecar_state_fingerprint() — a hashable snapshot folding the #91 sidecar status + #93 permission status, so the GUI can tell whether the observable state actually changed and skip a redundant refresh.
sidecar_state_changed() — explicit named equality for that decision.
GUI (thin wiring, smoke-tested headlessly with QT_QPA_PLATFORM=offscreen)
QFileSystemWatcher over the selection's sidecar path(s) + BCC's own config; debounced 300 ms.
Re-arm on every event — an atomic-rename replace drops the inode from the watcher, so wanted paths are re-added before the next check.
Focus-in fallback via changeEvent(ActivationChange) — covers what watchers miss (atomic replaces, not-yet-created files).
recheck_advisories() only recomputes warning labels; it never touches field values, so a live reload cannot clobber unsaved edits.
An external edit to BCC's own config shows a non-destructive Reload banner (never a silent overwrite); reload confirms-on-dirty via the existing path.
GUI click-through (needs a human)
Add an ssh-mcp server (npx -y ssh-mcp --host=h --user=u), select it.
In a terminal, mkdir -p ~/Library/Application\ Support/ssh-mcp && printf '[server]\nhost="h"\n' > ~/Library/Application\ Support/ssh-mcp/config.toml (macOS path). The "arguments are inert" advisory should appear within ~1s, no restart.
chmod 644 that file → the permission advisory appears; chmod 600 → it clears.
Edit BCC's config JSON in another editor and save → the Reload banner appears; click Reload (prompts if you have unsaved edits).
Delete the config.toml → advisory clears. Switch focus away and back to confirm the focus-in fallback also refreshes.
Base: main. First of a stack — #102 (sidecar editor) is branched off this one.
Closes #101.
Live hot-reload so external changes to a server's sidecar (ssh-mcp's `config.toml`) or to BCC's own loaded config surface **without a restart**. Detection (#91/#93) previously ran only at profile load / server selection.
### Core (pure, unit-tested — CI has no PySide6)
- `sidecar_watch_paths()` — the external paths worth watching for a server: the resolved sidecar file, its **directory** (so create/delete and atomic-rename replaces register), and the wrong-path/doc file. Order-stable, de-duplicated.
- `sidecar_state_fingerprint()` — a hashable snapshot folding the #91 sidecar status + #93 permission status, so the GUI can tell whether the *observable* state actually changed and skip a redundant refresh.
- `sidecar_state_changed()` — explicit named equality for that decision.
### GUI (thin wiring, smoke-tested headlessly with `QT_QPA_PLATFORM=offscreen`)
- `QFileSystemWatcher` over the selection's sidecar path(s) + BCC's own config; **debounced 300 ms**.
- **Re-arm on every event** — an atomic-rename replace drops the inode from the watcher, so wanted paths are re-added before the next check.
- **Focus-in fallback** via `changeEvent(ActivationChange)` — covers what watchers miss (atomic replaces, not-yet-created files).
- `recheck_advisories()` only recomputes warning labels; it never touches field values, so a live reload **cannot clobber unsaved edits**.
- An external edit to BCC's own config shows a **non-destructive Reload banner** (never a silent overwrite); reload confirms-on-dirty via the existing path.
### GUI click-through (needs a human)
1. Add an ssh-mcp server (`npx -y ssh-mcp --host=h --user=u`), select it.
2. In a terminal, `mkdir -p ~/Library/Application\ Support/ssh-mcp && printf '[server]\nhost="h"\n' > ~/Library/Application\ Support/ssh-mcp/config.toml` (macOS path). The **"arguments are inert"** advisory should appear within ~1s, no restart.
3. `chmod 644` that file → the **permission** advisory appears; `chmod 600` → it clears.
4. Edit BCC's config JSON in another editor and save → the **Reload banner** appears; click Reload (prompts if you have unsaved edits).
5. Delete the `config.toml` → advisory clears. Switch focus away and back to confirm the focus-in fallback also refreshes.
Base: `main`. First of a stack — #102 (sidecar editor) is branched off this one.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Detection (#91/#93) previously ran only at profile load / server
selection, so a config.toml created or chmod-ed while BCC was running
stayed invisible until a restart. Make the view react on its own.
Core (pure, unit-tested — CI has no PySide6):
- sidecar_watch_paths(): the external paths worth watching for a server
— the resolved sidecar file, its directory (so create/delete and
atomic-rename replaces register), and the wrong-path/doc file — order-
stable and de-duplicated.
- sidecar_state_fingerprint(): a hashable snapshot folding the #91
sidecar status and #93 permission status, so the GUI can tell whether
the *observable* state actually changed and skip a redundant refresh.
- sidecar_state_changed(): explicit, named equality for that decision.
GUI (thin wiring, smoke-tested headlessly):
- QFileSystemWatcher over the selection's sidecar path(s) + BCC's own
loaded config; debounced (300 ms) so a burst of writes doesn't thrash.
- Re-arm on every event: an atomic-rename replace drops the inode from
the watcher, so wanted paths are re-added before the next check.
- Focus-in fallback via changeEvent(ActivationChange) — always works
where watchers miss (atomic replaces, not-yet-created files).
- recheck_advisories() only recomputes warning labels from the form +
filesystem; it never touches field values, so a live reload cannot
clobber unsaved edits.
- An external edit to BCC's own config surfaces a non-destructive
Reload banner (never a silent overwrite); confirm-on-dirty reuses the
existing load path.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Closes #101.
Live hot-reload so external changes to a server's sidecar (ssh-mcp's
config.toml) or to BCC's own loaded config surface without a restart. Detection (#91/#93) previously ran only at profile load / server selection.Core (pure, unit-tested — CI has no PySide6)
sidecar_watch_paths()— the external paths worth watching for a server: the resolved sidecar file, its directory (so create/delete and atomic-rename replaces register), and the wrong-path/doc file. Order-stable, de-duplicated.sidecar_state_fingerprint()— a hashable snapshot folding the #91 sidecar status + #93 permission status, so the GUI can tell whether the observable state actually changed and skip a redundant refresh.sidecar_state_changed()— explicit named equality for that decision.GUI (thin wiring, smoke-tested headlessly with
QT_QPA_PLATFORM=offscreen)QFileSystemWatcherover the selection's sidecar path(s) + BCC's own config; debounced 300 ms.changeEvent(ActivationChange)— covers what watchers miss (atomic replaces, not-yet-created files).recheck_advisories()only recomputes warning labels; it never touches field values, so a live reload cannot clobber unsaved edits.GUI click-through (needs a human)
npx -y ssh-mcp --host=h --user=u), select it.mkdir -p ~/Library/Application\ Support/ssh-mcp && printf '[server]\nhost="h"\n' > ~/Library/Application\ Support/ssh-mcp/config.toml(macOS path). The "arguments are inert" advisory should appear within ~1s, no restart.chmod 644that file → the permission advisory appears;chmod 600→ it clears.config.toml→ advisory clears. Switch focus away and back to confirm the focus-in fallback also refreshes.Base:
main. First of a stack — #102 (sidecar editor) is branched off this one.🤖 Generated with Claude Code