Skip to content

fix: default PROMPT_EOL_MARK= in spawned shells#114

Merged
ThomasK33 merged 1 commit into
mainfrom
fix/prompt-eol-mark-default
Jun 2, 2026
Merged

fix: default PROMPT_EOL_MARK= in spawned shells#114
ThomasK33 merged 1 commit into
mainfrom
fix/prompt-eol-mark-default

Conversation

@ThomasK33
Copy link
Copy Markdown
Member

What

Spawned shells now default PROMPT_EOL_MARK= (empty) in the session environment. This suppresses zsh's inverse-video % end-of-partial-line marker, which was leaking into snapshots, screenshots, and recordings.

Why

agent-tty injects a hidden completion-marker postamble after each run and strips that postamble's echo from the output stream. The strip leaves the rendered cursor mid-line, so zsh's unconditional end-of-line mark (PROMPT_EOL_MARK, default %B%S%#%s%b) surfaces as a stray standout % in captured artifacts. In a real terminal it's overwritten at column 0; in agent-tty's renderer it stays visible.

Before / after (echo hello snapshot):

❯ echo hello          ❯ echo hello
hello                  hello

❯ %          --->      ❯

❯                      ❯

How

A new pure, testable resolvePtyEnv(env, term, baseEnv) helper in src/pty/createPty.ts assembles the shell env with precedence (lowest→highest): inherited process env → PROMPT_EOL_MARK='' default → caller --envTERM. The default is gated on 'PROMPT_EOL_MARK' in env (the user-explicit set), so a --env value always wins — even an explicit empty one — and is ordered after the inherited env so it also overrides an inherited value, keeping captures deterministic.

The marker is zsh-only and inert in other shells (bash, etc.), so it's safe to set unconditionally. The default is applied at PTY spawn time and is not written to the manifest, so inspect, list, and create --json env maps are unchanged.

Notes & caveats (documented in docs/USAGE.md / docs/TROUBLESHOOTING.md)

  • Opt back in per session: agent-tty create --env PROMPT_EOL_MARK='%B%S%#%s%b' -- <shell> restores zsh's styled default. A lone '%' does not restore it (zsh treats it as a prompt escape that expands to nothing).
  • A user ~/.zshrc that reassigns PROMPT_EOL_MARK runs after env import and wins — best-effort, documented.

Tests

  • Unit (test/unit/pty/createPty.test.ts): default injected, caller value wins (incl. empty), overrides inherited, TERM forcing, undefined-drop.
  • Integration (test/integration/lifecycle.test.ts): parent exports a sentinel PROMPT_EOL_MARK; asserts the spawned shell sees it empty — verified to fail without the fix and pass with it.
  • Full suite green locally: 1196 unit, lifecycle 17/17, pty-basics + run 19/19; typecheck/lint/format clean.

🤖 Generated with Claude Code

Spawned shells now default PROMPT_EOL_MARK to empty so zsh's standout "%"
end-of-partial-line marker no longer leaks into snapshots, screenshots,
and recordings. agent-tty strips a hidden per-run completion-marker
postamble, which desynced the rendered cursor from the shell's and left
the "%" visible. The marker is zsh-only and inert in other shells.

The default is applied at PTY spawn time in resolvePtyEnv and is not
written to the manifest, so inspect/list/create --json env maps are
unchanged. An explicit `--env PROMPT_EOL_MARK=...` always wins (use
'%B%S%#%s%b' to restore zsh's styled default; a lone '%' expands to
nothing).

Change-Id: Ia6f199bb33e52baff73a008a39c74500e5c5e050
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Thomas Kosiewski <tk@coder.com>
@ThomasK33 ThomasK33 force-pushed the fix/prompt-eol-mark-default branch from 7776fed to 5d68553 Compare June 2, 2026 20:07
@ThomasK33 ThomasK33 merged commit 9ef5a96 into main Jun 2, 2026
12 checks passed
@ThomasK33 ThomasK33 deleted the fix/prompt-eol-mark-default branch June 2, 2026 20:45
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