Files
fish-config/docs/manual/07-customization.md
T
rootiest d9b56790c5 fix(agents-vault): keep the knowledge walk and the launch push inside their bounds
The agy knowledge allowlist walked the store with `**` and copied with
plain cp, so a symlink inside the store was both followed and dereferenced.
The extension rule still bounded what kind of file was collected, but not
whose: a link to a home directory hands over settings.json, CLAUDE.md and
every cached .json in it, and those reached a commit. A link to / made the
walk itself unbounded, on the path that runs before every agent launch.
The tree is now walked a level at a time and nothing that is a symlink is
followed or copied.

Autopush had the same shape one layer out. Neither GIT_TERMINAL_PROMPT nor
GIT_ASKPASS closes a socket, and git has no connect timeout to set: against
a blackholed address a push took 135s with http.lowSpeedLimit and
http.lowSpeedTime set as well as without them. ssh can time itself out and
is now told to; the autopush pull and push are additionally capped with
timeout(1). An explicit --push stays uncapped, since it is watched and has
to report what a real transfer really did.

Also: scaffold /.migrate-stash into .gitignore beside /.adopt-stash, which
the comment already claimed was covered; and drop the live memory path
during a slug migration only when it is a link. Reached from the
path-derived fallback candidate it can be a real populated directory, where
rm -f correctly refuses -- but said so in rm's voice, so a --silent run that
had succeeded printed what read as an error.
2026-09-03 18:56:46 -04:00

12 KiB

title, manTitle, sidebar, helpKeywords
title manTitle sidebar helpKeywords
Customization 7. CUSTOMIZATION
order
11
customization
customize

This section explains how to adapt the configuration to your specific workflow, including local machine overrides and opinionated component toggles.

Machine-local Configuration

Place machine-specific settings that should not be committed to git in:

$__fish_user_dots_path/local.fish

__fish_user_dots_path defaults to ~/.config/.user-dots/fish. Set a custom location with:

set -U __fish_user_dots_path /path/to/your/dots/fish

Typical uses: additional PATH entries, local aliases, hostname-specific env vars, work-specific tool configs.

For convenience, a git-ignored user-dots symlink in the fish config directory tracks $__fish_user_dots_path so the overlay can be browsed from ~/.config/fish/. It is created if missing and repointed if the path changes. Opt out by setting __fish_user_dots_symlink to a falsy value, or toggling "Dots link" off on the config-settings Paths page — this stops generation and removes any existing link. It only ever manages a symlink and never clobbers a real file or directory at that path.

Secrets and API Keys

$__fish_user_dots_path/secrets.fish

Store API tokens, GPG keys, private credentials here. This file is never committed. It is sourced by local.fish directly, not by config.fish.

local.fish is sourced at the end of config.fish on every interactive session, so it and its companion secrets.fish can override anything set earlier.

Overriding Configuration Variables

Any variable set in local.fish after the main config loads takes effect. Example: to increase the scrollback history limit:

# in local.fish
set -gx SCROLLBACK_HISTORY_MAX_FILES 200

Fish Universal Variables

Some settings (fzf colors, theme) are stored in fish_variables via set -U. These are machine-local and git-ignored. Do not commit fish_variables.

Opinionated Components (Minimal Mode)

Every opinionated piece of this config is active by default but can be switched off through six category opt-out variables, each evaluated via __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, yes, on, y) to re-enable. Unset means enabled — except for C5 logging, which is opt-in (see below).

An explicit per-category truthy value takes precedence over the master switch: setting __fish_config_opinionated=0 disables all unset categories, but a category with an explicit truthy value remains enabled regardless.

C5 (logging) is the one exception to "unset means enabled". Because it writes terminal output to disk, it is opt-in: unset means disabled, and the master switch cannot enable it. Only an explicit truthy value turns logging on.

