Command catalog
This is the grouped lookup for commands that are useful but not always front-and-center.
GitHub / PR helpers
| Command | Description |
|---|---|
,view-my-issues | Browse your GitHub issues with fzf preview |
,remove-comment | Delete a comment from the current PR via fzf picker |
,gh-subissues-create | Draft multiple sub-issues in your editor, create them, and attach to a parent issue via GitHub's sub-issue GraphQL API |
,check-backport-progress | Find PRs missing backports or required labels across target branches |
,disable-auto-merge | Disable auto-merge for all open PRs targeting a base branch |
,enable-auto-merge | Enable auto-merge for all open PRs targeting a base branch |
,trace-string-pr | Locate the PR that introduced a matching string and open it in the browser |
,hey-branch | Quick "am I in sync with upstream?" status: ahead/behind plus missing remote |
,codeowners | List matching owners, owned paths, or the last CODEOWNERS owner for a path |
Search / discovery helpers
| Command | Description |
|---|---|
,grepo | Grep for a pattern across files and open the selected match in $EDITOR at the right line |
,search-brew-desc | Search installed Homebrew formula descriptions as JSON |
,fuzzy-brew-search | Fuzzy search Homebrew descriptions, then drive an "add this to Brewfile" workflow |
,search-gh-topic | Search GitHub repos by topic with preview, then open the selected repo |
,youtube-search | Search YouTube from an fzf TUI with filters, preview, browser open, and mpv playback |
Testing / analysis helpers
| Command | Description |
|---|---|
,jest-test-title-report | Compare Jest test titles between two worktrees and emit a CSV report |
,get-risky-tests | Run Jest and report tests whose runtime exceeds a threshold |
,get-age-buckets | Compute file age buckets from git history to spot stale areas |
,generate-git-sandbox | Create a throwaway git repo for testing rebases, merges, and scripts |
Kibana development helpers
| Command | Description |
|---|---|
,kbn-stack | Spin up an ES + Kibana dev stack for the current worktree: auto-allocates a slot (unique port, cookie name, encryption key) so many worktrees run in parallel without /etc/hosts; default snapshot starts share one background ES per resolved ES version (the worktree package.json version, which is what pnpm es snapshot downloads, or yarn es snapshot on a branch without pnpm-lock.yaml): the first compatible start creates the instance under the reserved __es__ registry key with data dir es_data/shared-<version> and later compatible starts attach their Kibana to it instead of spawning another JVM, while any ES-level override (-E, --data, non-default --es-heap, or explicit --isolated-es) keeps the historical fully isolated per-worktree ES (-K/--groups never affect sharing; same-version Kibanas share .kibana* saved objects like an HA pair, and a branch whose saved-object migrations clash should rerun with --isolated-es); before allocating a snapshot slot it reclaims stale slots by probing Kibana/ES ports and cleaning up any surviving half, then chooses the lowest free slot, but keeps a slot reserved while a recorded launcher or stack PID is alive so a bootstrapping stack with no bound ports is not mistaken for dead; before starting anything it fails fast when a foreign process already holds the slot's Kibana/ES ports, naming the squatting pid and its command (an orphaned stack would otherwise FATAL the new Kibana while answering /api/status with stale code); a share-eligible start also settles the worktree's previous non-shared stack first: an orphaned isolated ES half (Kibana dead, no recorded process alive) is stopped so it cannot leak untracked once the entry is overwritten, while a still-owned previous stack (any recorded process alive, Kibana listening, or serverless containers up) fails the start with a --stop hint; --status works outside a Kibana worktree and lists all registry entries as ready, starting, degraded, or stale from recorded readiness plus current process and Kibana/ES port liveness without mutating the registry; --prune removes only fully stale entries and never stops a worktree stack (its only stop is an idle shared ES, see below), and interactive ES/Kibana exits invoke the same pruning path so the registry entry disappears after both halves are down while starting, ready, and degraded entries remain; --es snapshot (default; isolated snapshot stacks stay fully parallel) or --es serverless (single-instance: kbn-es runs fixed es01/es02 containers, so serverless pins to slot 0, auto-stops agent-owned serverless stacks first, refuses to auto-stop user-owned serverless stacks from agent mode, and refuses to start over a snapshot stack or live shared ES on the conflicting low ports); --project-type accepts Kibana names (es, security, oblt): the serverless ES command maps es to elasticsearch_general_purpose, oblt to observability, and leaves security unchanged, while Kibana retains its short --serverless value; serverless ES uses HTTPS and passes the host data parent as --basePath plus a relative --dataPath inside the Docker mount, waits for serverless security-index readiness (--waitForReady), skips snapshot trial-license setup, records detached process IDs before readiness waits, and removes both ES and UIAM containers on --stop; keeps --data/-E flexibility (snapshot starts also pass -E indices.merge.disk.watermark.high=2gb as an absolute merge-disk floor before user -E flags, so a later -E of the same key overrides) and adds -K key=value (repeatable) to start Kibana with extra settings such as a dev/feature flag (-K xpack.index_management.dev.enableSemanticField=true) in one shot, recorded in the registry entry's kbn_flags; defaults --groups platform (injected as plugins.allowlistPluginGroups, restart to change; --groups all loads every group) and snapshot --es-heap 1g (--es-heap 1536m restores the kbn-es snapshot default). Interactive default runs ES in the current tmux pane and auto-launches Kibana in a second pane once ES is ready (splits the window if only one pane exists, reuses an existing 2-pane layout otherwise); a shared ES instead runs detached (it must outlive the pane) with the current pane following its log — Ctrl-C detaches from the log without stopping ES — and an interactive attach to an already-live shared ES launches only Kibana. --detach is the agent mode: starts ES + Kibana headless in the background (attaching to a compatible live shared ES starts only Kibana), waits until Kibana answers /api/status and the port listener belongs to the spawned Kibana's process tree (an orphan squatting the port can answer the status probe while the new Kibana died on bind — that stack is marked not ready and the squatter is named), marks the stack ready with started_by: "agent" and start_mode: "agent-detach" in the registry, then returns. --stop tears down the current worktree's registered stack and drops its registry entry: it kills recorded detached/serverless process groups when present, then kills whatever still listens on the slot's Kibana/ES ports by signaling the listener process group (so a Kibana that closes the port and hangs still gets SIGKILL), dropping the entry even when nothing is left running; on a shared-ES stack --stop kills only that worktree's Kibana half and refcounts the shared ES — it keeps running while any other registered worktree references it and is stopped by the last detach; --stop-all tears down every registered stack the same way, including pid-less interactive tmux entries and shared ES instances, then clears the registry. Snapshot data dirs carry a one-shot 30-day trial license: the tool records the expiry in <data dir>/.kbn-stack-license.json, and before a start (recorded expiry passed) or when the ES log reports LICENSE [EXPIRED] it moves the dir to <name>.expired-<timestamp> and starts a fresh cluster once (moved dirs are kept; delete es_data/*.expired-* to reclaim disk); an ES launcher that exits before setup completes fails the start immediately with the log's last error lines instead of waiting out the 600s timeout. A shared ES lives only while it has a Kibana client (a Kibana listening on an attached slot, a recorded Kibana process still alive through a dev-mode restart, or an attached start still bootstrapping): a detached reaper watchdog per instance (reaper_pid, re-armed on every attach) stops it about 60 seconds after the last client disappears, with starts, --prune, and interactive-exit pruning applying the same rule as a fallback; --status shows (N attached, no client Ns). A share-eligible start also inspects the branch diff (merge base with main plus uncommitted edits): server-side saved-object definitions, model versions, migrations, index templates, or ingest pipelines force an isolated ES with the files named, and --share-es overrides that. Internals live in ~/lib/,kbn-stack/kbn_stack/ (config, cli, checkout, procs, store, slots, liveness, trial_license, es_log, shared_es, lifecycle, launch) behind the thin main.py entrypoint |
AI / agent helpers
| Command | Description |
|---|---|
,agent-memory | Standalone launcher into ~/lib/,agent-memory/ (no repository lookup): inspect /tmp/specs hook memory, bind one agent session to a shared topic bucket, record structured insight notes, merge near-duplicate topics, or wipe selected topic files (named topics are mirrored to persistent state and restored after reboot) |
,artifact | Create cache-only local HTML artifacts and live-page feedback overlays with hidden-by-default feedback capture (click pins one anchor, Cmd-click pins multiple targets for a single prompt); tagged artifacts can return generic semantic entity IDs, ancestors, and relations from data-artifact-id plus an embedded manifest; per-session feedback pollers stay outside the worktree |
,ai | Resolve generated model availability plus orthogonal depth/execution/connectivity controls into a redacted InvocationPlan, then delegate to the existing harness leaf; unsupported explicit hard constraints fail before launch. |
,q | One-shot OpenRouter pi agent (inclusionai/ling-3.0-flash) with tools on, a short system prompt, and skills/context/extensions/APPEND_SYSTEM off |
,ai-kb | Manage the durable local agent knowledge base from its deployed ~/lib/,ai-kb/ core; ordinary operations use one-shot embeddings, automatic per-turn adapters connect only to the session-warmed resident worker, and harvest flushes the bounded worklog queue before reading |
,ai-usage | Cost-weighted token usage from local harness records: fresh input, cache read, cache write, output and reasoning per session, with the cache-hit rate, read from Claude transcripts, Codex rollouts, Pi and OMP sessions, the OpenCode database and Copilot session events (--days, --harness, --by harness or --by model,--json); raw provider counts, no prices, and Cursor is listed as unmeasured because it keeps no local record |
,proof | Maintain repo-external durable receipts for narrowly gated freeform work, with criteria/evidence assessments, mandatory finalization before reports, provenance visibility, secret scanning, and age-based pruning |
,doctor ai | Report the ownership-aware effective state of generated AI configs; --json is scriptable and --live adds deduplicated local consumer probes without applying or refreshing anything |
,probe | Record a failed probe (,probe fail, chained onto the failing command; pass is accepted but not recorded by agents) to the active session's JSONL ledger so the per-turn hook can surface the "re-read the source" hint after 3 failures within 30 minutes; the session-scoped path resolves through ,agent-memory, and entries recorded without a harness session id land in the workspace ad-hoc ledger, which the per-turn reader consumes as a fallback under the same 30-minute window (Agent reasoning failure modes) |
,llama-cpp | Manage the local llama.cpp endpoint, including shared leases that auto-start a loopback router, configurable last-consumer grace, and an ownership-safe explicit stop that treats zombie owners as already stopped |
,codex | Launch Codex with local llama.cpp model catalog metadata injected when a local model is selected; hosted MCP auth needs no launch-time work because those servers run as ,mcp-token --bridge stdio bridges |
,claude-codex | Launch Claude Code through an authenticated loopback adapter that translates Anthropic Messages to the current Codex ChatGPT subscription; accepts wrapper-level model and reasoning-effort overrides, derives Claude's compaction window from the selected Codex model metadata, and inherits Codex's category lane schema |
,claude-copilot | Launch Claude Code through an authenticated loopback using the current GitHub Copilot subscription; passes native Anthropic Messages through and translates Responses/Chat Completions models, validates model, effort, thinking mode, and default/long_context context tier against the live catalog, keeps the GitHub token out of Claude's environment, and inherits Copilot's category lane schema |
,claude-llama-cpp | Launch Claude Code with a shared auto-managed llama.cpp router lease |
,claude-openrouter | Launch Claude Code against OpenRouter's Anthropic Messages endpoint, defaulting the root session to z-ai/glm-5.3-flash at high effort while delegated lanes inherit Pi's OpenRouter schema through alias defaults (fable: Fable 5.1, opus: GPT-5.6 SOL, sonnet: GLM 5.3 Flash, haiku: Gemini memory); --context short|long keeps the wire model bare and sets a compaction budget that fits the root and reachable aliases |
,codex-llama-cpp | Launch Codex with a shared auto-managed llama.cpp router lease |
,codex-openrouter | Launch Codex against OpenRouter's OpenAI Responses endpoint, defaulting the root session to z-ai/glm-5.3-flash at high effort while delegated lanes inherit Pi's OpenRouter schema |
,codex-copilot | Launch Codex through an authenticated loopback using the current GitHub Copilot subscription; passes native Responses through and translates Messages/Chat Completions models, exposes the selected tier's prompt limit to Codex and auto-compacts at 90% of it, applies --thinking auto|on|off when the selected backend is Claude/Messages-capable, keeps the GitHub token out of Codex's environment, and inherits Copilot's category lane schema; projects session-local entitled child models and leaf profiles without changing native Codex profiles |
,opencode-llama-cpp | Launch OpenCode with a shared auto-managed llama.cpp router lease and profile-specific context/output limits |
,copilot | Launch the real GitHub Copilot CLI; bare --resume selects from the local session store first and then launches --session-id=<id>, avoiding Copilot 1.0.73's temporary-session MCP startup race and throwaway session row. Explicit resume IDs and other arguments pass through unchanged; this remains the stable entry point for ,copilot-* BYOK wrappers. Hosted MCP auth needs no launch-time work because those servers run as ,mcp-token --bridge stdio bridges |
,copilot-codex | Launch GitHub Copilot CLI through an authenticated loopback adapter that converts its Responses request to the current Codex ChatGPT subscription's required streaming transport; accepts wrapper-level model and reasoning-effort overrides and inherits Codex's category lane schema |
,copilot-openrouter | Launch GitHub Copilot CLI against OpenRouter's cache-capable Anthropic Messages endpoint, defaulting the root session to z-ai/glm-5.3-flash at high effort while delegated lanes inherit Pi's OpenRouter schema; --context short|long resolves separate prompt/output budgets from OpenRouter's live catalog |
,cursor | Launch cursor-agent natively after validating each authenticated HTTP MCP token (oauth or auth.CLIENT_ID) and checking each hosted server's current-working-workspace cache; a workspace missing auth is seeded from the newest verified cached chain, with that workspace's browser login as last resort before launch, while proactive rotation stays runtime-owned and critical/expired/revoked tokens still refresh synchronously; admin subcommands bypass the preflight |
,cursor-codex | Launch Cursor's local-agent flavor through an authenticated loopback adapter that translates Chat Completions to the current Codex ChatGPT subscription and inherits Codex's category lane schema |
,cursor-copilot | Launch Cursor's local-agent flavor through an authenticated loopback adapter backed by the current GitHub Copilot subscription, including separate --thinking auto|on|off for Claude/Messages-capable selected backends, and inherits Copilot's category lane schema |
,cursor-llama-cpp | Launch Cursor's version-matched agent-cli-local flavor with a shared auto-managed llama.cpp router lease; accepts the llama.cpp router ids and supplies their context metadata through a local proxy |
,cursor-openrouter | Launch Cursor's agent-cli-local flavor (auto-installed in lockstep with cursor-agent from Cursor's per-version S3 tarballs) against OpenRouter's OpenAI-compatible endpoint, defaulting the root session to z-ai/glm-5.3-flash at high; delegated lanes inherit Pi's OpenRouter schema. Every session runs through the loopback shim, which allowlists the root and Pi lane wire ids at the HTTP layer, strips strict from openai/* tool schemas, rewrites inbound Bash tool calls to Shell, and retries empty successful tool-mode responses without tools so Cursor can use no-tools chat paths for affected models |
,mcp-token | Print a valid MCP token for slack/scsi-main from cursor's OAuth cache; direct --login guarantees runway (--no-proactive-rotation keeps proactive rotation off the critical path, ensures current-workspace auth by seeding a missing workspace cache from a verified cached chain with browser last, and still rotates synchronously in the blocking window or for expired/revoked tokens); --bridge --url serves a stdio MCP bridge that injects a fresh bearer per request, rotates the current workspace's refresh chain even when cursor omitted .workspace-trusted, and resurrects server-expired sessions; generated read-only endpoints may opt into one exact upstream connection-timeout retry |
,letsfg-docker | Run LetsFG in a headless Docker/Podman container with Xvfb for browser-based flight connectors |
Provider wrappers with model choices accept --model <id> / -m <id>; older direct-provider wrappers may also accept a model ID as the first argument. The four *-openrouter wrappers clear inherited subscription and Claude/Codex lane maps before selecting Pi/OpenRouter routing. They default to z-ai/glm-5.3-flash at high but accept --model and --effort, composing <model>@preset/effort-<level> for every model. Before launch, they prepare the selected effort plus the delegated low, high, and xhigh presets in the active OpenRouter account, once per distinct level, and leave existing presets unchanged. Claude maps Fable/high to fable, SOL/high to opus, GLM/high to sonnet, and Gemini/low to haiku; its unmatched SOL/xhigh refute pair is denied rather than substituted. Cursor admits the exact Gemini memory wire alongside the other Pi lanes; unrelated model wires remain denied. Levels include none (disables reasoning) through max. All four OpenRouter wrappers accept --context short|long: short stays below the first pricing transition when present; both tiers reserve output space within provider capacity. Claude/Copilot use the smallest reachable model budget; Codex/Cursor receive per-model context metadata. The default resolves to z-ai/glm-5.3-flash@preset/effort-high with short context. Fish completions list choices only where the wrapper accepts them.
The model-selecting wrappers expose --effort <level>, --thinking <mode>, and --no-thinking when the route has an equivalent control. Copilot-backed suffix wrappers use --thinking auto|on|off separately from --effort for Claude/Messages-capable selected backends, and reject the thinking override for other selected backends. The Codex subscription wrappers accept none|minimal|low|medium|high|xhigh|max|ultra; explicit wrapper controls select the root; only explicit lane tags select child model/effort controls. Claude aliases carry exact pairs and deny unrepresentable pairs. Cursor/Codex/Copilot subscription frontends without verified child-tag transport run delegation unpinned; their root sessions and native harness routes remain available. The selected backend model still decides which values it supports. Pi maps to --thinking; OpenCode maps effort to run --variant; direct Codex wrappers map to model_reasoning_effort; direct Copilot wrappers map --thinking to --effort.
Plain interactive claude stays native. Plain interactive codex, copilot, and cursor-agent route through the managed ,codex / ,copilot / ,cursor wrappers (the agent alias also routes through ,cursor); hosted MCP tokens for Copilot and Codex are injected per request by ,mcp-token --bridge stdio servers, while ,cursor validates cursor's own OAuth tokens before launch. Local/provider-specific wrappers (*,llama-cpp, ,claude-codex, ,copilot-codex, ,claude-copilot, ,codex-copilot, ,codex-openrouter, ,claude-openrouter, ,copilot-openrouter) select their own upstreams.
Unified harness launcher: ,ai
~/bin/,ai is a thin launcher for ~/lib/,ai/main.py. It resolves three independent fields:
--depth fast|balanced|deepis a soft preference. Unsupported transports remain visible asadvisoryin the plan instead of failing.- Explicit
--execution readonly|supervised|autonomousand--connectivity online|offlineare hard constraints. A harness without a verified transport fails before launch. --alias auditexpands todepth=deepplusexecution=readonly;--alias offlineexpands toconnectivity=offline. A conflicting explicit field or leaf argument is an error, not an override.
,ai claude --depth deep --execution readonly --dry-run
,ai pi --provider openrouter --execution readonly --explain
,ai copilot --execution autonomous -- --name hands-off
--dry-run emits redacted InvocationPlan JSON and executes no harness. --explain renders the same harness resolution for people. Plans include every field's provenance, bounded consumer_view.v1 catalog metadata, and the exact generated leaf argv/environment delta. Real runs export AI_AGENT_DEPTH, AI_AGENT_EXECUTION, and AI_AGENT_CONNECTIVITY, then exec the stable existing leaf (,cursor, claude, ,codex, agy, opencode, pi, or ,copilot) so token/config logic stays in its current owner. The unified selector remains gemini; it launches Antigravity CLI.
The capability matrix is intentionally asymmetric: no harness currently has a verified provider-isolating offline transport, so explicit connectivity=offline and the offline alias fail closed. Pi's native --offline only disables startup network operations. OpenCode has no verified read-only transport, Pi has no verified supervised approval mode, Antigravity and the effort-aware harnesses receive explicit depth flags, and Cursor depth needs a concrete model to carry its parameterized effort. Pi's default OpenRouter route supplies openai/gpt-5.6-sol at thinking xhigh automatically. Naming a non-OpenRouter model (the llama-cpp nemotron-3.5/qwen3.5-9b/qwen3.8-27b{,-instruct} ids) or an explicit --depth falls through to normal resolution; only an explicit --provider openrouter re-enters the pin and rejects --depth.
Planning reads ~/.config/ai/model-mirrors.v1.json through the same shared consumer module used by the repo generator and never contacts providers. A known, complete available catalog rejects absent explicit models; incomplete or unknown catalogs preserve low-level explicit selection. The Pi OpenRouter route is the deliberate exception: it emits openai/gpt-5.6-sol and --thinking xhigh; a missing or malformed generated mirror fails visibly. An explicit openrouter/... model is accepted only when the mirror's per-harness available list sanctions it (Pi: the bare route set — GPT-5.6 SOL, GLM 5.3 Flash, DeepSeek V4.1 Flash, Gemini 3.8 Flash, Sonnet 4.6, Kimi, and GLM-5.2; OpenCode: the preset-suffixed GLM 5.3 Flash, DeepSeek, Kimi, and GLM-5.2 ids) — anything else is rejected as a route escape, and --depth is rejected only when the accepted id carries an effort-baking @preset/ slug.
Token usage across harnesses: ,ai-usage
,ai-usage # last 7 days, one row per session
,ai-usage --days 30 --by harness
,ai-usage --harness codex --by model --json
Raw input-token counts overstate cost: providers re-read most of a long conversation from cache at a discounted rate, and only new material is written at full price. The report splits every session into fresh input, cache read, cache write, output and reasoning so routes can be compared on what is actually billed. It applies no prices. Harnesses without a local record (Cursor) are listed as unmeasured, never as zero. --signals adds prompts, user-correction signals, SOP re-injections, and cache misses per session; a miss is a call that re-read under half of the previous call's context, the moment the prompt cache was lost and rebuilt at full price.
Codex rollout input includes both cache reads and writes. For per-call observations and session totals, fresh input is max(0, input_tokens - cached_input_tokens - cache_write_input_tokens). Missing write counters count as zero; writes are not added twice to context or the cache-miss threshold.
One-shot pi agent: ,q
,q "What is 2+2?"
,q --dry-run "ping"
printf '%s' "$prompt" | ,q
~/bin/,q is a thin launcher for ~/lib/,q/main.py. It skips harness resolution and the GLM 5.3 Flash pin. It execs pi against OpenRouter inclusionai/ling-3.0-flash with --thinking off, --no-session, --offline, a short --system-prompt, empty --append-system-prompt (skips ~/.pi/agent/APPEND_SYSTEM.md), and the --no-skills / --no-themes / --no-context-files / --no-prompt-templates / --no-extensions discovery flags. Tools stay enabled. The short prompt replaces Pi's coding-assistant default; Pi still appends the cwd. AGENTS.md, skills, and extensions stay off. Prompt words are the user message; with no words, stdin is the prompt. The explicitly loaded q_literal.md template passes one quoted argument through as literal text, preserving leading flags, @, quotes, and whitespace; default template discovery remains off. --dry-run emits the pi argv JSON.
Utility helpers
| Command | Description |
|---|---|
,cp-files-for-llm | Copy a directory tree's text contents to the clipboard with file headers |
,appid | Print the macOS bundle identifier for an app name/path |
,dumputi | Dump the system's registered Uniform Type Identifiers |
,to-gif | Convert a video to an optimized GIF |
,vid-ipad | Re-encode a video for iPad playback |
,pdf-diff | Visual diff two PDFs by compositing pages |
,nano-banana | Cloud Gemini generate/edit/compose/inpaint (uploads to Google) |
,image-local | On-device FLUX.2 klein 9B generate (512 default) and -i edit at input size |
,image-openrouter | OpenRouter generate/edit; Seedream 5 Pro; strips input metadata; ZDR routing |
,image-codex | Codex subscription GPT Image 2 generate/edit; automatic settings; strips inputs |
,image-openai | Native GPT Image 2 generate/edit/mask with quality, size, and format controls |
,set-default-mic | Select the preferred external microphone, falling back to the MacBook microphone |
,update | Reconcile dotfiles and package-manager update categories |
,parallel | Forward to GNU Parallel when both GNU Parallel and semantic-git are installed |
,sem | Forward to Ataraxy semantic-git's entity-level CLI (telemetry, update check, cloud off) |
,format-md | Conservatively format AI Markdown; leave ordinary Markdown unchanged |
,weave-setup-local | Configure weave merge driver in repo-local git config and .git/info/attributes |
,weave-unsetup-local | Remove the local-only weave merge driver setup |
Fish history sync: ,history-sync
- Source:
home/exact_bin/executable_,history-sync - Merge logic:
home/exact_lib/exact_,history-sync/fish-history-merge.py - Stores the synced history in the 1Password document
fish-history-sync, which doubles as an off-machine backup. - Merges by command text, keeping the most recent timestamp and writing entries chronologically.
Safety behavior:
- Before replacing local history, it writes
~/.local/share/fish/fish_history.bak. - It refuses to install/push a merged result with fewer entries than the remote copy.
- If remote pull fails but the
fish-history-syncitem exists, it aborts instead of overwriting good remote history with local-only history.
If you restore history out-of-band while fish is running, run history merge in active fish shells or restart them.
Internal plumbing
These are used by scripts, fzf integrations, and Neovim; you rarely invoke them directly.
| Command | Description |
|---|---|
,bat-preview | Smart preview for fzf: images via chafa, binaries via hexyl, directories via ls, text via bat |
,fzf-git-changed-lines | Emit changed lines as grep-like entries for fzf |
,fzf-preview-follow | Center fzf preview around a match line |
,fzf-rg-multiline | Convert ripgrep output into NUL-delimited multi-line fzf entries |
Verification
make verify-bin-surface
command -v ,w
command -v ,gh-prw
command -v ,tmux-run-all
If commands are missing after apply, verify the script exists under home/exact_bin/, has the correct executable_ prefix, has a matching Fish completion under home/dot_config/fish/completions/, and that ~/bin is on PATH.