docs(docs): update ctrl‑a keybinding docs to use omp‑session and add omp‑session script description

This commit is contained in:
Prad Nukala committed 2026-09-30 16:20:16 -04:00
1 parent 8b4a52a66d
commit 945cf46048
7 files changed
+57 -11

No files matched your search

+1 -1
View File
@@ -57,5 +57,5 @@ None of these files are role-gated: `.chezmoiignore.tmpl` applies them on every
## Shell entry points ## Shell entry points
- `ai` (fish function) opens a `gum choose` picker over `claude`, `opencode`, `codex`, `hermes`, and `fractal`. Picking `claude` runs `claude --dangerously-skip-permissions`; the others run the binary of the same name. See [fish](/shell/fish). - `ai` (fish function) opens a `gum choose` picker over `claude`, `opencode`, `codex`, `hermes`, and `fractal`. Picking `claude` runs `claude --dangerously-skip-permissions`; the others run the binary of the same name. See [fish](/shell/fish).
- <kbd>Ctrl</kbd> <kbd>A</kbd> opens the `agents` television cable from the fish prompt: every installed agent CLI (omp, claude, codex, opencode, …); <kbd>enter</kbd> starts it ([television](/tools/television#agents)). In zsh it still launches `omp`. - <kbd>Ctrl</kbd> <kbd>A</kbd> runs [`omp-session`](/shell/scripts#omp-session) from the fish and zsh prompt: on the default branch it resumes a session written in the last 3 hours, else opens the `omp-sessions` television cable; on any other branch it resumes that branch's newest session or starts a new one. `tv agents` still lists every installed agent CLI ([television](/tools/television#agents)).
- `launch_omp_livediff_overlay` and `lc-elir` are omp helpers in `~/.local/bin`; see [omp](/ai/omp#shell-integration) and [scripts](/shell/scripts). - `launch_omp_livediff_overlay` and `lc-elir` are omp helpers in `~/.local/bin`; see [omp](/ai/omp#shell-integration) and [scripts](/shell/scripts).
+1 -1
View File
@@ -168,7 +168,7 @@ Both count as done only when the full artifact is pasted in the chat.
| Entry point | Source | What it does | | Entry point | Source | What it does |
| --- | --- | --- | | --- | --- | --- |
| fish completions | `dot_config/fish/completions/omp.fish` | `omp completions fish \| source` generates completions at load time | | fish completions | `dot_config/fish/completions/omp.fish` | `omp completions fish \| source` generates completions at load time |
| <kbd>Ctrl</kbd> <kbd>A</kbd> | fish `fish_user_key_bindings` → `_agents_bind`, zsh `keybinds.zsh` | fish: the `agents` tv cable, with `omp` first; zsh: launches `omp` from the prompt | | <kbd>Ctrl</kbd> <kbd>A</kbd> | fish `fish_user_key_bindings`, zsh `keybinds.zsh` → `dot_local/bin/executable_omp-session` | Resumes or starts omp for the current repo: default branch → the session written in the last 3 hours, else the `omp-sessions` tv cable; other branches → that branch's newest session, else a new one. See [omp-session](/shell/scripts#omp-session) |
| `launch_omp_livediff_overlay` | `dot_local/bin/executable_launch_omp_livediff_overlay`, fish function of the same name | Opens omp as a kitty overlay on the current window with a `livediff` vsplit beside it, focus kept on omp. Needs `KITTY_LISTEN_ON` (kitty remote control). | | `launch_omp_livediff_overlay` | `dot_local/bin/executable_launch_omp_livediff_overlay`, fish function of the same name | Opens omp as a kitty overlay on the current window with a `livediff` vsplit beside it, focus kept on omp. Needs `KITTY_LISTEN_ON` (kitty remote control). |
| `lc-elir [root]` | `dot_local/bin/executable_lc-elir`, fish function | fzf multi-picks numbered LeetCode files (`1365.slug.js`/`.ts`) with a bat preview and runs `omp -p "/leetcode-eli5 <file>"` on each | | `lc-elir [root]` | `dot_local/bin/executable_lc-elir`, fish function | fzf multi-picks numbered LeetCode files (`1365.slug.js`/`.ts`) with a bat preview and runs `omp -p "/leetcode-eli5 <file>"` on each |
+1 -1
View File
@@ -92,7 +92,7 @@ The repo is a [chezmoi](https://chezmoi.io) source directory. It lives at `~/.lo
| `.chezmoiignore.tmpl` | — | Target paths chezmoi skips; gates the Linux desktop layer by role. | | `.chezmoiignore.tmpl` | — | Target paths chezmoi skips; gates the Linux desktop layer by role. |
| `.chezmoiscripts/`, root `run_*` | — | Install and housekeeping scripts. See [Apply scripts](/chezmoi/scripts). | | `.chezmoiscripts/`, root `run_*` | — | Install and housekeeping scripts. See [Apply scripts](/chezmoi/scripts). |
| `dot_config/` | `~/.config/` | Per-tool config. Documented under [Shell](/shell), [Terminal](/terminal), [Tools](/tools), [Desktop](/desktop). | | `dot_config/` | `~/.config/` | Per-tool config. Documented under [Shell](/shell), [Terminal](/terminal), [Tools](/tools), [Desktop](/desktop). |
| `dot_local/bin/` | `~/.local/bin/` | 33 standalone scripts shared by every shell. | | `dot_local/bin/` | `~/.local/bin/` | 34 standalone scripts shared by every shell. |
| `dot_claude/` | `~/.claude/` | Claude Code settings, commands, and hooks. See [AI agents](/ai/claude-code). | | `dot_claude/` | `~/.claude/` | Claude Code settings, commands, and hooks. See [AI agents](/ai/claude-code). |
| `dot_omp/` | `~/.omp/` | omp agent config and loops. | | `dot_omp/` | `~/.omp/` | omp agent config and loops. |
| `dot_leetcode/` | `~/.leetcode/` | leetcode CLI workspace state. | | `dot_leetcode/` | `~/.leetcode/` | leetcode CLI workspace state. |
+1 -1
View File
@@ -75,7 +75,7 @@ The tv pickers have their own widgets, because `tv --inline` opens on the line b
| <kbd>ctrl-p</kbd> | `pj-inline` (`pj` cable) | | <kbd>ctrl-p</kbd> | `pj-inline` (`pj` cable) |
| <kbd>ctrl-t</kbd> | tv smart autocomplete (from `tv init zsh`) | | <kbd>ctrl-t</kbd> | tv smart autocomplete (from `tv init zsh`) |
| <kbd>down</kbd> | `pj-down`: `PJ_QUIET=1 pj` on an empty prompt, otherwise `down-line-or-history` (bound to `^[[B` and `^[OB`) | | <kbd>down</kbd> | `pj-down`: `PJ_QUIET=1 pj` on an empty prompt, otherwise `down-line-or-history` (bound to `^[[B` and `^[OB`) |
| <kbd>ctrl-a</kbd> | `omp` | | <kbd>ctrl-a</kbd> | `omp-session`: resume or start omp for the current repo ([Scripts](/shell/scripts#omp-session)) |
| <kbd>ctrl-g</kbd> | `lazygit` | | <kbd>ctrl-g</kbd> | `lazygit` |
| <kbd>ctrl-q</kbd> | `exit` | | <kbd>ctrl-q</kbd> | `exit` |
| <kbd>ctrl-c</kbd> | At the prompt: kill the buffer, clear the screen and kitty scrollback (`ESC[2J ESC[3J`), reset the prompt | | <kbd>ctrl-c</kbd> | At the prompt: kill the buffer, clear the screen and kitty scrollback (`ESC[2J ESC[3J`), reset the prompt |
+3 -2
View File
@@ -186,7 +186,7 @@ The header comment says the file should stay empty, but it holds the following:
| <kbd>ctrl-y</kbd> | `clip-last`: re-run the last command and copy its output | | <kbd>ctrl-y</kbd> | `clip-last`: re-run the last command and copy its output |
| <kbd>ctrl-o</kbd> | `_gho_bind`: `gho` (pick a ghq repo or Obsidian vault from the `ghq-repos` cable and cd into it), then repaint | | <kbd>ctrl-o</kbd> | `_gho_bind`: `gho` (pick a ghq repo or Obsidian vault from the `ghq-repos` cable and cd into it), then repaint |
| <kbd>ctrl-p</kbd> | `_pj_bind`: `pj`, the task runner on the `pj` cable ([Scripts](/shell/scripts#pj)), then repaint | | <kbd>ctrl-p</kbd> | `_pj_bind`: `pj`, the task runner on the `pj` cable ([Scripts](/shell/scripts#pj)), then repaint |
| <kbd>ctrl-a</kbd> | `_agents_bind`: pick an installed AI agent from the `agents` cable and start its TUI ([television](/tools/television#agents)), then repaint | | <kbd>ctrl-a</kbd> | `omp-session`, then repaint: resume or start omp for the current repo by branch and session age, opening the `omp-sessions` cable only when nothing qualifies ([Scripts](/shell/scripts#omp-session)) |
| <kbd>ctrl-w</kbd> | `atuin ai inline`: natural-language command overlay | | <kbd>ctrl-w</kbd> | `atuin ai inline`: natural-language command overlay |
| <kbd>ctrl-g</kbd> | `lazygit` | | <kbd>ctrl-g</kbd> | `lazygit` |
| <kbd>down</kbd> | `_pj_bind_down`: opens the `pj` cable on an idle, empty prompt, otherwise fish's `down-or-search` | | <kbd>down</kbd> | `_pj_bind_down`: opens the `pj` cable on an idle, empty prompt, otherwise fish's `down-or-search` |
@@ -211,7 +211,8 @@ The pickers run `tv --inline`, which opens on the line below the prompt and leav
| `_tv_inline ARGS` | `tv ARGS --inline` | `\033[A` (cursor up), returns tv's status | | `_tv_inline ARGS` | `tv ARGS --inline` | `\033[A` (cursor up), returns tv's status |
| `_gho_bind` | `gho` | `\033[A` if the cwd did not change; `\n` after a cd, so the prompt lands below onefetch | | `_gho_bind` | `gho` | `\033[A` if the cwd did not change; `\n` after a cd, so the prompt lands below onefetch |
| `_pj_bind [--quiet]` | `pj` with `PJ_STATE` set to a temp file | `\033[A` for `open` (cancelled) or empty (no task sources); `\n` for `ran` (the task printed output) | | `_pj_bind [--quiet]` | `pj` with `PJ_STATE` set to a temp file | `\033[A` for `open` (cancelled) or empty (no task sources); `\n` for `ran` (the task printed output) |
| `_agents_bind` | `tv agents --inline` with `AGENTS_STATE` set to a temp file | `\033[A` unless the cable's `launch` action wrote `ran` (an agent started) |
`omp-session` (<kbd>ctrl-a</kbd>) does its own `\033[A` when its `omp-sessions` picker is cancelled, so the binding only repaints.
zsh and bash bind <kbd>ctrl-o</kbd>, <kbd>ctrl-e</kbd>, <kbd>ctrl-p</kbd>, <kbd>down</kbd>, and <kbd>ctrl-t</kbd> the same way ([bash and zsh](/shell/bash-zsh)). Inside television, <kbd>ctrl-e</kbd> runs the channel's `edit` action and <kbd>ctrl-h</kbd> its `goto_parent_dir` action (`television/config.toml`). The config and cables are on the [television](/tools/television) page. zsh and bash bind <kbd>ctrl-o</kbd>, <kbd>ctrl-e</kbd>, <kbd>ctrl-p</kbd>, <kbd>down</kbd>, and <kbd>ctrl-t</kbd> the same way ([bash and zsh](/shell/bash-zsh)). Inside television, <kbd>ctrl-e</kbd> runs the channel's `edit` action and <kbd>ctrl-h</kbd> its `goto_parent_dir` action (`television/config.toml`). The config and cables are on the [television](/tools/television) page.
+37 -1
View File
@@ -46,6 +46,7 @@ Several scripts below also exist as fish functions of the same name (`ai`, `c2p`
| [`mdcp`](#mdcp) | sh | Fetch a URL as Markdown, copy it, preview it | | [`mdcp`](#mdcp) | sh | Fetch a URL as Markdown, copy it, preview it |
| [`mdp`](#mdp) | sh | fzf Markdown picker with mdfried preview | | [`mdp`](#mdp) | sh | fzf Markdown picker with mdfried preview |
| [`mtime-sort`](#mtime-sort) | sh + perl | Sort path lines newest-first by mtime | | [`mtime-sort`](#mtime-sort) | sh + perl | Sort path lines newest-first by mtime |
| [`omp-session`](#omp-session) | python3 | Resume or start omp for the current repo; backend of the `omp-sessions` cable |
| [`pj`](#pj) | bash | Task runner across every project task source, on a tv cable | | [`pj`](#pj) | bash | Task runner across every project task source, on a tv cable |
| [`yazi-nvim-open`](#yazi-nvim-open) | sh | yazi opener that targets the host Neovim | | [`yazi-nvim-open`](#yazi-nvim-open) | sh | yazi opener that targets the host Neovim |
@@ -236,10 +237,45 @@ Lists `*.md` files up to 3 directories deep with `fd`. fzf shows an `mdfried` pr
Reads lines on stdin and prints them newest-first by the mtime of each line's last tab-separated field (the whole line when it has no tab). With `--repo`, it stats `<path>/.git/index` first, so a repo sorts by its last git activity. Lines whose path does not exist are dropped. Ties keep input order. Reads lines on stdin and prints them newest-first by the mtime of each line's last tab-separated field (the whole line when it has no tab). With `--repo`, it stats `<path>/.git/index` first, so a repo sorts by its last git activity. Lines whose path does not exist are dropped. Ties keep input order.
**Used by:** every custom [television](/tools/television) cable and `pj --list`. tv layers match quality and frecency on top of this order. **Used by:** every custom [television](/tools/television) cable except `agents` and `omp-sessions`, and `pj --list`. tv layers match quality and frecency on top of this order.
**Needs:** `perl`. **Needs:** `perl`.
## omp-session
```sh
omp-session
```
Starts or resumes [omp](/ai/omp) for the current git repo by fixed rules, so <kbd>ctrl-a</kbd> never asks when the answer is obvious.
| HEAD | Does |
| --- | --- |
| Default branch | Resumes the newest session on it when that session was written less than 3 hours ago. Otherwise opens the `omp-sessions` [television](/tools/television#omp-sessions) cable over all of the repo's sessions; <kbd>enter</kbd> resumes the pick, <kbd>esc</kbd> returns to the prompt. With no sessions at all it starts a new one |
| Any other branch | Resumes the newest session on that branch, or starts a new one |
| Detached | Opens the `omp-sessions` cable (a new session when there are none) |
| Outside a git repo | Plain `omp` |
Resuming runs `omp --resume <session file>`; omp switches to the session's own cwd.
**Sessions.** Every `*/*.jsonl` under `$PI_CODING_AGENT_DIR/sessions` (default `~/.omp/agent/sessions`) whose `session` header `cwd` is the worktree root or below it, excluding worktrees nested inside it. Session age is the file's mtime (the last write).
**Branches.** omp does not record the git branch. A session's branch is the one HEAD was on when the file was last written, replayed from the worktree's `git reflog` (`checkout: moving from A to B`, `Branch: renamed`, `rebase (finish): returning to`). Sessions older than the oldest reflog move belong to the branch that move left; with no moves they all belong to the current branch. The default branch is `origin/HEAD`, else `init.defaultBranch`, `main`, or `master`, whichever exists.
**Entry points.** The cable calls back into the script:
| Command | Does |
| --- | --- |
| `omp-session --list` | Prints `<age> <branch> <title>[ · <subdir>]<TAB><session file>` per session, newest first. The title is omp's session title, else the first user message |
| `omp-session --preview FILE` | Title, last-write time, cwd, then the text of every user and assistant message (thinking, tool calls, and tool results skipped) |
| `omp-session --resume FILE` | Writes `ran` to `$OMP_SESSION_STATE` when set, then `exec omp --resume FILE` (enter) |
**Prompt redraw.** The launcher runs `tv omp-sessions --inline` with `OMP_SESSION_STATE` set to a temp file. When the picker is cancelled (no `ran`), it prints `\033[A` to `/dev/tty` so the shell redraws the prompt in place; the key bindings just repaint.
**Launched by:** <kbd>ctrl-a</kbd> in fish and zsh.
**Needs:** `python3`, `git`, `omp`, `tv`.
## pj ## pj
```sh ```sh
+13 -4
View File
@@ -62,7 +62,7 @@ Global keys added on top of the defaults:
## Sorting ## Sorting
Every custom cable except `agents` (a fixed list, see [agents](#agents)) pipes its source through [`mtime-sort`](/shell/scripts#mtime-sort), which orders lines newest-first by the mtime of the path in the line's last tab-separated field (`--repo` stats `<path>/.git/index` first). tv then ranks match quality and frecency on top of that order. All custom cables set `shell = "bash"`, because `$SHELL` is fish. Every custom cable except `agents` (a fixed list, see [agents](#agents)) and `omp-sessions` (sorted by [`omp-session`](/shell/scripts#omp-session) itself) pipes its source through [`mtime-sort`](/shell/scripts#mtime-sort), which orders lines newest-first by the mtime of the path in the line's last tab-separated field (`--repo` stats `<path>/.git/index` first). tv then ranks match quality and frecency on top of that order. All custom cables set `shell = "bash"`, because `$SHELL` is fish.
## Custom cables ## Custom cables
@@ -73,9 +73,10 @@ Every custom cable except `agents` (a fixed list, see [agents](#agents)) pipes i
| [`pj`](#pj) | `cable/pj.toml` | <kbd>ctrl-p</kbd>, <kbd>down</kbd> on an empty prompt (`pj`) | | [`pj`](#pj) | `cable/pj.toml` | <kbd>ctrl-p</kbd>, <kbd>down</kbd> on an empty prompt (`pj`) |
| [`files`](#files) | `cable/files.toml` | `tv`, <kbd>ctrl-t</kbd> autocomplete | | [`files`](#files) | `cable/files.toml` | `tv`, <kbd>ctrl-t</kbd> autocomplete |
| [`obsidian`](#obsidian) | `cable/obsidian.toml` | `tv obsidian` | | [`obsidian`](#obsidian) | `cable/obsidian.toml` | `tv obsidian` |
| [`agents`](#agents) | `cable/agents.toml` | <kbd>ctrl-a</kbd> in fish (`_agents_bind`) | | [`agents`](#agents) | `cable/agents.toml` | `tv agents` |
| [`omp-sessions`](#omp-sessions) | `cable/omp-sessions.toml` | `tv omp-sessions`, <kbd>ctrl-a</kbd> (`omp-session`) when it has nothing to resume |
The keys are bound in fish (`fish_user_key_bindings.fish`), zsh (`keybinds.zsh`), and bash (`keybinds.bash`), except <kbd>ctrl-a</kbd>, which only fish binds to `agents` (zsh's <kbd>ctrl-a</kbd> still runs `omp`). See [fish](/shell/fish#key-bindings) and [bash and zsh](/shell/bash-zsh). The keys are bound in fish (`fish_user_key_bindings.fish`), zsh (`keybinds.zsh`), and bash (`keybinds.bash`); bash has no <kbd>ctrl-a</kbd> binding. See [fish](/shell/fish#key-bindings) and [bash and zsh](/shell/bash-zsh).
### ghq-repos ### ghq-repos
@@ -142,6 +143,14 @@ The source is a table of known agent CLIs in the cable, `binary|launch command|d
The preview shows the launch command, the path on `PATH`, its `readlink -f` target, and, for the `~/.local/bin` wrappers that install the agent through mise on first run, the mise tool. It never runs the agent, since some wrappers take seconds to answer `--version`. The preview shows the launch command, the path on `PATH`, its `readlink -f` target, and, for the `~/.local/bin` wrappers that install the agent through mise on first run, the mise tool. It never runs the agent, since some wrappers take seconds to answer `--version`.
<kbd>enter</kbd> runs `launch` in execute mode: tv exits and the launch command runs in its place, in the current directory. Before that it writes `ran` to `$AGENTS_STATE` when set, which is how `_agents_bind` tells a started agent from a cancel. Plain `tv agents` works the same way. <kbd>enter</kbd> runs `launch` in execute mode: tv exits and the launch command runs in its place, in the current directory.
**Needs:** nothing beyond the agents themselves. **Needs:** nothing beyond the agents themselves.
### omp-sessions
Source `omp-session --list`: the [omp](/ai/omp) sessions of the current git repo, newest first, as `<age> <branch> <title>[ · <subdir>]<TAB><session file>`. tv shows and matches the display column, so typing a branch name filters to its sessions. The branch is the one HEAD was on when the session was last written, from the reflog; see [omp-session](/shell/scripts#omp-session).
The preview runs `omp-session --preview`: title, last-write time and cwd, then the text of every user and assistant message. <kbd>enter</kbd> runs `resume` in execute mode, `omp-session --resume <file>`, which `exec`s `omp --resume <file>`.
**Needs:** `omp-session`, `omp`.