Skip to content

fix(bin): forward PI_CODING_AGENT_DIR to Pi crewmates - #3494

Open
pperanich wants to merge 1 commit into
kunchenguid:mainfrom
pperanich:fix/spawn-forward-pi-coding-agent-dir
Open

fix(bin): forward PI_CODING_AGENT_DIR to Pi crewmates#3494
pperanich wants to merge 1 commit into
kunchenguid:mainfrom
pperanich:fix/spawn-forward-pi-coding-agent-dir

Conversation

@pperanich

Copy link
Copy Markdown

Intent

Forward PI_CODING_AGENT_DIR onto pi and pi-signed crewmate launches in bin/fm-spawn.sh, only when it is set, exactly mirroring how PR #1195 forwards CLAUDE_CONFIG_DIR for claude crewmates. Motivation: crewmate panes come from the long-lived tmux/herdr daemon and do not inherit the primary's environment, so a firstmate primary started under an alternate Pi profile (PI_CODING_AGENT_DIR pointing at a profile with different settings, packages, extensions, auth) spawned crewmates on the default ~/.pi/agent profile. Verified by reading fm-spawn.sh and backends/tmux.sh (send-keys into a new window of the firstmate session) and by launching a pi worker in a fresh tmux shell. Deliberate decisions: keep the change minimal (no new profile concept, no pinning, unlike the stale PRs #877/#966); apply to both pi and pi-signed since both share the Pi launch template; place the block directly after the CLAUDE_CONFIG_DIR block with a matching comment; never prefix when the variable is unset so the default single-profile path is byte-identical to before. Tests: in tests/fm-spawn-dispatch-profile.test.sh pin PI_CODING_AGENT_DIR empty in run_spawn (opt-in via FM_TEST_PI_CODING_AGENT_DIR) and in the four ad-hoc spawn invocations that already pin CLAUDE_CONFIG_DIR, so assertions never depend on the developer's shell; add three cases mirroring the claude ones: pi forwards when set, pi omits the prefix when unset, a non-pi harness (claude) ignores it. No docs changed, matching PR #1195's file set. Commit follows Conventional Commits with no AI attribution.

What Changed

  • Pin PI_CODING_AGENT_DIR in spawn fixtures and cover forwarding, omission, and non-Pi behavior.
  • Forward a set PI_CODING_AGENT_DIR to pi and pi-signed crewmates while leaving other launches unchanged.

Risk Assessment

✅ Low: The change is narrowly scoped, matches the CLAUDE_CONFIG_DIR precedent, safely quotes the value, covers both Pi harnesses, preserves the unset path, and adds behavior-level spawn tests.

Testing

After repository bootstrap, the targeted suite and focused cases passed. The base source failed the new forwarding test as expected, while the end-to-end CLI transcript showed the profile prefix on pi and pi-signed launches and nowhere else. The worktree remained clean.

Evidence: End-to-end Pi spawn transcript

Source: End-to-end Pi spawn transcript

CASE pi with alternate profile
spawned evidence-pi-set-z1 harness=pi kind=ship mode=no-mistakes yolo=off window=firstmate:fm-evidence-pi-set-z1 worktree=/private/var/folders/1c/sz9p1x8j1msd9cmf3f8rfgrw0000gn/T/fm-spawn-dispatch-profile.5kdLNh/evidence-pi-set/wt
TMUX_PAYLOAD=PI_CODING_AGENT_DIR='/opt/profiles/alternate-pi' env -u CURSOR_AGENT -u CURSOR_INVOKED_AS FM_PI_HARNESS=pi '/private/var/folders/1c/sz9p1x8j1msd9cmf3f8rfgrw0000gn/T/fm-spawn-dispatch-profile.5kdLNh/evidence-pi-set/fake/fakebin/pi' --tui-mode regular -e '/private/var/folders/1c/sz9p1x8j1msd9cmf3f8rfgrw0000gn/T/fm-spawn-dispatch-profile.5kdLNh/evidence-pi-set/home/state/evidence-pi-set-z1.pi-ext.ts' "$('~/.no-mistakes/worktrees/74c906478ac0/01M1G1SDSM8C5Q0TKAE006FE9F/bin/fm-operational-input.sh' encode launch-brief < '/private/var/folders/1c/sz9p1x8j1msd9cmf3f8rfgrw0000gn/T/fm-spawn-dispatch-profile.5kdLNh/evidence-pi-set/home/data/evidence-pi-set-z1/brief.md')"

CASE pi-signed with alternate profile
spawned evidence-pi-signed-set-z2 harness=pi-signed kind=ship mode=no-mistakes yolo=off window=firstmate:fm-evidence-pi-signed-set-z2 worktree=/private/var/folders/1c/sz9p1x8j1msd9cmf3f8rfgrw0000gn/T/fm-spawn-dispatch-profile.5kdLNh/evidence-pi-signed-set/wt
TMUX_PAYLOAD=PI_CODING_AGENT_DIR='/opt/profiles/alternate-pi' env -u CURSOR_AGENT -u CURSOR_INVOKED_AS FM_PI_HARNESS=pi-signed '/private/var/folders/1c/sz9p1x8j1msd9cmf3f8rfgrw0000gn/T/fm-spawn-dispatch-profile.5kdLNh/evidence-pi-signed-set/fake/fakebin/pi-signed' --tui-mode regular -e '/private/var/folders/1c/sz9p1x8j1msd9cmf3f8rfgrw0000gn/T/fm-spawn-dispatch-profile.5kdLNh/evidence-pi-signed-set/home/state/evidence-pi-signed-set-z2.pi-ext.ts' "$('~/.no-mistakes/worktrees/74c906478ac0/01M1G1SDSM8C5Q0TKAE006FE9F/bin/fm-operational-input.sh' encode launch-brief < '/private/var/folders/1c/sz9p1x8j1msd9cmf3f8rfgrw0000gn/T/fm-spawn-dispatch-profile.5kdLNh/evidence-pi-signed-set/home/data/evidence-pi-signed-set-z2/brief.md')"

CASE pi with PI_CODING_AGENT_DIR unset
spawned evidence-pi-unset-z3 harness=pi kind=ship mode=no-mistakes yolo=off window=firstmate:fm-evidence-pi-unset-z3 worktree=/private/var/folders/1c/sz9p1x8j1msd9cmf3f8rfgrw0000gn/T/fm-spawn-dispatch-profile.5kdLNh/evidence-pi-unset/wt
PROFILE_PREFIX=absent

CASE claude while PI_CODING_AGENT_DIR is set
spawned evidence-claude-pi-set-z4 harness=claude kind=ship mode=no-mistakes yolo=off window=firstmate:fm-evidence-claude-pi-set-z4 worktree=/private/var/folders/1c/sz9p1x8j1msd9cmf3f8rfgrw0000gn/T/fm-spawn-dispatch-profile.5kdLNh/evidence-claude-pi-set/wt
PI_PROFILE_PREFIX=absent
Evidence: Baseline regression reproduction

Source: Baseline regression reproduction

Baseline regression check: target behavioral test against base fm-spawn.sh
not ok - pi launch did not forward firstmate's PI_CODING_AGENT_DIR to the crewmate pane (missing: 'PI_CODING_AGENT_DIR='/opt/test/pi-work' env -u CURSOR_AGENT -u CURSOR_INVOKED_AS FM_PI_HARNESS=pi '/private/var/folders/1c/sz9p1x8j1msd9cmf3f8rfgrw0000gn/T/fm-spawn-dispatch-profile.lSoIfP/profile-pi-agentdir/fake/fakebin/pi' --tui-mode regular')
--- output ---
env -u CURSOR_AGENT -u CURSOR_INVOKED_AS FM_PI_HARNESS=pi '/private/var/folders/1c/sz9p1x8j1msd9cmf3f8rfgrw0000gn/T/fm-spawn-dispatch-profile.lSoIfP/profile-pi-agentdir/fake/fakebin/pi' --tui-mode regular -e '/private/var/folders/1c/sz9p1x8j1msd9cmf3f8rfgrw0000gn/T/fm-spawn-dispatch-profile.lSoIfP/profile-pi-agentdir/home/state/profile-pi-agentdir-z20.pi-ext.ts' "$('/private/tmp/fm-pi-agentdir-baseline.XvlGVv/bin/fm-operational-input.sh' encode launch-brief < '/private/var/folders/1c/sz9p1x8j1msd9cmf3f8rfgrw0000gn/T/fm-spawn-dispatch-profile.lSoIfP/profile-pi-agentdir/home/data/profile-pi-agentdir-z20/brief.md')"
baseline_exit=1 (expected nonzero)
Evidence: Dispatch-profile test log

Source: Dispatch-profile test log

