Lets fish-config own the Kitty scrollback watcher the way it already owns the paru/yay wrappers — ship it, install/update it, and wire it into kitty.conf — instead of relying on a manually-placed watcher.py.
kitty/fish-config-watcher.py — canonical, version-marked watcher (capture + prune, sentinel-gated). The # fish-config-watcher-version: N marker lets install detect and refresh a stale copy.
functions/kitty-logging.fish — install / uninstall / status / dismiss. install resolves the Kitty config dir ($KITTY_CONFIG_DIRECTORY → $XDG_CONFIG_HOME/kitty → ~/.config/kitty), copies the watcher in, and adds a sentinel-marked managed block to the top-level kitty.conf, commenting out any conflicting watcher line to avoid double-capture. Idempotent; refreshes stale watchers; uninstall cleanly reverts.
conf.d/kitty-watcher-reminder.fish — non-blocking, per-session nudge shown inside Kitty until you run kitty-logging install or kitty-logging dismiss. Suppressed automatically if any watcher line already exists (so existing setups are never nagged).
Runtime enable/disable stays governed by the existing C5 .logging_disabled sentinel; install affects new Kitty windows only (a watcher binds at window creation and can't be retrofitted — acceptable, and you confirmed the sentinel covers mid-session disable).
Why not parse the resolved kitty config / per-toggle regeneration?
Kitty 0.47 has no stable resolved-config dump that includes watchers, and modular configs make scanning includes unreliable. Instead we own a marked block in the entry-point kitty.conf only. And because the sentinel already handles runtime disable, this is an install-once concern, not paru/yay-style per-toggle churn.
Hardening from review
install aborts if the watcher copy fails (was wiring a block pointing at a missing file and reporting success).
dismiss works even without kitty installed (handled before the kitty guard).
uninstall requires both block markers before its sed range-delete, so a malformed block can't delete to EOF.
Tests
TDD throughout — self-contained fish assert scripts cover: helper resolution/version/has-watcher (5), install/idempotency/legacy-migration/version-refresh/uninstall/fresh-create/bad-subcommand (10), and the reminder's four guard cases. Also validated end-to-end against a copy of the real kitty.conf (migrates watcher watcher.py → managed block correctly).
Open a fresh fish shell inside Kitty (with no watcher line in kitty.conf) → the per-session reminder appears
Run kitty-logging install → managed block added to kitty.conf, fish-config-watcher.py copied into the Kitty config dir, any prior watcher line commented out
set -U __fish_config_op_logging off → watcher goes inert (no new logs) without uninstalling; re-enable resumes
## Summary
Lets fish-config **own** the Kitty scrollback watcher the way it already owns the paru/yay wrappers — ship it, install/update it, and wire it into `kitty.conf` — instead of relying on a manually-placed `watcher.py`.
- **`kitty/fish-config-watcher.py`** — canonical, version-marked watcher (capture + prune, sentinel-gated). The `# fish-config-watcher-version: N` marker lets `install` detect and refresh a stale copy.
- **`functions/kitty-logging.fish`** — `install` / `uninstall` / `status` / `dismiss`. `install` resolves the Kitty config dir (`$KITTY_CONFIG_DIRECTORY` → `$XDG_CONFIG_HOME/kitty` → `~/.config/kitty`), copies the watcher in, and adds a sentinel-marked managed block to the top-level `kitty.conf`, commenting out any conflicting `watcher` line to avoid double-capture. Idempotent; refreshes stale watchers; `uninstall` cleanly reverts.
- **`conf.d/kitty-watcher-reminder.fish`** — non-blocking, per-session nudge shown inside Kitty until you run `kitty-logging install` or `kitty-logging dismiss`. Suppressed automatically if any `watcher` line already exists (so existing setups are never nagged).
- **Helpers** — `__kitty_logging_dir`, `__kitty_logging_version`, `__kitty_logging_has_watcher`.
Runtime enable/disable stays governed by the existing C5 `.logging_disabled` sentinel; install affects **new** Kitty windows only (a watcher binds at window creation and can't be retrofitted — acceptable, and you confirmed the sentinel covers mid-session disable).
## Why not parse the resolved kitty config / per-toggle regeneration?
Kitty 0.47 has no stable resolved-config dump that includes watchers, and modular configs make scanning includes unreliable. Instead we own a marked block in the entry-point `kitty.conf` only. And because the sentinel already handles runtime disable, this is an install-once concern, not paru/yay-style per-toggle churn.
## Hardening from review
- `install` aborts if the watcher copy fails (was wiring a block pointing at a missing file and reporting success).
- `dismiss` works even without kitty installed (handled before the kitty guard).
- `uninstall` requires **both** block markers before its `sed` range-delete, so a malformed block can't delete to EOF.
## Tests
TDD throughout — self-contained `fish` assert scripts cover: helper resolution/version/has-watcher (5), install/idempotency/legacy-migration/version-refresh/uninstall/fresh-create/bad-subcommand (10), and the reminder's four guard cases. Also validated end-to-end against a copy of the real `kitty.conf` (migrates `watcher watcher.py` → managed block correctly).
Spec & plan: `docs/superpowers/specs/2026-06-16-kitty-watcher-ownership-design.md`, `docs/superpowers/plans/2026-06-16-kitty-watcher-ownership.md`.
## Manual Verification
- [x] Open a fresh fish shell inside Kitty (with no `watcher` line in `kitty.conf`) → the per-session reminder appears
- [x] Run `kitty-logging install` → managed block added to `kitty.conf`, `fish-config-watcher.py` copied into the Kitty config dir, any prior `watcher` line commented out
- [x] `kitty-logging status` → reports managed block present, watcher version, C5 enabled
- [x] Open a **new** Kitty window, run commands, close it → a `scrollback_*.log` appears in `~/.terminal_history`
- [x] Start a new shell in Kitty after install → reminder no longer appears
- [x] `kitty-logging dismiss` (in a config without the watcher) → reminder silenced; works even on a machine without kitty
- [x] `kitty-logging uninstall` → managed block + watcher file removed, rest of `kitty.conf` intact
- [x] `set -U __fish_config_op_logging off` → watcher goes inert (no new logs) without uninstalling; re-enable resumes
- abort install if the watcher copy fails (was wiring a block pointing at
a missing file and reporting success)
- handle dismiss before the kitty guard so it works without kitty installed
- require both managed-block markers before the uninstall range-delete to
prevent deleting to EOF on a malformed block
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.
Summary
Lets fish-config own the Kitty scrollback watcher the way it already owns the paru/yay wrappers — ship it, install/update it, and wire it into
kitty.conf— instead of relying on a manually-placedwatcher.py.kitty/fish-config-watcher.py— canonical, version-marked watcher (capture + prune, sentinel-gated). The# fish-config-watcher-version: Nmarker letsinstalldetect and refresh a stale copy.functions/kitty-logging.fish—install/uninstall/status/dismiss.installresolves the Kitty config dir ($KITTY_CONFIG_DIRECTORY→$XDG_CONFIG_HOME/kitty→~/.config/kitty), copies the watcher in, and adds a sentinel-marked managed block to the top-levelkitty.conf, commenting out any conflictingwatcherline to avoid double-capture. Idempotent; refreshes stale watchers;uninstallcleanly reverts.conf.d/kitty-watcher-reminder.fish— non-blocking, per-session nudge shown inside Kitty until you runkitty-logging installorkitty-logging dismiss. Suppressed automatically if anywatcherline already exists (so existing setups are never nagged).__kitty_logging_dir,__kitty_logging_version,__kitty_logging_has_watcher.Runtime enable/disable stays governed by the existing C5
.logging_disabledsentinel; install affects new Kitty windows only (a watcher binds at window creation and can't be retrofitted — acceptable, and you confirmed the sentinel covers mid-session disable).Why not parse the resolved kitty config / per-toggle regeneration?
Kitty 0.47 has no stable resolved-config dump that includes watchers, and modular configs make scanning includes unreliable. Instead we own a marked block in the entry-point
kitty.confonly. And because the sentinel already handles runtime disable, this is an install-once concern, not paru/yay-style per-toggle churn.Hardening from review
installaborts if the watcher copy fails (was wiring a block pointing at a missing file and reporting success).dismissworks even without kitty installed (handled before the kitty guard).uninstallrequires both block markers before itssedrange-delete, so a malformed block can't delete to EOF.Tests
TDD throughout — self-contained
fishassert scripts cover: helper resolution/version/has-watcher (5), install/idempotency/legacy-migration/version-refresh/uninstall/fresh-create/bad-subcommand (10), and the reminder's four guard cases. Also validated end-to-end against a copy of the realkitty.conf(migrateswatcher watcher.py→ managed block correctly).Spec & plan:
docs/superpowers/specs/2026-06-16-kitty-watcher-ownership-design.md,docs/superpowers/plans/2026-06-16-kitty-watcher-ownership.md.Manual Verification
watcherline inkitty.conf) → the per-session reminder appearskitty-logging install→ managed block added tokitty.conf,fish-config-watcher.pycopied into the Kitty config dir, any priorwatcherline commented outkitty-logging status→ reports managed block present, watcher version, C5 enabledscrollback_*.logappears in~/.terminal_historykitty-logging dismiss(in a config without the watcher) → reminder silenced; works even on a machine without kittykitty-logging uninstall→ managed block + watcher file removed, rest ofkitty.confintactset -U __fish_config_op_logging off→ watcher goes inert (no new logs) without uninstalling; re-enable resumes