diff options
| author | JJ Liebig <jonathan.liebig@gmail.com> | 2026-09-12 15:52:18 +0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-09-12 13:52:18 +0200 |
| commit | a5d5f6f654a32b27b2bd4dd8edd82f6795359269 (patch) | |
| tree | 0b54a0fb4c1a136dff8224de617c8403756df19a /src | |
| parent | cc36a2943e85134768631d6d289e331c0edb940d (diff) | |
fix: ignore nested OMP session reports (#3994)
refs #2593
Diffstat (limited to 'src')
| -rw-r--r-- | src/integration/assets/herdr-agent-state.test.ts | 28 | ||||
| -rw-r--r-- | src/integration/assets/omp/herdr-agent-state.ts | 8 | ||||
| -rw-r--r-- | src/integration/mod.rs | 2 | ||||
| -rw-r--r-- | src/pane.rs | 13 |
4 files changed, 48 insertions, 3 deletions
diff --git a/src/integration/assets/herdr-agent-state.test.ts b/src/integration/assets/herdr-agent-state.test.ts index 48cc8708..19b36d94 100644 --- a/src/integration/assets/herdr-agent-state.test.ts +++ b/src/integration/assets/herdr-agent-state.test.ts @@ -11,6 +11,7 @@ const originalEnvironment = { HERDR_OMP_IDLE_DEBOUNCE_MS: process.env.HERDR_OMP_IDLE_DEBOUNCE_MS, HERDR_PANE_ID: process.env.HERDR_PANE_ID, HERDR_SOCKET_PATH: process.env.HERDR_SOCKET_PATH, + OMPCODE: process.env.OMPCODE, }; let server: Server | undefined; @@ -229,6 +230,33 @@ for (const integration of integrations) { }); } +test("OMP ignores nested sessions launched inside another OMP shell", async () => { + const requests = await startRecordingServer("omp-nested"); + process.env.OMPCODE = "1"; + const { handlers, pi } = createExtensionHarness(); + + const { default: install } = await importFresh("./omp/herdr-agent-state.ts"); + install(pi); + + // OMP sets OMPCODE on every shell it spawns. A nested `omp` inherits it and + // must not claim the pane's session for its short-lived conversation. + expect(handlers.size).toBe(0); + await handlers.get("session_start")?.( + { reason: "startup" }, + { + hasUI: true, + isIdle: () => true, + sessionManager: { + getSessionFile: () => "/tmp/omp-nested.jsonl", + getSessionId: () => "omp-nested", + }, + }, + ); + await Bun.sleep(25); + + expect(requests).toEqual([]); +}); + test("OMP accepts POSIX and Windows session paths", async () => { const { isAbsoluteSessionPath } = await importFresh("./omp/herdr-agent-state.ts"); diff --git a/src/integration/assets/omp/herdr-agent-state.ts b/src/integration/assets/omp/herdr-agent-state.ts index 0e493787..fce62106 100644 --- a/src/integration/assets/omp/herdr-agent-state.ts +++ b/src/integration/assets/omp/herdr-agent-state.ts @@ -2,7 +2,7 @@ // managed by herdr; reinstalling or updating the integration overwrites this file. // add custom hooks/plugins beside this file instead of editing it. // HERDR_INTEGRATION_ID=omp -// HERDR_INTEGRATION_VERSION=9 +// HERDR_INTEGRATION_VERSION=10 // @ts-nocheck import net from "node:net"; @@ -14,9 +14,13 @@ const socketEndpoint = process.platform === "win32" && socketPath ? `\\\\.\\pipe\\${socketPath}` : socketPath; const paneId = process.env.HERDR_PANE_ID; const source = "herdr:omp"; +// OMP marks every shell it spawns with OMPCODE=1. A nested `omp` launched from +// a parent session's shell inherits it, so that process is not the pane's root +// agent and must not report its short-lived session over the parent's. +const nestedOmpSession = process.env.OMPCODE === "1"; function enabled() { - return HERDR_ENV === "1" && !!socketPath && !!paneId; + return HERDR_ENV === "1" && !!socketPath && !!paneId && !nestedOmpSession; } let requestQueue = Promise.resolve(); diff --git a/src/integration/mod.rs b/src/integration/mod.rs index d956c7bc..49808ca2 100644 --- a/src/integration/mod.rs +++ b/src/integration/mod.rs @@ -27,7 +27,7 @@ const PI_EXTENSION_ASSET: &str = include_str!("assets/pi/herdr-agent-state.ts"); const PI_INTEGRATION_VERSION: u32 = 9; const OMP_EXTENSION_INSTALL_NAME: &str = "herdr-omp-agent-state.ts"; const OMP_EXTENSION_ASSET: &str = include_str!("assets/omp/herdr-agent-state.ts"); -const OMP_INTEGRATION_VERSION: u32 = 9; +const OMP_INTEGRATION_VERSION: u32 = 10; const CLAUDE_HOOK_INSTALL_NAME: &str = if cfg!(windows) { "herdr-agent-state.ps1" } else { diff --git a/src/pane.rs b/src/pane.rs index 0ba411d0..c56cfbb3 100644 --- a/src/pane.rs +++ b/src/pane.rs @@ -147,6 +147,9 @@ impl PaneLaunchEnv { fn apply_pane_launch_env(cmd: &mut CommandBuilder, launch_env: &PaneLaunchEnv) { cmd.env_remove("CODEX_THREAD_ID"); + // OMP sets OMPCODE for shells it spawns. A pane launched from inside OMP + // must not inherit it or its root agent would look like a nested session. + cmd.env_remove("OMPCODE"); for (key, value) in &launch_env.extra { cmd.env(key, value); } @@ -3558,6 +3561,16 @@ mod tests { } #[test] + fn pane_launch_env_removes_outer_ompcode_marker() { + let mut cmd = CommandBuilder::new("shell"); + cmd.env("OMPCODE", "1"); + + apply_pane_launch_env(&mut cmd, &PaneLaunchEnv::default()); + + assert!(cmd.get_env("OMPCODE").is_none()); + } + + #[test] fn pane_terminal_identity_removes_outer_windows_terminal_session() { let mut cmd = CommandBuilder::new("shell"); cmd.env("WT_SESSION", "outer-session"); |
