From 945cf460486a0eaa9945183aefdfdb4ee273c286 Mon Sep 17 00:00:00 2001 From: Prad Nukala Date: Wed, 30 Sep 2026 16:20:16 -0400 Subject: [PATCH] =?UTF-8?q?docs(docs):=20update=20ctrl=E2=80=91a=20keybind?= =?UTF-8?q?ing=20docs=20to=20use=20omp=E2=80=91session=20and=20add=20omp?= =?UTF-8?q?=E2=80=91session=20script=20description?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/ai/index.mdx | 2 +- docs/ai/omp.mdx | 2 +- docs/chezmoi/index.mdx | 2 +- docs/shell/bash-zsh.mdx | 2 +- docs/shell/fish.mdx | 5 +++-- docs/shell/scripts.mdx | 38 +++++++++++++++++++++++++++++++++++++- docs/tools/television.mdx | 17 +++++++++++++---- 7 files changed, 57 insertions(+), 11 deletions(-) diff --git a/docs/ai/index.mdx b/docs/ai/index.mdx index 709fcec..bf16ca8 100644 --- a/docs/ai/index.mdx +++ b/docs/ai/index.mdx @@ -57,5 +57,5 @@ None of these files are role-gated: `.chezmoiignore.tmpl` applies them on every ## 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). -- Ctrl A opens the `agents` television cable from the fish prompt: every installed agent CLI (omp, claude, codex, opencode, …); enter starts it ([television](/tools/television#agents)). In zsh it still launches `omp`. +- Ctrl A 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). diff --git a/docs/ai/omp.mdx b/docs/ai/omp.mdx index 9475b92..d3dbe23 100644 --- a/docs/ai/omp.mdx +++ b/docs/ai/omp.mdx @@ -168,7 +168,7 @@ Both count as done only when the full artifact is pasted in the chat. | Entry point | Source | What it does | | --- | --- | --- | | fish completions | `dot_config/fish/completions/omp.fish` | `omp completions fish \| source` generates completions at load time | -| Ctrl A | fish `fish_user_key_bindings` → `_agents_bind`, zsh `keybinds.zsh` | fish: the `agents` tv cable, with `omp` first; zsh: launches `omp` from the prompt | +| Ctrl A | 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). | | `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 "` on each | diff --git a/docs/chezmoi/index.mdx b/docs/chezmoi/index.mdx index 08531c1..2704976 100644 --- a/docs/chezmoi/index.mdx +++ b/docs/chezmoi/index.mdx @@ -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. | | `.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_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_omp/` | `~/.omp/` | omp agent config and loops. | | `dot_leetcode/` | `~/.leetcode/` | leetcode CLI workspace state. | diff --git a/docs/shell/bash-zsh.mdx b/docs/shell/bash-zsh.mdx index 144574e..cad50ea 100644 --- a/docs/shell/bash-zsh.mdx +++ b/docs/shell/bash-zsh.mdx @@ -75,7 +75,7 @@ The tv pickers have their own widgets, because `tv --inline` opens on the line b | ctrl-p | `pj-inline` (`pj` cable) | | ctrl-t | tv smart autocomplete (from `tv init zsh`) | | down | `pj-down`: `PJ_QUIET=1 pj` on an empty prompt, otherwise `down-line-or-history` (bound to `^[[B` and `^[OB`) | -| ctrl-a | `omp` | +| ctrl-a | `omp-session`: resume or start omp for the current repo ([Scripts](/shell/scripts#omp-session)) | | ctrl-g | `lazygit` | | ctrl-q | `exit` | | ctrl-c | At the prompt: kill the buffer, clear the screen and kitty scrollback (`ESC[2J ESC[3J`), reset the prompt | diff --git a/docs/shell/fish.mdx b/docs/shell/fish.mdx index ec7a293..898f109 100644 --- a/docs/shell/fish.mdx +++ b/docs/shell/fish.mdx @@ -186,7 +186,7 @@ The header comment says the file should stay empty, but it holds the following: | ctrl-y | `clip-last`: re-run the last command and copy its output | | ctrl-o | `_gho_bind`: `gho` (pick a ghq repo or Obsidian vault from the `ghq-repos` cable and cd into it), then repaint | | ctrl-p | `_pj_bind`: `pj`, the task runner on the `pj` cable ([Scripts](/shell/scripts#pj)), then repaint | -| ctrl-a | `_agents_bind`: pick an installed AI agent from the `agents` cable and start its TUI ([television](/tools/television#agents)), then repaint | +| ctrl-a | `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)) | | ctrl-w | `atuin ai inline`: natural-language command overlay | | ctrl-g | `lazygit` | | down | `_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 | | `_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) | -| `_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` (ctrl-a) does its own `\033[A` when its `omp-sessions` picker is cancelled, so the binding only repaints. zsh and bash bind ctrl-o, ctrl-e, ctrl-p, down, and ctrl-t the same way ([bash and zsh](/shell/bash-zsh)). Inside television, ctrl-e runs the channel's `edit` action and ctrl-h its `goto_parent_dir` action (`television/config.toml`). The config and cables are on the [television](/tools/television) page. diff --git a/docs/shell/scripts.mdx b/docs/shell/scripts.mdx index cbca7db..e04249a 100644 --- a/docs/shell/scripts.mdx +++ b/docs/shell/scripts.mdx @@ -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 | | [`mdp`](#mdp) | sh | fzf Markdown picker with mdfried preview | | [`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 | | [`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 `/.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`. +## omp-session + +```sh +omp-session +``` + +Starts or resumes [omp](/ai/omp) for the current git repo by fixed rules, so ctrl-a 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; enter resumes the pick, esc 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 `; 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 ` [ · <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 ```sh diff --git a/docs/tools/television.mdx b/docs/tools/television.mdx index 7e2d659..75b6f16 100644 --- a/docs/tools/television.mdx +++ b/docs/tools/television.mdx @@ -62,7 +62,7 @@ Global keys added on top of the defaults: ## 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 @@ -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`) | | [`files`](#files) | `cable/files.toml` | `tv`, <kbd>ctrl-t</kbd> autocomplete | | [`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 @@ -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`. -<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. + +### 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`.