diff --git a/docs/build-manual.py b/docs/build-manual.py index 69c2252..961eb7b 100644 --- a/docs/build-manual.py +++ b/docs/build-manual.py @@ -18,6 +18,37 @@ import manualtools as mt DOCS = Path(__file__).parent MANUAL = DOCS / "manual" +FUNCTIONS = DOCS.parent / "functions" +SLUG_DIR = "reference" + + +def _is_function_page(path: Path, root: Path) -> bool: + """True for a Section 5 category stub (not its index).""" + rel = path.relative_to(root) + return bool(rel.parts) and rel.parts[0].endswith("-functions") and rel.name != "index.md" + + +def _entry_slug(title: str) -> str: + """The site's page slug for an entry heading.""" + return re.sub(r"[^\w-]+", "-", title.strip().lower()).strip("-") + + +def _entry_link(name: str, functions: dict) -> str: + """Link a dependency name to its entry page; plain code span if unknown.""" + fn = functions.get(name) + if not fn: + return f"`{name}`" + category = re.sub(r"^\d+-", "", fn["CATEGORY"][0]) + return f"[`{name}`](/{SLUG_DIR}/{category}/{_entry_slug(name)}/)" + + +def _with_entries(body: str, path: Path, entries: dict) -> str: + """Append this category's generated `## name` entries to its stub body.""" + generated = entries.get(path.stem, []) + if not generated: + return body + blocks = [f"## {name}\n\n{entry}" for name, entry in generated] + return "\n\n".join(([body] if body.strip() else []) + blocks) def build_concat(root: Path) -> str: @@ -32,6 +63,7 @@ def build_concat(root: Path) -> str: present, its contents are re-emitted byte-for-byte as the leading `---`-fenced block, ahead of every heading. """ + entries = build_entries(mt.parse_functions(FUNCTIONS)) chunks: list[str] = [] pandoc_path = root / "_pandoc.yml" if pandoc_path.exists(): @@ -43,6 +75,8 @@ def build_concat(root: Path) -> str: continue heading = fm.get("manTitle") or fm.get("title", path.stem) chunks.append("#" * (depth + 1) + " " + heading) + if _is_function_page(path, root): + body = _with_entries(body, path, entries) if body: chunks.append(mt.shift_headings(body, depth)) return "\n\n".join(chunks) + "\n" @@ -73,19 +107,46 @@ def _jsx_attr_escape(value: str) -> str: def _first_sentence(body: str) -> str: """Extract a one-line description from the start of an entry body. - `Synopsis:` lines are skipped: they restate the calling convention, + The `Synopsis:` block is skipped whole — label line plus its + deeper-indented continuation lines. It restates the calling convention, which the card already shows as its title, so using one as the card description wastes the line. + + Source prose is hard-wrapped, so the leading paragraph is unwrapped + before the sentence match — otherwise a card truncates at the first + line break, mid-clause. """ - for line in body.split("\n"): - line = line.strip() - if not line or line.startswith(("#", "```", "|", "-", "*", ">")): + para: list[str] = [] + in_fence = False + syn_indent: int | None = None + for raw in body.split("\n"): + line = raw.strip() + indent = len(raw) - len(raw.lstrip()) + if syn_indent is not None: + if line and indent <= syn_indent: + syn_indent = None + else: + continue + if line.startswith("```"): + in_fence = not in_fence + if para: + break + continue + if in_fence: + continue + if not line or line.startswith(("#", "|", "-", "*", ">")): + if para: + break continue if line.startswith("Synopsis:"): + syn_indent = indent continue - m = SENTENCE_RE.match(line) - return (m.group(1) if m else line)[:160] - return "" + para.append(line) + if not para: + return "" + text = " ".join(para) + m = SENTENCE_RE.match(text) + return (m.group(1) if m else text)[:160] # Commands common enough in this manual that a block whose every line starts @@ -222,8 +283,12 @@ def _prettify_block(block: list[str], entry_name: str | None) -> str: out: list[str] = [] if lines and lines[0].startswith(SYNOPSIS_PREFIX): - synopsis = lines.pop(0)[len(SYNOPSIS_PREFIX) :].strip() - out.append(f"```fish\n{synopsis}\n```") + synopsis = [lines.pop(0)[len(SYNOPSIS_PREFIX) :].strip()] + # A multi-line synopsis is authored aligned under the first line; + # keep the whole thing in one fence rather than orphaning the rest. + while lines and lines[0].startswith(" "): + synopsis.append(lines.pop(0).strip()) + out.append("```fish\n" + "\n".join(synopsis) + "\n```") para: list[str] = [] for line in lines + [""]: @@ -268,6 +333,76 @@ def prettify(body: str, entry_name: str | None = None) -> str: return "\n".join(out) +ENTRY_HEADS = {"ARGUMENTS": "Arguments:", "RETURNS": "Returns:", "NOTES": "Notes:"} + + +def render_entry(fn: dict[str, list[str]], used_by: list[str], link=None) -> str: + """Render one parsed function header as a manual entry body. + + Emits the same man-page shape Section 5 was authored in — one 4-space + indented block opening with `Synopsis:` — so `prettify` keeps handling it + for the site and pandoc keeps handling it for the man page, with no + special case on either side. + + `link` maps a function name to its markdown link, or is None for the man + page, where a URL in the middle of a sentence is noise. + """ + out: list[str] = [] + syn = fn.get("SYNOPSIS", []) + if syn: + pad = " " * len(SYNOPSIS_PREFIX + " ") + out.append(f"{SYNOPSIS_PREFIX} {syn[0]}") + out += [pad + line for line in syn[1:]] + out.append("") + for line in fn.get("DESCRIPTION", []): + out.append(line) + for label, head in ENTRY_HEADS.items(): + body = fn.get(label) + if not body: + continue + out += ["", head] + [" " + line for line in body] + if fn.get("EXAMPLE"): + out += [""] + fn["EXAMPLE"] + + block = "\n".join((INDENT + line).rstrip() for line in out) + + def names(raw: list[str]) -> list[str]: + return [n for n in re.split(r"[,\s]+", " ".join(raw)) if n] + + refs = [] + for label, values in ( + ("Dependencies", names(fn.get("DEPENDENCIES", []))), + ("Used by", sorted(used_by)), + ): + if values: + rendered = ", ".join(link(v) if link else f"`{v}`" for v in values) + refs.append(f"**{label}:** {rendered}") + if refs: + block += "\n\n" + "\n\n".join(refs) + return block + + +def build_entries(functions: dict[str, dict], link=None) -> dict[str, list[tuple[str, str]]]: + """Group rendered entries by category stem, ordered by function name. + + The `Used by` reverse index is computed here in one pass rather than + authored: a bidirectional link maintained by hand drifts the moment one + side is edited. + """ + used_by: dict[str, list[str]] = {} + for name, fn in functions.items(): + for dep in re.split(r"[,\s]+", " ".join(fn.get("DEPENDENCIES", []))): + if dep in functions: + used_by.setdefault(dep, []).append(name) + + out: dict[str, list[tuple[str, str]]] = {} + for name in sorted(functions): + fn = functions[name] + body = render_entry(fn, used_by.get(name, []), link) + out.setdefault(fn["CATEGORY"][0], []).append((name, body)) + return out + + def _page_fm(fm: dict) -> dict: """Strip pipeline-only keys from frontmatter destined for the site.""" return {k: v for k, v in fm.items() if k not in PIPELINE_KEYS} @@ -315,6 +450,9 @@ def build_site(root: Path, out: Path) -> list[dict]: shutil.rmtree(out) out.mkdir(parents=True) + functions = mt.parse_functions(FUNCTIONS) + entries = build_entries(functions, link=lambda n: _entry_link(n, functions)) + sidebar: list[dict] = [] functions_group: dict = {} for path, _depth in mt.walk(root): @@ -341,7 +479,7 @@ def build_site(root: Path, out: Path) -> list[dict]: # upload. The pages build fine and never arrive — every entry 404s in # production while working locally. test_site_avoids_reserved_dir # guards this. - slug_dir = "reference" + slug_dir = SLUG_DIR if rel.name == "index.md": target = out / slug_dir / "index.md" target.parent.mkdir(parents=True, exist_ok=True) @@ -360,12 +498,12 @@ def build_site(root: Path, out: Path) -> list[dict]: category = re.sub(r"^\d+-", "", rel.stem) cat_dir = out / slug_dir / category cat_dir.mkdir(parents=True, exist_ok=True) - intro, entries = _split_entries(body) + intro, page_entries = _split_entries(_with_entries(body, path, entries)) cards = [] links = [] - for title, entry_body in entries: - entry_slug = re.sub(r"[^\w-]+", "-", title.strip().lower()).strip("-") + for title, entry_body in page_entries: + entry_slug = _entry_slug(title) desc = _first_sentence(entry_body) entry_fm = {"title": title} if desc: diff --git a/docs/fish-config.md b/docs/fish-config.md index abf355c..dfd2bc2 100644 --- a/docs/fish-config.md +++ b/docs/fish-config.md @@ -527,8 +527,14 @@ Add -i (interactive confirmation) to destructive commands: ### cat Synopsis: cat [args...] - Wraps bat for files with syntax highlighting and line numbers. - Passes directories to ls. Falls back to /usr/bin/cat. + + Enhanced cat replacement. Wraps bat for files, giving syntax highlighting + and line numbers; passes directories to ls; falls back to raw cat for + ANSI-colored log files, and finally to /usr/bin/cat if bat is not + installed. + + Arguments: + args... Files or directories to display cat README.md cat ~/projects/myapp @@ -536,19 +542,30 @@ Add -i (interactive confirmation) to destructive commands: ### copy Synopsis: copy - Wraps cp, stripping trailing slashes from source directories to - prevent unintended nesting inside the destination. + Wrapper for cp that strips trailing slashes from source directories, + preventing unwanted nested copies when the destination already exists. + + Arguments: + source Source file or directory + dest Destination path + + copy ./mydir/ ~/backup copy ./mydir/ ~/backup # copies mydir INTO backup, not backup/mydir/ ### du Synopsis: du [--disk|--dir|--dua] [args...] - Smart disk-usage dispatcher: - --disk force duf (disk-level free/used overview) - --dir force dust (per-directory tree breakdown) - --dua force dua (fast space analyzer) - Without flags, routes to the most appropriate tool by context. + + Smart disk-usage dispatcher. Without flags, routes to the most appropriate + tool by context; explicit flags force one. Falls back to system du when the + preferred tool is not installed. + + Arguments: + --disk Force duf (disk-level free/used overview) + --dir Force dust (per-directory tree breakdown) + --dua Force dua (fast interactive space analyzer) + args... Files/directories or flags forwarded to the selected tool du ~/Downloads du --disk @@ -556,156 +573,282 @@ Add -i (interactive confirmation) to destructive commands: ### dusize Synopsis: dusize [dir] - Human-readable disk usage for a directory via du -sh. Defaults to cwd. + Shows a human-readable disk usage summary using du -sh. Defaults to the + current directory if no argument is given. + + Arguments: + dir Directory to summarize (defaults to current directory) + + dusize ~/Downloads dusize ~/Videos ### lD Synopsis: lD [args...] - Lists directories only in long format with icons. Uses eza, falls back - to lsd, then system ls. + + Lists only directories in long format with icons and hyperlinks. Uses eza, + falls back to lsd, then to system ls. + + Arguments: + args... Arguments forwarded to the listing command lD ~/projects ### ls Synopsis: ls [args...] - Lists files in long format with icons and hyperlinks. Uses eza, falls - back to lsd, then system ls. + Lists all files in long format with icons and hyperlinks. Uses eza, + falls back to lsd, then to system ls. + + Arguments: + args... Arguments forwarded to the listing command + + ls ~/projects ls ls -a ~/projects ### lsr Synopsis: lsr [args...] - Lists files sorted by modification time, oldest first. Uses eza. + + Lists files sorted by modification time in reverse (oldest first), one + per line with icons. Uses eza, falls back to lsd, then to system ls. + + Arguments: + args... Arguments forwarded to the listing command + + lsr ~/projects ### lss Synopsis: lss [args...] - Lists files sorted by size with gradient color scaling. Uses eza. + + Lists all files sorted by size in long format with gradient color scaling. + Uses eza, falls back to lsd, then to system ls. + + Arguments: + args... Arguments forwarded to the listing command + + lss ~/downloads ### lstree Synopsis: lstree [args...] - Full recursive tree view with icons. Uses eza. + + Displays a full recursive tree of the current directory with icons. + Uses eza, falls back to lsd, then to system ls -R. + + Arguments: + args... Arguments forwarded to the listing command lstree ~/projects/myapp ### lt Synopsis: lt [args...] - Tree view limited to depth 2 with icons. Uses eza. + + Displays a directory tree limited to depth 2 with icons. Uses eza, + falls back to lsd, then to system ls -R. + + Arguments: + args... Arguments forwarded to the listing command lt ~/projects ### ltr Synopsis: ltr [args...] - Lists files sorted by modification time, oldest first, long format with - age-based gradient scaling. Uses eza. + + Lists all files sorted by modification time in reverse (oldest first) in + long format with age-based gradient color scaling. Uses eza, falls back + to lsd, then to system ls. + + Arguments: + args... Arguments forwarded to the listing command + + ltr ~/projects ### lx Synopsis: lx [args...] - Lists files sorted by extension, long format. Uses eza. + + Lists all files sorted by file extension in long format with icons. Uses + eza, falls back to lsd, then to system ls -lX. + + Arguments: + args... Arguments forwarded to the listing command + + lx ~/projects + +### mkcd + + Synopsis: mkcd [-s | --silent] + + Creates a directory (including any missing parent directories) and + immediately changes into it. Prints a tree of created directories by + default, or suppresses output with -s. Delegates creation to + _fish_mkdir_p. + + Arguments: + -h, --help Show usage help + -s, --silent Suppress directory creation output + Directory to create and enter + + Returns: + 0 Directory created (or already existed) and entered successfully + 1 Directory creation or cd failed + + mkcd ~/projects/myapp + mkcd ~/projects/newapp/src ### mkdir Synopsis: mkdir [args...] - Interactive mkdir that prints a tree of created directories. - Falls back to mkdir -p silently. + + Interactive wrapper around mkdir that calls _fish_mkdir_p for each + directory argument to display created path components. Falls back to + command mkdir -p when flags (e.g. -m 755) are present, and to plain + command mkdir in non-interactive contexts. + + Arguments: + args... Directories to create, or flags passed through to command mkdir mkdir ~/projects/myapp/src -### mkcd - - Synopsis: mkcd [-s] - Creates a directory (including parents) and cd into it. Prints a tree - of created dirs by default; -s/--silent suppresses output. - - mkcd ~/projects/newapp/src - ### poke Synopsis: poke [file...] - Creates files via touch, automatically creating any missing parent - directories first. + + Creates files using touch, automatically creating any missing parent + directories via _fish_mkdir_p with tree output. + + Arguments: + file One or more file paths to create + + Returns: + 0 Files created + 1 No file argument provided poke ~/projects/new/src/main.fish -### rm - - Synopsis: rm [-e [opts] | -S | args...] - Safe rm wrapper routing to trash: - - (no args) List current trash contents - -e/--empty Empty the trash (pass options to trash-empty) - -S/--secure Permanently delete via rm -rf + fstrim (irreversible) - -r/-R/--recursive Move to trash - Move to trash (safe delete) - - Falls back to /usr/bin/rm when trash is unavailable. - - rm file.txt # moves to trash - rm -e # empty trash - rm -S sensitive.pem # permanent delete - ### rg Synopsis: rg [args...] - In Kitty, wraps ripgrep with --hyperlink-format=kitty so search - results are clickable file links in the terminal. Falls back to - system rg in any other terminal. All other arguments pass through - unchanged. + Wraps ripgrep with --hyperlink-format=kitty when running inside Kitty + terminal, enabling clickable file links in search results. Falls back + to plain rg on other terminals. + + Arguments: + args... Arguments forwarded to ripgrep + + rg "TODO" src/ rg "fish_greeting" ~/.config/fish/ rg -l "TODO" ~/projects/myapp +### rm + + Synopsis: rm [-e [options] | -S | args...] + + Enhanced rm that routes deletions through trash when safe. With no + arguments, lists current trash contents. -e/--empty empties the trash + (with optional trash-empty sub-arguments). -S/--secure permanently + deletes via rm -rf and triggers fstrim. Plain paths and -r/-R are sent + to trash put; any other flags fall back to system rm. + + Opinionated component (C1): when disabled via __fish_config_op_aliases + (or the __fish_config_opinionated master), behaves exactly like bare + command rm — no wrapper, no trash, no trapping. + + Arguments: + (none) List current trash contents + -e, --empty [opts] Empty the trash; opts forwarded to trash empty + -S, --secure Permanently delete targets and run fstrim (irreversible) + -r, -R, --recursive Forwarded to trash put alongside path arguments + args... Files or paths to trash or remove + + Returns: + 0 Operation succeeded + 1 trash put failed or file not found + + Notes: + Falls back to /usr/bin/rm when trash is unavailable. + + rm file.txt + rm -e + rm -S sensitive_key.pem + ### scrub Synopsis: scrub [-a] [-d] [-h] - Recursively removes OS metadata, editor artifacts, compiler output, - and dev caches using fd. - -a/--aggressive Also removes node_modules, logs, .cache, IDE dirs, - AI session artifacts - -d/--dry-run Print what would be removed without deleting + Recursively finds and removes OS metadata, editor artifacts, compiler + garbage, and dev caches from the current directory using fd. Routes + deletions through the custom rm function, trashy, trash-cli, or system + rm -rf in that priority order. Aggressive mode adds node_modules, logs, + IDE directories, and AI tool artifacts. + + Arguments: + -a, --aggressive Also purge node_modules, *.log, .cache, .idea, AI artifacts + -d, --dry-run Show targets without deleting + -h, --help Show usage help + + Returns: + 0 Sweep completed (or dry run shown) + 1 fd not found, or unknown argument provided scrub scrub -a scrub -d ---- - ## 5.2 Navigation ### cdi Synopsis: cdi [query] - Interactive directory picker combining zoxide frecency with fzf. - Equivalent to zi. + + Alias for zi — opens zoxide's interactive directory picker for jumping to + frequently-visited directories using fzf. + + Arguments: + query Optional search term to pre-filter the directory list cdi myproject ### clone Synopsis: clone [args...] - Clone a git repository into a new Kitty window. Kitty-only. + + Alias for clone-in-kitty that clones a repository into a new Kitty terminal + window. Only works inside the Kitty terminal. + + Arguments: + args... Arguments forwarded to clone-in-kitty (typically a repo URL) + + Returns: + 0 Repository cloned + 1 Not running inside Kitty terminal clone https://github.com/user/repo.git ### clonet Synopsis: clonet [args...] - Clone a git repository into a new Kitty tab. Kitty-only. + + Alias for clone-in-kitty --type=tab that clones a repository into a new + Kitty terminal tab. Only works inside the Kitty terminal. + + Arguments: + args... Arguments forwarded to clone-in-kitty (typically a repo URL) + + Returns: + 0 Repository cloned + 1 Not running inside Kitty terminal clonet https://github.com/user/repo.git ---- - ## 5.3 Editors and Viewers ### edit @@ -714,8 +857,8 @@ Add -i (interactive confirmation) to destructive commands: Opens files in a text editor, choosing a terminal or GUI editor and resolving a rich chain of fallbacks. With no --visual/--terminal flag the - mode is auto-detected: interactive terminals use the terminal editor - ($EDITOR), while detached invocations (e.g. desktop shortcuts) use the GUI + mode is auto-detected: interactive terminals get the terminal editor + ($EDITOR), while detached invocations (desktop shortcuts) get the GUI editor ($VISUAL). Clipboard contents and literal strings can be opened as throwaway temp files. Editor output is suppressed unless --verbose. @@ -723,19 +866,24 @@ Add -i (interactive confirmation) to destructive commands: gnome-text-editor → gedit Terminal fallback chain: nvim → vim → micro → nano → vi - Options: + Arguments: + FILE... Files to open (any number) -V, --visual Force the GUI editor ($VISUAL or fallbacks) -t, --terminal Force the terminal editor ($EDITOR or fallbacks) -e, --editor=X Use a specific editor binary X -c, --clipboard Open the clipboard contents (as a temp file) -x, --text=STR Open STR as the contents of a new temp file - -n, --new Force a new window/instance (best-effort) - -v, --verbose Print the launch command and editor output + -n, --new Force a new window/instance (best-effort, where supported) + -v, --verbose Print the launch command and let editor output through -s, --silent Suppress all output, including the editor's -h, --help Show this help message - edit ~/.config/fish/config.fish - edit --visual notes.txt + Returns: + 0 Editor launched successfully + 1 Conflicting flags, no editor found, or clipboard read failed + + edit notes.txt + edit --visual ~/.config/fish/config.fish edit --terminal --new todo.md edit --editor=code --clipboard edit --text="hello world" @@ -743,8 +891,18 @@ Add -i (interactive confirmation) to destructive commands: ### fc Synopsis: fc [command_prefix] - Edit the last shell command (or one matching a prefix) in $EDITOR, - then execute the result. Bash-style fc behaviour. + + Edits the last shell command -- or the most recent one matching a + prefix -- in $EDITOR, then executes the result. Bash-style fc + behaviour. Falls back to vi when $EDITOR is unset, and aborts without + executing if the buffer is left empty. + + Arguments: + command_prefix Search history for the newest command matching this + + Returns: + The edited command's exit status, or a message when history lookup + found nothing. fc fc git @@ -752,25 +910,39 @@ Add -i (interactive confirmation) to destructive commands: ### less Synopsis: less [args...] - Pager wrapper with fallback chain: $PAGER -> ov -> less -> more -> cat. + + Pager wrapper that tries $PAGER, then ov, then less, then more, then cat + as fallbacks in that order. + + Arguments: + args... Files or options forwarded to the pager less /var/log/syslog ### rawfish Synopsis: rawfish [args...] - Launches Fish with NO_TMUX=1, bypassing any tmux auto-attach logic. - Useful when you need a clean shell without session management. + + Launches a Fish shell with NO_TMUX=1 set, bypassing any tmux + auto-attach or session management hooks. + + Arguments: + args... Arguments forwarded to fish + + rawfish ### view Synopsis: view [args...] - Opens files in nvim read-only mode (-R). Falls back to less. + + Opens files in nvim read-only mode (-R). Falls back to less if nvim + is not installed. + + Arguments: + args... Files or options forwarded to nvim -R or less view /etc/fstab ---- - ## 5.4 Git and Version Control ### auto-pull @@ -780,18 +952,27 @@ Add -i (interactive confirmation) to destructive commands: auto-pull remove auto-pull status - Manages the registry of repositories that are background fast-forwarded - when you enter them (see "Auto-pull fast-forward" under the C2 component - reference). The fish-config repo is always covered as a baseline. The - registry is machine-local at `$__fish_user_dots_path/auto-pull.list` (defaults - to `~/.config/.user-dots/fish/auto-pull.list`), one absolute path per line, - and is never committed. Registry management works - even when C2 auto-execution is disabled; only the background sync is gated. + Manages the auto-pull registry: the list of repositories that are + background fast-forwarded when you enter them (see conf.d/auto-pull.fish + and _auto_pull_sync). The fish-config repo is always covered as a baseline + and does not need to be added. The registry is a plain text file, one + absolute git-toplevel path per line, stored machine-locally at + $__fish_user_dots_path/auto-pull.list (defaults to + ~/.config/.user-dots/fish/auto-pull.list) and never committed. - list Show registered repos (default) - add [PATH] Register PATH's git root (default: current repo) + Registry management works regardless of the C2 auto-execution guard; only + the background sync itself is gated by __fish_config_op_autoexec. + + Arguments: + list Show registered repos (default when no subcommand given) + add [PATH] Register PATH's git root; defaults to the current repo remove Unregister by basename or exact path - status Show enabled/disabled state, repo count, list path + status Show enabled/disabled state, repo count, and registry path + -h, --help Show this help message + + Returns: + 0 Subcommand succeeded + 1 Bad usage, target is not a git repo, or target not registered cd ~/src/qmk_firmware; and auto-pull add auto-pull add ~/work/api @@ -801,21 +982,40 @@ Add -i (interactive confirmation) to destructive commands: ### branch Synopsis: branch - Switches to a local branch, or creates it if it does not exist. + + Switches to a local git branch, creating it if it does not already + exist. Extra arguments are forwarded to git checkout. + + Arguments: + branch_name Branch to switch to or create + + Returns: + 0 Branch checked out or created + 1 Not inside a git work tree branch feature/new-ui ### gi Synopsis: gi [-h] [-b] [-p] [-s] [-l] [targets...] - Generates .gitignore content from the gitignore.io API with MD5-based - deduplication (patterns already present are not re-appended). - -b/--boilerplate Append generic boilerplate first - -p/--prompt Prompt interactively for targets - -s/--stdout Print to stdout instead of appending to .gitignore - -l/--list List all available targets - targets Comma-separated or space-separated target names + Generates .gitignore content by querying the gitignore.io API. Appends + results to the repository's .gitignore with MD5-based deduplication — + patterns already present are not re-appended — or prints to stdout with + -s. Supports generic boilerplate and interactive prompt modes. + + Arguments: + -h, --help Show help message + -d, --description Show the function description + -l, --list List all supported targets from the API + -b, --boilerplate Append boilerplate from $GITIGNORE_BOILERPLATE + -p, --prompt Prompt for patterns to append + -s, --stdout Print API output to stdout instead of .gitignore + targets Comma- or space-separated list of language/tool names + + Returns: + 0 Patterns appended or printed + 1 Not in a git repository or API fetch failed gi python,venv gi -b -p @@ -823,102 +1023,164 @@ Add -i (interactive confirmation) to destructive commands: ### git-clean - Synopsis: git-clean [-f] - Fetches and prunes the remote, fast-forwards the current branch, then - deletes local branches whose remote tracking branch has been deleted. - Switches to main/master automatically if the current branch is orphaned. + Synopsis: git-clean [-h] [-f] - -f/--force Force-delete unmerged branches too + Fetches and prunes the remote, fast-forwards the current branch, and + deletes local branches whose tracking remote has been deleted. Switches to + main/master automatically if the current branch is orphaned. + + Arguments: + -h, --help Show help message + -f, --force Force-delete unmerged orphaned branches (git branch -D) + + Returns: + 0 Cleanup complete + 1 Argument parsing failed - git-clean git-clean --force - -### gitup - - Synopsis: gitup [args...] - Fetches updates from the remote and shows git status. Extra args are - forwarded to git fetch. - - gitup - gitup --all + git-clean ### gitui Synopsis: gitui [args...] - Launches gitui with the Catppuccin Frappe theme pre-applied. + + Launches gitui with the Catppuccin Frappe theme (frappe.ron), passing any + additional arguments through to the gitui command. + + Arguments: + args... Arguments forwarded to the gitui command + + gitui + +### gitup + + Synopsis: gitup [args...] + + Fetches updates from the remote and shows git status. Extra arguments + are forwarded to git fetch. + + Arguments: + args... Forwarded verbatim to git fetch + + Returns: + 0 Fetch and status succeeded + 1 Not inside a git work tree + + gitup + gitup --all ### hist Synopsis: hist - Searches shell history with fzf, inserts the selection into the command - line, and copies it to the clipboard via wl-copy. ---- + Searches fish history interactively using fzf, inserts the selected command + into the command line, and copies it to the clipboard via wl-copy. + + hist ## 5.5 Package Management +### cleanup + + Synopsis: cleanup + + Identifies and removes Arch Linux orphan packages using pacman. Logs + package names and versions to ~/.removed_orphans before removal. + + cleanup + +### parur + + Synopsis: parur + + Presents an fzf picker of all installed packages (via pacman -Qqs) with + pacman -Qi previews, then removes the selected packages using paru or yay. + Arch Linux only. + + Returns: + 0 Packages removed or none selected + 1 No AUR helper (paru or yay) found + + parur + ### pkg Synopsis: pkg [-h] [-i|-u] [package...] - Installs or removes packages using the detected system package manager. - Supports: paru, yay, pacman, apt, dnf, zypper, yum, brew, pkg. - (no flag) Auto mode: installs missing packages, removes installed ones - -i/--install Force install - -u/--uninstall Force uninstall + Installs or removes packages using the system's available package manager. + Supports paru, yay, pacman, apt, dnf, zypper, yum, brew, and pkg. + In auto mode (no flag), detects whether each package is installed and + toggles it — installing if absent, removing if present. - pkg firefox # auto: install if missing, remove if present - pkg -i ripgrep fd # force install - pkg -u cowsay # force uninstall + The package-installed check uses the correct query for each manager: - The package-installed check uses the correct query for each PM: pacman/paru/yay pacman -Qi apt dpkg -s dnf/zypper/yum rpm -q brew brew list pkg pkg info + Arguments: + -h, --help Show help message + -i, --install Force install mode + -u, --uninstall Force uninstall mode + package One or more package names to install or remove + + Returns: + 0 Operation completed + 1 No supported package manager found, unknown flag, or package operation failed + + pkg firefox + pkg -i ripgrep fd-find + pkg -u cowsay + ### search Synopsis: search [args...] - Interactive AUR package search and install via paru or yay. - Arch Linux only. + + Delegates to paru or yay for interactive AUR package search and + installation. Falls back to yay if paru is not installed. Arch Linux only. + + Arguments: + args... Arguments forwarded to paru or yay + + Returns: + 0 AUR helper ran successfully + 1 No AUR helper (paru or yay) found search neovim ### upgrade Synopsis: upgrade - Full system upgrade via paru -Syu --noconfirm or yay -Syu --noconfirm. - Arch Linux only. -### cleanup + Runs a full system upgrade via paru or yay with --noconfirm. Falls + back to yay if paru is not installed. Arch Linux only. - Synopsis: cleanup - Lists and removes orphan packages via pacman, logging their names to - ~/.removed_orphans. Arch Linux only. + Returns: + 0 Upgrade completed successfully + 1 No AUR helper (paru or yay) found -### parur - - Synopsis: parur - Opens an fzf picker of all installed packages (with pacman -Qi previews), - then removes the selected packages via paru or yay. Arch Linux only. - - parur - ---- + upgrade ## 5.6 Dependency Management +### check_fish_deps + + Synopsis: check_fish_deps + + Backwards-compatibility wrapper that delegates to fish-deps status to + report which fish shell dependencies are installed or missing. + + check_fish_deps + ### fish-deps Synopsis: fish-deps [status|install|update|sync] - Unified command for managing all tools this configuration depends on. - status (default) Show installed/missing status grouped by tier - install Interactively install each missing dependency - update Update all installed dependencies - sync Install missing deps, then update all + Unified command for managing all tools this configuration depends on, + dispatching to subcommand handlers. Defaults to status when no subcommand + is given. Install method priority (highest to lowest): 1. git+cargo source build (fish shell itself) @@ -937,93 +1199,172 @@ Add -i (interactive confirmation) to destructive commands: btop, dust, duf, prettyping, ov, ripgrep, lazygit, lazydocker, trash, kitty, wezterm, python3, yt-dlp + Arguments: + status Report installed/missing deps (default) + install Install missing deps interactively + update Update all installed deps + sync Install missing deps, then update all + + Returns: + 0 Subcommand completed + 1 Unknown subcommand + + fish-deps sync fish-deps fish-deps install fish-deps update - fish-deps sync - -### check_fish_deps - - Synopsis: check_fish_deps - Backwards-compatibility alias for `fish-deps status`. - ---- ## 5.7 System and Monitoring -### top - - Synopsis: top [args...] - Launches btop as a modern resource monitor. Falls back to system top. - -### swapstat - - Synopsis: swapstat - Displays a colorized memory report: kernel swappiness, zRAM compression - ratio, zRAM device details, and active swap priorities. - -### sbver - - Synopsis: sbver [--brief] - Verifies Secure Boot signatures on all EFI binaries tracked by sbctl. - Color-codes results: green checkmark (verified), red X (unsigned). - Prints a pass/fail summary. - - --brief Suppress per-file output, show only the summary - - sbver - sbver --brief - -### ports - - Synopsis: ports - Lists active TCP listeners with lsof, showing port/address without - hostname resolution. - -### screensleep - - Synopsis: screensleep - Turns off the display via KDE PowerDevil's "Turn Off Screen" action, - invoked through busctl. - -### lock - - Synopsis: lock - Locks the current desktop session using loginctl lock-session. - -### sudo-toggle - - Synopsis: sudo-toggle - Toggles the sudo NOPASSWD rule on/off via /etc/sudoers.d/nofail-toggle. - Useful for automated tasks that would otherwise require password entry. - ### limine-edit Synopsis: limine-edit - Opens /boot/limine.conf in sudoedit, then automatically re-enrolls the - config hash, runs CachyOS boot hooks, and re-signs Secure Boot files. - Combines the edit and sign steps into a single command. ---- + Opens /boot/limine.conf in sudoedit, then re-enrolls the config hash, + runs CachyOS boot hooks (limine-mkinitcpio), and re-signs all Secure Boot + files tracked by sbctl. Combines the edit and sign steps into a single + command. + + limine-edit + +### lock + + Synopsis: lock + + Locks the current desktop session using loginctl lock-session. + + lock + +### ports + + Synopsis: ports + + Lists all active TCP listeners on the system using lsof, showing + port numbers and addresses without hostname resolution. + + ports + +### sbver + + Synopsis: sbver [--brief] + + Verifies Secure Boot signatures on all EFI binaries tracked by sbctl, + filtering out "invalid PE header" noise. Color-codes each file as + verified (green ✓) or unsigned (red ✗) and prints a final summary + count. + + Arguments: + --brief Suppress per-file output; show only the final summary + + Returns: + 0 All binaries verified (or summary shown) + 1 sbctl is not installed + + sbver + sbver --brief + +### screensleep + + Synopsis: screensleep + + Turns off the display after a 1-second delay by invoking the KDE + PowerDevil "Turn Off Screen" global shortcut via busctl. + + screensleep + +### sudo-toggle + + Synopsis: sudo-toggle + + Toggles the sudo NOPASSWD rule on and off via + /etc/sudoers.d/nofail-toggle. Useful for automated tasks that would + otherwise require a password entry. Clears the sudo credential cache + when re-enabling, so the lockdown takes effect immediately. + + Returns: + 0 Rule toggled + + sudo-toggle + +### swapstat + + Synopsis: swapstat + + Displays a colorized memory report showing kernel swappiness, + zRAM compression ratio, zRAM device details (via zramctl), and + active swap priority (via swapon). + + swapstat + +### top + + Synopsis: top [args...] + + Wraps btop as a modern replacement for top. Falls back to system top + if btop is not installed. + + Arguments: + args... Arguments forwarded to btop or system top + + top ## 5.8 Terminal Management -### tab +### bkg - Synopsis: tab [args...] - Opens a new tab in Kitty (kitty @ launch --type=tab), WezTerm - (wezterm cli spawn), or Konsole. Uses current working directory, - or $cdto if set. + Synopsis: bkg [args...] - tab + Launches a command in the background, fully detached from the terminal + using nohup. All stdout and stderr output is discarded. Simpler than + detach; no --version flag. + + Arguments: + command The command to run detached + args... Additional arguments for the command + + Returns: + 0 Command launched successfully + 1 No command provided + + bkg firefox + +### detach + + Synopsis: detach [-h] [--version] [args...] + + Runs a command in the background using nohup, fully detached from the + terminal with stdout/stderr discarded. The command survives the current + session. + + Arguments: + -h, --help Show help message + --version Show version information + command The command to run detached + args... Additional arguments for the command + + Returns: + 0 Command launched or help/version shown + 1 No command provided or unknown option + + detach rsync -a ./data remote:/backup/ ### split - Synopsis: split [-h|-v] [command...] - Opens a new pane in Kitty or WezTerm, optionally running a command. + Synopsis: split [-h | -v] [command...] - -h/--horizontal (default) Split below - -v/--vertical Split to the right + Opens a new pane split in Kitty or WezTerm, optionally running a + command in it. Defaults to a horizontal (bottom) split. The new pane + inherits the current working directory. + + Arguments: + -h, --horizontal Open a horizontal split (default) + -v, --vertical Open a vertical split + command... Command to run in the new pane; opens a bare fish + shell if omitted + + Returns: + 0 Pane opened successfully + 1 Not running inside Kitty or WezTerm split split -v nvim README.md @@ -1031,107 +1372,173 @@ Add -i (interactive confirmation) to destructive commands: ### spwin Synopsis: spwin [args...] - Spawns a new terminal OS window in Kitty (via spawn-window.sh or - kitty @ launch --type=os-window) or WezTerm (wezterm cli spawn --new-window). -### detach + Spawns a new terminal OS window in Kitty (via spawn-window.sh if + present, otherwise kitty @ launch) or WezTerm (via wezterm cli spawn). - Synopsis: detach [-h] [--version] [args...] - Runs a command fully detached via nohup with stdout/stderr discarded. - The command survives the current session. + Arguments: + args... Arguments forwarded to the spawn command - detach rsync -a ./data remote:/backup/ + Returns: + 0 Window opened successfully + 1 Not running inside Kitty or WezTerm -### bkg - - Synopsis: bkg [args...] - Launches a command in the background via nohup with output discarded. - Simpler than detach; no version flag. - - bkg firefox + spwin ### ssh Synopsis: ssh [args...] - In Kitty, wraps ssh with kitten ssh for better terminal integration - (multiplexing, copy/paste support). Falls back to system ssh elsewhere. + + Wraps ssh with kitten ssh inside Kitty terminal for better terminal + integration (terminfo forwarding, multiplexing, copy/paste support). + Falls back to system ssh on + other terminals. + + Arguments: + args... Arguments forwarded to kitten ssh or system ssh ssh user@host ---- +### tab + + Synopsis: tab [args...] + + Opens a new tab in Kitty, WezTerm, or Konsole using the current + working directory (or $cdto if set). Arguments are forwarded to the + terminal's tab-open command. + + Arguments: + args... Arguments forwarded to the terminal's launch command + + Returns: + 0 Tab opened successfully + 1 No supported terminal found + + tab ## 5.9 Clipboard -### y - - Synopsis: y [text...] - Copies text to the clipboard via wl-copy (Wayland) or xclip (X11). - Reads from stdin if no arguments given. - - y "hello world" - ls | y - cat file.txt | y - ### p Synopsis: p [args...] - Outputs clipboard contents to stdout. + + Outputs clipboard contents to stdout. Uses wl-paste on Wayland, + falls back to xclip on X11. Supports -h/--help for usage info. + + Arguments: + -h, --help Show usage help + args... Arguments forwarded to the clipboard tool + + Returns: + 0 Clipboard contents printed successfully + 1 No supported clipboard tool found p | grep foo p > file.txt ### paste - Alias for p. Identical behaviour. + Synopsis: paste [args...] ---- + Outputs clipboard contents to stdout. Uses wl-paste on Wayland, + falls back to xclip on X11. + + Arguments: + args... Arguments forwarded to the clipboard tool + + Returns: + 0 Clipboard contents printed successfully + 1 No supported clipboard tool found + + paste > file.txt + +### y + + Synopsis: y [text...] + + Copies text to the system clipboard using wl-copy (Wayland) or xclip (X11). + Reads from stdin when no arguments are given. + + Arguments: + text Text to copy; reads from stdin if omitted + + Returns: + 0 Text copied to clipboard + 1 No clipboard provider found + + y "hello world" + ls | y + cat file.txt | y ## 5.10 Network ### gip Synopsis: gip - Fetches and prints both the public IPv4 and IPv6 address via - icanhazip.com. + + Fetches and prints both the public IPv4 and IPv6 addresses using + icanhazip.com. Shows "Not detected" for any address that times out. + + gip ### gip4 Synopsis: gip4 - Fetches and prints the public IPv4 address. + + Fetches and prints the machine's public IPv4 address using icanhazip.com. + + gip4 ### gip6 Synopsis: gip6 - Fetches and prints the public IPv6 address. Returns 1 if IPv6 is - unavailable. + + Fetches and prints the machine's public IPv6 address using icanhazip.com. + Prints an error message if IPv6 is unavailable on the current network. + + Returns: + 0 IPv6 address printed + 1 IPv6 unavailable or not supported on this network + + gip6 ### ping Synopsis: ping [args...] - Wraps prettyping with --nolegend. Pass --legend to show the legend. - Falls back to system ping. + + Wraps prettyping with --nolegend by default for a cleaner display. + Pass --legend to show the legend. Falls back to system ping if + prettyping is not installed. + + Arguments: + --legend Show the prettyping legend (overrides default --nolegend) + args... Arguments forwarded to prettyping or system ping ping google.com + ping --legend google.com ### qr Synopsis: qr [text...] - Generates a UTF-8 QR code from text or stdin. Uses qrencode locally; - falls back to the qrenco.de API. + + Generates a UTF-8 QR code from the given text or from stdin if no + argument is provided. Uses qrencode locally if available, otherwise + falls back to the qrenco.de API via curl. + + Arguments: + text... Text to encode; reads from stdin if omitted qr "https://example.com" - echo "https://example.com" | qr - ---- + echo "hello" | qr ## 5.11 Pager and Logging ### logs - Synopsis: logs [-c ] - Interactively browses terminal log files sorted newest-first using fzf. + Synopsis: logs [-h] [-c ] - -c/--category Filter to: scrollback, paru, or yay + Interactively browses terminal log files (scrollback, paru, yay) sorted + newest-first using fzf. Supports viewing in $PAGER, editing, and deletion. Keybindings inside the fzf browser: Enter Open in $PAGER @@ -1143,122 +1550,223 @@ Add -i (interactive confirmation) to destructive commands: headers. Scrollback logs open in ov with per-command sticky prompt headers based on OSC 133 markers. - logs + Arguments: + -h, --help Show help message + -c, --category cat Filter to one category: scrollback, paru, or yay + + Returns: + 0 File viewed or no file selected + 1 No log files found + logs -c paru + logs logs -c scrollback ### smart_exit - Synopsis: smart_exit [-n] - Closes the shell session. In Kitty, captures the terminal scrollback to - a timestamped log file in $SCROLLBACK_HISTORY_DIR before exiting. - Automatically prunes the oldest logs when the count exceeds + Synopsis: smart_exit [-h] [-n] + + Closes the shell session. In Kitty, captures the terminal scrollback to a + timestamped log file in $SCROLLBACK_HISTORY_DIR before exiting. + Automatically prunes junk and the oldest logs when the count exceeds $SCROLLBACK_HISTORY_MAX_FILES. - -n/--no-log Exit without saving a scrollback log + Arguments: + -h, --help Show help message + -n, --no-log Exit without saving a scrollback log - The exit builtin is wired to smart_exit for interactive sessions. - Typing exit or Ctrl+D behaves identically to smart_exit. + Returns: + 0 Shell session exited + 1 Argument parsing failed + + Notes: + The exit builtin is wired to smart_exit for interactive sessions. Typing + `exit` or Ctrl+D behaves identically to calling smart_exit directly. smart_exit smart_exit --no-log ---- - ## 5.12 AI and Developer Tools -### agy - - Synopsis: agy [args...] - Wrapper for the agy Antigravity AI CLI. Before launching, delegates to - agents-init --agents to ensure AGENTS/ is scaffolded and CLAUDE.md is - symlinked to AGENTS/AGENTS.md in the current project, then forwards all - arguments verbatim to the real agy binary. Command shadow (C1): when - __fish_config_op_aliases (or the master) is disabled, the call is - passed through to the real agy binary unchanged. - - agy chat - agy resume - -### antigravity-ide - - Synopsis: antigravity-ide [args...] - Runs the antigravity-ide editor with warnings filtered. - ### agents-init - Synopsis: agents-init [--agents | --plugins] - Scaffold an AGENTS/ sub-repository for tracking agent specs, plans, specs, - and dev logs. Creates AGENTS/ as a standalone git repo, moves any existing - AGENTS.md into it, and replaces it with a relative symlink (plus - CLAUDE.md -> AGENTS/AGENTS.md so Claude Code picks up the shared agent - instructions). Consolidates plans/ and specs/ directly under AGENTS/ - (merging any legacy docs/plans, docs/superpowers/plans, or old - AGENTS/plugins/ locations into the canonical AGENTS/), creates - AGENTS/devlogs/, and wires docs/superpowers/{plans,specs} symlinks back to - them. Adds managed paths to .gitignore and auto-commits every change inside - the AGENTS/ sub-repo; pulls first when the sub-repo has an upstream. - Fully idempotent: a second run produces no output and no new commits. - Flags: --agents re-runs only the AGENTS.md / symlink step; --plugins - re-runs only the plans/specs/devlogs wiring step. Called automatically by - the claude and agy wrappers on every invocation. + Synopsis: agents-init [-a | --agents] [-p | --plugins] [-v | --verbose] + [-q | --quiet] [-s | --silent] [-h | --help] - Structure versioning: each AGENTS/ repo carries a self-contained version - bumper. AGENTS/.version holds MAJOR.MINOR.PATCH (seeded 1.0.0). Committed - git hooks under AGENTS/.agents-tools/ (wired via core.hooksPath) bump it on - every commit: MINOR (resetting PATCH) when the tracked directory set - changes, PATCH otherwise; MAJOR is manual-only. A prepare-commit-msg hook - appends "(vX.Y.Z)" to the commit subject. Downstream tooling can read - AGENTS/.version - a changed MINOR field signals a structure change. Because - core.hooksPath is a single setting, the local override would otherwise - shadow your global hooks; after bumping the version, each shim chains - (execs) to the global/system core.hooksPath hook of the same name so global - pre-commit / prepare-commit-msg hooks (e.g. ggshield, Git LFS) still run. - The script and hooks are shipped from scripts/agents-tools/ and refreshed - when their version marker is stale. + Scaffolds an AGENTS/ sub-repository inside a project directory. Creates + a self-contained git repo for agent specifications, moves any existing + agent-related files into it, and replaces them with symlinks so the outer + project never tracks agent files directly. + + File layout after setup: + AGENTS/AGENTS.md canonical agent spec (real file) + AGENTS/CLAUDE.md real file (if CLAUDE.md existed separately) + or symlink → AGENTS.md (single-source case) + /AGENTS.md → AGENTS/AGENTS.md + /CLAUDE.md → AGENTS/CLAUDE.md + AGENTS/plans superpowers plans (real dir, .gitkeep) + AGENTS/specs superpowers specs (real dir, .gitkeep) + AGENTS/devlogs agent development logs (real dir, .gitkeep) + AGENTS/.version MAJOR.MINOR.PATCH structure version (seed 1.0.0) + AGENTS/.agents-tools/ committed version-bump script + git hook shims + docs/superpowers/plans → ../../AGENTS/plans (always) + docs/superpowers/specs → ../../AGENTS/specs (always) + docs/plans → ../AGENTS/plans (only if docs/plans existed) + docs/specs → ../AGENTS/specs (only if docs/specs existed) + docs/devlogs → ../AGENTS/devlogs (only if docs/devlogs existed) + + plans/ and specs/ are merged from every legacy location (docs/, + docs/superpowers/, and the old AGENTS/plugins/ layout) into the + canonical AGENTS/; the AGENTS/plugins/ layer is removed. + + Each AGENTS repo carries a self-contained version bumper wired via + core.hooksPath: a pre-commit hook bumps AGENTS/.version on every commit + (MINOR when the tracked directory set changes, PATCH otherwise; MAJOR is + manual-only), and a prepare-commit-msg hook appends "(vX.Y.Z)" to the + commit subject. Each shim then chains (execs) to the global/system + core.hooksPath hook of the same name, so this local override does not + shadow global hooks (e.g. ggshield, Git LFS). The script/hooks are + version-managed from scripts/agents-tools/ and refreshed when their marker + is stale. + + Downstream tooling can read AGENTS/.version directly — a changed MINOR + field signals a structure change. + + With no flags, runs both --agents and --plugins setup; --agents re-runs + only the AGENTS.md / symlink step and --plugins only the plans/specs/ + devlogs wiring step. Managed paths are added to .gitignore. The sub-repo + is pulled first when it has an upstream, and at the end of every + invocation any uncommitted changes inside it are auto-committed so + agent-made edits are captured automatically. Fully idempotent: a second + run produces no output and no new commits. + + Called automatically by the claude and agy wrappers on every invocation. + + Arguments: + -a, --agents Set up AGENTS/ repo + AGENTS.md / CLAUDE.md symlinks only + -p, --plugins Set up AGENTS/ repo + plans/specs/devlogs dirs + docs/ symlinks only + -v, --verbose Print all per-step output (default) + -q, --quiet Print one summary line only if changes were made + -s, --silent Suppress all output; errors only (standard UNIX convention) + -h, --help Show this help message and exit + + Returns: + 0 Setup completed successfully + 1 Fatal error (git init failed, move failed, etc.) agents-init agents-init --agents agents-init --plugins + agents-init --quiet + +**Used by:** `agy`, `claude` + +### agy + + Synopsis: agy [ARGS...] + + Wrapper for the agy Antigravity AI CLI that ensures the AGENTS/ + sub-repository is initialized and any agent-made changes are committed + before launch. Delegates all scaffold and commit logic to agents-init + --quiet (full setup), which ensures AGENTS/ is scaffolded and CLAUDE.md + is symlinked to AGENTS/AGENTS.md in the current project. All arguments + are forwarded verbatim to the real agy binary. + + Opinionated component (C1): when disabled via __fish_config_op_aliases + (or the __fish_config_opinionated master), the command is passed through + to the real agy binary unchanged. + + Arguments: + ARGS Any arguments forwarded verbatim to the underlying agy binary + + Returns: + Exit status of the underlying agy binary + + agy + agy chat + agy resume + +**Dependencies:** `agents-init` + +### antigravity-ide + + Synopsis: antigravity-ide [args...] + + Wrapper for the antigravity-ide command that filters a known noisy warning + about an unrecognized 'app' option from stderr. + + Arguments: + args... Arguments passed through to the antigravity-ide command + + antigravity-ide ### claude - Synopsis: claude [args...] - Wrapper for the claude CLI. Before launching, delegates to agents-init - --agents to ensure AGENTS/ is scaffolded and CLAUDE.md is symlinked to - AGENTS/AGENTS.md in the current project, then forwards all arguments - verbatim to the real claude binary. Command shadow (C1): when - __fish_config_op_aliases (or the master) is disabled, the call is - passed through to the real claude binary unchanged. + Synopsis: claude [ARGS...] + + Wrapper for the claude CLI that ensures the AGENTS/ sub-repository is + initialized and any agent-made changes are committed before launch. + Delegates all scaffold and commit logic to agents-init --quiet (full + setup), which ensures AGENTS/ is scaffolded and CLAUDE.md is symlinked + to AGENTS/AGENTS.md in the current project. + All arguments are forwarded verbatim to the real claude binary. + + Opinionated component (C1): when disabled via __fish_config_op_aliases + (or the __fish_config_opinionated master), the command is passed through + to the real claude binary unchanged. + + Arguments: + ARGS Any arguments forwarded verbatim to the underlying claude binary + + Returns: + Exit status of the underlying claude binary claude claude --resume + claude "Explain the recent changes" + +**Dependencies:** `agents-init` ### claude-docs Synopsis: claude-docs + Invokes Claude Code to analyze recent repository changes and update - README.md, ensuring all documented features and examples are accurate. + README.md, ensuring all features and examples are accurate and pruning + obsolete content. + + claude-docs ### claude-pr Synopsis: claude-pr - Invokes Claude Code to run the full PR workflow: create branch, - conventional commit, verification, push, and open a PR with a manual - verification checklist. + + Invokes Claude Code to perform a full PR workflow: create a kebab-case + branch, write a Conventional Commit, run verification, push, and open a + pull request with a manual verification checklist. + + claude-pr ### qc Synopsis: qc [prompt...] + Quick-chat wrapper around the aichat LLM CLI that defaults to the "cli" - role - a system prompt tuned for concise, terminal-friendly output. On - first use it installs the bundled role by symlinking - scripts/cli-agent.md to $XDG_CONFIG_HOME/aichat/roles/cli.md (creating - the directory if needed). Inherits every aichat flag and tab completion - (--wraps aichat); passing --role/-r overrides the default role, so qc - forwards to aichat unchanged. The function is only defined when aichat - is installed. Run qc --help for aichat's full flag reference with the - command name rewritten to qc. + role — a system prompt tuned for concise, terminal-friendly output. + Resolves the aichat config directory (honoring $XDG_CONFIG_HOME), creates + it if missing, and on first use installs the bundled role by symlinking + scripts/cli-agent.md to $XDG_CONFIG_HOME/aichat/roles/cli.md. Inherits + every aichat flag and tab completion (--wraps aichat); passing --role/-r + overrides the default role, so qc forwards to aichat unchanged. The + function is only defined when aichat is installed. Run `qc --help` for + aichat's full flag reference with the command name rewritten to qc. + + Arguments: + prompt... Prompt forwarded to aichat + -h, --help Show usage help + + Returns: + aichat's exit status. qc "how do I list open ports on linux?" qc -m ollama:llama3 "explain this error" @@ -1267,202 +1775,227 @@ Add -i (interactive confirmation) to destructive commands: ### superpowers Synopsis: superpowers [on|off] [-g] - Enables or disables the Superpowers plugin for Antigravity and Claude - Code at workspace/project scope (default) or user scope (-g/--global). + + Enables or disables the superpowers plugin for both antigravity-cli + (workspace scope) and Claude (project scope). Use -g/--global to apply + at the user scope instead of workspace/project. + + Arguments: + on Enable superpowers for both tools + off Disable superpowers for both tools + -g, --global Apply at user/global scope instead of workspace/project + -h, --help Show usage help + + Returns: + 0 Mode applied successfully + 1 No on/off mode specified superpowers on superpowers off -g ---- - ## 5.13 Media and Utilities ### dng2avif - Synopsis: dng2avif [-i ] [-o ] [-q ] [-s ] [input.dng] - Converts a DNG raw image to a 10-bit HDR AVIF using an ImageMagick, - ffmpeg, avifenc pipeline with metadata sync via exiftool. + Synopsis: dng2avif [-h] [-i ] [-o ] [-q ] [-s ] [input.dng] - -i/--input Input file (or positional arg) - -o/--output Output file (default: same name, .avif extension) - -q/--quality Quality 0-100 (default 92) - -s/--speed Encoding speed 0-10 (default 3) + Converts a DNG raw image to a 10-bit HDR AVIF using a three-step pipeline: + develop with ImageMagick, encode with ffmpeg+avifenc, sync metadata with + exiftool. Requires magick, ffmpeg, avifenc, and exiftool. + + Arguments: + -i, --input FILE Input DNG file + -o, --output FILE Output AVIF file (defaults to input basename) + -q, --quality N Encoding quality 0-100 (default: 92) + -s, --speed N Encoder speed 0-10 (default: 3, 0 = slowest) + -h, --help Show help message + + Returns: + 0 Conversion complete + 1 File not found, missing dependency, or encode step failed dng2avif photo.dng dng2avif -q 85 -s 5 -i shot.dng -o out.avif -### steam-dl - - Synopsis: steam-dl - Launches Steam under systemd-inhibit, preventing the system from going - idle or sleeping while a download is in progress. - ### spark Synopsis: spark [--min=] [--max=] [numbers...] + Renders a Unicode sparkline bar chart for a sequence of numbers. - Reads from stdin if no numbers are given. + Reads numbers from arguments or from stdin if none are provided. + Optional --min and --max clamp the scale range. + + Arguments: + --min= Minimum value for scale (default: list minimum) + --max= Maximum value for scale (default: list maximum) + numbers... Space-separated numbers to chart; reads stdin if omitted + -v, --version Print version + -h, --help Show usage help spark 1 1 2 5 14 42 + seq 64 | sort --random-sort | spark echo "3 7 2 9 1" | spark +### steam-dl + + Synopsis: steam-dl + + Launches Steam with systemd-inhibit to prevent the system from idling + or sleeping during active downloads. + + steam-dl + ### yt-dlp Synopsis: yt-dlp [args...] URL [URL...] - Wraps yt-dlp, prepending sane defaults: --sponsorblock-remove all, - --embed-subs, --embed-metadata, and --embed-thumbnail. Each default - is suppressed when you already pass that flag, its alias, or its - negation (e.g. --no-embed-thumbnail drops the thumbnail default; - --no-sponsorblock or your own --sponsorblock-remove drops ours). All - other arguments pass through unchanged, and --help falls through to - real yt-dlp. Opinionated component (C1 aliases); when disabled it - passes straight through to the system yt-dlp. + + Wraps yt-dlp, injecting sane embedding + SponsorBlock defaults + (--sponsorblock-remove all, --embed-subs, --embed-metadata, + --embed-thumbnail). Each default is suppressed if the user already + passes that flag, its alias, or its negation (e.g. --no-embed-thumbnail + drops our --embed-thumbnail; --no-sponsorblock or your own + --sponsorblock-remove drops ours). All other arguments pass through + untouched. --help and friends fall through to real yt-dlp. + + Opinionated component (C1): when disabled via __fish_config_op_aliases + (or the __fish_config_opinionated master), passes straight through to + the system yt-dlp with no defaults injected. + + Arguments: + args... Arguments forwarded to yt-dlp (defaults prepended) + --no-embed-thumbnail Skip thumbnail embedding for this run yt-dlp dQw4w9WgXcQ - yt-dlp --no-embed-thumbnail dQw4w9WgXcQ - ---- + yt-dlp --no-embed-thumbnail dQw4w9WgXcQ # drops our thumbnail default ## 5.14 Miscellaneous +### bash + + Synopsis: bash [args...] + + Switches the current shell session to bash, loading config from the XDG + config directory. Resets $SHELL back to fish on exit. + + Arguments: + args... Arguments passed through to the bash command + + bash + +### bd-pull + + Synopsis: bd-pull + + Fetches unlinked issues from a Gitea repository, creates corresponding local + Beads entries, and updates the Gitea issue titles to include the new Bead IDs. + Requires $GITEA_TOKEN and $GITEA_URL to be set. + + Arguments: + owner/repo The repository path in owner/name format + + Returns: + 0 Issues linked and synced (or no unlinked issues found) + 1 Missing required argument or environment variables + + bd-pull myuser/myproject + bd-pull rootiest/fish-config + +### cffetch + + Synopsis: cffetch [args...] + + Clears the screen and displays system information using fastfetch with a + custom config if available. Falls back to neofetch if fastfetch is not installed. + + Arguments: + args... Additional arguments forwarded to fastfetch or neofetch + + cffetch + +### cheat + + Synopsis: cheat [args...] + + Displays colorized cheatsheets using cheat -c. Falls back to tldr, then + man, if cheat is not installed. + + Arguments: + topic The command or topic to look up + args... Additional arguments forwarded to cheat, tldr, or man + + cheat tar + cheat git + ### config-help - Synopsis: config-help [SECTION] + Synopsis: config-help [section] config-help --html - config-help [SECTION] --man - config-help -h | --help + config-help [section] --man + config-help --help - Opens the offline fish shell configuration manual. Without flags, opens - the Markdown source in the best available pager (ov > bat > man > less > - cat). If SECTION is given, jumps to the first heading matching that - keyword (case-insensitive; checks fish-config.index aliases first). + Opens the offline fish shell configuration manual in the best available + pager. Falls back through ov -> bat -> man -> less -> cat. + If a section keyword is provided, the pager opens at the first heading + that matches the keyword. Lookup order: docs/fish-config.index (exact + keyword aliases), then a normalized heading scan as fallback. + When opened with ov a sticky navigation hint is shown at the top of the + screen. Section matching is case-insensitive. Pass --html / -w to open + the published documentation website (https://fish-config-docs.pages.dev/) + in the default browser via xdg-open — deep links to a section aren't + supported there, so if a keyword is given a note points you to the site's + search box instead. Pass --man / -m to open the compiled man page + (docs/fish-config.1) via `man -l`; if a section keyword is given, the + pager opens at the nearest match. Pass --help or -h for usage and the + navigation key reference. - Flags: - --html / -w Open the published documentation website - (https://fish-config-docs.pages.dev/) in the default - browser via xdg-open. Deep links to a section aren't - supported; if SECTION is given, a note points you to the - site's search box instead. - --man / -m Open docs/fish-config.1 via man -l directly. - If SECTION is given, jumps to the nearest match. - --help / -h Print usage and navigation key reference. + Arguments: + section Optional keyword to jump to a matching section heading + -w, --html Open the published documentation website in the default browser + -m, --man Open the compiled man page via man -l + -h, --help Print usage and navigation reference, then exit + Returns: + 0 Manual displayed (or --help printed) + 1 Documentation file not found, or required tool not available + + Notes: + The preferred invocation is `help config [...]` — this function is + registered as a handler in the help wrapper so that syntax works + transparently. Direct `config-help` calls are also valid. + + config-help config-help keybindings config-help pkg + config-help fish-deps config-help --html config-help --man + config-help keys --man + config-help --help config-help pkg --man - Also available as: help config [SECTION] [FLAGS] - -### open-url - - Synopsis: open-url [-s|--silent] [-v|--verbose] - open-url -h | --help - - Opens a URL or file:// URI in the best available graphical web browser, - backgrounded so it never blocks the terminal. Resolves a real browser - binary rather than deferring to xdg-open, whose MIME dispatch can hand - local text/html files to non-browser apps (e.g. ebook readers). - - Silent by default: prints nothing on success (errors always go to - stderr). Pass --verbose / -v to report which browser is launched; - --silent / -s is accepted for explicitness. - - Resolution order: - 1. $fish_help_browser (explicit override) - 2. $BROWSER (validated; errors if not a command) - 3. xdg-mime default handler for x-scheme-handler/https - 4. First known browser binary found in a built-in list - 5. xdg-open (last resort) - - open-url https://git.rootiest.dev/rootiest/fish-config - open-url -v https://fish-config-docs.pages.dev/ - - Used internally by config-help --html. - - Typo abbreviation: url-open (expands to open-url on space/enter). - -### repo-open - - Synopsis: repo-open [-p|--print] [-r|--root] - repo-open -h | --help - - Opens the web page for the current repository's `origin` remote in a - browser (via open-url). Deep-links to the current branch when it exists - on the remote — falling back to the remote's default branch (main/master) - otherwise — and to the current sub-directory when run below the repo root. - - The remote URL is normalized from HTTPS and SSH/scp forms - (git@host:owner/repo.git, ssh://…, https://…). The web path layout is - provider-specific; the provider is resolved in order: - - 1. git config browse.provider (per-repo or --global override) - 2. Hostname heuristic (github / gitlab / gitea / bitbucket; - codeberg → gitea) - 3. Default: github-style layout - - Self-hosted hosts the heuristic can't classify (a Gitea/GitLab instance - on a custom domain) need a one-time override: - - git config browse.provider gitea - - Flags: - --print / -p Print the resolved URL instead of opening it. - --root / -r Ignore the current sub-directory; link to the repo root. - --help / -h Show usage. - - repo-open - repo-open --print - repo-open --root - - Typo abbreviation: open-repo (expands to repo-open on space/enter). - -### config-update - - Synopsis: config-update [-h] [-n] [-f] - - Pulls the latest fish configuration from the upstream repository - (https://git.rootiest.dev/rootiest/fish-config.git) into ~/.config/fish. - The remote URL is hard-coded, so this works on fresh clones with no git - remote configured. All git output is suppressed; colored messages report - fetch and merge status. After a successful pull, run `exec fish` to - reload. - - Flags: - --dry-run / -n Fetch and show available commits without applying them. - --force / -f Stash local changes, pull, then restore the stash. - --help / -h Show usage. - - config-update - config-update --dry-run - config-update --force - ### config-settings - Synopsis: config-settings [-h] + Synopsis: config-settings [-h | --help] - Opens an interactive TUI for managing fish configuration settings across - four pages, without having to type or remember variable names. Tab cycles - forward through the pages; Shift-Tab cycles backward. + Opens an interactive full-screen TUI for managing fish config settings + across four pages, without having to type or remember variable names: - Universal — opinionated category toggles (C1–C6) + master, persistent (set -U) + Universal — opinionated-category toggles (C1–C6) + master, persistent (set -U) Session — the same toggles, current shell only (set -g) Sponge — sponge history-scrubbing settings: delay, successful exit codes, purge-only-on-exit, allow-previously-successful, and extra sensitive variable-name tokens - Paths — scrollback log directory, scrollback max files, the - user-dots path, and the user-dots convenience symlink toggle - (Dots link) + Paths — scrollback log directory, scrollback max files, the user-dots + path, and the user-dots convenience symlink toggle (Dots link) - Toggle rows use ← → (or h/l) along an OFF ← DEFAULT → ON scale; DEFAULT - erases the variable so the master switch / built-in default applies. Value - rows (the path/int/list settings on the Sponge and Paths pages) use Enter to - edit inline; ← / h clears the value back to its default. List rows (e.g. - Extra secret, OK codes) accept values separated by commas and/or whitespace - — "A, B", "A,B" and "A B" all yield the same two entries. Changes apply - immediately. Always available regardless of the __fish_config_opinionated - master state. + Toggle rows use ← / → (or h / l) to step OFF ← DEFAULT → ON; DEFAULT erases + the variable so the master switch / built-in default applies. Value rows + (Sponge, Paths) use Enter to edit inline; ← / h clears to default. List rows + (e.g. Extra secret, OK codes) accept values separated by commas and/or + whitespace — "A, B", "A,B" and "A B" all yield the same two entries. + Tab / Shift-Tab cycle forward / backward through pages. + Changes apply immediately — no confirm step. Always available regardless of + __fish_config_opinionated state. The Sponge and Paths pages always write universal variables — these are persistent, set-and-forget settings with no per-session scope. Editing a @@ -1471,10 +2004,10 @@ Add -i (interactive confirmation) to destructive commands: zellij log wrappers (which read the exported names) see the change in the running session. - The panel adapts to the terminal width automatically, selecting from - four layout tiers (with a 6-column buffer on each side before stepping - up to the next tier) and horizontally centering the box. The panel - redraws within ~0.3 s of a terminal resize with no keypress required. + The panel adapts to the terminal width automatically, selecting from four + layout tiers (with a 6-column buffer on each side before stepping up to the + next tier) and horizontally centering the box. The panel redraws within + ~0.3 s of a terminal resize with no keypress required. COLUMNS >= 90 → 78-wide panel (most detail) COLUMNS >= 86 → 74-wide panel @@ -1489,119 +2022,267 @@ Add -i (interactive confirmation) to destructive commands: Tab / S-Tab Next / previous page q / Escape Exit - Flags: - --help / -h Show usage. + Arguments: + -h, --help Print usage and exit + + Returns: + 0 Exited normally (q or Escape pressed) + 1 Unknown flag passed config-settings -### config-toggle (deprecated) +**Used by:** `config-toggle` - Deprecated alias for config-settings. Prints a deprecation notice to - stderr, then delegates all arguments to config-settings. +### config-toggle - config-toggle + Synopsis: config-toggle [args...] -### bash + Deprecated alias for config-settings. Prints a one-line deprecation + notice to stderr, then delegates all arguments to config-settings. - Synopsis: bash [args...] - Switches to bash, with XDG config applied. On exit, $SHELL is reset - back to fish. + Arguments: + args Passed through verbatim to config-settings -### bd-pull + Returns: + Same as config-settings - Synopsis: bd-pull - Fetches unlinked Gitea issues and creates local Beads entries, updating - issue titles with the assigned Beads IDs. - Requires $GITEA_TOKEN and $GITEA_URL to be set. + config-toggle # opens config-settings with a deprecation notice - bd-pull rootiest/fish-config +**Dependencies:** `config-settings` -### cheat +### config-update - Synopsis: cheat [args...] - Displays a colorized cheatsheet using cheat -c, falls back to tldr, - then man. + Synopsis: config-update [-h | --help] [-f | --force] [-n | --dry-run] - cheat tar - cheat git + Pulls the latest fish shell configuration from the upstream repository + (https://git.rootiest.dev/rootiest/fish-config.git) into ~/.config/fish. + The remote URL is hard-coded so the update works even if the local clone + has no configured remote. Git output is suppressed; status is reported + through colored messages. After a successful pull the function prints a + short summary of changed files; run `exec fish` to reload the shell. -### cffetch / ffetch + Arguments: + -h, --help Show this help message and exit + -f, --force Stash local changes before pulling, then pop the stash + -n, --dry-run Check for upstream changes without applying them - Synopsis: cffetch [args...] / ffetch [args...] - Clears the screen and displays system information via fastfetch with - the custom config at ~/.fastfetch.jsonc. Falls back to neofetch. + Returns: + 0 Config updated (or already up to date) + 1 Update failed (network error, merge conflict, or not a git repo) + + config-update + config-update --dry-run + config-update --force ### dockup Synopsis: dockup [-h] [directory] - Pulls latest Docker images, restarts services in the given Docker - Compose project, and prunes dangling images. + + Pulls the latest Docker images and restarts all services in a Docker Compose + project, then prunes dangling images. Accepts an optional target directory. + + Arguments: + -h, --help Show help message + directory Path to the compose project (defaults to current directory) + + Returns: + 0 Services updated and running + 1 Directory not found or no docker-compose.yml present dockup ~/myapp +### ffetch + + Synopsis: ffetch [args...] + + Alias for fastfetch that loads a custom config from ~/.fastfetch.jsonc when + present. Falls back to neofetch if fastfetch is not installed. + + Arguments: + args... Arguments forwarded to fastfetch or neofetch + + ffetch + ### joplin Synopsis: joplin [args...] - Runs the Joplin CLI with Node.js deprecation warnings suppressed. + + Runs the Joplin CLI with Node deprecation warnings suppressed via + NODE_OPTIONS=--no-deprecation. + + Arguments: + args... Arguments forwarded to the joplin command + + Returns: + 0 Joplin ran successfully + 1 joplin binary not found in PATH joplin ls -### ld - - Synopsis: ld - Launches lazydocker targeting the currently active Docker context, - detected via docker context inspect. - -### replay - - Synopsis: replay - Runs Bash commands and replays any resulting changes to environment - variables, aliases, and the working directory back into the current - Fish session. Useful for sourcing Bash scripts. - - replay "source ~/.bashrc" - replay "export FOO=bar" - ### kitty-logging - Synopsis: kitty-logging [install|uninstall|status|dismiss] [-h] + Synopsis: kitty-logging [install | uninstall | status | dismiss] [-h] - Manages the Kitty scrollback watcher that powers C5 logging. Ships a - canonical watcher and symlinks it into the Kitty config directory (so it - always tracks the source), wiring it into kitty.conf through a - sentinel-marked managed block. Commenting out any conflicting watcher line - avoids double-capture. - - Commands: - install Symlink the watcher and add the managed block - uninstall Remove the managed block and the watcher symlink - status Show wiring, installed watcher version, and C5 state - dismiss Stop the per-session setup reminder + Manages the fish-config Kitty scrollback watcher that powers C5 logging. + `install` symlinks the canonical watcher into the Kitty config dir (so it + always tracks the source) and wires it into kitty.conf via a + sentinel-marked managed block, commenting out any conflicting active + watcher line to avoid double-capture. `uninstall` reverses it. `status` + reports wiring, installed watcher version, and C5 logging state. `dismiss` + silences the per-session setup reminder. Runtime capture stays governed by the C5 .logging_disabled sentinel, so disabling __fish_config_op_logging makes the watcher inert without uninstalling. Install affects new Kitty windows only. - Example: - kitty-logging install - kitty-logging status + Arguments: + install Symlink the watcher and add the managed block to kitty.conf + uninstall Remove the managed block and the watcher symlink + status Report wiring, watcher version, and C5 logging state + dismiss Stop the per-session reminder + -h, --help Show this help + + Returns: + 0 Success + 1 Unknown subcommand/flag, kitty missing, or a write failure + + kitty-logging install + kitty-logging status + +### ld + + Synopsis: ld + + Launches lazydocker targeting the currently active Docker context by + resolving the host endpoint from docker context inspect. + + ld + +### open-url + + Synopsis: open-url [-s|--silent] [-v|--verbose] + open-url --help + + Opens a URL (or file:// URI) in the best available graphical web browser, + backgrounded so it never blocks the terminal. Resolves a real browser + binary rather than deferring to xdg-open, whose MIME dispatch can hand + local text/html files to non-browser apps (e.g. ebook readers). + + Silent by default: prints nothing on success (errors always go to stderr); + --silent / -s is accepted for explicitness. + + Resolution order: + 1. $fish_help_browser (explicit override) + 2. $BROWSER (validated; errors if not a command) + 3. xdg-mime default handler for x-scheme-handler/https + 4. First known browser binary found in a built-in list + 5. xdg-open (last resort) + + Arguments: + url The URL or file:// URI to open (required) + -s, --silent Suppress success output (the default) + -v, --verbose Print which browser is being launched + -h, --help Print usage and exit + + Returns: + 0 Browser launched + 1 No URL given, invalid $BROWSER, or no browser found + + Notes: + Typo abbreviation: url-open (expands to open-url on space/enter). + + open-url https://git.rootiest.dev/rootiest/fish-config + open-url -v https://fish-config-docs.pages.dev/ + +**Used by:** `repo-open` + +### replay + + Synopsis: replay + + Runs the given commands in Bash and replays any resulting environment + variable, alias, and directory changes back into the current Fish + session. Useful for sourcing Bash-only scripts. + + Arguments: + commands Bash command string to execute and replay + + Returns: + 0 Commands ran successfully and changes were replayed + 1 Bash command exited with a non-zero status + + replay "source ~/.bashrc" + replay "export FOO=bar" + +### repo-open + + Synopsis: repo-open [-p|--print] [-r|--root] + repo-open --help + + Opens the web page for the current repository's `origin` remote in a + browser (via open-url). Deep-links to the current branch when it exists + on the remote, falling back to the remote's default branch (main/master) + otherwise, and to the current sub-directory when invoked below the repo + root. + + The remote URL is normalized from both HTTPS and SSH/scp forms + (git@host:owner/repo.git, ssh://…, https://…). The web path layout is + provider-specific; the provider is resolved in this order: + + 1. git config browse.provider (per-repo or --global override) + 2. Hostname heuristic (github / gitlab / gitea / bitbucket; + codeberg → gitea) + 3. Default: github-style layout + + For a self-hosted host the heuristic can't classify (e.g. a Gitea or + GitLab instance on a custom domain), set the provider once: + + git config browse.provider gitea + + Arguments: + -p, --print Print the resolved URL instead of opening it + -r, --root Ignore the current sub-directory; link to the repo root + -h, --help Print usage and exit + + Returns: + 0 URL opened (or printed) + 1 Not a git repo, no origin remote, or browser launch failed + + Notes: + Typo abbreviation: open-repo (expands to repo-open on space/enter). + + repo-open # open current branch (+ subdir) in browser + repo-open --print # just print the URL + repo-open --root # repo home page for the current branch + +**Dependencies:** `open-url` ### tmux-clean Synopsis: tmux-clean - Kills all detached (unattached) tmux sessions, leaving attached ones - running. + + Kills all detached (unattached) tmux sessions, leaving any currently + attached sessions running. + + tmux-clean ### wake-lock Synopsis: wake-lock [args...] - Runs a command under systemd-inhibit, preventing the system from going - idle or sleeping until the command completes. + + Runs a command under systemd-inhibit to prevent the system from idling + or sleeping for the duration of the command. + + Arguments: + command Command to run with sleep inhibition active + args... Arguments forwarded to the command + + Returns: + 0 Command ran and completed + 1 No command provided wake-lock rsync -avz src/ dest/ ---- - # 6. DEPENDENCY CATALOG fish-deps manages these tools. Run `fish-deps` to check status, or diff --git a/docs/manual/05-functions/01-file-and-directory.md b/docs/manual/05-functions/01-file-and-directory.md index 80d3219..f50a0fa 100644 --- a/docs/manual/05-functions/01-file-and-directory.md +++ b/docs/manual/05-functions/01-file-and-directory.md @@ -7,158 +7,4 @@ helpKeywords: - files --- -## cat - Synopsis: cat [args...] - Wraps bat for files with syntax highlighting and line numbers. - Passes directories to ls. Falls back to /usr/bin/cat. - - cat README.md - cat ~/projects/myapp - -## copy - - Synopsis: copy - Wraps cp, stripping trailing slashes from source directories to - prevent unintended nesting inside the destination. - - copy ./mydir/ ~/backup # copies mydir INTO backup, not backup/mydir/ - -## du - - Synopsis: du [--disk|--dir|--dua] [args...] - Smart disk-usage dispatcher: - --disk force duf (disk-level free/used overview) - --dir force dust (per-directory tree breakdown) - --dua force dua (fast space analyzer) - Without flags, routes to the most appropriate tool by context. - - du ~/Downloads - du --disk - -## dusize - - Synopsis: dusize [dir] - Human-readable disk usage for a directory via du -sh. Defaults to cwd. - - dusize ~/Videos - -## lD - - Synopsis: lD [args...] - Lists directories only in long format with icons. Uses eza, falls back - to lsd, then system ls. - - lD ~/projects - -## ls - - Synopsis: ls [args...] - Lists files in long format with icons and hyperlinks. Uses eza, falls - back to lsd, then system ls. - - ls - ls -a ~/projects - -## lsr - - Synopsis: lsr [args...] - Lists files sorted by modification time, oldest first. Uses eza. - -## lss - - Synopsis: lss [args...] - Lists files sorted by size with gradient color scaling. Uses eza. - -## lstree - - Synopsis: lstree [args...] - Full recursive tree view with icons. Uses eza. - - lstree ~/projects/myapp - -## lt - - Synopsis: lt [args...] - Tree view limited to depth 2 with icons. Uses eza. - - lt ~/projects - -## ltr - - Synopsis: ltr [args...] - Lists files sorted by modification time, oldest first, long format with - age-based gradient scaling. Uses eza. - -## lx - - Synopsis: lx [args...] - Lists files sorted by extension, long format. Uses eza. - -## mkdir - - Synopsis: mkdir [args...] - Interactive mkdir that prints a tree of created directories. - Falls back to mkdir -p silently. - - mkdir ~/projects/myapp/src - -## mkcd - - Synopsis: mkcd [-s] - Creates a directory (including parents) and cd into it. Prints a tree - of created dirs by default; -s/--silent suppresses output. - - mkcd ~/projects/newapp/src - -## poke - - Synopsis: poke [file...] - Creates files via touch, automatically creating any missing parent - directories first. - - poke ~/projects/new/src/main.fish - -## rm - - Synopsis: rm [-e [opts] | -S | args...] - Safe rm wrapper routing to trash: - - (no args) List current trash contents - -e/--empty Empty the trash (pass options to trash-empty) - -S/--secure Permanently delete via rm -rf + fstrim (irreversible) - -r/-R/--recursive Move to trash - Move to trash (safe delete) - - Falls back to /usr/bin/rm when trash is unavailable. - - rm file.txt # moves to trash - rm -e # empty trash - rm -S sensitive.pem # permanent delete - -## rg - - Synopsis: rg [args...] - In Kitty, wraps ripgrep with --hyperlink-format=kitty so search - results are clickable file links in the terminal. Falls back to - system rg in any other terminal. All other arguments pass through - unchanged. - - rg "fish_greeting" ~/.config/fish/ - rg -l "TODO" ~/projects/myapp - -## scrub - - Synopsis: scrub [-a] [-d] [-h] - Recursively removes OS metadata, editor artifacts, compiler output, - and dev caches using fd. - - -a/--aggressive Also removes node_modules, logs, .cache, IDE dirs, - AI session artifacts - -d/--dry-run Print what would be removed without deleting - - scrub - scrub -a - scrub -d - ---- diff --git a/docs/manual/05-functions/02-navigation.md b/docs/manual/05-functions/02-navigation.md index 0cc6ff6..dc85960 100644 --- a/docs/manual/05-functions/02-navigation.md +++ b/docs/manual/05-functions/02-navigation.md @@ -7,26 +7,4 @@ helpKeywords: - nav-fns --- -## cdi - Synopsis: cdi [query] - Interactive directory picker combining zoxide frecency with fzf. - Equivalent to zi. - - cdi myproject - -## clone - - Synopsis: clone [args...] - Clone a git repository into a new Kitty window. Kitty-only. - - clone https://github.com/user/repo.git - -## clonet - - Synopsis: clonet [args...] - Clone a git repository into a new Kitty tab. Kitty-only. - - clonet https://github.com/user/repo.git - ---- diff --git a/docs/manual/05-functions/03-editors-and-viewers.md b/docs/manual/05-functions/03-editors-and-viewers.md index 58caadf..026a1a8 100644 --- a/docs/manual/05-functions/03-editors-and-viewers.md +++ b/docs/manual/05-functions/03-editors-and-viewers.md @@ -7,65 +7,4 @@ helpKeywords: - editors --- -## edit - Synopsis: edit [-V|-t] [-e EDITOR] [-c] [-x TEXT] [-n] [-v|-s] [FILE...] - - Opens files in a text editor, choosing a terminal or GUI editor and - resolving a rich chain of fallbacks. With no --visual/--terminal flag the - mode is auto-detected: interactive terminals use the terminal editor - ($EDITOR), while detached invocations (e.g. desktop shortcuts) use the GUI - editor ($VISUAL). Clipboard contents and literal strings can be opened as - throwaway temp files. Editor output is suppressed unless --verbose. - - GUI fallback chain: zed → antigravity-ide → code → kate → kwrite → - gnome-text-editor → gedit - Terminal fallback chain: nvim → vim → micro → nano → vi - - Options: - -V, --visual Force the GUI editor ($VISUAL or fallbacks) - -t, --terminal Force the terminal editor ($EDITOR or fallbacks) - -e, --editor=X Use a specific editor binary X - -c, --clipboard Open the clipboard contents (as a temp file) - -x, --text=STR Open STR as the contents of a new temp file - -n, --new Force a new window/instance (best-effort) - -v, --verbose Print the launch command and editor output - -s, --silent Suppress all output, including the editor's - -h, --help Show this help message - - edit ~/.config/fish/config.fish - edit --visual notes.txt - edit --terminal --new todo.md - edit --editor=code --clipboard - edit --text="hello world" - -## fc - - Synopsis: fc [command_prefix] - Edit the last shell command (or one matching a prefix) in $EDITOR, - then execute the result. Bash-style fc behaviour. - - fc - fc git - -## less - - Synopsis: less [args...] - Pager wrapper with fallback chain: $PAGER -> ov -> less -> more -> cat. - - less /var/log/syslog - -## rawfish - - Synopsis: rawfish [args...] - Launches Fish with NO_TMUX=1, bypassing any tmux auto-attach logic. - Useful when you need a clean shell without session management. - -## view - - Synopsis: view [args...] - Opens files in nvim read-only mode (-R). Falls back to less. - - view /etc/fstab - ---- diff --git a/docs/manual/05-functions/04-git-and-version-control.md b/docs/manual/05-functions/04-git-and-version-control.md index bf2e8f6..8ed3199 100644 --- a/docs/manual/05-functions/04-git-and-version-control.md +++ b/docs/manual/05-functions/04-git-and-version-control.md @@ -7,84 +7,4 @@ helpKeywords: - git --- -## auto-pull - Synopsis: auto-pull [list] - auto-pull add [PATH] - auto-pull remove - auto-pull status - - Manages the registry of repositories that are background fast-forwarded - when you enter them (see "Auto-pull fast-forward" under the C2 component - reference). The fish-config repo is always covered as a baseline. The - registry is machine-local at `$__fish_user_dots_path/auto-pull.list` (defaults - to `~/.config/.user-dots/fish/auto-pull.list`), one absolute path per line, - and is never committed. Registry management works - even when C2 auto-execution is disabled; only the background sync is gated. - - list Show registered repos (default) - add [PATH] Register PATH's git root (default: current repo) - remove Unregister by basename or exact path - status Show enabled/disabled state, repo count, list path - - cd ~/src/qmk_firmware; and auto-pull add - auto-pull add ~/work/api - auto-pull list - auto-pull remove qmk_firmware - -## branch - - Synopsis: branch - Switches to a local branch, or creates it if it does not exist. - - branch feature/new-ui - -## gi - - Synopsis: gi [-h] [-b] [-p] [-s] [-l] [targets...] - Generates .gitignore content from the gitignore.io API with MD5-based - deduplication (patterns already present are not re-appended). - - -b/--boilerplate Append generic boilerplate first - -p/--prompt Prompt interactively for targets - -s/--stdout Print to stdout instead of appending to .gitignore - -l/--list List all available targets - targets Comma-separated or space-separated target names - - gi python,venv - gi -b -p - gi -s node > .gitignore - -## git-clean - - Synopsis: git-clean [-f] - Fetches and prunes the remote, fast-forwards the current branch, then - deletes local branches whose remote tracking branch has been deleted. - Switches to main/master automatically if the current branch is orphaned. - - -f/--force Force-delete unmerged branches too - - git-clean - git-clean --force - -## gitup - - Synopsis: gitup [args...] - Fetches updates from the remote and shows git status. Extra args are - forwarded to git fetch. - - gitup - gitup --all - -## gitui - - Synopsis: gitui [args...] - Launches gitui with the Catppuccin Frappe theme pre-applied. - -## hist - - Synopsis: hist - Searches shell history with fzf, inserts the selection into the command - line, and copies it to the clipboard via wl-copy. - ---- diff --git a/docs/manual/05-functions/05-package-management.md b/docs/manual/05-functions/05-package-management.md index 9c15231..1b6a73f 100644 --- a/docs/manual/05-functions/05-package-management.md +++ b/docs/manual/05-functions/05-package-management.md @@ -8,53 +8,4 @@ helpKeywords: - packages --- -## pkg - Synopsis: pkg [-h] [-i|-u] [package...] - Installs or removes packages using the detected system package manager. - Supports: paru, yay, pacman, apt, dnf, zypper, yum, brew, pkg. - - (no flag) Auto mode: installs missing packages, removes installed ones - -i/--install Force install - -u/--uninstall Force uninstall - - pkg firefox # auto: install if missing, remove if present - pkg -i ripgrep fd # force install - pkg -u cowsay # force uninstall - - The package-installed check uses the correct query for each PM: - pacman/paru/yay pacman -Qi - apt dpkg -s - dnf/zypper/yum rpm -q - brew brew list - pkg pkg info - -## search - - Synopsis: search [args...] - Interactive AUR package search and install via paru or yay. - Arch Linux only. - - search neovim - -## upgrade - - Synopsis: upgrade - Full system upgrade via paru -Syu --noconfirm or yay -Syu --noconfirm. - Arch Linux only. - -## cleanup - - Synopsis: cleanup - Lists and removes orphan packages via pacman, logging their names to - ~/.removed_orphans. Arch Linux only. - -## parur - - Synopsis: parur - Opens an fzf picker of all installed packages (with pacman -Qi previews), - then removes the selected packages via paru or yay. Arch Linux only. - - parur - ---- diff --git a/docs/manual/05-functions/06-dependency-management.md b/docs/manual/05-functions/06-dependency-management.md index e9b4882..378b01c 100644 --- a/docs/manual/05-functions/06-dependency-management.md +++ b/docs/manual/05-functions/06-dependency-management.md @@ -7,41 +7,4 @@ helpKeywords: - deps --- -## fish-deps - Synopsis: fish-deps [status|install|update|sync] - Unified command for managing all tools this configuration depends on. - - status (default) Show installed/missing status grouped by tier - install Interactively install each missing dependency - update Update all installed dependencies - sync Install missing deps, then update all - - Install method priority (highest to lowest): - 1. git+cargo source build (fish shell itself) - 2. cargo (Rust tools — gets latest crate version) - 3. system PM (paru/apt/brew/etc.) - 4. git clone (fzf) - 5. curl installer (starship, fisher, uv) - - When multiple methods are available you are prompted to choose. - - Dependencies are grouped into three tiers: - - Required fish, fzf, zoxide - Integrations wakatime, tailscale - Recommended cargo, starship, uv, direnv, paru, yay, eza, lsd, bat, - btop, dust, duf, prettyping, ov, ripgrep, lazygit, - lazydocker, trash, kitty, wezterm, python3, yt-dlp - - fish-deps - fish-deps install - fish-deps update - fish-deps sync - -## check_fish_deps - - Synopsis: check_fish_deps - Backwards-compatibility alias for `fish-deps status`. - ---- diff --git a/docs/manual/05-functions/07-system-and-monitoring.md b/docs/manual/05-functions/07-system-and-monitoring.md index 9f47fc3..4c44eea 100644 --- a/docs/manual/05-functions/07-system-and-monitoring.md +++ b/docs/manual/05-functions/07-system-and-monitoring.md @@ -7,57 +7,4 @@ helpKeywords: - system --- -## top - Synopsis: top [args...] - Launches btop as a modern resource monitor. Falls back to system top. - -## swapstat - - Synopsis: swapstat - Displays a colorized memory report: kernel swappiness, zRAM compression - ratio, zRAM device details, and active swap priorities. - -## sbver - - Synopsis: sbver [--brief] - Verifies Secure Boot signatures on all EFI binaries tracked by sbctl. - Color-codes results: green checkmark (verified), red X (unsigned). - Prints a pass/fail summary. - - --brief Suppress per-file output, show only the summary - - sbver - sbver --brief - -## ports - - Synopsis: ports - Lists active TCP listeners with lsof, showing port/address without - hostname resolution. - -## screensleep - - Synopsis: screensleep - Turns off the display via KDE PowerDevil's "Turn Off Screen" action, - invoked through busctl. - -## lock - - Synopsis: lock - Locks the current desktop session using loginctl lock-session. - -## sudo-toggle - - Synopsis: sudo-toggle - Toggles the sudo NOPASSWD rule on/off via /etc/sudoers.d/nofail-toggle. - Useful for automated tasks that would otherwise require password entry. - -## limine-edit - - Synopsis: limine-edit - Opens /boot/limine.conf in sudoedit, then automatically re-enrolls the - config hash, runs CachyOS boot hooks, and re-signs Secure Boot files. - Combines the edit and sign steps into a single command. - ---- diff --git a/docs/manual/05-functions/08-terminal-management.md b/docs/manual/05-functions/08-terminal-management.md index a4193df..62228a9 100644 --- a/docs/manual/05-functions/08-terminal-management.md +++ b/docs/manual/05-functions/08-terminal-management.md @@ -7,54 +7,4 @@ helpKeywords: - terminal-mgmt --- -## tab - Synopsis: tab [args...] - Opens a new tab in Kitty (kitty @ launch --type=tab), WezTerm - (wezterm cli spawn), or Konsole. Uses current working directory, - or $cdto if set. - - tab - -## split - - Synopsis: split [-h|-v] [command...] - Opens a new pane in Kitty or WezTerm, optionally running a command. - - -h/--horizontal (default) Split below - -v/--vertical Split to the right - - split - split -v nvim README.md - -## spwin - - Synopsis: spwin [args...] - Spawns a new terminal OS window in Kitty (via spawn-window.sh or - kitty @ launch --type=os-window) or WezTerm (wezterm cli spawn --new-window). - -## detach - - Synopsis: detach [-h] [--version] [args...] - Runs a command fully detached via nohup with stdout/stderr discarded. - The command survives the current session. - - detach rsync -a ./data remote:/backup/ - -## bkg - - Synopsis: bkg [args...] - Launches a command in the background via nohup with output discarded. - Simpler than detach; no version flag. - - bkg firefox - -## ssh - - Synopsis: ssh [args...] - In Kitty, wraps ssh with kitten ssh for better terminal integration - (multiplexing, copy/paste support). Falls back to system ssh elsewhere. - - ssh user@host - ---- diff --git a/docs/manual/05-functions/09-clipboard.md b/docs/manual/05-functions/09-clipboard.md index c2fe7f0..636d715 100644 --- a/docs/manual/05-functions/09-clipboard.md +++ b/docs/manual/05-functions/09-clipboard.md @@ -7,26 +7,4 @@ helpKeywords: - clipboard --- -## y - Synopsis: y [text...] - Copies text to the clipboard via wl-copy (Wayland) or xclip (X11). - Reads from stdin if no arguments given. - - y "hello world" - ls | y - cat file.txt | y - -## p - - Synopsis: p [args...] - Outputs clipboard contents to stdout. - - p | grep foo - p > file.txt - -## paste - - Alias for p. Identical behaviour. - ---- diff --git a/docs/manual/05-functions/10-network.md b/docs/manual/05-functions/10-network.md index 46dd3de..a203b2f 100644 --- a/docs/manual/05-functions/10-network.md +++ b/docs/manual/05-functions/10-network.md @@ -7,38 +7,4 @@ helpKeywords: - network --- -## gip - Synopsis: gip - Fetches and prints both the public IPv4 and IPv6 address via - icanhazip.com. - -## gip4 - - Synopsis: gip4 - Fetches and prints the public IPv4 address. - -## gip6 - - Synopsis: gip6 - Fetches and prints the public IPv6 address. Returns 1 if IPv6 is - unavailable. - -## ping - - Synopsis: ping [args...] - Wraps prettyping with --nolegend. Pass --legend to show the legend. - Falls back to system ping. - - ping google.com - -## qr - - Synopsis: qr [text...] - Generates a UTF-8 QR code from text or stdin. Uses qrencode locally; - falls back to the qrenco.de API. - - qr "https://example.com" - echo "https://example.com" | qr - ---- diff --git a/docs/manual/05-functions/11-pager-and-logging.md b/docs/manual/05-functions/11-pager-and-logging.md index 872fca6..4db19bb 100644 --- a/docs/manual/05-functions/11-pager-and-logging.md +++ b/docs/manual/05-functions/11-pager-and-logging.md @@ -7,41 +7,4 @@ helpKeywords: - logging --- -## logs - Synopsis: logs [-c ] - Interactively browses terminal log files sorted newest-first using fzf. - - -c/--category Filter to: scrollback, paru, or yay - - Keybindings inside the fzf browser: - Enter Open in $PAGER - Ctrl+E Open in $EDITOR - Ctrl+D Delete (with confirmation) - ? Toggle keybind help overlay - - Paru and yay logs open in ov with syntax highlighting and sticky section - headers. Scrollback logs open in ov with per-command sticky prompt headers - based on OSC 133 markers. - - logs - logs -c paru - logs -c scrollback - -## smart_exit - - Synopsis: smart_exit [-n] - Closes the shell session. In Kitty, captures the terminal scrollback to - a timestamped log file in $SCROLLBACK_HISTORY_DIR before exiting. - Automatically prunes the oldest logs when the count exceeds - $SCROLLBACK_HISTORY_MAX_FILES. - - -n/--no-log Exit without saving a scrollback log - - The exit builtin is wired to smart_exit for interactive sessions. - Typing exit or Ctrl+D behaves identically to smart_exit. - - smart_exit - smart_exit --no-log - ---- diff --git a/docs/manual/05-functions/12-ai-and-developer-tools.md b/docs/manual/05-functions/12-ai-and-developer-tools.md index 21bbf6b..c957ccc 100644 --- a/docs/manual/05-functions/12-ai-and-developer-tools.md +++ b/docs/manual/05-functions/12-ai-and-developer-tools.md @@ -7,110 +7,4 @@ helpKeywords: - ai --- -## agy - Synopsis: agy [args...] - Wrapper for the agy Antigravity AI CLI. Before launching, delegates to - agents-init --agents to ensure AGENTS/ is scaffolded and CLAUDE.md is - symlinked to AGENTS/AGENTS.md in the current project, then forwards all - arguments verbatim to the real agy binary. Command shadow (C1): when - __fish_config_op_aliases (or the master) is disabled, the call is - passed through to the real agy binary unchanged. - - agy chat - agy resume - -## antigravity-ide - - Synopsis: antigravity-ide [args...] - Runs the antigravity-ide editor with warnings filtered. - -## agents-init - - Synopsis: agents-init [--agents | --plugins] - Scaffold an AGENTS/ sub-repository for tracking agent specs, plans, specs, - and dev logs. Creates AGENTS/ as a standalone git repo, moves any existing - AGENTS.md into it, and replaces it with a relative symlink (plus - CLAUDE.md -> AGENTS/AGENTS.md so Claude Code picks up the shared agent - instructions). Consolidates plans/ and specs/ directly under AGENTS/ - (merging any legacy docs/plans, docs/superpowers/plans, or old - AGENTS/plugins/ locations into the canonical AGENTS/), creates - AGENTS/devlogs/, and wires docs/superpowers/{plans,specs} symlinks back to - them. Adds managed paths to .gitignore and auto-commits every change inside - the AGENTS/ sub-repo; pulls first when the sub-repo has an upstream. - Fully idempotent: a second run produces no output and no new commits. - Flags: --agents re-runs only the AGENTS.md / symlink step; --plugins - re-runs only the plans/specs/devlogs wiring step. Called automatically by - the claude and agy wrappers on every invocation. - - Structure versioning: each AGENTS/ repo carries a self-contained version - bumper. AGENTS/.version holds MAJOR.MINOR.PATCH (seeded 1.0.0). Committed - git hooks under AGENTS/.agents-tools/ (wired via core.hooksPath) bump it on - every commit: MINOR (resetting PATCH) when the tracked directory set - changes, PATCH otherwise; MAJOR is manual-only. A prepare-commit-msg hook - appends "(vX.Y.Z)" to the commit subject. Downstream tooling can read - AGENTS/.version - a changed MINOR field signals a structure change. Because - core.hooksPath is a single setting, the local override would otherwise - shadow your global hooks; after bumping the version, each shim chains - (execs) to the global/system core.hooksPath hook of the same name so global - pre-commit / prepare-commit-msg hooks (e.g. ggshield, Git LFS) still run. - The script and hooks are shipped from scripts/agents-tools/ and refreshed - when their version marker is stale. - - agents-init - agents-init --agents - agents-init --plugins - -## claude - - Synopsis: claude [args...] - Wrapper for the claude CLI. Before launching, delegates to agents-init - --agents to ensure AGENTS/ is scaffolded and CLAUDE.md is symlinked to - AGENTS/AGENTS.md in the current project, then forwards all arguments - verbatim to the real claude binary. Command shadow (C1): when - __fish_config_op_aliases (or the master) is disabled, the call is - passed through to the real claude binary unchanged. - - claude - claude --resume - -## claude-docs - - Synopsis: claude-docs - Invokes Claude Code to analyze recent repository changes and update - README.md, ensuring all documented features and examples are accurate. - -## claude-pr - - Synopsis: claude-pr - Invokes Claude Code to run the full PR workflow: create branch, - conventional commit, verification, push, and open a PR with a manual - verification checklist. - -## qc - - Synopsis: qc [prompt...] - Quick-chat wrapper around the aichat LLM CLI that defaults to the "cli" - role - a system prompt tuned for concise, terminal-friendly output. On - first use it installs the bundled role by symlinking - scripts/cli-agent.md to $XDG_CONFIG_HOME/aichat/roles/cli.md (creating - the directory if needed). Inherits every aichat flag and tab completion - (--wraps aichat); passing --role/-r overrides the default role, so qc - forwards to aichat unchanged. The function is only defined when aichat - is installed. Run qc --help for aichat's full flag reference with the - command name rewritten to qc. - - qc "how do I list open ports on linux?" - qc -m ollama:llama3 "explain this error" - qc --role coder "refactor this function" - -## superpowers - - Synopsis: superpowers [on|off] [-g] - Enables or disables the Superpowers plugin for Antigravity and Claude - Code at workspace/project scope (default) or user scope (-g/--global). - - superpowers on - superpowers off -g - ---- diff --git a/docs/manual/05-functions/13-media-and-utilities.md b/docs/manual/05-functions/13-media-and-utilities.md index 49c7f58..39d4c03 100644 --- a/docs/manual/05-functions/13-media-and-utilities.md +++ b/docs/manual/05-functions/13-media-and-utilities.md @@ -7,48 +7,4 @@ helpKeywords: - media --- -## dng2avif - Synopsis: dng2avif [-i ] [-o ] [-q ] [-s ] [input.dng] - Converts a DNG raw image to a 10-bit HDR AVIF using an ImageMagick, - ffmpeg, avifenc pipeline with metadata sync via exiftool. - - -i/--input Input file (or positional arg) - -o/--output Output file (default: same name, .avif extension) - -q/--quality Quality 0-100 (default 92) - -s/--speed Encoding speed 0-10 (default 3) - - dng2avif photo.dng - dng2avif -q 85 -s 5 -i shot.dng -o out.avif - -## steam-dl - - Synopsis: steam-dl - Launches Steam under systemd-inhibit, preventing the system from going - idle or sleeping while a download is in progress. - -## spark - - Synopsis: spark [--min=] [--max=] [numbers...] - Renders a Unicode sparkline bar chart for a sequence of numbers. - Reads from stdin if no numbers are given. - - spark 1 1 2 5 14 42 - echo "3 7 2 9 1" | spark - -## yt-dlp - - Synopsis: yt-dlp [args...] URL [URL...] - Wraps yt-dlp, prepending sane defaults: --sponsorblock-remove all, - --embed-subs, --embed-metadata, and --embed-thumbnail. Each default - is suppressed when you already pass that flag, its alias, or its - negation (e.g. --no-embed-thumbnail drops the thumbnail default; - --no-sponsorblock or your own --sponsorblock-remove drops ours). All - other arguments pass through unchanged, and --help falls through to - real yt-dlp. Opinionated component (C1 aliases); when disabled it - passes straight through to the system yt-dlp. - - yt-dlp dQw4w9WgXcQ - yt-dlp --no-embed-thumbnail dQw4w9WgXcQ - ---- diff --git a/docs/manual/05-functions/14-miscellaneous.md b/docs/manual/05-functions/14-miscellaneous.md index bab9ee4..d595c9c 100644 --- a/docs/manual/05-functions/14-miscellaneous.md +++ b/docs/manual/05-functions/14-miscellaneous.md @@ -7,279 +7,4 @@ helpKeywords: - miscfns --- -## config-help - Synopsis: config-help [SECTION] - config-help --html - config-help [SECTION] --man - config-help -h | --help - - Opens the offline fish shell configuration manual. Without flags, opens - the Markdown source in the best available pager (ov > bat > man > less > - cat). If SECTION is given, jumps to the first heading matching that - keyword (case-insensitive; checks fish-config.index aliases first). - - Flags: - --html / -w Open the published documentation website - (https://fish-config-docs.pages.dev/) in the default - browser via xdg-open. Deep links to a section aren't - supported; if SECTION is given, a note points you to the - site's search box instead. - --man / -m Open docs/fish-config.1 via man -l directly. - If SECTION is given, jumps to the nearest match. - --help / -h Print usage and navigation key reference. - - config-help keybindings - config-help pkg - config-help --html - config-help --man - config-help pkg --man - - Also available as: help config [SECTION] [FLAGS] - -## open-url - - Synopsis: open-url [-s|--silent] [-v|--verbose] - open-url -h | --help - - Opens a URL or file:// URI in the best available graphical web browser, - backgrounded so it never blocks the terminal. Resolves a real browser - binary rather than deferring to xdg-open, whose MIME dispatch can hand - local text/html files to non-browser apps (e.g. ebook readers). - - Silent by default: prints nothing on success (errors always go to - stderr). Pass --verbose / -v to report which browser is launched; - --silent / -s is accepted for explicitness. - - Resolution order: - 1. $fish_help_browser (explicit override) - 2. $BROWSER (validated; errors if not a command) - 3. xdg-mime default handler for x-scheme-handler/https - 4. First known browser binary found in a built-in list - 5. xdg-open (last resort) - - open-url https://git.rootiest.dev/rootiest/fish-config - open-url -v https://fish-config-docs.pages.dev/ - - Used internally by config-help --html. - - Typo abbreviation: url-open (expands to open-url on space/enter). - -## repo-open - - Synopsis: repo-open [-p|--print] [-r|--root] - repo-open -h | --help - - Opens the web page for the current repository's `origin` remote in a - browser (via open-url). Deep-links to the current branch when it exists - on the remote — falling back to the remote's default branch (main/master) - otherwise — and to the current sub-directory when run below the repo root. - - The remote URL is normalized from HTTPS and SSH/scp forms - (git@host:owner/repo.git, ssh://…, https://…). The web path layout is - provider-specific; the provider is resolved in order: - - 1. git config browse.provider (per-repo or --global override) - 2. Hostname heuristic (github / gitlab / gitea / bitbucket; - codeberg → gitea) - 3. Default: github-style layout - - Self-hosted hosts the heuristic can't classify (a Gitea/GitLab instance - on a custom domain) need a one-time override: - - git config browse.provider gitea - - Flags: - --print / -p Print the resolved URL instead of opening it. - --root / -r Ignore the current sub-directory; link to the repo root. - --help / -h Show usage. - - repo-open - repo-open --print - repo-open --root - - Typo abbreviation: open-repo (expands to repo-open on space/enter). - -## config-update - - Synopsis: config-update [-h] [-n] [-f] - - Pulls the latest fish configuration from the upstream repository - (https://git.rootiest.dev/rootiest/fish-config.git) into ~/.config/fish. - The remote URL is hard-coded, so this works on fresh clones with no git - remote configured. All git output is suppressed; colored messages report - fetch and merge status. After a successful pull, run `exec fish` to - reload. - - Flags: - --dry-run / -n Fetch and show available commits without applying them. - --force / -f Stash local changes, pull, then restore the stash. - --help / -h Show usage. - - config-update - config-update --dry-run - config-update --force - -## config-settings - - Synopsis: config-settings [-h] - - Opens an interactive TUI for managing fish configuration settings across - four pages, without having to type or remember variable names. Tab cycles - forward through the pages; Shift-Tab cycles backward. - - Universal — opinionated category toggles (C1–C6) + master, persistent (set -U) - Session — the same toggles, current shell only (set -g) - Sponge — sponge history-scrubbing settings: delay, successful exit - codes, purge-only-on-exit, allow-previously-successful, and - extra sensitive variable-name tokens - Paths — scrollback log directory, scrollback max files, the - user-dots path, and the user-dots convenience symlink toggle - (Dots link) - - Toggle rows use ← → (or h/l) along an OFF ← DEFAULT → ON scale; DEFAULT - erases the variable so the master switch / built-in default applies. Value - rows (the path/int/list settings on the Sponge and Paths pages) use Enter to - edit inline; ← / h clears the value back to its default. List rows (e.g. - Extra secret, OK codes) accept values separated by commas and/or whitespace - — "A, B", "A,B" and "A B" all yield the same two entries. Changes apply - immediately. Always available regardless of the __fish_config_opinionated - master state. - - The Sponge and Paths pages always write universal variables — these are - persistent, set-and-forget settings with no per-session scope. Editing a - scrollback row updates both the __fish_scrollback_history_* source-of-truth - variables and the exported SCROLLBACK_HISTORY_* mirrors, so the AUR/tmux/ - zellij log wrappers (which read the exported names) see the change in the - running session. - - The panel adapts to the terminal width automatically, selecting from - four layout tiers (with a 6-column buffer on each side before stepping - up to the next tier) and horizontally centering the box. The panel - redraws within ~0.3 s of a terminal resize with no keypress required. - - COLUMNS >= 90 → 78-wide panel (most detail) - COLUMNS >= 86 → 74-wide panel - COLUMNS >= 82 → 70-wide panel - COLUMNS < 82 → 52-wide panel (default) - - Navigation: - ↑ ↓ / k j Move cursor - ← → / h l Toggle rows: OFF ← DEFAULT → ON - ← / h Value rows: clear to default - Enter Value rows: edit inline (Sponge / Paths pages) - Tab / S-Tab Next / previous page - q / Escape Exit - - Flags: - --help / -h Show usage. - - config-settings - -## config-toggle (deprecated) - - Deprecated alias for config-settings. Prints a deprecation notice to - stderr, then delegates all arguments to config-settings. - - config-toggle - -## bash - - Synopsis: bash [args...] - Switches to bash, with XDG config applied. On exit, $SHELL is reset - back to fish. - -## bd-pull - - Synopsis: bd-pull - Fetches unlinked Gitea issues and creates local Beads entries, updating - issue titles with the assigned Beads IDs. - Requires $GITEA_TOKEN and $GITEA_URL to be set. - - bd-pull rootiest/fish-config - -## cheat - - Synopsis: cheat [args...] - Displays a colorized cheatsheet using cheat -c, falls back to tldr, - then man. - - cheat tar - cheat git - -## cffetch / ffetch - - Synopsis: cffetch [args...] / ffetch [args...] - Clears the screen and displays system information via fastfetch with - the custom config at ~/.fastfetch.jsonc. Falls back to neofetch. - -## dockup - - Synopsis: dockup [-h] [directory] - Pulls latest Docker images, restarts services in the given Docker - Compose project, and prunes dangling images. - - dockup ~/myapp - -## joplin - - Synopsis: joplin [args...] - Runs the Joplin CLI with Node.js deprecation warnings suppressed. - - joplin ls - -## ld - - Synopsis: ld - Launches lazydocker targeting the currently active Docker context, - detected via docker context inspect. - -## replay - - Synopsis: replay - Runs Bash commands and replays any resulting changes to environment - variables, aliases, and the working directory back into the current - Fish session. Useful for sourcing Bash scripts. - - replay "source ~/.bashrc" - replay "export FOO=bar" - -## kitty-logging - - Synopsis: kitty-logging [install|uninstall|status|dismiss] [-h] - - Manages the Kitty scrollback watcher that powers C5 logging. Ships a - canonical watcher and symlinks it into the Kitty config directory (so it - always tracks the source), wiring it into kitty.conf through a - sentinel-marked managed block. Commenting out any conflicting watcher line - avoids double-capture. - - Commands: - install Symlink the watcher and add the managed block - uninstall Remove the managed block and the watcher symlink - status Show wiring, installed watcher version, and C5 state - dismiss Stop the per-session setup reminder - - Runtime capture stays governed by the C5 .logging_disabled sentinel, so - disabling __fish_config_op_logging makes the watcher inert without - uninstalling. Install affects new Kitty windows only. - - Example: - kitty-logging install - kitty-logging status - -## tmux-clean - - Synopsis: tmux-clean - Kills all detached (unattached) tmux sessions, leaving attached ones - running. - -## wake-lock - - Synopsis: wake-lock [args...] - Runs a command under systemd-inhibit, preventing the system from going - idle or sleeping until the command completes. - - wake-lock rsync -avz src/ dest/ - ---- diff --git a/docs/manualtools.py b/docs/manualtools.py index 685ed1e..793c543 100644 --- a/docs/manualtools.py +++ b/docs/manualtools.py @@ -3,7 +3,8 @@ # SPDX-License-Identifier: AGPL-3.0-or-later """Shared helpers for the docs/manual SSOT pipeline. -Frontmatter parsing, deterministic tree ordering, and heading level shifts. +Frontmatter parsing, deterministic tree ordering, heading level shifts, and +the `functions/*.fish` comment-header parser that is the SSOT for Section 5. Used by build-manual.py and verify-manual.py. """ @@ -57,6 +58,88 @@ def shift_headings(body: str, by: int) -> str: return "\n".join(out) +HEADER_LABEL = re.compile(r"^#\s+([A-Z][A-Z ]*[A-Z])\s*$") +FUNC_DEF = re.compile(r"^\s*function\s+(\S+)") +SECTIONS = ( + "CATEGORY", + "DEPENDENCIES", + "SYNOPSIS", + "DESCRIPTION", + "ARGUMENTS", + "RETURNS", + "EXAMPLE", + "NOTES", +) + + +def _header_blocks(lines: list[str]) -> list[tuple[int, dict[str, list[str]]]]: + """Find every man-page comment header in a file's lines. + + Yields (index of the line that ended the block, {LABEL: body lines}). + Body lines keep any indentation deeper than the standard `# ` prefix, + which is what lets nested option tables survive into the rendered entry. + Comment runs carrying no `# LABEL` line at all (the copyright preamble, + ordinary inline comments) produce nothing. + """ + out: list[tuple[int, dict[str, list[str]]]] = [] + cur: dict[str, list[str]] = {} + label: str | None = None + for i, line in enumerate(lines + [""]): + if not line.startswith("#"): + if cur: + out.append((i, cur)) + cur, label = {}, None + continue + m = HEADER_LABEL.match(line) + if m: + label = m.group(1) + cur.setdefault(label, []) + elif label is not None: + body = line[1:] + cur[label].append(body[3:] if body.startswith(" ") else body.strip()) + return out + + +def _trailing_blanks(lines: list[str]) -> int: + """Count the blank `#` separator lines closing a section.""" + n = 0 + while n < len(lines) and not lines[len(lines) - 1 - n].strip(): + n += 1 + return n + + +def parse_functions(root: Path) -> dict[str, dict[str, list[str]]]: + """Parse the comment header above every documented public function. + + `root` is the repository's `functions/` directory. Returns + `{name: {LABEL: [lines]}}`. + + `# CATEGORY` is the opt-in: a header without one produces no entry. That + keeps bundled-plugin and prompt internals (`fish_prompt`, `sponge_filter_*`, + `fisher`, …) out of the manual with no exclusion list to maintain. + + A file carrying exactly one header is associated with its own stem, so a + `function` nested inside a `type -q` guard still resolves. Only files with + several headers walk forward to the next `function` definition. + """ + out: dict[str, dict[str, list[str]]] = {} + for path in sorted(root.glob("*.fish")): + lines = path.read_text(encoding="utf-8").split("\n") + blocks = _header_blocks(lines) + for end, sections in blocks: + if len(blocks) == 1: + name = path.stem + else: + after = (m.group(1) for ln in lines[end:] if (m := FUNC_DEF.match(ln))) + name = next(after, path.stem) + if name.startswith("_") or "CATEGORY" not in sections: + continue + out[name] = { + k: v[: len(v) - _trailing_blanks(v)] for k, v in sections.items() + } + return out + + def _sort_key(entry: Path) -> tuple: """Order by sidebar.order when present, else by filename. Stable.""" target = entry / "index.md" if entry.is_dir() else entry diff --git a/docs/verify-manual.py b/docs/verify-manual.py index 6c7279c..74d6c94 100644 --- a/docs/verify-manual.py +++ b/docs/verify-manual.py @@ -4,6 +4,7 @@ """Verification checks for the docs/manual SSOT pipeline.""" import importlib.util +import re import sys import tempfile from pathlib import Path @@ -109,14 +110,113 @@ def test_manual_tree_exists(): assert len(cats) == 14, f"expected 14 function categories, got {len(cats)}: {cats}" -def test_function_entries_promoted_to_h2(): +def test_function_stubs_carry_no_entries(): + """Category files are stubs: entries come from functions/*.fish headers. + + An authored `##` entry here would be a second copy of a function's + documentation — exactly the duplication the header-SSOT migration + removed — and the generator would emit its own entry alongside it. + """ root = Path(__file__).parent / "manual" / "05-functions" for path in root.glob("*.md"): if path.name == "index.md": continue _, body = mt.parse(path) - assert "\n### " not in f"\n{body}", f"{path.name} still has H3 entries" - assert "\n## " in f"\n{body}", f"{path.name} has no H2 function entries" + stray = [ln for ln in body.split("\n") if ln.startswith(("## ", "### "))] + assert not stray, f"{path.name} has authored entries: {stray}" + + +def _parsed_functions() -> dict[str, dict[str, list[str]]]: + return mt.parse_functions(Path(__file__).parent.parent / "functions") + + +def test_every_categorised_function_produces_one_entry(): + import build_manual + + functions = _parsed_functions() + entries = build_manual.build_entries(functions) + got = [name for names in entries.values() for name, _ in names] + assert sorted(got) == sorted(functions), ( + f"entry/function mismatch: " + f"{sorted(set(functions) ^ set(got))}" + ) + assert len(got) == len(set(got)), "a function produced more than one entry" + + +def test_entries_carry_the_required_sections(): + missing = [] + for name, fn in _parsed_functions().items(): + absent = [s for s in ("SYNOPSIS", "DESCRIPTION", "EXAMPLE") if not fn.get(s)] + if absent: + missing.append(f"{name}: {', '.join(absent)}") + assert not missing, "headers missing required sections:\n " + "\n ".join(missing) + + +def test_every_category_resolves_to_a_stub(): + root = Path(__file__).parent / "manual" / "05-functions" + stubs = {p.stem for p in root.glob("*.md") if p.name != "index.md"} + used = {} + for name, fn in _parsed_functions().items(): + used.setdefault(" ".join(fn.get("CATEGORY", [])).strip(), []).append(name) + unknown = {c: v for c, v in used.items() if c not in stubs} + assert not unknown, f"# CATEGORY values with no stub: {unknown}" + empty = sorted(stubs - set(used)) + assert not empty, f"category stubs generating zero entries: {empty}" + + +def test_dependencies_resolve(): + """Every declared # DEPENDENCIES name must be a real function or binary. + + Catches typos, and catches stale entries when a dependency is renamed + or deleted. External binaries are accepted when some file in the tree + guards them with `type -q`, which is this repo's convention. + """ + repo = Path(__file__).parent.parent + functions = _parsed_functions() + known = {p.stem for p in (repo / "functions").glob("*.fish")} | set(functions) + for path in list(repo.glob("conf.d/*.fish")) + list((repo / "functions").glob("*.fish")): + known |= set(re.findall(r"type -q\s+(\S+)", path.read_text(encoding="utf-8"))) + dangling = [] + for name, fn in functions.items(): + for dep in (d for d in re.split(r"[,\s]+", " ".join(fn.get("DEPENDENCIES", []))) if d): + if dep not in known: + dangling.append(f"{name} -> {dep}") + assert not dangling, "unresolvable # DEPENDENCIES:\n " + "\n ".join(dangling) + + +def warn_public_functions_without_category(): + """Warn — never fail — on a public function carrying no `# CATEGORY`. + + Bundled plugin and prompt internals will always lack one, so this + cannot be a hard failure; a genuinely new user-facing function going + undocumented still needs to be visible in CI output. + """ + repo = Path(__file__).parent.parent + documented = set(_parsed_functions()) + orphans = sorted( + p.stem + for p in (repo / "functions").glob("*.fish") + if not p.stem.startswith("_") + and p.stem not in documented + and "# SYNOPSIS" in p.read_text(encoding="utf-8") + ) + if orphans: + print(f" WARN {len(orphans)} documented function(s) lack # CATEGORY:") + print(" " + ", ".join(orphans)) + + +def _without_section_5(text: str) -> str: + """Drop `# 5. FUNCTIONS REFERENCE` through the start of section 6. + + Section 5 is generated from `functions/*.fish` headers, so it + legitimately differs from the pre-migration snapshot. The round-trip + guard covers the authored sections either side of it. + """ + start = text.find("\n# 5. ") + if start == -1: + return text + end = text.find("\n# 6. ", start) + return text[:start] + (text[end:] if end != -1 else "") def _normalise(text: str) -> str: @@ -128,6 +228,11 @@ def _normalise(text: str) -> str: def test_concat_roundtrips_original(): """The concat of manual/ must reproduce the original fish-config.md exactly. + Section 5 is excluded: it is generated from `functions/*.fish` headers + and so legitimately differs from the snapshot. This test guarded the + *format* migration; the header-SSOT change is a *content* migration, + covered instead by the structural checks above. + Prefers docs/fish-config.md.orig (a snapshot of the pre-migration file) when present. Once that snapshot is deleted post-migration, docs/fish-config.md IS the concat output regenerated in Step 5, so @@ -149,8 +254,8 @@ def test_concat_roundtrips_original(): if not original.exists(): original = docs / "fish-config.md" label = "fish-config.md" - got = build_manual.build_concat(docs / "manual") - want = original.read_text() + got = _without_section_5(build_manual.build_concat(docs / "manual")) + want = _without_section_5(original.read_text()) if got != want: norm_got = _normalise(got) norm_want = _normalise(want) @@ -393,6 +498,7 @@ def main() -> int: except AssertionError as e: print(f" FAIL {t.__name__}: {e}", file=sys.stderr) failed += 1 + warn_public_functions_without_category() print(f"\n{len(TESTS) - failed}/{len(TESTS)} passed") return 1 if failed else 0 diff --git a/functions/agy.fish b/functions/agy.fish index a1f825b..2b4dd56 100644 --- a/functions/agy.fish +++ b/functions/agy.fish @@ -4,6 +4,9 @@ # CATEGORY # 12-ai-and-developer-tools # +# DEPENDENCIES +# agents-init +# # SYNOPSIS # agy [ARGS...] # diff --git a/functions/claude.fish b/functions/claude.fish index dad6ad4..b393cf9 100644 --- a/functions/claude.fish +++ b/functions/claude.fish @@ -4,6 +4,9 @@ # CATEGORY # 12-ai-and-developer-tools # +# DEPENDENCIES +# agents-init +# # SYNOPSIS # claude [ARGS...] # diff --git a/functions/config-toggle.fish b/functions/config-toggle.fish index 058f1e3..e8e329a 100644 --- a/functions/config-toggle.fish +++ b/functions/config-toggle.fish @@ -4,6 +4,9 @@ # CATEGORY # 14-miscellaneous # +# DEPENDENCIES +# config-settings +# # SYNOPSIS # config-toggle [args...] # diff --git a/functions/git-clean.fish b/functions/git-clean.fish index e43d60b..91ee5f2 100644 --- a/functions/git-clean.fish +++ b/functions/git-clean.fish @@ -13,8 +13,7 @@ # main/master automatically if the current branch is orphaned. # # ARGUMENTS -# -h, --help Show help message -# -f, --force Force-delete unmerged branches too +# -h, --help Show help message # -f, --force Force-delete unmerged orphaned branches (git branch -D) # # RETURNS diff --git a/functions/open-url.fish b/functions/open-url.fish index 6c6496d..29df418 100644 --- a/functions/open-url.fish +++ b/functions/open-url.fish @@ -39,8 +39,6 @@ # open-url -v https://fish-config-docs.pages.dev/ # # NOTES -# Used internally by config-help --html. -# # Typo abbreviation: url-open (expands to open-url on space/enter). function open-url --description 'Open a URL in the best available web browser' argparse h/help s/silent v/verbose -- $argv diff --git a/functions/repo-open.fish b/functions/repo-open.fish index c9f0375..99cc2fe 100644 --- a/functions/repo-open.fish +++ b/functions/repo-open.fish @@ -4,6 +4,9 @@ # CATEGORY # 14-miscellaneous # +# DEPENDENCIES +# open-url +# # SYNOPSIS # repo-open [-p|--print] [-r|--root] # repo-open --help