Idle filter: pivot per-distro → per-pane via TILETOPIA_PANE_ID env marker
Per-distro suppression (shipped earlier today) broke tiletopia's primary use case — multiple claude panes per distro means as soon as one runs claude, ALL Ubuntu panes go silent. Tested live: user couldn't reproduce idle on any pane because PID 46848 (their main session) tripped the gate. New mechanism, per-pane via env-var marker: 1. pty.rs tags every WSL spawn with TILETOPIA_PANE_ID=<id> as a Windows env var, plus WSLENV=...TILETOPIA_PANE_ID/u (appended to any pre- existing WSLENV) so the var forwards into the distro. Pane id is now reserved BEFORE build_command so the tag is available at spawn time. 2. probe.rs rewritten — is_watch_process_running(distro, pane_id) runs a bash one-liner that pgreps for each watched name, then for each PID checks /proc/<pid>/environ for the matching TILETOPIA_PANE_ID line. Env inheritance does the work: shell inherits from wsl.exe, claude inherits from shell. Cache keyed by (distro, pane_id). 3. Fail-safe INVERTED: probe failure now returns false (don't suppress) instead of true (suppress). A transient error should never silence the idle indicator permanently. Frontend catch updated to match. 4. LeafPane tracks PaneId in paneIdRef set by onPaneSpawned; idle ticks before spawn-completion pass 0, which won't match any real marker so the pane idles normally. Existing panes won't have the marker until respawned — they'll always show idle (since probe never matches). User opens fresh panes once after deploying this. Documented in memory.md follow-ups. pnpm check clean. Rust validation: cargo test --lib on Windows. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
d3474d33b0
commit
6772b8db37
6 changed files with 230 additions and 124 deletions
|
|
@ -154,7 +154,32 @@ impl PtyManager {
|
|||
_ => None,
|
||||
};
|
||||
|
||||
let (cmd, spawn_err) = build_command(&spec)?;
|
||||
// Reserve the pane id BEFORE spawning so we can tag the shell's
|
||||
// env with it — see TILETOPIA_PANE_ID below. We still insert into
|
||||
// the panes map further down, after the reader thread is wired.
|
||||
let id = self.next_id.fetch_add(1, Ordering::Relaxed);
|
||||
|
||||
let (mut cmd, spawn_err) = build_command(&spec)?;
|
||||
// WSL panes get a TILETOPIA_PANE_ID env marker so the idle-filter
|
||||
// probe (probe.rs) can tell which descendant processes belong to
|
||||
// which pane — inheritance does the work: the shell inherits from
|
||||
// wsl.exe via WSLENV, and every child (e.g. claude) inherits from
|
||||
// the shell, so checking `/proc/<pid>/environ` for the marker
|
||||
// answers "is this process running in pane N?" exactly.
|
||||
if matches!(spec, SpawnSpec::Wsl { .. }) {
|
||||
cmd.env("TILETOPIA_PANE_ID", id.to_string());
|
||||
// WSLENV controls which Windows-side env vars are forwarded into
|
||||
// the distro. Append our marker rather than clobbering — users
|
||||
// may have their own WSLENV set up. `/u` = always pass through
|
||||
// as a Unix-style env var.
|
||||
let existing = std::env::var("WSLENV").unwrap_or_default();
|
||||
let combined = if existing.is_empty() {
|
||||
"TILETOPIA_PANE_ID/u".to_string()
|
||||
} else {
|
||||
format!("{existing}:TILETOPIA_PANE_ID/u")
|
||||
};
|
||||
cmd.env("WSLENV", combined);
|
||||
}
|
||||
let child = pair.slave.spawn_command(cmd).context(spawn_err)?;
|
||||
|
||||
// We need to keep the master alive (drop = close the PTY), but we
|
||||
|
|
@ -170,8 +195,6 @@ impl PtyManager {
|
|||
let writer: SharedWriter = Arc::new(Mutex::new(writer_raw));
|
||||
let ring: Arc<Mutex<PaneRing>> = Arc::new(Mutex::new(PaneRing::new()));
|
||||
|
||||
let id = self.next_id.fetch_add(1, Ordering::Relaxed);
|
||||
|
||||
self.panes.lock().insert(
|
||||
id,
|
||||
PaneHandle {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue