fix(tmux-terminal): D7 resolveWorkerPath walks up to find agents/lib/bg-worker (symlink loading)#102
Merged
Merged
Conversation
…bg-worker (symlink loading)
Bug surfaced by interactive test: when tmux-terminal is loaded via the
~/.pi/agent/extensions symlink, resolveWorkerPath returns null and the
extension silently skips registerBgTerminalBackend — producing
"No terminal backend installed" on /agents bg.
Root cause: production-mode baseDir was computed as
`path.dirname(path.dirname(fileURLToPath(import.meta.url)))`, which for a
module at `tmux-terminal/lib/resolve-worker-path.ts` resolves to
`tmux-terminal/` — but bg-worker.ts actually lives in `agents/lib/`.
Fix: walk UP from the module's directory, checking for
`agents/lib/bg-worker.{ts,mjs,js}` at each level. Robust to:
- symlinked extensions (~/.pi/agent/extensions/tmux-terminal)
- arbitrary repo depth (the agents/ dir may be N levels above)
- ts vs mjs vs js worker variants
Test added (testProductionModeFindsWorkerByWalkingUp in test-helpers.mjs):
- Sets up a fake repo layout in a tmpdir
- Copies resolve-worker-path.ts + constants.ts into a fake-extension/lib dir
- Spawns a child node process to verify production-mode path resolves
- Uses copy (not symlink) so Node ESM doesn't resolve import.meta.url
to the real path
Why previous tests missed it:
- testWorkerPathIsRealpathed + testWorkerPathPrefersTsOverMjs use the
searchDir parameter, which bypasses production-mode path calc
- test-real-tmux-smoke.mjs passes workerPath directly to createTmuxBackend,
never going through resolveWorkerPath
- The production-mode (no args) path was never exercised in any test
Verification:
- bash tmux-terminal/test-fixtures/run-p5-tests.sh: 63/63 + REQ-13 OK
- bash agents/test-fixtures/run-p4-4-tests.sh: green
- node tmux-terminal/test-fixtures/test-real-tmux-smoke.mjs: 11/11
- D7 test against broken version: FAILS (regression guard works)
- Mutation #1 + #2: still discriminate correctly
Surfaces-by pattern: any production-mode code that depends on
import.meta.url for path computation needs at least one test that
simulates the symlink-loading case (via copy + child process, since
Node ESM resolves symlinks at load time).
lantiscooperdev
approved these changes
Jun 27, 2026
lantiscooperdev
pushed a commit
that referenced
this pull request
Jun 27, 2026
…103) Three-source sync per workplan-update runbook after PR #102 merged: 1. Episodic memory (canonical-workplan): revised to new episode ID 20260627-092842-p5-fully-shipped-d5-d6-d7-fixes-merged-p-7d1e which supersedes the D5+D6-only episode. New body documents D7 (symlink-loading fix), the full D5/D6/D7 deviation timeline, lessons stored globally, and points at P5b as the next natural extension. 2. WORKPLAN.md pointer refreshed to the new canonical-workplan episode. Tags include p5-pr-98, p5-pr-100, p5-pr-102, p5-d5-d6-fix, p5-d7-fix. 3. agents/P3_IMPLEMENTATION_SLICES.md top-level P5 entry updated: - Added PR #102 + commit 6ec1b4b next to PR #100 - Branches line updated to note all 3 deleted branches No code changes. No agent/lib/ changes. Pattern follows PR #99 and #101 docs-only sync PRs (also required because main is branch-protected). Co-authored-by: Charlton D. Ho <dev@znp.pw>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes D7:
resolveWorkerPath()production mode looked forbg-worker.tsin the wrong directory (tmux-terminal/instead ofagents/lib/), causing the extension to silently skip registration when loaded via symlink (~/.pi/agent/extensions/tmux-terminal).Bug surfaced by the user's interactive test — after running
ln -sand restarting pi,/agents bg scout "..."still said "No terminal backend installed". This bug was invisible to all 63 unit tests + the real-tmux smoke test (see "Why previous tests missed it" below).The bug
tmux-terminal/lib/resolve-worker-path.tscomputed the production-mode baseDir as:For a module at
tmux-terminal/lib/resolve-worker-path.ts, this resolves totmux-terminal/— butbg-worker.tsactually lives atagents/lib/bg-worker.ts. The production-mode path looked in the wrong directory and returnednull. The extension'sregisterBgTerminalBackendwas silently skipped (console.debug("tmux-terminal: worker not found, skipping registration")), andgetBgTerminalBackend()inagents/index.tsreturnednull, producing the "No terminal backend installed" warning.The fix
Production mode now walks UP from the module's directory, checking for
agents/lib/bg-worker.{ts,mjs,js}at each level until found or root reached. Robust to:~/.pi/agent/extensions/tmux-terminal)agents/dir may be N levels above)New test
testProductionModeFindsWorkerByWalkingUpintest-fixtures/test-helpers.mjs:agents/lib/bg-worker.ts+fake-extension/lib/{resolve-worker-path,constants}.tsimport.meta.urlto the real pathWhy previous tests missed it
testWorkerPathIsRealpathedresolveWorkerPath(searchDir)— bypasses production-mode pathtestWorkerPathPrefersTsOverMjssearchDirtest-real-tmux-smoke.mjsworkerPathdirectly tocreateTmuxBackend, never going throughresolveWorkerPath-e)import.meta.urlhappens to give a path where dirname(dirname(...)) findsagents/lib/Lesson: any production-mode code that depends on
import.meta.urlfor path computation needs at least one test that simulates symlink loading via copy + child process.Verification
bash tmux-terminal/test-fixtures/run-p5-tests.sh: 64/64 (was 63) + REQ-13 OKbash agents/test-fixtures/run-p4-4-tests.sh: green (regression intact)node tmux-terminal/test-fixtures/test-real-tmux-smoke.mjs: 11/11 against real tmuxFiles changed (3 files, +60/-5)
tmux-terminal/lib/resolve-worker-path.ts— walk-up logic for production modetmux-terminal/test-fixtures/test-helpers.mjs— new D7 regression testagents/P3_IMPLEMENTATION_SLICES.md— D7 documented in deviations listUser-visible fix
After this PR merges + symlink exists,
/agents bg scout "echo hello"should launch a tmux window (no more "No terminal backend installed" warning).🤖 Generated with pi-coding-agent