ok - no --model/--effort records defaults and types the claude launch instructions
ok - non-cursor launches clear inherited Cursor identity markers
ok - relative home overrides ignore CDPATH and become absolute before spawn launch construction
ok - FM_HOME defaults resolve relative paths and preserve absolute spellings
ok - absolute override spellings are preserved in spawn launch paths
ok - unresolvable relative spawn overrides fail with named diagnostics
ok - active crew-dispatch profile requires an explicit harness for ship spawns
ok - active crew-dispatch profile requires an explicit harness for scout spawns
ok - active crew-dispatch profile allows an explicit resolved harness
ok - active crew-dispatch profile allows the legacy positional harness form
ok - active crew-dispatch profile allows the raw launch-command escape hatch
ok - claude receives --model and --effort profile flags
ok - codex receives --model and model_reasoning_effort profile flags
ok - codex omits unsupported max effort instead of passing a bad config value
ok - grok receives --model and --reasoning-effort profile flags
ok - grok omits unsupported max reasoning effort
ok - grok omits unsupported xhigh reasoning effort
ok - cursor receives its model-qualified reasoning class and exact task workspace
ok - cursor refuses model ids absent from its resolved binary's live catalog
ok - cursor preserves the requested model when its live catalog is unreachable
ok - opencode receives --model and omits the unsupported effort axis
ok - pi receives --model and --thinking max profile flags
ok - Pi launch probing omits --tui-mode on older Pi and preserves it on supporting Pi
ok - pi-signed shares Pi launch semantics while preserving its configured and recorded identity
ok - pi-signed refuses safely and actionably when the selected executable is unavailable
ok - pi-signed is a distinct persistent secondmate runtime with shared Pi supervision semantics
ok - batch dispatch forwards shared --harness, --model, and --effort to every pair
ok - claude forwards firstmate's CLAUDE_CONFIG_DIR so the crewmate uses the same credential store
ok - claude omits the config-dir prefix when firstmate runs with the single-store default
ok - non-claude harnesses do not receive the claude CLAUDE_CONFIG_DIR prefix
ok - pi forwards firstmate's PI_CODING_AGENT_DIR so the crewmate uses the same agent profile
ok - pi omits the profile prefix when firstmate runs with the default agent directory
ok - non-pi harnesses do not receive the PI_CODING_AGENT_DIR prefix
ok - active crew-dispatch profile does not block secondmate launches
# all fm-spawn-dispatch-profile tests passed

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

✅ **Review** - passed

✅ No issues found.

✅ **Test** - passed

✅ No issues found.

  • Repository bootstrap: bin/fm-session-start.sh
  • Automated behavior suite: bash tests/fm-spawn-dispatch-profile.test.sh
  • Focused selectors: test_pi_forwards_firstmate_coding_agent_dir_when_set, test_pi_omits_coding_agent_dir_prefix_when_unset, and test_non_pi_harness_ignores_coding_agent_dir
  • Focused pi-signed spawn assertion through the shared Pi launch path
  • Regression reproduction: target test_pi_forwards_firstmate_coding_agent_dir_when_set executed against 54663948647a41e21b289d9992159b1bdc3bb6ca:bin/fm-spawn.sh
  • Evidence-producing executable check through fm-spawn.sh and captured tmux payloads for set Pi, set Pi Signed, unset Pi, and Claude
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

Crewmate panes are created by the long-lived tmux/herdr daemon and do not
inherit firstmate's environment. A primary running under an alternate Pi
profile (PI_CODING_AGENT_DIR) therefore spawned pi and pi-signed
crewmates on the default ~/.pi/agent, with whatever model, packages, and
extensions live there instead of the profile the primary was launched
with.

Forward PI_CODING_AGENT_DIR onto pi and pi-signed launches only when it
is set, mirroring the CLAUDE_CONFIG_DIR forwarding for claude crewmates.
Pin the variable empty in the dispatch-profile test harness so launch
assertions cannot depend on the developer's shell, and add the set,
unset, and non-pi-harness cases beside the claude ones.
@greptile-apps

greptile-apps Bot commented Sep 2, 2026

Copy link
Copy Markdown

Confidence Score: 5/5

The PR appears safe to merge with no actionable correctness, security, or repository-policy issues identified.

The new assignment is safely quoted, reaches both supported Pi harnesses through their shared launch path, remains a direct interactive command, and leaves unset and non-Pi launches unchanged.

Reviews (1): Last reviewed commit: "fix(spawn): forward PI_CODING_AGENT_DIR ..." | Re-trigger Greptile

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.

1 participant