docs(fisher): clarify bundled vs fisher-managed plugins; add sponge #37

Merged
rootiest merged 7 commits from docs/fisher-plugins-bundled into main 2026-06-09 02:31:32 +00:00
9 changed files with 290 additions and 142 deletions
+10
View File
@@ -62,6 +62,16 @@
opinionated_catalog.md
docs/superpowers
# ──────────────── Fisher-Managed Plugin Files ───────────────
# Fisher writes these into the repo directory on install/update.
# They are owned by Fisher — do not commit them.
functions/fisher.fish
completions/fisher.fish
conf.d/sponge.fish
functions/_sponge*.fish
functions/sponge_*.fish
!functions/sponge_filter_secrets.fish
# ─────────────────── AI Sessions and Rules ──────────────────
# Matches CLAUDE.md, .claud*, etc.
[Cc][Ll][Aa][Uu][Dd][Ee].[Mm][Dd]
+2 -2
View File
@@ -22,7 +22,7 @@ This config layers on top of the CachyOS base Fish configuration and adds:
- **Catppuccin Mocha** theming throughout (prompt, FZF, syntax highlighting)
- **Starship** prompt with VI key bindings
- **Fisher** plugin management with FZF key bindings and Catppuccin syntax colors
- **Fisher** plugin manager bootstrapped automatically; manages `sponge` (failed-command history filter); FZF bindings, Catppuccin theme, done, autopair, and puffer-fish are bundled directly with the config as customized versions
- **Smart CLI wrappers** that prefer modern tools (`eza`, `bat`, `btop`, `dust`, `prettyping`) with graceful fallbacks
- **Auto Python venv** activation on directory change (direnv-aware)
- **Kitty terminal** deep integration for splits, tabs, and SSH
@@ -66,7 +66,7 @@ mv ~/.config/fish ~/.config/fish.bak
git clone https://git.rootiest.dev/rootiest/fish-config.git ~/.config/fish
```
Then open a new Fish shell — Fisher and all plugins will be installed automatically on first launch, and the Catppuccin Mocha theme will be applied.
Then open a new Fish shell — Fisher will be installed automatically on first launch and the Catppuccin Mocha theme will be applied. All plugin functionality is bundled directly with this config and requires no additional installation.
A [chezmoi](https://www.chezmoi.io/) dotfile manager is also configured — secrets are sourced from `~/.config/.user-dots/fish/secrets.fish` and excluded from version control.
+1 -1
View File
@@ -35,7 +35,7 @@ if not type -q fisher
if curl -sL https://raw.githubusercontent.com/jorgebucaran/fisher/main/functions/fisher.fish | source
echo " [first-run] Fisher installed."
if not fisher update 2>/dev/null
echo " [first-run] Plugin sync failed — run 'fisher update' manually." >&2
echo " [first-run] Fisher update failed — run 'fisher update' manually." >&2
end
else
echo " [first-run] Fisher install failed — run 'fisher update' manually." >&2
+126
View File
@@ -0,0 +1,126 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
# ╭──────────────────────────────────────────────────────────╮
# │ Sponge Privacy Pattern Registration │
# ╰──────────────────────────────────────────────────────────╯
#
# Two-layer approach to keeping credentials out of shell history:
#
# Layer 1 — Static patterns (registered as universal, persistent):
# Covers structural signatures: auth flags, env var assignments,
# credential-bearing URLs, Authorization headers, sshpass, etc.
# Patterns are added idempotently; user additions are preserved.
#
# Layer 2 — Dynamic secret values (registered as session globals):
# On the first prompt (after secrets.fish has loaded), reads the
# literal values of all exported variables whose names indicate
# credentials (TOKEN, PASSWORD, SECRET, KEY, etc.) and adds them
# as a session-scoped pattern overlay. Refreshes automatically
# each login, so rotated tokens never leave stale patterns behind.
#
# Layer 3 — Per-command filter (sponge_filter_secrets):
# Catches mid-session variables set after login — e.g. a token
# exported interactively or sourced from a project .env file.
#
# To add your own persistent patterns:
# set -U -a sponge_regex_patterns 'your-regex-here'
if not status is-interactive
return
end
# Only register if sponge is loaded
if not set -q sponge_version
return
end
# ──────────────────── Layer 1: Static patterns ────────────────────
set -l _privacy_patterns
# Common auth flags with values: --password x, --token x, --passphrase x, --api-key x
# Use \- to avoid the pattern string starting with --, which string match
# would misinterpret as an unknown option flag.
set -a _privacy_patterns '\-\-(?:password|passwd|passphrase|token|secret|api[-_]key)(?:\s+|=)\S+'
# Inline env var assignments with sensitive names: GITHUB_TOKEN=xxx, MY_API_KEY=abc
set -a _privacy_patterns '(?i)\b[A-Z][A-Z0-9_]*(?:PASSWORD|PASSWD|SECRET|TOKEN|API_KEY|PRIVATE_KEY|ACCESS_KEY|AUTH_KEY|CREDENTIAL)[A-Z0-9_]*=\S+'
# Fish set with sensitive variable names: set -gx GITHUB_TOKEN xxx, set -U MY_SECRET yyy
set -a _privacy_patterns '(?i)set\s+-\S+\s+\S*(?:password|passwd|token|secret|api.?key|private.?key|access.?key|credential)\S*\s+\S+'
# URLs with embedded credentials: https://user:password@host
set -a _privacy_patterns 'https?://[^:@\s]+:[^@\s]+@'
# HTTP Authorization headers: curl -H "Authorization: Bearer xxx"
set -a _privacy_patterns 'curl\s.*[Aa]uthorization:'
# Basic auth flags: curl -u user:pass, wget --user user --password pass
set -a _privacy_patterns '(?:curl|wget)\s.*(?:-u|--user)\s+\S+:\S+'
# sshpass — exposes credentials as a CLI argument by design
set -a _privacy_patterns '\bsshpass\b'
# Docker login with inline password
set -a _privacy_patterns 'docker\s+login\s.*(?:-p|--password)\s+\S+'
# openssl passphrase arguments: -passin pass:xxx, -passout env:VAR
set -a _privacy_patterns 'openssl\s.*-pass(?:in|out)\s+\S+'
# Remove any previously stored patterns that begin with -- ; string match
# passes patterns before its own -- sentinel and would treat them as flags.
for _i in (seq (count $sponge_regex_patterns) -1 1)
if string match --quiet -- '--*' $sponge_regex_patterns[$_i]
set -Ue sponge_regex_patterns[$_i]
end
end
# Idempotent registration into universal sponge_regex_patterns
for _pattern in $_privacy_patterns
if not contains -- $_pattern $sponge_regex_patterns
set -U -a sponge_regex_patterns $_pattern
end
end
# ──────────── Layer 2: Dynamic secret values (session globals) ────────────
# Runs once on the first prompt — by which point config.fish and secrets.fish
# have fully loaded, so all secret env vars are in scope.
# Builds a session-scoped global that combines the universal static patterns
# with the literal values of any credential-holding env vars. Globals shadow
# universals in Fish, so the combined list is what sponge sees for this session.
function __sponge_register_secret_values --on-event fish_prompt
functions --erase __sponge_register_secret_values # run exactly once
set -l secret_values
set -l sensitive_vars (set --names --export | string match --regex -- \
'(?i)(?:TOKEN|PASSWORD|PASSWD|SECRET|API[_-]KEY|PRIVATE[_-]KEY|ACCESS[_-]KEY|AUTH[_-]KEY|CREDENTIAL|KOPIA_PASSWORD)')
for var in $sensitive_vars
# Take only the first element — array vars yield multiple values.
set -l value $$var[1]
# If the var is unset or holds an empty list, value has no elements;
# set -q catches that before string length receives zero arguments.
set -q value[1]; or continue
test (string length -- $value) -gt 8; or continue
string match --quiet --regex '^[/~]' -- $value; and continue
set -a secret_values (string escape --style=regex -- $value)
end
if test (count $secret_values) -gt 0
# Merge static universals + dynamic values into a session global
set -g sponge_regex_patterns $sponge_regex_patterns $secret_values
end
end
# ──────────── Layer 3: Mid-session filter (sponge_filter_secrets) ─────────
# Catches credentials in variables exported after login (e.g. project .env files).
# Only register if not already in sponge_filters.
if functions --query sponge_filter_secrets
if not contains -- sponge_filter_secrets $sponge_filters
set -U -a sponge_filters sponge_filter_secrets
end
end
+24 -5
View File
@@ -29,8 +29,8 @@ keybindings=# 3. KEY BINDINGS
bindings=# 3. KEY BINDINGS
key-bindings=# 3. KEY BINDINGS
keys=# 3. KEY BINDINGS
fzf-bindings=## FZF Bindings (from fzf --fish integration)
fzf=## FZF Bindings (from fzf --fish integration)
fzf-bindings=## FZF Bindings (bundled from PatrickF1/fzf.fish)
fzf=## FZF Bindings (bundled from PatrickF1/fzf.fish)
# ── Section 4: Abbreviations ──────────────────────────────────
abbreviations=# 4. ABBREVIATIONS
@@ -166,10 +166,29 @@ universal=## Fish Universal Variables
# ── Section 8: Fisher Plugins ─────────────────────────────────
plugins=# 8. FISHER PLUGINS
fisher=# 8. FISHER PLUGINS
fisher-managed=## Fisher-Managed Plugins
sponge=## Fisher-Managed Plugins
sponge-filtering=## Sponge History Filtering
history-filtering=## Sponge History Filtering
privacy=## Sponge History Filtering
bundled-plugins=## Bundled Plugin Functionality
fish-plugins-manifest=## fish_plugins Manifest
# ── Section 9: Viewing This Manual ───────────────────────────
viewing=# 9. VIEWING THIS MANUAL
manual=# 9. VIEWING THIS MANUAL
# ── Section 9: Installation ────────────────────────────────────
installation=# 9. INSTALLATION
install=# 9. INSTALLATION
sentinel=## Return Sentinel
updating=## Updating
# ── Section 10: Personalization ───────────────────────────────
personalization=# 10. PERSONALIZATION
personalize=# 10. PERSONALIZATION
secrets=## secrets.fish
local-config=## local.fish
# ── Section 11: Viewing This Manual ──────────────────────────
viewing=# 11. VIEWING THIS MANUAL
manual=# 11. VIEWING THIS MANUAL
ov=## With ov (recommended)
man-page=## As a man page (if compiled)
manpage=## As a man page (if compiled)
+71 -14
View File
@@ -279,7 +279,7 @@ are active in Insert, Normal, and Visual modes unless noted.
line to open an fzf picker and insert a selection
at the cursor position.
## FZF Bindings (from PatrickF1/fzf.fish)
## FZF Bindings (bundled from PatrickF1/fzf.fish)
Ctrl+R Search command history
Ctrl+Alt+F Search git-tracked files
@@ -1395,9 +1395,9 @@ To customize, override FZF_DEFAULT_OPTS in local.fish.
### Catppuccin Mocha Syntax Highlighting
The catppuccin/fish plugin applies syntax highlight colors on first run.
Colors are stored in fish_variables (universal). To switch variants, install
a different theme from the themes/ directory:
The Catppuccin Mocha theme ships with this config in themes/ and is applied
on first run via `conf.d/first_run.fish`. Colors are stored in fish_variables
(universal). To switch variants, install a different theme from themes/:
fish_config theme save "Catppuccin Latte"
@@ -1417,18 +1417,74 @@ testing), run:
Then open a new shell.
The plugin list is maintained in fish_plugins at the config root.
## Fisher-Managed Plugins
The following plugins are fully managed by Fisher. Their files are installed
into the repo directory by Fisher and are listed in `.gitignore` — do not
commit them. Fisher installs and updates them automatically.
jorgebucaran/fisher Plugin manager itself
catppuccin/fish Catppuccin Mocha color theme
PatrickF1/fzf.fish fzf integration for Fish
franciscolourenco/done Desktop notification when long commands finish
jorgebucaran/autopair.fish Auto-pair brackets and quotes
meaningful-ooo/sponge Remove failed commands from history
nickeb96/puffer-fish !! / !$ / ./ expansion
Run `fisher update` to update all plugins, or `fish-deps update` which
calls fisher update as its first step.
## Sponge History Filtering
Sponge removes failed commands from history and, via conf.d/sponge_privacy.fish,
also filters privacy-sensitive commands through three layers:
Layer 1 — Static patterns (universal, persistent across sessions):
Commands matching any of these structural signatures are never recorded:
--password / --token / --passphrase / --api-key flags with values
Inline env assignments: GITHUB_TOKEN=xxx, MY_API_KEY=abc
Fish set with sensitive names: set -gx GITHUB_TOKEN xxx
URLs with embedded credentials: https://user:pass@host
HTTP Authorization headers: curl -H "Authorization: ..."
Basic auth flags: curl -u user:pass
sshpass, docker login -p, openssl -passin/-passout
Layer 2 — Dynamic secret values (session globals, refreshed each login):
On the first prompt, after secrets.fish has loaded, the literal values of
all exported variables whose names suggest credentials (TOKEN, PASSWORD,
SECRET, API_KEY, etc.) are collected, regex-escaped, and added as a
session-scoped overlay. Because globals shadow universals in Fish, the
combined list is what sponge sees. Rotating a token takes effect on the
next login automatically.
Layer 3 — Per-command filter (sponge_filter_secrets):
Catches credentials in variables exported after login, such as tokens
sourced from a project .env file mid-session.
To add your own persistent patterns:
set -U -a sponge_regex_patterns 'your-regex-here'
## Bundled Plugin Functionality
The remaining plugin functionality is bundled directly with this config rather
than managed through Fisher. The bundled versions include customizations for
Fish 4.x compatibility and improved behavior that differ from their upstream
releases. Installing them through Fisher would overwrite these customizations.
Bundled components and their upstream origins:
catppuccin/fish → themes/ + conf.d/theme.fish
PatrickF1/fzf.fish → functions/_fzf_*.fish + conf.d/fzf.fish
franciscolourenco/done → conf.d/done.fish
jorgebucaran/autopair.fish → functions/_autopair_*.fish + conf.d/autopair.fish
nickeb96/puffer-fish → functions/_puffer_fish_*.fish + conf.d/puffer.fish
Do not run `fisher install` for these — it will overwrite the customized
versions. To update their behavior, edit the relevant bundled files directly.
## fish_plugins Manifest
The `fish_plugins` file at the config root:
jorgebucaran/fisher Plugin manager itself
meaningful-ooo/sponge Remove failed commands from history
To update all Fisher-managed plugins, run `fisher update` or `fish-deps
update` which calls it as its first step.
---
@@ -1439,8 +1495,9 @@ This configuration is managed as a git repository. To deploy on a new machine:
mv ~/.config/fish ~/.config/fish.bak # back up any existing config
git clone https://git.rootiest.dev/rootiest/fish-config.git ~/.config/fish
Then open a new Fish shell. Fisher and all plugins install automatically on
first launch and the Catppuccin Mocha theme is applied.
Then open a new Fish shell. Fisher installs automatically on first launch
and the Catppuccin Mocha theme is applied. All other plugin functionality is
bundled directly with this config and requires no additional installation.
## Return Sentinel
+1
View File
@@ -1 +1,2 @@
jorgebucaran/fisher
meaningful-ooo/sponge
+55
View File
@@ -0,0 +1,55 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
# SYNOPSIS
# sponge_filter_secrets <command> <exit_code> <previously_in_history>
#
# DESCRIPTION
# Custom sponge filter that prevents commands from being stored in history
# when they contain the literal value of any exported environment variable
# whose name indicates it holds a credential (TOKEN, PASSWORD, SECRET,
# API_KEY, etc.). This catches shell-expansion leakage where a variable
# value is embedded directly in the command string at execution time — a
# case that static regex patterns cannot cover.
#
# Any variable whose name matches the sensitive-name heuristic and whose
# value is longer than 8 characters (excluding bare paths) is checked.
# The value is escaped for literal regex matching before comparison.
#
# ARGUMENTS
# command The exact command that was entered
# exit_code Exit code of the command (unused)
# previously_in_history "true"/"false" flag (unused)
#
# RETURNS
# 0 Command contains a secret value — filter out of history
# 1 No secret value found — keep in history
#
# EXAMPLE
# # Register with sponge (done automatically by conf.d/sponge_privacy.fish):
# set -U -a sponge_filters sponge_filter_secrets
function sponge_filter_secrets --argument-names command
# Find all exported variables with security-sensitive names
set -l sensitive_vars (set --names --export | string match --regex -- \
'(?i)(?:TOKEN|PASSWORD|PASSWD|SECRET|API[_-]KEY|PRIVATE[_-]KEY|ACCESS[_-]KEY|AUTH[_-]KEY|CREDENTIAL|KOPIA_PASSWORD)')
for var in $sensitive_vars
# Take only the first element — array vars yield multiple values
set -l value $$var[1]
# Guard before string length: if var is unset, value is an empty list
# and string length receives zero arguments, breaking test.
set -q value[1]; or continue
# Skip short or path-like values — not real credentials
test (string length -- $value) -gt 8; or continue
string match --quiet --regex '^[/~]' -- $value; and continue
# Filter if the literal value appears anywhere in the command
if string match --quiet --regex -- (string escape --style=regex -- $value) $command
return 0
end
end
return 1
end
-120
View File
@@ -1,120 +0,0 @@
# Fish Config Requirements
Non-standard applications required by this fish shell configuration.
## Terminal Emulators
| Tool | Description | Notes |
|------|-------------|-------|
| `kitty` | GPU-accelerated terminal emulator | Primary terminal; used heavily for tab/window management via `kitty @` |
| `wezterm` | Cross-platform GPU-accelerated terminal | Referenced as alternative |
| `konsole` | KDE terminal emulator | Used in `tab.fish` as fallback |
## File & Directory Tools
| Tool | Description | Notes |
|------|-------------|-------|
| `lsd` | `ls` replacement with icons and colors | Wraps `ls`, `l`, `ll`, `lt`, `lstree`, `lS`, `ltr` |
| `bat` | `cat` replacement with syntax highlighting | Wraps `cat` |
| `dust` | Disk usage analyzer (Rust) | Used in `du.fish` |
| `duf` | Disk usage/free utility | Used in `du.fish` |
| `dua` | Fast disk space analyzer | Used in `du.fish` |
| `trash` / `trash-cli` | Safe file deletion to trash | Wraps `rm` |
## Editors
| Tool | Description | Notes |
|------|-------------|-------|
| `nvim` | Neovim text editor | Primary editor; used in `edit`, `view`, `nlazyup`, `nvimup` |
| `kate` | KDE text editor | Abbreviation target |
## Git & Version Control
| Tool | Description | Notes |
|------|-------------|-------|
| `lazygit` | Terminal Git UI | Abbreviation `lg` |
| `gitui` | Fast terminal Git UI | `gitui.fish` wrapper |
| `clone-in-kitty` | Clone repos into a Kitty window | Used in `clone.fish`, `clonet.fish` |
## System & Process Monitoring
| Tool | Description | Notes |
|------|-------------|-------|
| `btop` | Modern resource monitor | Wraps `top` |
| `fastfetch` | System info display | `ffetch.fish`, `cffetch.fish` |
| `neofetch` | System info display (fallback) | Fallback in `ffetch.fish` |
## Package Management
| Tool | Description | Notes |
|------|-------------|-------|
| `paru` | AUR helper (Arch Linux) | Used in `install`, `search`, `upgrade`, `parur` |
## Navigation & Search
| Tool | Description | Notes |
|------|-------------|-------|
| `zoxide` | Smart `cd` with frecency | Initialized in `zoxide.fish` |
| `fzf` | Fuzzy finder | Used in `parur.fish` and elsewhere |
| `ripgrep` / `rg` | Fast line-oriented search | Wrapped in `rg.fish` |
## Shell Prompt & Theme
| Tool | Description | Notes |
|------|-------------|-------|
| `starship` | Cross-shell prompt | Initialized in `config.fish` |
## Terminal Multiplexers
| Tool | Description | Notes |
|------|-------------|-------|
| `zellij` | Terminal workspace/multiplexer | `zellij.fish` wrapper |
## Network & Remote
| Tool | Description | Notes |
|------|-------------|-------|
| `tailscale` | VPN client | `tailscale.fish`, `tailart.fish` |
| `curl` | HTTP/data transfer | Used in `bd-pull.fish` |
## Developer & Productivity Tools
| Tool | Description | Notes |
|------|-------------|-------|
| `chezmoi` | Dotfile manager | Numerous abbreviations |
| `llm` | CLI for LLM interaction | `llm.fish` wrapper |
| `cheat` | Cheatsheet viewer | `cheat.fish`, `cheat.conf.d` |
| `wakatime` | Developer time tracking | Initialized in `wakatime.fish` |
| `bd` / `beads` | Lightweight issue tracker | `bd-pull.fish`, abbreviations |
| `lazybeads` | Terminal UI for beads | Abbreviation target |
| `agy` | antigravity-cli AI assistant | `antigravity.fish` wrapper, abbreviations |
| `antigravity-ide` | antigravity-ide editor | `antigravity-ide.fish` wrapper, abbreviations |
## Container Tools
| Tool | Description | Notes |
|------|-------------|-------|
| `docker` | Container platform | `dops.fish`, abbreviations |
| `lazydocker` | Terminal Docker UI | `ld` function in `config.fish` |
## Command Replacements / Enhancements
| Tool | Description | Notes |
|------|-------------|-------|
| `ov` | Modern pager | Sets `$PAGER`; wraps `less` with hierarchy fallback |
| `prettyping` | Pretty `ping` wrapper | Wraps `ping` |
| `sudo-rs` | Rust rewrite of sudo | Wraps `sudo` |
## Data & System Utilities
| Tool | Description | Notes |
|------|-------------|-------|
| `jq` | JSON processor | Used in `bd-pull.fish` |
| `wl-colorpicker-plasma` | Wayland color picker (KDE) | `get-color.fish` |
## Fish Shell Framework & Plugins
| Tool | Description | Notes |
|------|-------------|-------|
| `fisher` | Fish plugin manager | Manages plugins via `fish_plugins` |
| `catppuccin/fish` | Catppuccin theme for Fish | Listed in `fish_plugins` |