Context bar: match panes by live cwd via OSC 7 (was keyed on unset leaf.cwd)

The context indicator never showed because it matched on leaf.cwd, which
is almost always undefined (newLeaf sets none; the shell picker never
supplies one) — so the cwd<->transcript match never hit.

Fix: report each WSL pane's real working directory.
- pty.rs: inject PROMPT_COMMAND (forwarded via WSLENV) so the WSL shell
  emits OSC 7 (file://host/path) on every prompt. Default Ubuntu bash
  inherits an env-provided PROMPT_COMMAND; a shell that hard-assigns it,
  or a non-bash login shell, just won't report (indicator stays hidden,
  no breakage).
- XtermPane: register an OSC 7 handler, decode the path, emit onCwd.
- LeafPane: track liveCwd from onCwd and match the session on
  (liveCwd ?? leaf.cwd). OSC 7 fires at the bash prompt right before
  'claude' launches, so liveCwd is exactly claude's launch cwd; it also
  follows 'cd'.

tsc clean. Rust builds on the Windows host; needs runtime verification.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
megaproxy 2026-05-28 22:57:53 +01:00
parent 24ab7f067f
commit d776f962da
3 changed files with 56 additions and 1 deletions

View file

@ -354,6 +354,23 @@ fn build_command(spec: &SpawnSpec) -> Result<(CommandBuilder, &'static str)> {
let resolved_cwd = cwd.as_deref().unwrap_or("~");
c.arg("--cd");
c.arg(resolved_cwd);
// Make the shell report its working directory via OSC 7 on every
// prompt, so the frontend can map this pane to the claude session
// running in it (the context-fill indicator; see usage.rs +
// LeafPane). We set PROMPT_COMMAND in the environment and forward it
// through WSLENV — default Ubuntu bash inherits an env-provided
// PROMPT_COMMAND. A user shell that hard-assigns PROMPT_COMMAND (or
// a non-bash login shell) simply won't report, and the indicator
// stays hidden for that pane — no breakage either way.
c.env(
"PROMPT_COMMAND",
r#"printf '\033]7;file://%s%s\033\\' "$HOSTNAME" "$PWD""#,
);
let wslenv = match std::env::var("WSLENV") {
Ok(v) if !v.is_empty() => format!("{v}:PROMPT_COMMAND/u"),
_ => "PROMPT_COMMAND/u".to_string(),
};
c.env("WSLENV", wslenv);
Ok((c, "failed to spawn wsl.exe; is WSL installed?"))
}
SpawnSpec::Powershell => {