scope client env to sessions so herdr extensions see the right pane - #303
Conversation
There was a problem hiding this comment.
🟡 Medium
The new_session, switch_session, fork, and import_jsonl handlers rebuild the runtime via state.runtime's stored factory, which calls createAgentSessionRuntime() with the unwrapped this.options.createRuntime. Extensions are loaded during that factory call without withClientEnv(state.clientEnv, ...), so state.clientEnv is never applied to process.env and pane-scoped extensions cannot read their client identity (e.g. HERDR_PANE_ID). Only the explicit reload command wraps extension loading in withClientEnv, so any session-replacement flow silently drops client env from extension load context.
🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @packages/coding-agent/src/modes/daemon/daemon-mode.ts around line 1311:
The `new_session`, `switch_session`, `fork`, and `import_jsonl` handlers rebuild the runtime via `state.runtime`'s stored factory, which calls `createAgentSessionRuntime()` with the unwrapped `this.options.createRuntime`. Extensions are loaded during that factory call without `withClientEnv(state.clientEnv, ...)`, so `state.clientEnv` is never applied to `process.env` and pane-scoped extensions cannot read their client identity (e.g. `HERDR_PANE_ID`). Only the explicit `reload` command wraps extension loading in `withClientEnv`, so any session-replacement flow silently drops client env from extension load context.
…ak into subprocesses
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 423de56. Configure here.
…t mix with ambient values
…ssion # Conflicts: # packages/coding-agent/src/modes/daemon/daemon-mode.ts # packages/coding-agent/test/daemon-mode.test.ts
…rimeIntellect-ai#303) * pass herdr client env through the daemon scoped per session * inherit client env in subagents and guard against watcher and cross-session env leaks * bind client env once at session creation and never rebind on reuse * scope env around the daemon reload command and adopt env on env-less session reuse * propagate adopted client env to subagents spawned before adoption * let the primary interactive attach adopt env for env-less sessions * scope client env around all runtime rebuilds via a runtime env scope hook * cover adopt-if-absent client env semantics on session reuse * pin allowlisted exec env per session so foreign env windows cannot leak into subprocesses * pin the full allowlist inside env windows so partial client env cannot mix with ambient values

Note
Medium Risk
Touches daemon session lifecycle, concurrent env-window locking, and subprocess env for all extension exec paths; wrong scoping could leak or mix pane identity across sessions.
Overview
Replaces shared daemon
process.envmutation with per-session client env so concurrent herdr panes no longer clobber each other.Interactive clients send an allowlisted herdr env on create (and primary attach with
sendClientEnv). The daemon stores it onActiveSessionState, adopts-if-absent when reusing env-less sessions (e.g. cron), and never overwrites an existing identity.withClientEnvtemporarily pins that env during extension load/reload and serializes exclusive windows vs env-less loads.setRuntimeEnvScope/scopedBuildwrap every runtime rebuild (new/switch/fork/import, subagents).pi.execmerges session env at spawn viagetExecEnv/execEnvForSessionwithout mutating the daemon’s global env. Subagents inherit the parent’sclientEnv.Reviewed by Cursor Bugbot for commit a39171b. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Scope client env to daemon sessions so extensions see the correct environment per pane
DaemonClientEnvallowlist and protocol fields socreateandattachcommands carry the client's env to the daemon;attachadopts env only if the session has none (adopt-if-absent).pi.exec()subprocesses use the session's client env rather than the daemon's globalprocess.env.withClientEnvto ensure extension modules see the correct env during evaluation.withClientEnvuses an exclusive lock during env-bound loads; high session concurrency may serialize extension reloads briefly.Macroscope summarized a39171b.