Add per-worktree local port bundles for dispatch QA
Problem
Allocate unique local serve ports for each dispatched worktree, write a worktree-local ports file similar to .cbox-ports.json, and teach local serve/QA workflows to read it so parallel worktrees can run QA without port collisions.
Context
Possible Solutions
- Recommended: allocate a gitignored
.worktree-ports.jsonduringscripts/worktree-new, then teachjust worktree-serve,just worktree-restart-serve,scripts/dispatch, andqa-explorerdocs to consume the same manifest. This keeps the port source of truth in one file and mirrors the old cbox flow without introducing container-only assumptions.
Plan
- Add a small stdlib-only
scripts/worktree_ports.pyallocator that chooses the first free 100-port offset bundle and writes.worktree-ports.json. - Update
scripts/worktree-newandscripts/dispatchto generate/read the manifest and surface the worktree Cloud URL. - Add
just worktree-serveandjust worktree-restart-serve, plus worktree-specific health checks. - Update QA/task/PR docs to use the worktree-local manifest and keep markdown changes included in PRs.
- Cover the new script path with focused script tests.
Implementation Progress
- Added
scripts/worktree_ports.pywith allocation, shell export, and value lookup commands. scripts/worktree-newnow writes.worktree-ports.jsonand prints the Cloud URL for the new worktree.scripts/dispatchnow recordscloud_urlandports_filein its status/log output so QA can discover the right stack.- Added
just worktree-serve/just worktree-restart-serveandcheck_local_stack.py worktree. - Updated
qa-explorer,task-manager,AGENTS.md, and PR workflow docs to use the worktree manifest and to always include markdown changes in PRs. - Added script regressions for worktree port allocation, shell export formatting,
worktree-new, anddispatch.
QA Exploration
N/A. This is local-dev/worktree infrastructure, not a browser-facing product flow.
- [x] QA exploration completed (or N/A for non-UI tasks)
Review Feedback
- Added a defensive
No usable project foundguard in org chat scope resolution. - Hardened
emit_shell_exports()to use single-quoted shell values beforeeval. -
Removed the temporary
scripts/__init__.pypackage marker after it broke temp-repo PR script tests. -
[x] Review cleared