Repository navigation
Pass herdr env vars from interactive client through daemon protocol to extensions #276
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
a8217da
e91f028
305cc3d
147641b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -74,6 +74,29 @@ import { | |
| restrictDaemonSocketPath, | ||
| } from "./daemon-socket.js"; | ||
|
|
||
| /** Env vars from the client that should be exposed to extensions via process.env. */ | ||
| const CLIENT_ENV_KEYS = [ | ||
| "HERDR_ENV", | ||
| "HERDR_PANE_ID", | ||
| "HERDR_SOCKET_PATH", | ||
| "HERDR_TAB_ID", | ||
| "HERDR_WORKSPACE_ID", | ||
| ] as const; | ||
|
|
||
| /** | ||
| * Update process.env with the client's environment variables so extensions | ||
| * running in the daemon process can access them (e.g. herdr pane identity). | ||
| * Only a curated set of keys is applied to avoid leaking unrelated env vars. | ||
| */ | ||
| function applyClientEnvToProcess(env?: Record<string, string>): void { | ||
| if (!env) return; | ||
| for (const key of CLIENT_ENV_KEYS) { | ||
| if (env[key] !== undefined) { | ||
| process.env[key] = env[key]; | ||
| } | ||
| } | ||
| } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 Medium
function applyClientEnvToProcess(env?: Record<string, string>): void {
+ if (env) {
+ for (const key of CLIENT_ENV_KEYS) {
+ delete process.env[key];
+ }
+ }
if (!env) return;
for (const key of CLIENT_ENV_KEYS) {
if (env[key] !== undefined) {
process.env[key] = env[key];
}
}
}Also found in 1 other location(s)
🚀 Reply "fix it for me" or copy this AI Prompt for your agent: |
||
|
|
||
| export interface DaemonModeOptions { | ||
| socketPath?: string; | ||
| defaultSessionConfig: AgentSessionRuntimeConfig; | ||
|
|
@@ -898,6 +921,7 @@ export class AgentDaemon { | |
| } | ||
|
|
||
| case "create": { | ||
| applyClientEnvToProcess(command.env); | ||
| const state = await this.createRuntime(command); | ||
| return success(command.id, "create", summaryForActiveSession(state)); | ||
| } | ||
|
|
@@ -909,6 +933,8 @@ export class AgentDaemon { | |
| } | ||
| client.capabilities = normalizeClientCapabilities(command.capabilities, command.supportsExtensionUi); | ||
| client.supportsExtensionUi = client.capabilities.has("extension_ui"); | ||
| client.clientEnv = command.env; | ||
| applyClientEnvToProcess(command.env); | ||
|
cursor[bot] marked this conversation as resolved.
Resolved
|
||
| state.clients.add(client); | ||
| client.attachedActiveSessionIds.add(state.activeSessionId); | ||
| const result = this.createAttachResult(client, state, command); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🟠 High
daemon/daemon-mode.ts:86applyClientEnvToProcesswrites the client'sHERDR_*values into the sharedprocess.env, but it is only called duringcreateandattach. When two clients are attached to the same daemon, the last client to attach overwrites the previous client's values inprocess.env, and subsequent commands from the other client (e.g.prompt) never re-apply that client'sclientEnvbefore running extensions. This means extensions see whichever pane attached last, not the pane that issued the current command. Consider re-applying the invoking client'sclientEnvat the start of each command that may run extensions, or isolate the values per-call rather than mutating sharedprocess.env.🚀 Reply "fix it for me" or copy this AI Prompt for your agent: