A coding-agent conversation is a single thread: to try a risky direction you either lose the one that got you there, or you don't try it. Every agent tty7 resumes already knows how to branch — `codex fork <id>`, `claude --resume <id> --fork-session`, `opencode --session <id> --fork`, `grok --resume <id> --fork-session` — but nothing in tty7 reached them, so the capability was invisible from the terminal that already knows every pane's session id. Fork is a per-agent capability beside the existing resume table (`CLIAgent::fork_command`), not a Codex special case: it is the same `match self` shape, it reuses the same id validation and the same launch-flag replay, and four installed agents qualify today. Every command was checked against that CLI's own `--help`; agents with no fork tty7 could verify return `None` and are never offered the action, since a guessed flag shape would only ever produce a usage error in the pane. Flag replay needed one correctness fix to survive this. A forked pane's own argv *is* a fork command, so relaunching it would replay the stale subcommand and id (`codex fork <old>` → an old id as a positional prompt) or double the modifier (`--fork-session --fork-session`). `codex fork` now sheds its subcommand exactly as `codex resume` did, and `--fork-session` / `--fork` join their agents' stale session-targeting lists. That also settles restore: a forked pane restores through `resume_command`, which now drops the fork flag — a restart continues the fork rather than branching it again. Placement follows where the user asked from. A pane-level ask is spatial, so the pane right-click menu offers Split Right / Left / Down / Up (pane splits gained a `before` slot for the Left/Up half, which the tree had no way to express). A tab-level ask isn't, so the tab context menu — inherited verbatim by the sidebar rows, which is where the request came from — opens the fork in a new tab with no placement question. The bare action behind the palette, the File menu and Settings → Keybindings takes the tab-level meaning. The three ways a fork can't run all surface rather than no-op: no session id yet (hooks not installed) and a remote pane (the command would shell the *local* agent) render the row disabled instead of hiding it, so the capability stays discoverable, and the action paths that have no row to grey out say so in a notification. Forking mid-turn is allowed but announced — agents fork from the persisted transcript, so the turn in flight is absent from the copy — and the parent is untouched either way. Copy Session ID sits beside Copy Working Directory. Codex has no copy-or-duplicate subcommand, so "copy the session" is the id: paste it into `codex resume`, a bug report, or another tool. Deliberately not built: any reading or writing of an agent's own session files. tty7's exposure stays the public CLI contract plus the hook payload's session id, so a change to Codex's rollout format or its version-numbered SQLite index costs at most a visible shell error. Forked tabs also look exactly like their parent, by decision — "Rename Tab" is the answer. Closes #211
2.3 KiB
Project agent memory
This file is the project's committed home for project-intrinsic agent knowledge: build, test, release, architecture, and sharp-edge notes that should travel with the code.
- Add durable project-specific notes here as they are discovered through real work.
Adding a user-facing action
Actions are declared once in src/core/actions.rs and then wired into every
surface by hand — miss one and the action silently exists nowhere. The full
set of places, each a plain table you extend by copying the row above:
| File | What |
|---|---|
src/core/actions.rs |
declare it in actions! |
src/ui/app.rs |
an on_action listener in Render for Tty7App, and a run_command arm if it is in the palette |
src/ui/keymap.rs |
default_bindings() (empty string = bindable, no default chord) and make_binding() |
src/ui/palette.rs |
CommandKind variant, id(), the action-name map, and a Command::new row |
src/ui/theme.rs |
the macOS menu-bar item |
src/ui/tab_strip.rs |
tab_context_menu — the tab-strip chips and the sidebar rows share it verbatim, so a row added here appears in both |
src/terminal/view.rs |
the pane right-click menu. It has no Tty7App handle, so rows here must dispatch actions, not closures; a submenu needs its own action_context (it does not inherit the parent menu's) |
Third-party coding agents
src/core/cli_agent.rs is the whole registry: detection, per-agent resume /
fork commands, and the launch-flag replay that carries a pane's original flags
onto them. Per-agent behaviour is always a match self table returning None
for agents without the capability — follow that shape rather than special-casing
one agent. tty7 never reads or writes an agent's own session files; it shells
the agent's own subcommand, so an agent changing its on-disk format costs at
most a visible shell error. Only claim a flag you have checked against the
installed CLI's own --help.
Maintaining this file
Keep this file for knowledge useful to almost every future agent session in this project. Do not repeat what the codebase already shows; point to the authoritative file or command instead. Prefer rewriting or pruning existing entries over appending new ones. When updating this file, preserve this bar for all agents and keep entries concise.