python3 is used unguarded by the AI session helpers and (guarded) by the
paru/yay log cleaner, but was absent from the dependency catalog and docs.
uv does not provide python3 on PATH, and Arch's base omits it, so it is
tracked separately rather than assumed via uv.
- Add python3 (recommended tier, pm: python) to _fish_deps_catalog.fish
- Guard python3 calls in save_claude_session/save_antigravity_session with
`type -q python3`, emitting valid empty JSON when absent (Convention §6)
- Document python3 in docs/fish-config.md (§5.6 tiers + catalog entry)
The badge now positions each state by where it sits on the scale: OFF
left-aligned, DEFAULT centered, ON right-aligned. This makes the
OFF ← DEFAULT → ON ordering visible at a glance and reinforces the
direction the ←→/h l keys move.
Directional arrows fully cover value changes, so the Space cycle is
removed. Add h/l as vim-style aliases for ←/→ (matching the existing
j/k for up/down), keeping the whole keymap hjkl-consistent. Update the
in-panel hint, help text, docstrings, and offline docs accordingly.
Left/Right now adjust the highlighted value one step along the
OFF ← DEFAULT → ON scale, clamped at the ends (no wrap), complementing
Space which cycles through all states and wraps. Right steps toward ON,
Left toward OFF.
Extract the set/erase side-effect into __config_toggle_apply so Space,
Left, and Right share one implementation of the scope-aware
set -U/-g/-Ue/-eg logic. Update the in-panel keybind hint (now
width-padded via string pad so the border stays aligned) and the help
text and offline docs to cover the new keys.
fish's `read` invokes its interactive line editor on a TTY, which (1)
prints a `read> ` prompt below the panel, (2) intercepts Tab and arrow
keys for its own line editing so they never reach the switch, and (3)
shifts the cursor down a line, throwing off the `\e[14A` redraw so top
borders stacked on every keypress. Plain keys (j/k/q/space) passed
through, masking the problem.
Add __config_toggle_read_key: puts the terminal in raw, no-echo mode
(`stty raw -echo min 1 time 1`), reads one keypress from /dev/tty, and
returns a normalized token (up/down/left/right/tab/space/escape/quit or
the literal char) by decoding the bytes via od. Arrow keys and Tab now
work, there is no stray prompt, and the redraw stays aligned. Ctrl-C in
raw mode arrives as byte 3 and maps to quit; bare Esc exits after the
0.1s inter-byte timer.
Rewrite the event loop to consume these tokens and restore Esc to the
help text.
The event loop used `read -k 1`, but `-k` is not a valid fish read option
(it errors with "unknown option", status 2). read therefore returned
instantly every iteration without consuming a keypress, so the loop
redrew the panel as fast as the terminal could render and ignored all
input. The nchars flag is `-n`, not `-k`.
Switch to `read -s -n 1` (one char, silent so keystrokes don't garble the
panel) and add `or break` so a read failure (EOF / non-tty stdin) exits
cleanly instead of spinning. Applies to the primary read and both escape
sequence continuation reads.
fish's read -k N waits for exactly N bytes; single-char keys ('q', 'j',
Space, Tab) were blocking indefinitely waiting for 2 more bytes, causing
the input loop to appear unresponsive. Random 3-key bundles were then
processed as unrecognised input, triggering infinite redraws.
Switch to read -k 1 (one raw byte per call). Arrow keys still work: the
terminal sends ESC+[+A/B as a burst, so after reading ESC the two
continuation bytes are already in the TTY buffer and the follow-up reads
return immediately. Bare ESC now passes the next keypress through as the
effective key rather than exiting (q/Q remain the exit keys).
Replace two-read-k-1 ESC handling with a single read -k 3 so that a bare
ESC returns immediately instead of blocking the shell indefinitely waiting
for a second byte. Add trap - INT in the cleanup block so the signal
handler does not leak into the global session after config-toggle exits.
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.
--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.
C1 shadows (rm, cat, ls, less, du, bash, top, ping, ssh, rg, mkdir,
help) fall back to the bare command when __fish_config_op_aliases is
falsy; rm falls back to exact 'command rm' with no wrapper. C2 gates
the auto-venv PWD hook. C3 gates smart_exit (composing with Task #4
logging), fish_right_prompt, and all six expand_bang_*/expand_typo_sub
functions atomically with the bang-bang system. C4 integration commands
(spwin, tab, split, hist, logs, upgrade) refuse with a colored stderr
error when disabled. config.fish now also strips the CachyOS distro
config's own bang-bang bindings, history override, and alias opinions
per category, restoring fish stock functions where they exist.
- Section keyword is now extracted early and shared across all three
output modes (pager, HTML, man) rather than duplicated per branch
- --html with a section keyword resolves the heading to a pandoc anchor
ID and looks it up in docs/html/sitemap.json; handles both sub-section
fragment paths and top-level sections that are their own page
- --man with a section keyword overrides MANPAGER to `less +/pattern`
so the page opens at the nearest heading match
- --help output updated to show [section] in USAGE and section+flag
examples (help config keybindings --html, help config pkg --man)
- docs/fish-config.md §5.14 synopsis, flags, and examples updated
- docs/fish-config.md §11 "Viewing" sections updated for both HTML and
man page to document the section+flag invocation
- README table updated with section+html and section+man rows
- help.fish: expand SYNOPSIS/DESCRIPTION to document -w/--html, -m/--man,
-h/--help flags; note flags are only intercepted when 'config' is argv[1]
- config-help.fish: add # NOTES section explaining help config as the
preferred invocation; update --help banner to show both names; update
--help USAGE/EXAMPLES output to use `help config` syntax throughout
- docs/fish-config.md: update §5.14 synopsis/examples and "Viewing" sections
to use `help config` as primary form; inline note for direct config-help use
- README.md: update docs table to show `help config --html` / `--man`
conf.d/sponge_privacy.fish registers patterns and filters that prevent
credentials from reaching fish history:
Layer 1 (static regex, universal): auth flags, env assignments,
credential-bearing URLs, Authorization headers, sshpass, docker
login, openssl -passin/-passout
Layer 2 (dynamic values, session globals): on the first prompt, after
secrets.fish has loaded, reads the literal values of all exported
credential-named vars (TOKEN, PASSWORD, SECRET, etc.), escapes them
for regex, and merges them with the static patterns as a session
global — auto-refreshes on login so rotated tokens are never stale
Layer 3 (per-command filter, sponge_filter_secrets): catches
credentials in variables exported mid-session (e.g. project .env)
Also exempts functions/sponge_filter_secrets.fish from the sponge_*
gitignore glob so our custom filter is committed alongside the config.
config-help gains two new flags:
- --html / -w: opens docs/html/index.html in the default browser using
smart browser detection (xdg-mime https scheme handler → known binaries
→ xdg-open fallback) to avoid MIME-type mismatches with non-browser apps
- --man / -m: opens the compiled docs/fish-config.1 man page via man -l
config-update is a new function that pulls the latest fish config from the
hard-coded upstream URL without requiring a configured git remote. Suppresses
git output and reports status with colored messages. Supports --dry-run and
--force flags.
README updated to document all new commands.
Rename config_help → config-help and add a help wrapper that
intercepts 'help config [section]', forwarding sub-topics to
config-help. Update README and docs to use 'help config' as the
preferred interface so offline docs feel like a natural extension
of fish's built-in help system.
Section headers in bold blue, argument/flag names in yellow, command
examples in green, navigation keys in cyan, fallback chain numbers
dimmed. All reset to normal after each colored span.
- config_help --help / -h prints full usage, section keyword examples,
ov navigation key reference, and the pager fallback chain.
- Prepend a dim nav hint line to the ov input stream and pin it with
--header 1 so "Space=next section ^=prev Alt+u=sections /=search
q=quit" is always visible at the top of the screen.
- Add docs/fish-config.index mapping 100+ keyword aliases to exact heading
text; config_help looks up here first, falls back to normalized heading
scan (strips non-alphanumeric, lowercases both sides) for unknown terms.
- Resolve line numbers at runtime with grep -F so the index never goes
stale from doc edits — only heading renames require an update.
- Fix section jump: --section-header pins delimiter lines as sticky headers
removing them from ov pattern-search scope. Replace --pattern with
tail -n +$start_line piped before ov; the target section is the first
line so no search is needed and forward section nav still works.
- Fix empty sections sidebar: ov matches --section-delimiter against
logical (ANSI-stripped) text, so "^#" is correct for bat-colored output;
the previous ANSI escape-sequence regex never matched anything.
- docs/fish-config.md: curated terminal-optimized manual covering all
public functions, keybindings, abbreviations, configuration variables,
dependency catalog, and customization guide. Written for ov/bat/less
readability rather than browser rendering — no callouts, no hyperlinks.
Pandoc-compatible YAML front matter for man page compilation.
- functions/config_help.fish: viewer function with fallback chain
ov -> bat -> man -l -> less -> cat. Accepts an optional section
keyword to jump directly to the first matching heading.
- .gitea/workflows/man-page.yml: compiles docs/fish-config.md to
docs/fish-config.1 via pandoc on every push to main that touches the
source doc, then commits the result automatically.
- .gitea/workflows/docs-drift.yml: opens a reminder issue whenever
README.md changes without a corresponding docs/fish-config.md update
in the same push.
- README.md: documents config_help and the offline manual.
- AGENTS.md: adds Convention 10 requiring offline doc to be updated
alongside any function, keybinding, or config change.
Refactor pkg.fish to auto-detect the system package manager via
_fish_deps_detect_pm instead of hard-requiring paru/yay. Supports
install, uninstall, and auto (toggle) modes across paru, yay, pacman,
apt, dnf, zypper, yum, brew, and pkg. Package installed-checks now use
the correct query tool per PM (pacman -Qi, dpkg -s, rpm -q, etc.).
Also adds zypper to the _fish_deps_detect_pm detection priority list.
Replace all ad-hoc inline comments between license headers and function
declarations with consistent SYNOPSIS / DESCRIPTION / ARGUMENTS / RETURNS /
EXAMPLE blocks across all 99 project-owned functions/ files. No executable
logic, variable names, or exit codes were modified.
Completes Task #6 from AGENTS.md (Retroactive Function Documentation
Standardization).
Adds __fzf_inline_picker function and @@ keybinding (Emacs + all Vi
modes). Opens an fzf session and injects the selected item at the
cursor position in the current command line. Includes SYNOPSIS/
DESCRIPTION doc block per project conventions. Updates README with
new binding in the User Bindings table.
- mkdir: loop over path args calling _fish_mkdir_p --path; falls back
to command mkdir -p when flag args (e.g. -m 755) are present
- mkcd: default to _fish_mkdir_p --tree for new dirs; add -s/--silent
flag to suppress tree output (mkcd's own status message still prints)
- Add _fish_mkdir_p: reusable mkdir -p with three output modes:
--path (default): "Created: ~/full/path/" on one line
--tree: dimmed existing anchor + cyan tree of newly-created dirs
--silent: no output
HOME is substituted with ~ in all output paths
- Refactor poke to delegate to _fish_mkdir_p --tree; removes inline
mkdir/echo logic and gains ~ substitution and per-dir tree output
- Add poke: touch with automatic parent directory creation; prints
colored notice when new dirs are created; handles multiple file args
- Refactor config.fish CachyOS override block: consolidate copy into
the erase+source loop alongside ls/lt/cleanup
- fish-deps: replace most with ov (cargo crate + AUR pkg); add yay as
rec dep with yay-build special (paru -S yay or AUR makepkg); add
update handling for yay-build in _fish_deps_update
- README: document poke in Directory & File Listing table
Use a per-invocation temp ov config to set SectionLine Background/Foreground
to empty strings, preventing ov from overriding the ANSI colors embedded in
the starship prompt when it is pinned as a sticky section header.
Also adds a second return sentinel inside the interactive block of config.fish
to guard against tool-injected init lines that target the inner scope, and
updates README accordingly.
- logs.fish: add yay category, ov-powered viewing for paru/yay (section
headers, color highlights, ==> AUR build markers) and scrollback logs
(OSC 133;A sticky prompt headers); add fzf Ctrl-D delete with Y/n
confirm and list refresh, ? toggleable help overlay; run
_scrollback_prune_junk before building file list
- _scrollback_prune_junk: new utility to remove empty, single-line, and
Kitty tab-rename noise logs before display and before max-file pruning;
called from both logs and smart_exit
- smart_exit: call _scrollback_prune_junk before counting toward max files
- conf.d/yay-wrapper.fish: auto-generate ~/.local/bin/yay logging wrapper
mirroring paru-wrapper; tees output to timestamped logs, prunes old ones
- conf.d/starship.fish: move fish_prompt from config.fish; emit OSC 133;A
after the prompt's leading newline so the marker lands on the info-bar
line rather than the blank line above it; guard with type -q starship so
clean fish sessions use built-in markers unchanged
- config.fish: remove inline fish_prompt block (now in conf.d/starship.fish);
add return sentinel at EOF to prevent tool-injected init lines from running
- completions/ov.fish: add ov tab completions
- README.md: document all of the above
- Set $PAGER to ov in config.fish (falls back to less); remove LESS=-R
- Rewrite less wrapper with full hierarchy: $PAGER → ov → less → more → cat
- Simplify view.fish fallback to delegate to the less wrapper
- Add logs function: fzf browser for scrollback and paru logs, opens in $PAGER
- Add claude wrapper: auto-injects --remote-control unless already present
- Add conf.d/paru-wrapper.fish: generates ~/.local/bin/paru on first run,
versioned so future template changes auto-propagate on next shell start
- Sync README.md and requirements.md to document all of the above