Skip to content

Worktree add doesn't bootstrap dependencies (node_modules, submodules) #50

@chubes4

Description

@chubes4

Summary

studio wp datamachine-code workspace worktree add <repo> <slug> creates a fresh checkout but doesn't run any of the bootstrap steps the new working tree needs to be usable. For most non-trivial repos that means the worktree is checked out but tests can't run, builds can't run, and nothing that imports from node_modules resolves until the user manually bootstraps.

What the worktree is missing

git worktree add (which DMC's worktree add wraps) intentionally only replays git-tracked state. After DMC #45 the worktree also gets .claude/CLAUDE.local.md + .opencode/AGENTS.local.md injected. But:

  • node_modules — not tracked by git, not copied, no install run
  • Submodules — tracked by git via .gitmodules but git worktree add does not auto-init them
  • Repo-local bootstrap — any composer install, bundle install, nx build, schema init, etc. the repo normally needs on fresh checkout

Concrete failure I hit today

Stripping a commit from a PR on WordPress/wordpress-playground using:

```bash
git worktree add /tmp/pg-strip-eviction -b
```

To run vitest run packages/playground/cli/tests/run-cli.spec.ts in the fresh worktree, I had to:

  1. git submodule update --init --recursive — the isomorphic-git/ submodule wasn't initialized, so a transitive import isomorphic-git/src/models/GitPktLine.js failed to resolve and vitest couldn't even load the spec file
  2. npm install — no nx or vitest on the worktree's path

Neither step is exotic, but both are easy to miss, and the failure mode ("vitest can't load spec", "sh: nx: command not found") doesn't point at "your worktree isn't bootstrapped yet."

The symlink workaround (ln -s <primary>/node_modules <worktree>/node_modules) works for pure-TS specs but breaks the moment a test walks directories relative to the worktree root — exactly what the submodule case triggered.

Proposal

Add opt-in bootstrap to worktree add. Three shapes, increasing ambition:

1. Document the escape hatch (cheapest)

Add a NEXT STEPS block to worktree add's output:

```
Worktree ready at .
Remember to bootstrap before running tests/builds:
git -C submodule update --init --recursive
cd && install
```

Low cost, limited value — just turns silent gaps into visible ones.

2. --bootstrap flag (recommended)

```
studio wp datamachine-code workspace worktree add --bootstrap
```

Runs a detected bootstrap sequence:

  • git submodule update --init --recursive if .gitmodules exists
  • Package-manager install based on lockfile presence:
    • package-lock.jsonnpm ci
    • pnpm-lock.yamlpnpm install --frozen-lockfile
    • bun.lockbbun install --frozen-lockfile
    • yarn.lockyarn install --immutable
  • composer install --no-interaction if composer.lock exists

Off by default (fast worktree add stays fast when you just want to read code). Opt-in when you want test/build-ready.

3. Repo-declared manifest (future)

.datamachine/worktree.yml (or similar) in the repo root, declaring what bootstrap means there. Lets monorepos define non-obvious steps (nx build shared-types before anything else builds, WASM artifact symlinks, etc.) without baking repo-specific knowledge into DMC.

Why not just symlink node_modules

Tempting — fast, obvious. But:

  • Breaks for any test runner that walks paths relative to the worktree root (hit this today)
  • Breaks when lockfiles drift between branches (primary on trunk vs worktree on a feature branch that added deps)
  • Breaks on rm -rf node_modules in primary (blows away the worktree too)

Real npm install (or equivalent) is the honest answer.

Out of scope for this issue

  • Per-repo custom bootstrap hooks (option 3 above) — can be a follow-up
  • Teardown on worktree remove (probably also worth doing, separate issue)
  • Clever node_modules sharing (pnpm-style content-addressed store across worktrees) — interesting but a much bigger rabbit hole

Context

  • DMC worktree infrastructure: datamachine_worktree_metadata, wp datamachine-code workspace worktree add|list|remove|prune
  • Prior art for context injection: DMC Inject site-agent context into worktrees on creation #45 (merged) — sets the precedent that worktree add is a reasonable place to run additional setup
  • Primary checkout stays read-only by default; worktrees are always mutable — so --bootstrap running install in a worktree is consistent with the existing safety model

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions