Compare commits

...

11 Commits

Author SHA1 Message Date
rootiest 0cced863f8 Merge pull request 'feat(logging): add C5 — Logging & Capture opinionated guard' (#39) from feat/logging-toggle-c5 into main
Generate documentation / build-docs (push) Successful in 32s
Offline docs drift reminder / remind (push) Successful in 10s
Reviewed-on: #39
2026-06-11 02:05:06 +00:00
rootiest 7fcf268fc7 fix(logging): suppress Kitty watcher capture when C5 logging is disabled
When smart_exit skips fish-side capture due to the C5 guard, it now sets
logged_by_shell=true on the Kitty window before calling builtin exit. This
prevents watcher.py's on_close handler from capturing the scrollback even
if the sentinel file is absent, providing a second layer of protection.

Also restructures the capture block to be flat (no wrapper if-true) after
the early-exit guard.
2026-06-10 21:59:52 -04:00
rootiest 76349ad94b fix(logging): register C5 event handlers in conf.d for reliable startup
--on-variable handlers in functions/ are only autoloaded on explicit call,
so they never fire when a universal variable changes. Moving the definitions
to conf.d/logging-events.fish ensures they are registered at shell init.

Also adds a startup __fish_config_sync_logging call so pre-set variable
values (e.g. set before this shell was opened) take effect immediately
without requiring a re-set.
2026-06-10 21:54:56 -04:00
rootiest eb1b780a80 docs(logging): add C5 logging toggle to Minimal Mode in README 2026-06-10 21:49:47 -04:00
rootiest 2ce41d0c55 docs(logging): fix 'four' → 'five' category count in fish-config.md prose 2026-06-10 21:46:14 -04:00
rootiest e30ccbc633 docs(logging): document C5 logging guard in fish-config.md
Add __fish_config_op_logging (C5 — Logging & Capture) to the opinionated
components variable table and update the master-disable example comment
from "four categories" to "five categories".

AGENTS.md and opinionated_catalog.md are git-ignored per project policy;
those files were updated on disk but cannot be tracked in this repo.
2026-06-10 21:43:46 -04:00
rootiest 7e266cb61a feat(logging): gate paru/yay wrapper generation under C5 guard (Tasks 5-6)
Add C5 (Logging & Capture) guard to wrapper generation in both
conf.d/paru-wrapper.fish and conf.d/yay-wrapper.fish. When C5 logging
is disabled, the guard removes any generated wrapper and returns early,
allowing the system to fall back to the bare binary.

Also replaces stale Task #4 comment references with C5 classification.
2026-06-10 21:33:54 -04:00
rootiest be3dd7494e feat(logging): gate scrollback capture in smart_exit under C5 guard 2026-06-10 21:29:52 -04:00
rootiest 0382d6ab9c feat(logging): add C5 --on-variable event handlers for real-time sync 2026-06-10 21:28:13 -04:00
rootiest f17229d0b8 feat(logging): add __fish_config_sync_logging shared C5 state sync 2026-06-10 21:26:40 -04:00
rootiest 621d67e89e chore(logging): add .logging_disabled sentinel to .gitignore 2026-06-10 21:20:54 -04:00
8 changed files with 173 additions and 8 deletions
+5
View File
@@ -62,6 +62,11 @@
opinionated_catalog.md opinionated_catalog.md
docs/superpowers docs/superpowers
# ──────────────────── Runtime State Files ───────────────────
# Sentinel file written/removed at runtime to coordinate logging state
# across the fish config and the Kitty Python watcher. Never committed.
.logging_disabled
# ──────────────── Fisher-Managed Plugin Files ─────────────── # ──────────────── Fisher-Managed Plugin Files ───────────────
# Fisher writes these into the repo directory on install/update. # Fisher writes these into the repo directory on install/update.
# They are owned by Fisher — do not commit them. # They are owned by Fisher — do not commit them.
+3 -2
View File
@@ -166,7 +166,7 @@ end
## Minimal Mode ## Minimal Mode
Everything opinionated in this config — command shadows, startup side-effects, key and environment overrides, and terminal integrations — is active by default but can be switched off with universal variables. Four category toggles and one master switch are available: Everything opinionated in this config — command shadows, startup side-effects, key and environment overrides, terminal integrations, and logging — is active by default but can be switched off with universal variables. Five category toggles and one master switch are available:
| Variable | Disables | | Variable | Disables |
|---|---| |---|---|
@@ -174,7 +174,8 @@ Everything opinionated in this config — command shadows, startup side-effects,
| `__fish_config_op_autoexec` | Startup side-effects: Fisher bootstrap, theme apply, `paru`/`yay` wrapper generation, auto venv activation, WakaTime hook | | `__fish_config_op_autoexec` | Startup side-effects: Fisher bootstrap, theme apply, `paru`/`yay` wrapper generation, auto venv activation, WakaTime hook |
| `__fish_config_op_overrides` | Vi mode, `exit``smart_exit`, `$PAGER`/`$MANPAGER`/`$CDPATH`, bang-bang history expansion, autopair, puffer, Starship prompt, theme colors | | `__fish_config_op_overrides` | Vi mode, `exit``smart_exit`, `$PAGER`/`$MANPAGER`/`$CDPATH`, bang-bang history expansion, autopair, puffer, Starship prompt, theme colors |
| `__fish_config_op_integrations` | Kitty/WezTerm window abbreviations, `done` notifications, `spwin`/`tab`/`split`, `hist`, `logs`, `upgrade`, WakaTime | | `__fish_config_op_integrations` | Kitty/WezTerm window abbreviations, `done` notifications, `spwin`/`tab`/`split`, `hist`, `logs`, `upgrade`, WakaTime |
| `__fish_config_opinionated` | Master switch — all four categories at once | | `__fish_config_op_logging` | Scrollback capture on exit, `paru`/`yay` AUR log wrappers, Kitty watcher capture (sentinel-file coordinated) |
| `__fish_config_opinionated` | Master switch — all five categories at once |
Set any of them to a falsy value (`0`, `false`, `no`, `off`, `n`) to disable; erase the variable to re-enable: Set any of them to a falsy value (`0`, `false`, `no`, `off`, `n`) to disable; erase the variable to re-enable:
+27
View File
@@ -0,0 +1,27 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
#
# C5 — Logging & Capture: registers --on-variable event handlers at shell
# startup so that changes to __fish_config_op_logging or the master
# __fish_config_opinionated take effect immediately in every running shell.
# Also calls __fish_config_sync_logging once to reconcile sentinel-file and
# wrapper state with any variable values that were pre-set before this shell
# started.
#
# These functions must be defined in conf.d (not functions/) because fish
# only autoloads from functions/ on explicit call — event handlers that live
# solely in functions/ are never registered and their --on-variable triggers
# never fire.
function __fish_config_logging_changed --on-variable __fish_config_op_logging \
--description 'C5 event handler: sync logging state when __fish_config_op_logging changes'
__fish_config_sync_logging
end
function __fish_config_opinionated_changed --on-variable __fish_config_opinionated \
--description 'C5 event handler: sync logging state when master opinionated switch changes'
__fish_config_sync_logging
end
# Sync once at startup so pre-set variable values take effect without a re-set
__fish_config_sync_logging
+10 -1
View File
@@ -6,9 +6,18 @@
# timestamped log file and prunes old logs, mirroring smart_exit behavior. # timestamped log file and prunes old logs, mirroring smart_exit behavior.
# Auto-generating a wrapper in ~/.local/bin is opinionated (C2 auto-exec). # Auto-generating a wrapper in ~/.local/bin is opinionated (C2 auto-exec).
# Task #4's __fish_config_enable_logging will additionally gate this wrapper. # Wrapper generation is also gated by C5 (Logging & Capture).
__fish_config_op_enabled __fish_config_op_autoexec; or return __fish_config_op_enabled __fish_config_op_autoexec; or return
# C5 — Logging & Capture: remove generated wrapper and skip when logging is off
if not __fish_config_op_enabled __fish_config_op_logging
if test -f "$HOME/.local/bin/paru"
and grep -q "# paru-wrapper-version:" "$HOME/.local/bin/paru" 2>/dev/null
rm -f "$HOME/.local/bin/paru"
end
return
end
set -l _paru_real /usr/bin/paru set -l _paru_real /usr/bin/paru
set -l _paru_wrapper "$HOME/.local/bin/paru" set -l _paru_wrapper "$HOME/.local/bin/paru"
set -l _paru_wrapper_version 1 set -l _paru_wrapper_version 1
+10 -1
View File
@@ -6,9 +6,18 @@
# timestamped log file and prunes old logs, mirroring smart_exit behavior. # timestamped log file and prunes old logs, mirroring smart_exit behavior.
# Auto-generating a wrapper in ~/.local/bin is opinionated (C2 auto-exec). # Auto-generating a wrapper in ~/.local/bin is opinionated (C2 auto-exec).
# Task #4's __fish_config_enable_logging will additionally gate this wrapper. # Wrapper generation is also gated by C5 (Logging & Capture).
__fish_config_op_enabled __fish_config_op_autoexec; or return __fish_config_op_enabled __fish_config_op_autoexec; or return
# C5 — Logging & Capture: remove generated wrapper and skip when logging is off
if not __fish_config_op_enabled __fish_config_op_logging
if test -f "$HOME/.local/bin/yay"
and grep -q "# yay-wrapper-version:" "$HOME/.local/bin/yay" 2>/dev/null
rm -f "$HOME/.local/bin/yay"
end
return
end
set -l _yay_real /usr/bin/yay set -l _yay_real /usr/bin/yay
set -l _yay_wrapper "$HOME/.local/bin/yay" set -l _yay_wrapper "$HOME/.local/bin/yay"
set -l _yay_wrapper_version 1 set -l _yay_wrapper_version 1
+7 -2
View File
@@ -1382,7 +1382,7 @@ fish_variables.
## Opinionated Components (Minimal Mode) ## Opinionated Components (Minimal Mode)
Every opinionated piece of this config is active by default but can be Every opinionated piece of this config is active by default but can be
switched off through four category opt-out variables, each evaluated via switched off through five category opt-out variables, each evaluated via
__fish_variable_check. Set a variable to any falsy value (0, false, no, __fish_variable_check. Set a variable to any falsy value (0, false, no,
off, n) to disable its category; erase it or set a truthy value (1, true, off, n) to disable its category; erase it or set a truthy value (1, true,
yes, on, y) to re-enable. Unset means enabled. yes, on, y) to re-enable. Unset means enabled.
@@ -1410,13 +1410,18 @@ yes, on, y) to re-enable. Unset means enabled.
WezTerm window abbreviations, done WezTerm window abbreviations, done
notifications, spwin/tab/split, notifications, spwin/tab/split,
hist, logs, upgrade, WakaTime hist, logs, upgrade, WakaTime
__fish_config_op_logging Logging & capture: scrollback
capture on exit, paru/yay AUR log
wrappers, Kitty watcher capture;
sentinel file coordinates
cross-process state
Examples: Examples:
# Disable command shadows only (rm becomes plain rm again): # Disable command shadows only (rm becomes plain rm again):
set -U __fish_config_op_aliases off set -U __fish_config_op_aliases off
# Full minimal mode — disable all four categories at once: # Full minimal mode — disable all five categories at once:
set -U __fish_config_opinionated 0 set -U __fish_config_opinionated 0
# Re-enable everything: # Re-enable everything:
+99
View File
@@ -0,0 +1,99 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
# SYNOPSIS
# __fish_config_sync_logging
#
# DESCRIPTION
# Synchronises C5 logging state: creates or removes the Kitty sentinel
# file ($XDG_CONFIG_HOME/fish/.logging_disabled) and generates or removes
# the paru/yay AUR-helper log wrappers based on the combined value of
# __fish_config_opinionated (master) and __fish_config_op_logging (C5).
# Called by --on-variable event handlers whenever either variable changes.
# Safe to call at any time; wrapper removal only affects files bearing
# the generated version-marker comment.
#
# RETURNS
# 0 Always
#
# EXAMPLE
# __fish_config_sync_logging
function __fish_config_sync_logging --description 'Sync C5 logging state: sentinel file and paru/yay wrappers'
set -l config_home $XDG_CONFIG_HOME
if test -z "$config_home"
set config_home "$HOME/.config"
end
set -l sentinel "$config_home/fish/.logging_disabled"
set -l paru_wrapper "$HOME/.local/bin/paru"
set -l yay_wrapper "$HOME/.local/bin/yay"
set -l wrapper_version 1
if __fish_config_op_enabled __fish_config_op_logging
# Logging enabled: remove sentinel and regenerate wrappers if binaries exist
rm -f $sentinel
if test -x /usr/bin/paru
mkdir -p (dirname $paru_wrapper)
printf '%s\n' \
'#!/usr/bin/env bash' \
"# paru-wrapper-version: $wrapper_version" \
'# Auto-generated by conf.d/paru-wrapper.fish — do not edit by hand.' \
'# Tees paru output to a timestamped log file and prunes old ones.' \
'set -o pipefail' \
'' \
'log_dir="${SCROLLBACK_HISTORY_DIR:-$HOME/.terminal_history}"' \
'mkdir -p "$log_dir"' \
'log_file="$log_dir/paru_$(date +%Y-%m-%d_%H-%M-%S).log"' \
'' \
'/usr/bin/paru "$@" 2>&1 | tee "$log_file"' \
'' \
'max_files="${SCROLLBACK_HISTORY_MAX_FILES:-100}"' \
'mapfile -t logs < <(ls -1t "$log_dir"/paru_*.log 2>/dev/null)' \
'excess=$(( ${#logs[@]} - max_files ))' \
'for (( i = ${#logs[@]} - 1; i >= ${#logs[@]} - excess && i >= 0; i-- )); do' \
' rm -f "${logs[$i]}"' \
'done' \
>$paru_wrapper
chmod +x $paru_wrapper
end
if test -x /usr/bin/yay
mkdir -p (dirname $yay_wrapper)
printf '%s\n' \
'#!/usr/bin/env bash' \
"# yay-wrapper-version: $wrapper_version" \
'# Auto-generated by conf.d/yay-wrapper.fish — do not edit by hand.' \
'# Tees yay output to a timestamped log file and prunes old ones.' \
'set -o pipefail' \
'' \
'log_dir="${SCROLLBACK_HISTORY_DIR:-$HOME/.terminal_history}"' \
'mkdir -p "$log_dir"' \
'log_file="$log_dir/yay_$(date +%Y-%m-%d_%H-%M-%S).log"' \
'' \
'/usr/bin/yay "$@" 2>&1 | tee "$log_file"' \
'' \
'max_files="${SCROLLBACK_HISTORY_MAX_FILES:-100}"' \
'mapfile -t logs < <(ls -1t "$log_dir"/yay_*.log 2>/dev/null)' \
'excess=$(( ${#logs[@]} - max_files ))' \
'for (( i = ${#logs[@]} - 1; i >= ${#logs[@]} - excess && i >= 0; i-- )); do' \
' rm -f "${logs[$i]}"' \
'done' \
>$yay_wrapper
chmod +x $yay_wrapper
end
else
# Logging disabled: create sentinel and remove any generated wrappers
mkdir -p (dirname $sentinel)
touch $sentinel
if test -f $paru_wrapper
and grep -q "# paru-wrapper-version:" $paru_wrapper 2>/dev/null
rm -f $paru_wrapper
end
if test -f $yay_wrapper
and grep -q "# yay-wrapper-version:" $yay_wrapper 2>/dev/null
rm -f $yay_wrapper
end
end
end
+10
View File
@@ -48,6 +48,16 @@ function smart_exit --description 'Capture colorized scrollback before exiting,
return 0 return 0
end end
# C5 — Logging & Capture: skip all capture when logging is disabled.
# When disabled, tell Kitty the window is handled so its watcher doesn't
# capture either — belt-and-suspenders alongside the sentinel file.
if not __fish_config_op_enabled __fish_config_op_logging
if test -n "$KITTY_WINDOW_ID"
kitty @ set-user-vars "logged_by_shell=true" 2>/dev/null
end
builtin exit
end
set -l snapshot_dir (set -q SCROLLBACK_HISTORY_DIR; and echo $SCROLLBACK_HISTORY_DIR; or echo "$HOME/.terminal_history") set -l snapshot_dir (set -q SCROLLBACK_HISTORY_DIR; and echo $SCROLLBACK_HISTORY_DIR; or echo "$HOME/.terminal_history")
set -l max_files (set -q SCROLLBACK_HISTORY_MAX_FILES; and echo $SCROLLBACK_HISTORY_MAX_FILES; or echo 100) set -l max_files (set -q SCROLLBACK_HISTORY_MAX_FILES; and echo $SCROLLBACK_HISTORY_MAX_FILES; or echo 100)