Skip to content

Isolate innerdogfood ports and browser sessions per worktree - #605

Merged
nedtwigg merged 3 commits into
mainfrom
parallel-innerdogfood
Sep 10, 2026
Merged

Isolate innerdogfood ports and browser sessions per worktree#605
nedtwigg merged 3 commits into
mainfrom
parallel-innerdogfood

Conversation

@nedtwigg

Copy link
Copy Markdown
Member

Running pnpm innerdogfood in two worktrees previously collided on fixed ports and reused the same browser session. The harness now binds OS-assigned ports and derives a stable browser identity from the canonical worktree path. Inside Dormouse, dor ensure -- pnpm innerdogfood opens the worktree's browser pane automatically and prints its URL and browser command.

Explicit port and session overrides remain supported. Vite runs in the harness process so startup uses its actual listener; failed startup and shutdown clean up the harness's own servers, sidecar, and browser launcher, including launchers that ignore SIGTERM. The spec and debugging instructions document the new workflow and avoid global browser cleanup.

Validation:

  • Standalone suite, including concurrent harnesses with real Vite/HTTP listeners, HMR, bridge isolation, fixed-port conflicts, and shutdown behavior.
  • Mirrored-constants regression tests for pairing-walkthrough compatibility.
  • Spec and loopback lints with their self-tests.
  • Real staged-app browser smoke test: page loaded and terminal mounted on an allocated port.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Sep 10, 2026

Copy link
Copy Markdown

Deploying mouseterm with  Cloudflare Pages  Cloudflare Pages

Latest commit: ed086d6
Status: ✅  Deploy successful!
Preview URL: https://96c4e153.mouseterm.pages.dev
Branch Preview URL: https://parallel-innerdogfood.mouseterm.pages.dev

View logs

@nedtwigg
nedtwigg marked this pull request as ready for review September 10, 2026 01:16

@dormouse-bot dormouse-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Two inline notes, plus two things outside the diff.

.claude/skills/debug-standalone-agent-browser/SKILL.md still tells its reader that validating a harness change means node --check standalone/scripts/dev-agent-browser.mjs and pnpm --filter dormouse-standalone build — the "Validation" section, under "After changing the harness, run:". This PR adds the suite that is now the real gate, and standalone/package.json's test script already picks it up through node --test scripts/*.test.mjs, so the skill points at the weaker check. Adding pnpm --filter dormouse-standalone test there closes it; happy to push that as a commit.

#493 (draft) edits the same startup block this PR rewrote, so it will conflict — and the conflict is not purely textual. It appends an OSC 367 serve announcement built from JSON.stringify({ port: vitePort, name: 'Dormouse dev', v: 1 }), read at module scope. Under this PR vitePort is the requested port, 0 by default, and the bound port only exists afterwards as vite.httpServer.address().port. A resolution that carries that line across verbatim announces port: 0 to every Dormouse terminal, and #493's test pins the payload shape rather than the value, so it stays green. Whichever lands second wants the announcement moved below startVite() and sourced from the actual listener.

Comment thread standalone/scripts/dev-agent-browser.test.mjs Outdated
Comment thread standalone/scripts/dev-agent-browser.mjs Outdated
@nedtwigg

Copy link
Copy Markdown
Member Author

Addressed the inline findings in ed086d6 and added pnpm --filter dormouse-standalone test to the debugging skill’s Validation section. The standalone suite and spec/loopback lints pass.

Confirmed the overlap with draft #493. This PR does not yet emit OSC 367; I renamed its setting to requestedVitePort to distinguish the requested value (zero by default) from the bound listener. When the two PRs are combined, the serve announcement must move after await startVite() and use vite.httpServer.address().port; its regression test should assert a nonzero port matching the app URL. Carrying #493’s current startup line over unchanged would be incorrect.

@dormouse-bot

Copy link
Copy Markdown
Collaborator

Both fixes hold up on a read of ed086d69.

The close switch is right, including the ordering that decides it: wait() tests output.match(pattern) before it tests closed, so a chunk that lands during the final delay(25) is still matched on the next iteration rather than lost to the break. The hanging-launcher test can't deadlock the new promise either — the harness spawns the browser with its own ['ignore', 'pipe', 'pipe'], so the SIGTERM-ignoring stub never holds the harness's stdout open and close isn't waiting on it.

On sessionForKey, the runtime path was already covered before pretest: innerdogfood runs stage -> stage:dor-cli -> pnpm --filter dor build, and dor's own prebuild builds dor-lib-common. So pretest is exactly what was missing for test (which doesn't run stage), and pnpm innerdogfood from a fresh checkout won't hit a missing dist/agent-browser.js.

Nothing to add on #493requestedVitePort, plus moving the announcement below startVite() and sourcing it from vite.httpServer.address().port, is the resolution I had in mind. Asserting a nonzero port that matches the app URL is the part that closes the hole, since the current payload-shape assertion would stay green on port: 0.

Build & Test is still in flight on ed086d69; nothing on that commit has failed.

@nedtwigg
nedtwigg merged commit fff251c into main Sep 10, 2026
16 checks passed
@nedtwigg
nedtwigg deleted the parallel-innerdogfood branch September 10, 2026 02:56
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