Extract the user-dots symlink logic into the __fish_user_dots_link helper and
add a dedicated __fish_user_dots_symlink toggle, surfaced as a 'Dots link' bool
row on the config-settings Paths page. Unlike the opinionated categories it has
no universal/session split — it acts on a literal path.
Setting it falsy (or toggling off) stops symlink generation and removes any
existing link immediately, honoured regardless of the C2 master switch.
Creation remains a C2 startup side-effect. config.fish now calls the helper.
Docs: README, fish-config.md (C2 table, Paths page, machine-local section),
and fish-config.index updated.
Point $__fish_config_dir/user-dots at $__fish_user_dots_path on interactive
startup so the private overlay can be browsed from the fish config dir. The
link is created if missing and repointed if the path variable changes, only
ever managing a symlink (never clobbering a real file/dir). Gated as a C2
startup side-effect (__fish_config_op_autoexec) and git-ignored.
Docs: README overlay section and fish-config.md C2 table updated.
Extract the browser-detection and launch logic out of config-help into a
reusable open-url function, then build repo-open on top of it to open the
current repo's origin remote in a browser.
- open-url: resolve the best graphical browser (fish_help_browser -> BROWSER
-> xdg-mime https handler -> known binaries -> xdg-open) and launch it
backgrounded. Silent by default; -v/--verbose reports the browser, -s/--silent
is accepted explicitly. Browser console chatter is discarded.
- repo-open: normalize the origin URL from HTTPS and SSH/scp forms, deep-link
to the current branch (falling back to the remote default) and sub-directory.
Provider layout resolved via git config browse.provider, hostname heuristic
(github/gitlab/gitea/bitbucket, codeberg->gitea), then github default.
-p/--print emits the URL, -r/--root ignores the sub-directory.
- config-help: replace the inlined browser block with an open-url call.
- abbr: add open-repo and url-open abbreviations that expand to the canonical
command names on space/enter.
- docs: document both functions in the SSoT (fish-config.md + index) and add a
repo-open row to the README doc-browsing table.
Previously list rows (Extra secret, OK codes) split on spaces only, so
'KOPIA, TEST' produced the malformed token 'KOPIA,'. Collapse any run of
commas/whitespace to a single space before splitting, so 'A,B', 'A, B' and
'A B' all yield the same entries.
- §1 Scrollback History: __fish_scrollback_history_* source-of-truth + exported
mirror, and the no-global-shadow rationale
- §Sponge History Filtering: __fish_sponge_extra_sensitive name tokens (--entire
match) and the tuning vars surfaced on the Sponge page
- config-settings function reference: four-page model, Tab/Shift-Tab, value rows
- index + README updated
Both the auto-pull function and the PWD event handler hardcoded
$XDG_CONFIG_HOME/.user-dots/fish as the registry directory. They now
resolve $__fish_user_dots_path first, falling back to the same default,
so a custom path set via config-settings is honoured.
Allow users to customize the location of their private overlay directory
via `set -U __fish_user_dots_path /your/path`. Falls back to the previous
hardcoded default of `$XDG_CONFIG_HOME/.user-dots/fish` when unset.
Simplify the sourcing model: config.fish now sources only local.fish,
which is responsible for sourcing its own secrets.fish companion. The
redundant direct sourcing of secrets.fish from config.fish is removed.
Update docs/fish-config.md (Sections 1, 7, 10) and README.md to
document the new variable, the custom-path override pattern, and the
simplified sourcing model.
Add functions/yt-dlp.fish, shadowing yt-dlp to prepend sane defaults
(--sponsorblock-remove all, --embed-subs, --embed-metadata,
--embed-thumbnail). Each default is suppressed when the user already
passes that flag, its alias (--add-metadata), its negation
(--no-embed-thumbnail), the --opt=value form (--sponsorblock-remove=...),
or the global --no-sponsorblock kill. User args pass through last so an
explicit flag wins on precedence. Gated as a C1 opinionated alias;
falls back to bare `command yt-dlp` when disabled.
Register yt-dlp as a recommended (rec tier) dependency in the fish-deps
catalog and document the function (§5.13) and dependency in the SSOT
and index.
Add the auto-pull function entry (5.4 Git) and index entry, a C2 component
reference row plus explanatory paragraph in fish-config.md, and update the
README C2 disable-list. (AGENTS.md C2 table, file tree, and task #12 are
tracked in the git-ignored AGENTS/ dir.)
VISUAL was hardwired to $EDITOR (nvim), so 'edit --visual' would launch a
terminal editor detached with no tty. Comment it out so --visual falls
through to the GUI fallback chain, and let users set a real GUI editor via
local.fish. Update the editor-variable docs to match.
The local core.hooksPath override set by agents-init shadowed the user's
global hooks (ggshield, Git LFS) since git honors only one hooksPath. Each
shim now execs the global/system hook of the same name after running
version-bump, so global hooks still run after version increment. Bumped the
agents-tools version marker to 2 so existing AGENTS repos refresh.
Drop the save-session/resume system entirely:
- functions/save_claude_session.fish, save_antigravity_session.fish
(session-start hook scripts)
- functions/claude-resume.fish, antigravity-resume.fish, code-resume.fish
(consumers of the .claude_session/.antigravity_session files)
Also updates docs/fish-config.md (removes the three function sections,
drops the session-helper mention from the python3 dependency note) and
docs/fish-config.index (removes the orphaned keyword entries). Generated
html/wiki/man are rebuilt by build-docs.yml on merge.
External hook registrations were removed from ~/.claude/settings.json and
~/.gemini/settings.json (the latter pointed at an already-deleted
save_gemini_session.fish); those files live outside this repo.
The zellij wrapper (functions/zellij.fish) rewrote every `zellij`
invocation as `zellij options --theme catppuccin-mocha <args>`, which is
only valid for launching a new session. This mangled every subcommand,
including the `zellij action dump-screen` call inside _zellij_dump_log,
so no logs were ever produced. The theme is already set in config.kdl,
making the wrapper redundant — remove it.
Also harden _zellij_dump_log:
- dump-screen takes the file via stdout redirect, not a positional arg
(rejected by zellij 0.44) nor --path (server-side write, flaky)
- add --ansi to preserve color in the logs
- discard empty dumps instead of leaving junk files
Document the structural limitation: zellij can only snapshot on a clean
shell exit, unlike tmux's continuous pipe-pane stream. Closing a pane or
quitting zellij tears down the pane/server before it can be dumped.
Add a Session Logging section and a CAUTION callout to the README, and a
matching privacy notice to docs/fish-config.md, making clear that this
config logs terminal sessions (Kitty/tmux/zellij/paru/yay) to
~/.terminal_history by default. Point users at both the
__fish_config_op_logging variable and the interactive config-toggle TUI
for opting out.
Zellij has no live-stream facility like tmux pipe-pane, so capture is a
one-shot 'zellij action dump-screen --full' run from a fish_exit handler
(conf.d/zellij-logging.fish -> functions/_zellij_dump_log.fish). The C5
guard is checked inside the helper at exit time, so toggling logging
needs no sync_logging coordination — there is no persistent stream.
Extract pruning into functions/_prune_terminal_logs.fish, shared by both
the tmux and zellij helpers. This also fixes a latent bug in the tmux
helper: globbing tmux_*.log directly errored with 'No matches for
wildcard' on the first log in an empty dir. The shared helper globs via
'set' (tolerates no-match) and uses command ls/rm to bypass the eza and
trash C1 shadows.
Extract the tmux pipe-pane setup into functions/_tmux_pipe_log.fish,
called by both conf.d/tmux-logging.fish (startup) and
__fish_config_sync_logging (C5 re-enable). The helper prunes the oldest
tmux_*.log files by mtime to stay within SCROLLBACK_HISTORY_MAX_FILES,
matching the paru/yay wrappers.
Uses 'command ls' to bypass the eza ls shadow, which injects OSC-8
hyperlink escapes into paths and corrupted the filenames passed to rm.
Starts tmux pipe-pane capture for the current pane whenever fish
launches inside a tmux session. Each shell gets a timestamped log
in SCROLLBACK_HISTORY_DIR. Toggling __fish_config_op_logging stops
or restarts the pipe in all open fish shells via the existing
--on-variable event handlers.
Panel now selects from four width tiers based on $COLUMNS (with a 6-col
buffer per side before stepping up): 52-wide (default), 70, 74, or 78.
Each tier carries richer category descriptions sized to fit the layout.
The box is horizontally centered on every draw via a left-padding prefix.
Key reader switches from stty min 1 to min 0 / time 3, giving a 0.3 s
poll interval so COLUMNS changes are detected without a keypress. The
erase formula is now wrap-aware: prev_max_line_width / COLUMNS gives the
wrap factor, ensuring old wider panels are fully cleared after narrowing.
Idle timeout ticks that detect no resize are skipped entirely.
New functions/claude.fish wraps the claude CLI. Before launch it checks the
current directory and the git project root; when CLAUDE.md is absent but
AGENTS.md is present, it creates a relative symlink CLAUDE.md -> AGENTS.md so
Claude Code picks up shared agent instructions without duplicating the file.
Arguments are forwarded verbatim.
Implemented as a C1 command shadow: when __fish_config_op_aliases (or the
master __fish_config_opinionated) is disabled, the call passes through to the
bare claude binary unchanged. Link-creation notices print to stderr in green.
Documents the new shadow in docs/fish-config.md (section 5.12 AI tools, C1
component reference table, and C1 summary list) and adds a claude-cli anchor
to docs/fish-config.index.
Required tier is now fish, fzf, and zoxide only — the tools the config
meaningfully can't function without. Everything else degrades gracefully.
- cargo: only used by fish-deps to install Rust tools or build fish from
source; all paths are already gated on type -q cargo
- starship: type -q guard in conf.d/starship.fish; shell falls back to
fish's built-in prompt without it
- fisher: auto-bootstrapped by first_run.fish; no need for users or
fish-deps to manage it. Remove from catalog and clean up the now-dead
fisher-bootstrap/special-fisher installer cases.
Catalog arrays verified aligned at 26 entries each.
direnv integration is fully guarded with type -q direnv in config.fish.
The auto-venv script checks $DIRENV_DIR (set at runtime), not the binary.
Without direnv installed the hook simply never loads and venv activation
fires normally. No functionality breaks.
paru and yay were already classified as rec in _fish_deps_catalog.fish
(they've always been position 9-10 in the tiers array with rec values)
but docs/fish-config.md still listed them under Required. Non-Arch
systems have had silent guards throughout, so they were never truly
required. This syncs the docs with what the catalog already says.
uv is only used in the fish-deps fish-from-source build path
(uv run --no-managed-python cargo install --path .) and is not required
by the config at runtime. All consumers degrade gracefully without it.
pipx appeared in the installer's method-building and execution switch
blocks but no catalog entry ever sets special=pipx, making both branches
permanently unreachable dead code. The docs listed pipx as install
priority #6 which was equally misleading.
- _fish_deps_catalog: change uv tier from req → rec
- _fish_deps_install: remove case pipx method-builder and
special-pipx / special-pip execution cases
- docs/fish-config.md: move uv from Required to Recommended catalog
entry with accurate description; drop pipx from install priority
list and tier summary
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)
pacman/paru download progress is a multi-line terminal animation: it
repaints lines in place using ANSI cursor-movement (ESC[<n>A) and
erase-line (ESC[K) sequences, not just carriage returns. The previous
line-wise regex approaches could not reconstruct this — frames either
concatenated into one giant line (CR removed) or collapsed to blanks
(CR kept), discarding the final 100% frame.
Add scripts/clean_progress_log.py, a small dependency-free terminal
screen-buffer emulator that replays the cursor movements against an
in-memory grid and dumps the final static frame, preserving SGR color
so logs still render with color in ov/bat/less -R. It also drops the
script(1) header/footer.
Both wrappers now pipe the raw PTY capture through this cleaner (bumped
to version 5), falling back to stripping only the script(1) header when
python3 is unavailable. Document the scripts/ dir and mechanism in
AGENTS.md and docs/fish-config.md.
Piping through tee caused libalpm to detect a non-TTY stdout and
suppress download progress bars. Switch to script(1) with -q -e -c
which allocates a pseudo-TTY so paru/yay see a real terminal, then
strip ANSI escape sequences from the captured log for readability.
Bump wrapper version to 2 to force regeneration on next shell start.
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.
Promotes the internal opinionated_catalog.md (git-ignored dev reference)
to first-class user documentation in docs/fish-config.md Section 7.
- Add per-category component tables (C1–C6) under a new "Component
Reference" subsection in "Opinionated Components (Minimal Mode)"
- Document the C5 sentinel-file coordination mechanism and how
__fish_config_logging_changed propagates changes to all open shells
- Document C3/C5 composition (smart_exit wrapper vs capture block)
- Document bang-bang system atomicity across its multiple source files
- Add rg function entry to Section 5.1 (Kitty hyperlink wrapper)
- Update fish-config.index with keywords for all new headings
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.
Adds 'Opinionated Components (Minimal Mode)' to docs/fish-config.md
with index keywords (opinionated, minimal, minimal-mode, opt-out,
toggles) and a Minimal Mode section with toggle table to README.md.
AGENTS.md Task #3 checklist ticked locally (file is git-ignored).