Variable                        Disables
────────────────────────────────────────
__fish_config_op_aliases        Command shadows and flag injection:
                                ls->eza, cat->bat, cd->zoxide,
                                rm->trash, less->ov, top->btop,
                                ping->prettyping, ssh->kitten,
                                du->duf/dust, mkdir/bash wrappers,
                                history timestamps, grep/cp/mv/wget
                                flag injection, help intercept, claude
                                AGENTS.md auto-link
__fish_config_op_autoexec       Startup side-effects: Fisher
                                bootstrap, theme apply, paru/yay
                                wrapper generation, auto venv
                                activation, WakaTime hook
__fish_config_op_overrides      Key and env overrides: Vi mode,
                                exit->smart_exit, PAGER/MANPAGER,
                                CDPATH, bang-bang system, autopair,
                                puffer, starship prompt, theme
                                colors, FZF_DEFAULT_OPTS, right
                                prompt
__fish_config_op_integrations   Terminal/tool coupling: Kitty/
                                WezTerm window abbreviations, done
                                notifications, spwin/tab/split,
                                hist, logs, upgrade, WakaTime
__fish_config_op_logging        Logging & capture (OPT-IN — this one
                                is off unless explicitly enabled):
                                scrollback capture on exit, paru/yay
                                AUR log wrappers, Kitty watcher
                                capture; sentinel file coordinates
                                cross-process state
__fish_config_op_greeting       Greeting & first-run UI: per-session
                                fish_greeting override (defines empty
                                function late in config.fish to
                                suppress distro greetings such as
                                CachyOS fastfetch); first-run welcome
                                banner in conf.d/first_run.fish

Examples:

# Disable command shadows only (rm becomes plain rm again):
set -U __fish_config_op_aliases off

# Turn session logging on (opt-in; off until you do this):
set -U __fish_config_op_logging on

# Full minimal mode — disable all six categories at once:
set -U __fish_config_opinionated 0

# Re-enable everything (except C5 logging, which stays opt-in):
set -Ue __fish_config_opinionated

# Minimal mode but keep the greeting:
set -U __fish_config_opinionated 0
set -U __fish_config_op_greeting 1
# (erase both to go back to full-flavor defaults)

For an interactive alternative to setting these variables by hand, run config-settings — a full-screen TUI that flips any category (including C5 logging) on or off, per session or universally. See its entry in Section 5.

NOTE:

  • Command shadows (rm, cat, ls, ...) react immediately; conf.d-level components (bindings, prompt, abbreviations, hooks) take effect in new shells.
  • With aliases disabled, rm falls back to bare command rm — files are deleted permanently, not trashed.
  • Disabled integration commands (spwin, tab, split, hist, logs, upgrade) print an error naming the variable that disabled them.
  • On CachyOS, the distro fish config's own aliases, history override, and bang-bang bindings are stripped per category as well.

Sub-categories

Each of the six categories further sub-divides into two to six sub-categories, each with its own __fish_config_op_<category>_<subcategory> variable (e.g. __fish_config_op_aliases_filesystem). These follow the exact same truthy/falsy/unset cascade one level deeper: an explicit sub-category value overrides the master switch and the parent category's setting, and an unset sub-category inherits from its parent category (which in turn inherits from __fish_config_opinionated). Run config-settings and press Enter on a category row to browse and toggle its sub-categories interactively. See Components Reference for the full sub-category breakdown of every category.

Agent Memory Vault

__fish_agent_vault_dir

Overrides the agent memory vault location. Defaults to
$XDG_DATA_HOME/agent-vault (or ~/.local/share/agent-vault).

__fish_agent_vault_autopush

When set to 1, agents-vault also pushes on wrapper launch. Defaults to
off: the vault commits locally on every launch and pushes from the
Claude Code SessionEnd hook or an explicit agents-vault --push. That
push is synchronous, so with autopush on the pull and the push are
each capped at 20 seconds; an explicit --push is left uncapped.

