with one click
environments-manager
// Set up per-worktree environments for Claude Code, Cursor, or Codex. Use for worktree-ready repos, IDE environment config, worktree-up/down scripts, or dev.sh wiring.
// Set up per-worktree environments for Claude Code, Cursor, or Codex. Use for worktree-ready repos, IDE environment config, worktree-up/down scripts, or dev.sh wiring.
A brief description of what this skill does
Create and maintain agent rules in AGENTS.md and .agents/rules/. Use for project rules, conventions, constraints, rule indexes, or requests to add or optimize agent rules.
Create or edit Claude, Codex, and Cursor skills/rules. Use for SKILL.md, .cursor/rules, AGENTS.md, skill prompts, frontmatter, references, scripts, and discovery rules.
Expert guidance for creating, building, and using Claude Code agents and the Task tool. Use when working with agents, setting up agent configurations, understanding how agents work, or using the Task tool to launch specialized agents.
| name | environments-manager |
| description | Set up per-worktree environments for Claude Code, Cursor, or Codex. Use for worktree-ready repos, IDE environment config, worktree-up/down scripts, or dev.sh wiring. |
| disable-model-invocation | false |
| allow_implicit_invocation | true |
Set up per-worktree environments so a fresh worktree is instantly ready to run: env files copied, dependencies installed, isolated database created, and common commands one click away. Supports Claude Code, Cursor, and Codex - the shared scripts are the same on every IDE; only the config file that points at them differs.
This skill is interactive. Ask the user the two questions below before writing anything - the right setup depends on the project. Use whichever interactive question mechanism the host harness provides. Do not assume answers.
Ask the user what the setup script should do, as a multi-select. The first option is the default-on baseline; the rest are additive opt-ins:
| Option | What it adds to scripts/worktree-up.sh |
|---|---|
| Copy ignored env files from the source checkout | cp of .env, .env.local, .env.development.local (default - almost always wanted) |
| Install dependencies | pnpm install / bun install / npm install based on lockfile |
| Create an isolated database for this worktree | Build a unique DB name from the worktree dir, rewrite DATABASE_URL in .env, run createdb + import |
| Run codegen (Prisma, Drizzle, generated types) | pnpm prisma:generate / bun run db:generate / etc. |
If the user has project-specific steps (seed data, S3 sync, etc.), ask a follow-up free-form question to capture them.
Ask a multi-select with options: Claude Code, Cursor, Codex. The user can pick any combination - the shared scripts/ directory only gets generated once.
For each selected IDE, read the matching reference file and apply only its linking config. Do not duplicate the script logic - the IDE config just points at scripts/worktree-up.sh, scripts/worktree-down.sh, and scripts/dev.sh.
references/claude.mdreferences/cursor.mdreferences/codex.mdEvery project that uses this skill ends up with:
scripts/
āāā worktree-up.sh # idempotent setup
āāā worktree-down.sh # cleanup before worktree teardown
āāā dev.sh # start dev server on a free port
āāā (project-specific helpers, all *.sh)
Plus one or more IDE config files (see references). The IDE config is thin; all logic lives in scripts/.
Naming convention: every generated script MUST end in .sh. No bare worktree-up, no dev. IDE configs reference scripts by full filename (scripts/worktree-up.sh, not scripts/worktree-up). This is enforced in every reference file and example.
Each IDE exposes different variables. The shared scripts accept all of them, in this priority:
WORKTREE_PATH="${CODEX_WORKTREE_PATH:-${CURSOR_WORKTREE_PATH:-$(pwd)}}"
SOURCE_PATH="${CODEX_SOURCE_TREE_PATH:-${ROOT_WORKTREE_PATH:-}}"
| Platform | Worktree path | Source checkout path | Setup trigger |
|---|---|---|---|
| Codex | $CODEX_WORKTREE_PATH | $CODEX_SOURCE_TREE_PATH | [setup] script in TOML, runs once per worktree |
| Cursor | pwd inside worktree | $ROOT_WORKTREE_PATH | setup-worktree-unix in JSON, runs once per worktree |
| Claude | pwd inside worktree (the hook wrapper cd's in) | $CLAUDE_PROJECT_DIR (source repo, exposed inside the hook); the wrapper re-exports it as ROOT_WORKTREE_PATH | WorktreeCreate hook, runs once per worktree |
Important about Claude Code: do NOT use SessionStart for setup - it fires every session. Use the WorktreeCreate hook, which fires once when claude --worktree creates the worktree. The Claude wrapper script (scripts/claude-worktree-create.sh) is responsible for calling git worktree add itself, then handing off to scripts/worktree-up.sh inside the new worktree with ROOT_WORKTREE_PATH set. See references/claude.md.
If no env var yields a source checkout, fall back to a project-specific absolute path (e.g. $HOME/Developer/saas/<repo>). Ask the user during Step 1 if you cannot infer it.
scripts/worktree-up.shSetup must be idempotent - reruns are safe. Built from the user's Step 1 selections. Required behavior in order:
set -euo pipefail.WORKTREE_PATH and SOURCE_PATH.cd "$WORKTREE_PATH"..env, .env.local, .env.development.local only when the source has them and the worktree does not.basename "$WORKTREE_PATH" | tr '/' '-', rewrite only DATABASE_URL (and any related vars) in the copied .env, create the DB if missing. Provide a reset escape hatch: <PROJECT>_RESET_DB=1 drops and recreates.Reference template (adjust based on selections):
#!/usr/bin/env bash
set -euo pipefail
WORKTREE_PATH="${CODEX_WORKTREE_PATH:-${CURSOR_WORKTREE_PATH:-$(pwd)}}"
SOURCE_PATH="${CODEX_SOURCE_TREE_PATH:-${ROOT_WORKTREE_PATH:-$HOME/Developer/saas/<repo>}}"
cd "$WORKTREE_PATH"
# Copy ignored env files.
# NOTE for Claude Code users: .worktreeinclude handles this natively. Prefer it
# over the cp loop when the project uses Claude's --worktree.
for f in .env .env.local .env.development.local; do
if [[ -f "$SOURCE_PATH/$f" && ! -f "$WORKTREE_PATH/$f" ]]; then
cp "$SOURCE_PATH/$f" "$WORKTREE_PATH/$f"
echo "copied $f"
fi
done
# Install deps
if [[ -f pnpm-lock.yaml ]]; then pnpm install
elif [[ -f bun.lock || -f bun.lockb ]]; then bun install
elif [[ -f yarn.lock ]]; then yarn install
elif [[ -f package-lock.json ]]; then npm install
fi
# Project-specific DB isolation and codegen go here.
scripts/worktree-down.shCleanup runs before the IDE destroys the worktree.
set -euo pipefail.cd "$WORKTREE_PATH"..env. Never guess from branch names.dropdb --if-exists per DB found, against a maintenance database.#!/usr/bin/env bash
set -euo pipefail
WORKTREE_PATH="${CODEX_WORKTREE_PATH:-${CURSOR_WORKTREE_PATH:-$(pwd)}}"
cd "$WORKTREE_PATH"
if [[ ! -f .env ]]; then
echo "no .env in worktree, nothing to clean"
exit 0
fi
db_name=$(grep -E '^DATABASE_URL=' .env | sed -E 's|.*/([^/?]+).*|\1|' | head -n1 || true)
if [[ -n "${db_name:-}" ]] && command -v dropdb >/dev/null 2>&1; then
dropdb --if-exists -d postgres "$db_name" || true
fi
rm -f .env .env.local .env.development.local
scripts/dev.shPick a free port so multiple worktrees can run in parallel.
#!/usr/bin/env bash
set -euo pipefail
WORKTREE_PATH="${CODEX_WORKTREE_PATH:-${CURSOR_WORKTREE_PATH:-$(pwd)}}"
cd "$WORKTREE_PATH"
port="${DEV_PORT_START:-3910}"
while lsof -nP -iTCP:"$port" -sTCP:LISTEN >/dev/null 2>&1; do
port=$((port + 1))
done
echo "Starting app on http://localhost:$port"
exec pnpm dev -p "$port" # adjust for the project package manager
Every project should expose these four actions through the IDE's own mechanism (see references). Wire them per IDE.
| Action | Command (typical) |
|---|---|
| Dev | scripts/dev.sh |
| Typecheck | pnpm ts / bun run typecheck |
| Unit tests | pnpm test:ci / bun test |
| Lint | pnpm lint:ci / bun run lint |
Add E2E as an action only if the suite is cheap enough to run interactively.
.env.scripts/; the IDE config just calls those scripts.${DEV_PORT_START:-3910}.<PROJECT>_RESET_DB=1).prod/production and require an explicit override env var (<PROJECT>_ALLOW_PROD_SOURCE=1). Even a single mistaken --replace-all against the wrong source can nuke a teammate's dev environment or, worse, leak prod data into a feature branch. Default the source to dev and validate before each export.assert_dev_source() {
case "$1" in
prod|prod:*|prod/*|production|production:*|production/*)
echo "refusing prod source: $1" >&2; exit 1 ;;
*prod*|*production*)
[ "${ALLOW_PROD_SOURCE:-0}" = "1" ] || { echo "looks like prod: $1" >&2; exit 1; } ;;
esac
}
/dev/tty, a wrong default Node version, and CLI prompts. See references/claude.md ā "Hook Robustness" for the five concrete fixes.After generating files:
bash -n scripts/worktree-up.sh scripts/worktree-down.sh scripts/dev.sh
git status --short
If Python 3.11+ is available, validate any generated TOML:
python3 - <<'PY'
import tomllib
with open(".codex/environments/environment.toml", "rb") as f:
tomllib.load(f)
PY
For JSON configs:
python3 -c "import json; json.load(open('.cursor/worktrees.json'))"
python3 -c "import json; json.load(open('.claude/settings.json'))"
After the shared scripts are written, for each IDE selected in Step 2, load the matching reference file and apply only its linking config:
.claude/settings.json SessionStart hook + custom slash commands as actions..cursor/worktrees.json setup keys..codex/environments/environment.toml setup, cleanup, and actions.If multiple IDEs were selected, generate scripts/ once and then apply each reference in turn.
Working copies of every file this skill generates live under examples/. Use them as the source-of-truth shape when writing into a real project. Adapt the project section (package manager, DB name prefix, codegen step) for the target repo.
examples/
āāā scripts/
ā āāā worktree-up.sh # pnpm + Postgres + Prisma reference
ā āāā worktree-down.sh # pnpm + Postgres reference
ā āāā dev.sh # free-port dev server reference
ā āāā claude-worktree-create.sh # Claude WorktreeCreate hook wrapper
ā āāā claude-worktree-remove.sh # Claude WorktreeRemove hook wrapper
āāā claude/
ā āāā .worktreeinclude # native env-file copy list
ā āāā settings.json # WorktreeCreate + WorktreeRemove hooks
ā āāā commands/ # optional slash-command actions
ā āāā dev.md
ā āāā typecheck.md
ā āāā test.md
ā āāā lint.md
āāā cursor/
ā āāā worktrees.json # setup-worktree-unix -> scripts/worktree-up.sh
āāā codex/
āāā environments/
āāā environment.toml # setup, cleanup, four actions
Read the relevant example before writing the file into the target project. Do not copy verbatim - the user's Step 1 selections determine which sections of worktree-up.sh survive.