Skip to content

Fix agent resume, command injection and GitHub CLI probing in terminals - #388

Open
0x92 wants to merge 2 commits into
dcouple:mainfrom
0x92:fix/agent-terminal-robustness
Open

Fix agent resume, command injection and GitHub CLI probing in terminals#388
0x92 wants to merge 2 commits into
dcouple:mainfrom
0x92:fix/agent-terminal-robustness

Conversation

@0x92

@0x92 0x92 commented Aug 11, 2026

Copy link
Copy Markdown

Description

Three independent fixes to agent terminals. None of them is a feature; all three are about a failure that looks like the agent misbehaving.

1. Resumed sessions came back empty. Every spawned terminal inherited the launching process's environment wholesale. When Pane itself is started from inside a Claude Code session — a terminal, a script, a dev run — that includes CLAUDE_CODE_CHILD_SESSION, and Claude Code responds by switching transcript persistence off ("Transcript saving is off — inherited CLAUDE_CODE_CHILD_SESSION marker"). Nothing is written, so the next claude --resume <id> fails with "No conversation found with session ID" and the pane comes back blank after a restart, with nothing on screen explaining why. Those markers are now stripped at spawn: every terminal Pane starts is a new top-level session, so the launching agent's identity is always wrong to pass on.

2. The resume command sometimes ran as laude. A terminal that has just printed its prompt can lose the first character it is given — ConPTY switches input modes around the prompt, and a resize arriving in the same moment makes it likelier. The command then fails as "command not found" and reads as if Pane sent nonsense. It shows up on restart, exactly when a session is trying to resume its agent. The command is now preceded by a byte that costs nothing either way: Ctrl-U clears the input line, and at a fresh prompt there is nothing to clear. Whatever the shell swallows is not part of the command; the command follows 60 ms later.

3. Two red console lines per session, per refresh, on machines without gh. PR enrichment ran gh pr list on every git status refresh regardless of whether the GitHub CLI exists. Availability is now probed once per execution context — keyed by WSL distribution, since the host and a distro have separate PATHs — and the lookup itself is silent. A repository with no GitHub remote, or an unauthenticated gh, is a normal state for a local project, not something to shout about.

Notes

Both new modules (agentSessionEnv, terminalInjection) sit next to terminalPanelManager rather than inside it, so they can be unit-tested without pulling in the database singleton it depends on.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)

Checklist

  • I have read the CONTRIBUTING.md guidelines
  • My code follows the code style of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • I have run pnpm typecheck and pnpm lint locally
  • I have tested the Electron app locally with pnpm electron-dev

Critical Areas Modified

  • State management/IPC events

Additional Notes

Tests: 5 for environment stripping, 4 for the injection sequence, and the existing PR-enrichment tests now count gh pr list lookups rather than every command, since the availability probe adds one.

Verified in the running app: a session whose agent had been resumed after a restart, on a host where Pane itself was launched from inside a Claude Code session.

0x92 added 2 commits August 11, 2026 11:53
Two independent fixes to agent terminals, both about noise and silent
failure rather than features.

Resume: every spawned terminal inherited the launching process's
environment wholesale. When Pane itself is started from inside a Claude
Code session — a terminal, a script, a dev run — that includes
CLAUDE_CODE_CHILD_SESSION, and Claude Code responds by switching transcript
persistence off. Nothing is written, so the next `claude --resume <id>`
fails with "No conversation found" and the pane comes back empty after a
restart, with nothing on screen explaining why. Those markers are now
stripped at spawn: every terminal Pane starts is a new top-level session,
so the launching agent's identity is always wrong to pass on.

GitHub CLI: PR enrichment ran `gh pr list` on every git status refresh. On
a machine without `gh` that is two console errors per session per refresh
for something that was never going to work. Availability is now probed once
per execution context (keyed by WSL distribution, since the host and a
distro have separate PATHs) and the lookup itself is silent — a repository
with no GitHub remote, or an unauthenticated `gh`, is a normal state.

Tests: environment stripping (5); the PR enrichment tests now count
lookups rather than every command, since the probe adds one.
A terminal that has just printed its prompt can lose the first character
it is given. ConPTY switches input modes around the prompt, and a resize
arriving in the same moment makes it likelier. The symptom is a command
that runs with its first letter missing — `laude --resume <id>`, which
fails as "command not found" and reads as if Pane sent nonsense. It shows
up on restart, exactly when a session is trying to resume its agent.

The command is now preceded by a byte that costs nothing either way:
Ctrl-U, which clears the input line and at a fresh prompt has nothing to
clear. Whatever the shell swallows, it is not part of the command. The
command follows 60ms later, once that window has passed.

Kept in its own module so it can be unit-tested without dragging in the
database singleton that terminalPanelManager depends on.
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