NOTE: With autopush off and no SessionEnd hook installed, backups accumulate locally and never reach the remote. Run agents-vault --status to check how far ahead the vault is.

Prompt and Theme

Starship

The primary prompt is Starship, initialized by conf.d/starship.fish. Configure it via ~/.config/starship.toml.

conf.d/starship.fish defines a fish_prompt wrapper that only activates when starship is in PATH and C3 overrides are enabled (see Opinionated Components above). It emits OSC 133;A (prompt start) immediately before Starship renders and OSC 133;B (input start) immediately after, placing both markers on the prompt line itself. This allows ov to use them as sticky section headers when browsing scrollback logs. It also prints a blank line before the prompt, skipped in private mode or on a freshly cleared screen. Without Starship, fish's built-in prompt handles these markers automatically.

Catppuccin Fallback Prompt

When Starship is absent or C3 overrides are disabled, a built-in nim-style two-line prompt activates from functions/fish_prompt.fish. No external dependencies — fish builtins only.

Layout (a dim job line appears between the two rows for each running background job):

┬─[user@host:~/path] (main)
│ nvim notes.md
╰─>$

Elements:

Segment           Meaning
────────────────────────────────────────────────────────────────
user              Yellow (Catppuccin Yellow); red if root
@host             Blue (local) or Teal (SSH)
~/path            prompt_pwd abbreviation (Catppuccin Text)
─[N/I/R/V/O]      Vi-mode indicator (Normal/Insert/Replace/Visual/Operator);
                  shown only when vi or hybrid key bindings are active
─[V:name]         Active Python venv basename; omitted when none
(main)            Current git branch in Catppuccin Pink, with ↑/↓
                  upstream-tracking arrows when applicable;
                  omitted outside repos
┬─ / ╰─>          Connector lines: Catppuccin Green on success,
                  Red on failure

The right prompt (fish_right_prompt.fish) always renders, independently of which left prompt is active:

Segment           Shown when
────────────────────────────────────────────────────────────────
✘ <code>          The previous command exited non-zero (red)
󰡨 <context>       docker and starship are both installed, C3
                  overrides are enabled, and the active Docker
                  context is set and non-default
<timestamp>       Always (dim, Catppuccin Overlay0)

The exit-status and Docker segments are independent — for example, right after a failing command with a non-default Docker context active:

✘ 1  󰡨 myctx  Fri Jun 12 00:51:21 2026

A successful command with the same Docker context shows the segment too:

󰡨 myctx  Fri Jun 12 00:51:21 2026

And without Starship (or with C3 disabled, or Docker not installed), only the exit-status prefix and timestamp ever appear:

✘ 1  Fri Jun 12 00:51:21 2026

FZF

FZF is themed to Catppuccin Mocha via FZF_DEFAULT_OPTS, set in conf.d/theme.fish (opinionated; disabled by __fish_config_op_overrides, see Opinionated Components above). The colors applied:

Hex        Role                     Catppuccin name
────────────────────────────────────────────────────────
#1E1E2E    Background               Base
#313244    Highlighted background   Surface0
#45475A    Selected background      Surface1
#CDD6F4    Foreground               Text
#F38BA8    Highlight / header       Red
#CBA6F7    Info / prompt            Mauve
#B4BEFE    Marker                   Lavender
#F5E0DC    Spinner / pointer        Rosewater
#6C7086    Border                   Overlay0

To customize, override FZF_DEFAULT_OPTS in local.fish — it is sourced after conf.d/theme.fish on every session, so a set -Ux FZF_DEFAULT_OPTS ... there always wins.

Catppuccin Mocha Syntax Highlighting

The Catppuccin Mocha theme ships with this config in themes/ and is applied automatically on first run via conf.d/first_run.fish (gated by __fish_config_op_autoexec; see Opinionated Components above). Colors are stored in fish_variables (universal). Three other bundled variants are available in themes/ — Latte, Frappé, and Macchiato. To switch:

fish_config theme choose "Catppuccin Latte"