Skip to content

feat: remember agent cli options when resuming sessions - #3

Closed
dhh wants to merge 2 commits into
masterfrom
feature/remember-agent-launch-options
Closed

feat: remember agent cli options when resuming sessions#3
dhh wants to merge 2 commits into
masterfrom
feature/remember-agent-launch-options

Conversation

@dhh

@dhh dhh commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

Native agent session restore rebuilt the resume command from the session reference alone, so a pane started as claude --permission-mode bypassPermissions came back as plain claude --resume <id> with default permissions.

What changed

Capture — the foreground process probe already reads each process's argv, so when it identifies an agent it now also extracts the command line after the agent token (detect::agent_launch_args_in_job, which handles wrapped invocations like node .../cli.js --flag). A new AgentLaunchArgsDetected event records it on the terminal, deduped so it fires once per change rather than once per probe.

Persist — a new optional agent_launch: {agent, args} field on the pane snapshot, stored per agent so a pane that later ran a different agent never resumes with the previous agent's options.

Replayagent_resume::plan_with_launch_args() appends the surviving options after the session reference. src/agent_launch_args.rs decides what survives, with two rules:

  • Options that select a conversation or a one-shot run are dropped, per agent (--resume, --continue, --session, --print, --prompt). Herdr supplies its own session reference.
  • A bare word is kept only when it directly follows a kept option, where it is that option's value. Bare words elsewhere are prompts, subcommands, or positional paths.

Everything else is replayed, including options Herdr has never heard of, so a new flag in a future agent release survives a resume without anyone touching Herdr.

The second rule is what makes the first one cheap: the value of a dropped option disappears for free, because it is a bare word following no kept option. --resume <id> loses the id without Herdr knowing that --resume takes one. The same falls out for agents that select a session through a subcommand and a positional id, so codex resume <id> --full-auto needs no special case.

That also stops a resume from compounding: after Herdr resumes a pane once, the live process argv contains the --resume <id> Herdr itself appended, and the next restore drops it before adding the current one.

Deliberate limits

  • An option given several separate values keeps the first: --add-dir /a /b resumes as --add-dir /a.
  • A prompt written directly after a flag cannot be told apart from that flag's value, so it is replayed. claude "fix the bug" and a prompt following a value are both dropped; claude --dangerously-skip-permissions "fix the bug" is not.

Both are documented in the module and on the session-state docs page.

Verification

cargo nextest run green (3376 passed), fmt and clippy clean.

Verified live against a throwaway herdr-dev session on the debug build:

  • a pane agent started as claude --permission-mode bypassPermissions recorded agent_launch: {agent: "claude", args: ["--permission-mode", "bypassPermissions"]} in session.json
  • a snapshot seeded with session ref verify-session-id and args ["--model", "sonnet", "--resume", "stale-session", "some prompt"] resumed as hermes --resume verify-session-id --model sonnet — option replayed, stale session flag and its id dropped, trailing prompt left behind

Commits

The first commit carried per-agent tables of every option and its arity, used to tell a flag's value apart from a prompt. The second deletes them (573 lines) once the bare-word rule made them unnecessary. Reviewing the two together shows the reasoning; the end state is the second.

dhh added 2 commits August 10, 2026 10:48
Native agent session restore rebuilt the resume command from the session
reference alone, so a pane started as `claude --permission-mode
bypassPermissions` came back with default permissions.

Capture the options the agent process was started with during foreground
process detection, persist them per agent in the session snapshot, and
replay them after the session reference on resume. Session-selection,
non-interactive, and prompt arguments are never replayed, and an
unrecognized option followed by a bare token is dropped together with that
token so a resume command is never left missing a value.
The tables existed only to tell an option's value apart from a prompt.
Keeping a bare word solely when it directly follows a kept option gets the
same result without them, and drops the value of a dropped option for free
because that value follows no kept option.

Only the per-agent list of session-selection and one-shot options remains.
Every other option now survives a resume, including options no table knows
about. An option given several separate values keeps the first, and a
prompt written directly after a flag is still indistinguishable from that
flag's value.
@dhh

dhh commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator Author

Moved upstream to herdrdev#2614. Leaving the branch in place: omarchy-pkgs pins commit 4fa315e for the herdr 0.8.0.r8 build, so the archive URL must keep resolving.

@dhh dhh closed this Aug 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant