Skip to content

feat(cli): inject codebase env vars for bash nodes#1069

Closed
cburyta wants to merge 3 commits intocoleam00:devfrom
cburyta:feat/cli-inject-codebase-env-vars
Closed

feat(cli): inject codebase env vars for bash nodes#1069
cburyta wants to merge 3 commits intocoleam00:devfrom
cburyta:feat/cli-inject-codebase-env-vars

Conversation

@cburyta
Copy link
Copy Markdown

@cburyta cburyta commented Apr 11, 2026

Summary

  • Problem: CLI-executed workflow bash nodes don't receive codebase env vars stored in Archon's database. AI nodes get them via the Claude SDK client, but bash nodes are spawned as direct child processes and only see process.env.
  • Why it matters: Bash nodes exist to avoid AI credits for simple shell commands. Without env vars, scripts like source setup-env.sh && terraform validate can't resolve credentials, making bash nodes useless against cloned codebases that rely on DB-stored env vars.
  • What changed: After codebase resolution in the CLI workflow runner, load env vars from the DB and merge into process.env before executeWorkflow(). All child processes (bash and AI) inherit them.
  • What did not change: Server-side execution, AI node env var injection (Claude SDK client), the env var DB schema, or any workflow executor logic.

UX Journey

Before

  User                   CLI                      Bash Node
  ----                   ---                      ---------
  archon workflow run --> resolves codebase
                         starts workflow
                         spawns bash node -------> source setup-env.sh
                                                   MY_API_TOKEN=(empty)
                                                   tool-that-needs-auth FAILS
  sees "FAIL" <--------- reports result

After

  User                   CLI                      Bash Node
  ----                   ---                      ---------
  archon workflow run --> resolves codebase
                         [loads env vars from DB]
                         [merges into process.env]
                         starts workflow
                         spawns bash node -------> source setup-env.sh
                                                   MY_API_TOKEN=[SET]
                                                   tool-that-needs-auth runs
  sees result <--------- reports result

Architecture Diagram

Before

  CLI (workflow.ts)
    |
    +-- resolves codebase (codebaseDb)
    |
    +-- executeWorkflow(deps, adapter, cwd, ...)
          |
          +-- AI nodes --> Claude SDK --> subprocess (has env vars via SDK)
          |
          +-- Bash nodes --> child_process --> subprocess (NO env vars)

After

  CLI (workflow.ts)
    |
    +-- resolves codebase (codebaseDb)
    |
    +-- [~] loads env vars (envVarDb) --> Object.assign(process.env, vars)
    |
    +-- executeWorkflow(deps, adapter, cwd, ...)
          |
          +-- AI nodes --> Claude SDK --> subprocess (has env vars via SDK + process.env)
          |
          +-- Bash nodes --> child_process --> subprocess (inherits process.env)

Connection inventory:

From To Status Notes
CLI workflow.ts codebaseDb unchanged Codebase resolution
CLI workflow.ts envVarDb new Load codebase env vars
CLI workflow.ts process.env new Merge env vars before execution
process.env bash child_process unchanged Standard inheritance (now has vars)

Label Snapshot

  • Risk: risk: low
  • Size: size: XS
  • Scope: cli
  • Module: cli:workflow

Change Metadata

  • Change type: feature
  • Primary scope: cli

Linked Issue

  • None (discovered during workflow testing with cloned codebases)

Validation Evidence (required)

bun run validate  # PASS - type-check, lint, format, tests all green (exit code 0)
  • Test: Ran a workflow with a bash node (source setup-env.sh && terraform validate) against an Archon-cloned codebase (no .env file on disk). Before the fix: env vars empty. After: all 8 codebase env vars injected, tools authenticated successfully.
  • bun run test — all packages pass, 0 failures.

Security Impact (required)

  • New permissions/capabilities? No — env vars are already stored in the DB and used by AI nodes. This extends the same access to bash nodes.
  • New external network calls? No
  • Secrets/tokens handling changed? Yes — codebase env vars (which may contain API tokens) are now merged into process.env for the CLI process lifetime. This is the same trust boundary as the existing Claude SDK injection.
  • File system access scope changed? No
  • Mitigation: Env vars are already trusted (user configured them). The CLI is a single-developer local tool. No new trust boundary crossed.

Compatibility / Migration

  • Backward compatible? Yes — if no codebase is resolved or no env vars are set, behavior is unchanged.
  • Config/env changes? No
  • Database migration needed? No

Human Verification (required)

  • Verified: Workflow with bash node against Archon-cloned codebase — env vars injected, downstream tools authenticated
  • Verified: Same workflow against local repo with .env on disk — still works (env vars from both sources merge)
  • Edge cases checked: No codebase found (skips injection), empty env vars (no-op), DB read failure (logs warning, continues)
  • Not verified: Server-side execution path (unchanged, should not be affected)

Side Effects / Blast Radius (required)

  • Affected: CLI workflow execution only (workflowRunCommand in packages/cli/src/commands/workflow.ts)
  • Potential: If a codebase env var name collides with an existing process.env var, the DB value wins (Object.assign overwrites). This is intentional — codebase-specific config should override ambient env.
  • Guardrails: Logged at info level with count of injected vars. Failed loads logged at warn level.

Rollback Plan (required)

  • Fast rollback: Revert single commit (1 file, 20 lines)
  • Feature flags: None — always active when a codebase is resolved
  • Observable failure: If reverted, bash nodes in CLI workflows won't see codebase env vars (same as before this PR)

Risks and Mitigations

  • Risk: Env var name collision between codebase vars and existing process.env
    • Mitigation: Intentional behavior — codebase config takes precedence. Logged for observability.
  • Risk: Env vars persist in process.env after workflow completes (if CLI reused for multiple runs)
    • Mitigation: CLI process exits after each archon workflow run invocation. No persistence across runs.

Summary by CodeRabbit

  • New Features
    • Workflows now automatically load and inject codebase environment variables during execution with graceful error handling.
  • Bug Fixes
    • Environment variables injected for a workflow are restored to their prior state after the run to avoid leaking changes.
  • Chores
    • Added success and warning logs for environment variable load/injection events.

Bash nodes in CLI workflows were not receiving codebase env
vars from the database. After codebase resolution, load env
vars and merge into process.env so all child processes
(bash and AI nodes) inherit them.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 11, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6b316bec-0830-44ca-90ad-283c1d6f3b5a

📥 Commits

Reviewing files that changed from the base of the PR and between 6942847 and 108addf.

📒 Files selected for processing (1)
  • packages/cli/src/commands/workflow.ts

📝 Walkthrough

Walkthrough

Loads codebase-scoped environment variables from the DB before executing the workflow, injects them into process.env for the run, logs injection or load warnings, and restores the original process.env values after workflow execution.

Changes

Cohort / File(s) Summary
Environment Variable Injection
packages/cli/src/commands/workflow.ts
Add DB dependency and call getCodebaseEnvVars(codebase.id) pre-execution. Snapshot existing process.env values, merge returned vars into process.env so spawned processes inherit them, log success (cli.codebase_env_vars_injected) with codebaseId and injected key count, log warning on load failure (cli.codebase_env_vars_load_failed) without aborting, and restore original env entries (delete keys that were previously undefined) in the finally block before unsubscribing from events.

Sequence Diagram(s)

sequenceDiagram
  participant CLI as CLI Command
  participant DB as EnvVar DB
  participant OS as process.env / Spawned Processes
  participant Workflow as executeWorkflow()

  CLI->>DB: getCodebaseEnvVars(codebase.id)
  alt vars returned
    DB-->>CLI: {KEY: value, ...}
    CLI->>CLI: snapshot existing process.env keys
    CLI->>OS: merge loaded vars into process.env
    CLI->>CLI: log cli.codebase_env_vars_injected(codebaseId, count)
  else load fails
    DB-->>CLI: error
    CLI->>CLI: log cli.codebase_env_vars_load_failed(...)
  end
  CLI->>Workflow: executeWorkflow()
  Workflow->>OS: spawn child processes (inherit env)
  Workflow-->>CLI: completes
  CLI->>CLI: restore original process.env values (delete newly undefined)
  CLI->>CLI: unsubscribe from workflow events
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰🌱
A hop, a sniff, the keys aligned,
I tuck them in the env I find.
Workflow leaps with nourished cheer,
I tidy up when run is clear.
A rabbit's nod — safe changes here.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed Title clearly and concisely summarizes the main change: adding codebase environment variable injection for bash nodes in the CLI workflow command.
Description check ✅ Passed Description comprehensively covers all template sections including problem, UX journey, architecture diagrams, validation evidence, security impact, compatibility, human verification, side effects, and rollback plan.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/cli/src/commands/workflow.ts`:
- Around line 595-613: The code injects codebase env vars into process.env via
Object.assign(process.env, codebaseEnvVars) (using envVarDb.getCodebaseEnvVars
and getLog()) but never restores the previous process.env, causing injected keys
to leak across reuses of workflowRunCommand (resume/approve/reject flows); fix
by snapshotting the set of keys added (or the prior values) before assignment,
perform the injection as now, and ensure in a finally block after execution you
remove the added keys or restore prior values so process.env is returned to its
original state for subsequent runs.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 039b9ab9-81c8-4b9f-aa0b-a82deebc82f8

📥 Commits

Reviewing files that changed from the base of the PR and between 536584d and 6942847.

📒 Files selected for processing (1)
  • packages/cli/src/commands/workflow.ts

Comment thread packages/cli/src/commands/workflow.ts
cburyta added 2 commits April 11, 2026 21:16
Snapshot injected env var keys before mutation and restore previous
values in a finally block after workflow execution completes.
Prevents env var bleed if workflowRunCommand is ever called multiple
times in the same process (e.g. future long-lived process reuse).
@Wirasm
Copy link
Copy Markdown
Collaborator

Wirasm commented Apr 13, 2026

Closing — this feature (bash node managed env injection) is now tracked as part of #1161, which covers all execution surfaces consistently. The approach here (mutating process.env at the CLI level) would affect all subprocesses globally rather than per-node. The #1161 approach is to pass { ...process.env, ...managedEnv } explicitly via the env option on execFileAsync per-node. Thanks for identifying the gap — it's a real product need and will land as part of the broader managed env consistency work.

@Wirasm Wirasm closed this Apr 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants