Files
tty7/AGENTS.md
T
l0ng-ai 65892e155e feat(agents): fork an agent session, and copy its session id
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
2026-07-29 00:12:07 +08:00

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.