feat(dx): Phase 2 — worktree-aware development with worktrunk#35101
feat(dx): Phase 2 — worktree-aware development with worktrunk#35101spbolton wants to merge 1 commit intophase-1/development-environment-setupfrom
Conversation
Layers worktree-specific features on top of the Phase 1 universal dev setup. Requires worktrunk (wt) for full functionality. Adds: - .config/wt.toml — post-create/pre-remove hooks for warm worktree starts - .worktreeinclude — files copied between worktrees via reflink - dotcms-worktree skill — branching, merging, agent spawning patterns - worktrunk tool in .mise.toml with shell integration in setup - Worktrees section in AGENTS.md with EnterWorktree warning - Worktrunk section in DEV_ENVIRONMENT_SETUP.md - Branch-based slugs (_worktree-slug) layered on folder-based (_project-slug) - worktree-init recipe wrapping init with worktree-specific steps - dev-shared-drop-worktree recipe for worktree cleanup - Worktree references in dev-services skill and CONTEXT_ARCHITECTURE.md Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
❌ Issue Linking RequiredThis PR could not be linked to an issue. All PRs must be linked to an issue for tracking purposes. How to fix this:Option 1: Add keyword to PR body (Recommended - auto-removes this comment)
Why is this required?Issue linking ensures proper tracking, documentation, and helps maintain project history. It connects your code changes to the problem they solve.--- This comment was automatically generated by the issue linking workflow |
|
Claude finished @spbolton's task in 2m 37s —— View job PR Review — Phase 2: Worktree-Aware Development
Issues Found1.
|
| Pattern | Size | Claimed |
|---|---|---|
target/ |
~3GB | Maven build output |
core-web/node_modules/ |
~2.8GB | Frontend dependencies |
.cache/ |
varies | Maven build cache |
But .worktreeinclude explicitly says the opposite:
# Intentionally excludes target/ and .cache/...
# node_modules is NOT copied — yarn install must run fresh...
And the wt.toml comment confirms: "Nx/Angular caches only, NOT node_modules". The docs describe warm-start as avoiding a rebuild, but without target/ being copied that claim doesn't hold. This will mislead anyone reading the docs about what actually gets copied and whether a rebuild is needed. Fix this →
3. wt.toml template filters sanitize and hash_port need verification
image = """
docker tag "dotcms/dotcms-test:{{ base | sanitize }}" "dotcms/dotcms-test:{{ branch | sanitize }}" ...
"""
port = "echo {{ branch | hash_port }} > {{ worktree_path }}/.dev-port"If sanitize or hash_port are not valid worktrunk template filters, {{ branch | hash_port }} will be written literally to .dev-port. Then dev-run reads that file as PORT, and Maven receives a non-numeric port — hard failure. The image hook is less critical since it falls through to || true, but the port hook has no fallback (other than the default 8082, which won't be used since .dev-port will exist with garbage content). Worth confirming these filters exist in the worktrunk docs before merging.
4. _worktree-slug slug collision: same branch, two local directories
Phase 1's _project-slug used basename "$(pwd)" — folder-based, unique on a single machine. Phase 2 uses git rev-parse --abbrev-ref HEAD — branch-based. If a developer has the same branch checked out in two directories (e.g., testing a rebase), both get the same slug → same container name dotbuild_dotcms-core_${WSLUG}_dotcms → docker run fails on the second one with a name conflict. Phase 1 didn't have this problem. Low probability but worth documenting as a gotcha.
5. Slug sanitization duplicated between justfile and wt.toml
The post-remove cleanup in wt.toml duplicates the slug sanitization:
# wt.toml post-remove
SLUG=$(echo "{{ branch }}" | sed 's/[^a-zA-Z0-9._-]/-/g; s/^[.-]*//' | cut -c1-64)# justfile _worktree-slug
@git rev-parse --abbrev-ref HEAD 2>/dev/null \
| sed 's/[^a-zA-Z0-9._-]/-/g; s/^[.-]*//' | cut -c1-64 \These are identical today, but if one diverges the cleanup will target the wrong container. This is unavoidable (the worktree may already be removed during post-remove, so just _worktree-slug can't run). Adding a comment noting this coupling would reduce future breakage risk.
Minor
dotcms-dev-services/SKILL.mdstill uses "project" terminology internally (lines 46, 84, 88, 90, etc.) after the rename wave — inconsistent with the new "worktree" language, though functionally harmless.- The
just worktree-initrecipe comment says "Called by wt.toml post-create hook — keeps logic in one place" — good, but thesetupdependency it chains means every new worktree creation re-runs the worktrunk shell integration install (wt config shell install). This is idempotent per the|| true, so no real harm.
|
Claude finished @spbolton's task in 1m 11s —— View job Rollback Safety Analysis
All 10 changed files are developer experience / tooling changes only:
No matches found against any unsafe category (C-1 through C-4, H-1 through H-7, M-1 through M-4):
|
Summary
Layers worktree-specific features on top of Phase 1's universal dev setup. Requires worktrunk (
wt) for full functionality.just setup.config/wt.toml— post-create hooks: copy caches via reflink, runjust init, re-tag Docker image, assign deterministic port.worktreeinclude— scopes which gitignored files get copied between worktrees (Nx cache, Angular cache, .venv)dotcms-worktreeskill — branching patterns, sub-task workflows, agent spawning (3 options), merge/cleanup_worktree-slug) layered on folder-based (_project-slug) for richer container namingworktree-initrecipe wrappinginitwith worktree-specific stepsdev-shared-drop-worktreerecipe for per-worktree shared data cleanupEnterWorktreewarningStacked on
Phase 1: #35100
Test plan
just setupinstalls worktrunk and shell integrationwt switch --create test-branchcreates warm-start worktree.dev-portfile created with deterministic portjust dev-runuses worktree-specific image tagjust dev-shared-drop-worktreecleans DB + indexes for current worktree🤖 Generated with Claude Code
Fixes: #34722