baldart 3.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +599 -0
- package/README.md +566 -0
- package/VERSION +1 -0
- package/bin/baldart.js +143 -0
- package/framework/.claude/agents/REGISTRY.md +169 -0
- package/framework/.claude/agents/api-perf-cost-auditor.md +291 -0
- package/framework/.claude/agents/code-reviewer.md +350 -0
- package/framework/.claude/agents/codebase-architect.md +391 -0
- package/framework/.claude/agents/coder.md +291 -0
- package/framework/.claude/agents/deep-human-insight.md +198 -0
- package/framework/.claude/agents/doc-reviewer.md +440 -0
- package/framework/.claude/agents/email-deliverability-architect.md +193 -0
- package/framework/.claude/agents/hybrid-ml-architect.md +285 -0
- package/framework/.claude/agents/hyper-gamification-designer.md +149 -0
- package/framework/.claude/agents/legal-counsel-gdpr.md +179 -0
- package/framework/.claude/agents/marketing-conversion-strategist.md +162 -0
- package/framework/.claude/agents/motion-expert.md +108 -0
- package/framework/.claude/agents/onboarding-architect-lead.md +230 -0
- package/framework/.claude/agents/plan-auditor.md +546 -0
- package/framework/.claude/agents/prd-card-writer.md +372 -0
- package/framework/.claude/agents/prd.md +744 -0
- package/framework/.claude/agents/qa-sentinel.md +305 -0
- package/framework/.claude/agents/remotion-animator-orchestrator.md +218 -0
- package/framework/.claude/agents/security-reviewer.md +276 -0
- package/framework/.claude/agents/senior-researcher.md +175 -0
- package/framework/.claude/agents/seo-analytics-strategist.md +156 -0
- package/framework/.claude/agents/skill-improver.md +61 -0
- package/framework/.claude/agents/ui-expert.md +191 -0
- package/framework/.claude/agents/visual-designer.md +190 -0
- package/framework/.claude/agents/website-orchestrator.md +118 -0
- package/framework/.claude/agents/wiki-curator.md +145 -0
- package/framework/.claude/commands/baldart-push.md +15 -0
- package/framework/.claude/commands/check.md +237 -0
- package/framework/.claude/commands/codexreview.md +203 -0
- package/framework/.claude/commands/design-review.md +11 -0
- package/framework/.claude/commands/issue-review.md +34 -0
- package/framework/.claude/commands/new.md +331 -0
- package/framework/.claude/commands/qa.md +257 -0
- package/framework/.claude/hooks/framework-edit-gate.js +208 -0
- package/framework/.claude/hooks/lint-before-commit.sh.template +66 -0
- package/framework/.claude/settings.local.json.example +32 -0
- package/framework/.claude/skills/api-design-principles/SKILL.md +567 -0
- package/framework/.claude/skills/api-design-principles/assets/api-design-checklist.md +155 -0
- package/framework/.claude/skills/api-design-principles/assets/rest-api-template.py +182 -0
- package/framework/.claude/skills/api-design-principles/references/graphql-schema-design.md +583 -0
- package/framework/.claude/skills/api-design-principles/references/rest-best-practices.md +408 -0
- package/framework/.claude/skills/baldart-push/SKILL.md +222 -0
- package/framework/.claude/skills/bug/SKILL.md +200 -0
- package/framework/.claude/skills/bug/references/logging-patterns.md +174 -0
- package/framework/.claude/skills/capture/SKILL.md +125 -0
- package/framework/.claude/skills/capture/references/synthesis-template.md +42 -0
- package/framework/.claude/skills/context-primer/SKILL.md +189 -0
- package/framework/.claude/skills/copywriting/SKILL.md +273 -0
- package/framework/.claude/skills/copywriting/references/copy-frameworks.md +338 -0
- package/framework/.claude/skills/copywriting/references/natural-transitions.md +252 -0
- package/framework/.claude/skills/doc-writing-for-rag/SKILL.md +119 -0
- package/framework/.claude/skills/doc-writing-for-rag/references/before-after-examples.md +291 -0
- package/framework/.claude/skills/doc-writing-for-rag/references/compact-templates.md +183 -0
- package/framework/.claude/skills/doc-writing-for-rag/references/frontmatter-minimal.md +112 -0
- package/framework/.claude/skills/doc-writing-for-rag/references/line-count-targets.md +110 -0
- package/framework/.claude/skills/doc-writing-for-rag/references/schemas-and-errors.md +129 -0
- package/framework/.claude/skills/find-skills/SKILL.md +133 -0
- package/framework/.claude/skills/frontend-design/LICENSE.txt +177 -0
- package/framework/.claude/skills/frontend-design/SKILL.md +84 -0
- package/framework/.claude/skills/gamification-design/SKILL.md +130 -0
- package/framework/.claude/skills/issue-review/SKILL.md +45 -0
- package/framework/.claude/skills/kie-ai/SKILL.md +262 -0
- package/framework/.claude/skills/kie-ai/references/models-catalog.md +272 -0
- package/framework/.claude/skills/kie-ai/scripts/kie_api.sh +209 -0
- package/framework/.claude/skills/kie-ai/scripts/remove_greenscreen.py +69 -0
- package/framework/.claude/skills/kie-ai/scripts/setup_api_key.sh +77 -0
- package/framework/.claude/skills/motion-design/LICENSE +21 -0
- package/framework/.claude/skills/motion-design/README.md +82 -0
- package/framework/.claude/skills/motion-design/SKILL.md +336 -0
- package/framework/.claude/skills/motion-design/director/choreography.md +93 -0
- package/framework/.claude/skills/motion-design/director/context-adaptation.md +83 -0
- package/framework/.claude/skills/motion-design/director/core-philosophy.md +53 -0
- package/framework/.claude/skills/motion-design/director/decision-framework.md +91 -0
- package/framework/.claude/skills/motion-design/director/disney-principles.md +102 -0
- package/framework/.claude/skills/motion-design/director/emotion-mapping.md +71 -0
- package/framework/.claude/skills/motion-design/director/motion-personality.md +89 -0
- package/framework/.claude/skills/motion-design/director/narrative-structure.md +62 -0
- package/framework/.claude/skills/motion-design/patterns/ambient-continuous.md +81 -0
- package/framework/.claude/skills/motion-design/patterns/entrance-exit.md +82 -0
- package/framework/.claude/skills/motion-design/patterns/multi-element.md +69 -0
- package/framework/.claude/skills/motion-design/patterns/state-feedback.md +96 -0
- package/framework/.claude/skills/motion-design/reference/property-selection.md +95 -0
- package/framework/.claude/skills/motion-design/reference/quality-checklist.md +67 -0
- package/framework/.claude/skills/motion-design/reference/timing-easing-tables.md +106 -0
- package/framework/.claude/skills/motion-design/reference/troubleshooting.md +73 -0
- package/framework/.claude/skills/new/SKILL.md +1687 -0
- package/framework/.claude/skills/playwright-skill/API_REFERENCE.md +652 -0
- package/framework/.claude/skills/playwright-skill/SKILL.md +157 -0
- package/framework/.claude/skills/playwright-skill/package.json +26 -0
- package/framework/.claude/skills/prd/SKILL.md +228 -0
- package/framework/.claude/skills/prd/assets/card-template.yml +232 -0
- package/framework/.claude/skills/prd/assets/epic-template.yml +190 -0
- package/framework/.claude/skills/prd/assets/prd-template.md +230 -0
- package/framework/.claude/skills/prd/assets/state-template.md +78 -0
- package/framework/.claude/skills/prd/references/api-perf-gate.md +152 -0
- package/framework/.claude/skills/prd/references/audit-phase.md +478 -0
- package/framework/.claude/skills/prd/references/backlog-phase.md +145 -0
- package/framework/.claude/skills/prd/references/discovery-phase.md +359 -0
- package/framework/.claude/skills/prd/references/impact-analysis.md +233 -0
- package/framework/.claude/skills/prd/references/prd-add-phase.md +214 -0
- package/framework/.claude/skills/prd/references/prd-writing-phase.md +145 -0
- package/framework/.claude/skills/prd/references/research-phase.md +216 -0
- package/framework/.claude/skills/prd/references/ui-design-phase.md +61 -0
- package/framework/.claude/skills/prd/references/validation-phase.md +72 -0
- package/framework/.claude/skills/prd-add/SKILL.md +222 -0
- package/framework/.claude/skills/prd-add/references/impact-analysis.md +233 -0
- package/framework/.claude/skills/remotion-best-practices/SKILL.md +48 -0
- package/framework/.claude/skills/remotion-best-practices/rules/3d.md +86 -0
- package/framework/.claude/skills/remotion-best-practices/rules/animations.md +29 -0
- package/framework/.claude/skills/remotion-best-practices/rules/assets/charts-bar-chart.tsx +173 -0
- package/framework/.claude/skills/remotion-best-practices/rules/assets/text-animations-typewriter.tsx +100 -0
- package/framework/.claude/skills/remotion-best-practices/rules/assets/text-animations-word-highlight.tsx +108 -0
- package/framework/.claude/skills/remotion-best-practices/rules/assets.md +78 -0
- package/framework/.claude/skills/remotion-best-practices/rules/audio.md +169 -0
- package/framework/.claude/skills/remotion-best-practices/rules/calculate-metadata.md +104 -0
- package/framework/.claude/skills/remotion-best-practices/rules/can-decode.md +75 -0
- package/framework/.claude/skills/remotion-best-practices/rules/charts.md +58 -0
- package/framework/.claude/skills/remotion-best-practices/rules/compositions.md +141 -0
- package/framework/.claude/skills/remotion-best-practices/rules/display-captions.md +184 -0
- package/framework/.claude/skills/remotion-best-practices/rules/extract-frames.md +229 -0
- package/framework/.claude/skills/remotion-best-practices/rules/fonts.md +152 -0
- package/framework/.claude/skills/remotion-best-practices/rules/get-audio-duration.md +58 -0
- package/framework/.claude/skills/remotion-best-practices/rules/get-video-dimensions.md +68 -0
- package/framework/.claude/skills/remotion-best-practices/rules/get-video-duration.md +58 -0
- package/framework/.claude/skills/remotion-best-practices/rules/gifs.md +141 -0
- package/framework/.claude/skills/remotion-best-practices/rules/images.md +130 -0
- package/framework/.claude/skills/remotion-best-practices/rules/import-srt-captions.md +69 -0
- package/framework/.claude/skills/remotion-best-practices/rules/light-leaks.md +73 -0
- package/framework/.claude/skills/remotion-best-practices/rules/lottie.md +67 -0
- package/framework/.claude/skills/remotion-best-practices/rules/maps.md +401 -0
- package/framework/.claude/skills/remotion-best-practices/rules/measuring-dom-nodes.md +34 -0
- package/framework/.claude/skills/remotion-best-practices/rules/measuring-text.md +143 -0
- package/framework/.claude/skills/remotion-best-practices/rules/parameters.md +98 -0
- package/framework/.claude/skills/remotion-best-practices/rules/sequencing.md +118 -0
- package/framework/.claude/skills/remotion-best-practices/rules/subtitles.md +36 -0
- package/framework/.claude/skills/remotion-best-practices/rules/tailwind.md +11 -0
- package/framework/.claude/skills/remotion-best-practices/rules/text-animations.md +20 -0
- package/framework/.claude/skills/remotion-best-practices/rules/timing.md +179 -0
- package/framework/.claude/skills/remotion-best-practices/rules/transcribe-captions.md +70 -0
- package/framework/.claude/skills/remotion-best-practices/rules/transitions.md +197 -0
- package/framework/.claude/skills/remotion-best-practices/rules/transparent-videos.md +106 -0
- package/framework/.claude/skills/remotion-best-practices/rules/trimming.md +52 -0
- package/framework/.claude/skills/remotion-best-practices/rules/videos.md +171 -0
- package/framework/.claude/skills/seo-audit/SKILL.md +394 -0
- package/framework/.claude/skills/seo-audit/references/aeo-geo-patterns.md +279 -0
- package/framework/.claude/skills/seo-audit/references/ai-writing-detection.md +190 -0
- package/framework/.claude/skills/simplify/SKILL.md +137 -0
- package/framework/.claude/skills/skill-creator/LICENSE.txt +202 -0
- package/framework/.claude/skills/skill-creator/SKILL.md +356 -0
- package/framework/.claude/skills/skill-creator/references/output-patterns.md +82 -0
- package/framework/.claude/skills/skill-creator/references/workflows.md +28 -0
- package/framework/.claude/skills/skill-creator/scripts/init_skill.py +303 -0
- package/framework/.claude/skills/skill-creator/scripts/package_skill.py +110 -0
- package/framework/.claude/skills/skill-creator/scripts/quick_validate.py +95 -0
- package/framework/.claude/skills/ui-design/SKILL.md +199 -0
- package/framework/.claude/skills/ui-design/references/component-discovery.md +54 -0
- package/framework/.claude/skills/ui-design/references/evaluation.md +171 -0
- package/framework/.claude/skills/ui-design/references/generation.md +109 -0
- package/framework/.claude/skills/ui-design/references/inventory.md +59 -0
- package/framework/.claude/skills/webapp-testing/LICENSE.txt +202 -0
- package/framework/.claude/skills/webapp-testing/SKILL.md +123 -0
- package/framework/.claude/skills/webapp-testing/examples/console_logging.py +35 -0
- package/framework/.claude/skills/webapp-testing/examples/element_discovery.py +40 -0
- package/framework/.claude/skills/webapp-testing/examples/static_html_automation.py +33 -0
- package/framework/.claude/skills/webapp-testing/scripts/with_server.py +106 -0
- package/framework/.claude/skills/worktree-manager/SKILL.md +680 -0
- package/framework/AGENTS.md +240 -0
- package/framework/agents/api-contracts.md +137 -0
- package/framework/agents/architecture.md +145 -0
- package/framework/agents/coding-standards.md +148 -0
- package/framework/agents/data-model.md +110 -0
- package/framework/agents/deployment-protocol.md +232 -0
- package/framework/agents/design-review.md +172 -0
- package/framework/agents/env-reference.md +171 -0
- package/framework/agents/github-issue-subagent.md +252 -0
- package/framework/agents/index.md +261 -0
- package/framework/agents/llm-wiki-methodology.md +216 -0
- package/framework/agents/maintenance-protocol.md +305 -0
- package/framework/agents/observability.md +162 -0
- package/framework/agents/performance.md +155 -0
- package/framework/agents/project-context.md +145 -0
- package/framework/agents/runbook.md +208 -0
- package/framework/agents/security.md +168 -0
- package/framework/agents/skills-mapping.md +286 -0
- package/framework/agents/testing.md +111 -0
- package/framework/agents/workflows.md +215 -0
- package/framework/docs/PROJECT-CONFIGURATION.md +336 -0
- package/framework/docs/references/brand-guidelines.md +170 -0
- package/framework/docs/references/ui-guidelines.template.md +182 -0
- package/framework/routines/code-review.routine.yml +46 -0
- package/framework/routines/doc-review.routine.yml +45 -0
- package/framework/routines/ds-drift.routine.yml +52 -0
- package/framework/routines/full-sweep.routine.yml +51 -0
- package/framework/routines/index.yml +70 -0
- package/framework/routines/skill-improve.routine.yml +50 -0
- package/framework/routines/wiki-review.routine.yml +45 -0
- package/framework/templates/baldart.config.template.yml +113 -0
- package/framework/templates/breaking-change-checklist.md +484 -0
- package/framework/templates/feature-card.template.yml +125 -0
- package/framework/templates/overlays/README.md +44 -0
- package/framework/templates/overlays/copywriting.fidelity-example.md +62 -0
- package/framework/templates/overlays/ui-design.fidelity-example.md +75 -0
- package/framework/templates/skill-project-context.snippet.md +19 -0
- package/framework/templates/spec.template.md +208 -0
- package/package.json +51 -0
- package/src/commands/add.js +229 -0
- package/src/commands/configure.js +385 -0
- package/src/commands/doctor.js +486 -0
- package/src/commands/migrate.js +185 -0
- package/src/commands/push.js +0 -0
- package/src/commands/routines.js +269 -0
- package/src/commands/status.js +130 -0
- package/src/commands/update.js +419 -0
- package/src/commands/version.js +88 -0
- package/src/utils/contamination.js +400 -0
- package/src/utils/git.js +181 -0
- package/src/utils/hooks.js +152 -0
- package/src/utils/routine-adapters/claude-code-cloud.js +78 -0
- package/src/utils/routine-adapters/cron.js +138 -0
- package/src/utils/routine-adapters/github-actions.js +141 -0
- package/src/utils/routine-adapters/index.js +21 -0
- package/src/utils/routines.js +166 -0
- package/src/utils/state.js +143 -0
- package/src/utils/symlinks.js +425 -0
- package/src/utils/ui.js +133 -0
|
@@ -0,0 +1,680 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: worktree-manager
|
|
3
|
+
description: >
|
|
4
|
+
Manage fully independent git worktrees for parallel coding agents.
|
|
5
|
+
Commands: /nw (new worktree) creates an isolated workspace with its own
|
|
6
|
+
node_modules, .next cache, and dev server port; /mw (merge worktree) commits,
|
|
7
|
+
pushes, creates PR to develop, merges, and cleans up; /lw (list worktrees)
|
|
8
|
+
shows status of all active worktrees; /cw (cleanup worktrees) removes stale
|
|
9
|
+
or already-merged worktrees without the full PR flow.
|
|
10
|
+
Also used programmatically by /new orchestrator for batch card worktree ops.
|
|
11
|
+
Trigger on: /nw, /mw, /lw, /cw, "new worktree", "merge worktree",
|
|
12
|
+
"list worktrees", "cleanup worktree".
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Worktree Manager
|
|
16
|
+
|
|
17
|
+
**IMMEDIATE EXECUTION**: When invoked via `/nw`, `/mw`, `/lw`, or `/cw`, do NOT explain the process. Start executing the matching command flow immediately:
|
|
18
|
+
|
|
19
|
+
- `/nw` → Ask for **slug** (required) and optionally a **card ID**, then execute all steps (pre-flight → create → install → build → report). If the user provided args, skip questions and use them directly. Supports three forms:
|
|
20
|
+
- `/nw FEAT-0500 menu-fix` — with card ID and slug
|
|
21
|
+
- `/nw menu-fix` — slug only (no card, branch: `feat/menu-fix`)
|
|
22
|
+
- Add `--dev` to also start the dev server (e.g., `/nw --dev menu-fix`).
|
|
23
|
+
- `/mw` → Read registry, identify worktree, start merge flow.
|
|
24
|
+
- `/lw` → Read registry + `git worktree list`, show status table.
|
|
25
|
+
- `/cw` → Scan for removable worktrees, present options.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
Four commands for fully isolated parallel workspaces + programmatic API for orchestrators.
|
|
30
|
+
|
|
31
|
+
## Programmatic API (for /new orchestrator)
|
|
32
|
+
|
|
33
|
+
### /nw programmatic
|
|
34
|
+
|
|
35
|
+
Input: `{ cards: string[], groupParent: string|null, slug: string, branch?: string }`
|
|
36
|
+
Output: `{ path: string, branch: string, port: number }`
|
|
37
|
+
|
|
38
|
+
### /mw programmatic
|
|
39
|
+
|
|
40
|
+
Input: `{ worktreePath: string, checksAlreadyPassed?: boolean }`
|
|
41
|
+
Output: `{ merged: boolean, developVerified: boolean, prNumber: number, mergeCommit: string }`
|
|
42
|
+
|
|
43
|
+
Note: since v3.4.0 the merge happens via `gh pr merge` against GitHub (NOT a local `git checkout develop` + `git merge`). `mergeCommit` is the SHA returned by the GitHub merge API. The orchestrator can use `prNumber` for follow-up (linking, deploy webhooks, etc.).
|
|
44
|
+
|
|
45
|
+
### /cw programmatic
|
|
46
|
+
|
|
47
|
+
Input: `{ worktreePath: string, force?: boolean }`
|
|
48
|
+
Output: `{ removed: boolean }`
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
Registry file: `.worktrees/registry.json` — tracks all active worktrees.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Registry
|
|
57
|
+
|
|
58
|
+
All worktree operations read/write `.worktrees/registry.json`:
|
|
59
|
+
|
|
60
|
+
```json
|
|
61
|
+
{
|
|
62
|
+
"worktrees": [
|
|
63
|
+
{
|
|
64
|
+
"card": "FEAT-0200",
|
|
65
|
+
"cards": ["FEAT-0200", "FEAT-0201"],
|
|
66
|
+
"groupParent": "FEAT-0200",
|
|
67
|
+
"slug": "menu-ranking",
|
|
68
|
+
"branch": "feat/FEAT-0200-menu-ranking",
|
|
69
|
+
"path": "/absolute/path/.worktrees/feat-FEAT-0200-menu-ranking",
|
|
70
|
+
"port": 3001,
|
|
71
|
+
"createdAt": "2026-03-09T10:00:00Z",
|
|
72
|
+
"envSyncedAt": "2026-03-09T10:00:00Z",
|
|
73
|
+
"buildVerified": true
|
|
74
|
+
}
|
|
75
|
+
]
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
- `card`: primary card ID (first card or group parent), or `null` for slug-only worktrees
|
|
80
|
+
- `cards`: all card IDs sharing this worktree (for batches), or `[]` for slug-only
|
|
81
|
+
- `groupParent`: from backlog card `group.parent` field, or `null` for standalone/slug-only
|
|
82
|
+
- `buildVerified`: true if `npm run build` passed after setup
|
|
83
|
+
|
|
84
|
+
Create the file if it doesn't exist. Update it on every `/nw`, `/mw`, `/cw` operation.
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## /nw — New Worktree
|
|
89
|
+
|
|
90
|
+
Supports three modes:
|
|
91
|
+
- **Interactive** (user invokes `/nw`): asks for slug (required) and optionally card ID
|
|
92
|
+
- **Slug-only** (user invokes `/nw <slug>`): creates a worktree without a backlog card
|
|
93
|
+
- **Programmatic** (called by `/new` orchestrator): receives card IDs, group.parent, and branch name
|
|
94
|
+
|
|
95
|
+
### 1. Pre-flight checks
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
# Fetch latest develop from remote — read-only, does NOT touch the main repo's HEAD.
|
|
99
|
+
# We branch the new worktree from `origin/develop` directly (step 3), so we never
|
|
100
|
+
# need to checkout develop on the main repo. This is the absolute rule:
|
|
101
|
+
# /nw must not run `git checkout`, `git switch`, `git checkout -b`, or
|
|
102
|
+
# `git branch` on the main repo (it's shared across parallel terminals; many
|
|
103
|
+
# consumer projects declare this as a hard rule in CLAUDE.md and the classifier
|
|
104
|
+
# will block the call preemptively).
|
|
105
|
+
git fetch origin develop
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
(There is no need to check `git status --porcelain` on the main repo here — we
|
|
109
|
+
do not touch it. If the user has uncommitted work on the main repo it stays
|
|
110
|
+
exactly where it is.)
|
|
111
|
+
|
|
112
|
+
Check registry for duplicate:
|
|
113
|
+
- If a card ID is provided and a worktree for the same card ID already exists, WARN and ask to confirm.
|
|
114
|
+
- If a worktree for the same `groupParent` exists, WARN — cards should share the existing worktree.
|
|
115
|
+
- If slug-only and a worktree with the same slug already exists, WARN and ask to confirm.
|
|
116
|
+
|
|
117
|
+
### 2. Determine branch name
|
|
118
|
+
|
|
119
|
+
**Interactive mode** — ask the user for:
|
|
120
|
+
- **Short slug** (e.g. `menu-ranking`) — REQUIRED
|
|
121
|
+
- **Backlog card ID** (e.g. `FEAT-0200`, `BUG-0500`) — OPTIONAL
|
|
122
|
+
|
|
123
|
+
**Slug-only mode** (no card ID):
|
|
124
|
+
- Branch name: `feat/<slug>` (e.g. `feat/menu-ranking`)
|
|
125
|
+
- Registry `card` field: `null`
|
|
126
|
+
- Registry `cards` field: `[]`
|
|
127
|
+
|
|
128
|
+
**Programmatic mode** (from `/new` orchestrator) — apply grouping logic:
|
|
129
|
+
1. Check each card's `group.parent` field in backlog YAML.
|
|
130
|
+
2. If all cards share the same `group.parent` → ONE worktree, branch from parent card.
|
|
131
|
+
3. If cards have no `group.parent` but share a common ID prefix → suggest grouping.
|
|
132
|
+
4. If cards are unrelated → each gets its own worktree.
|
|
133
|
+
5. Read parent card's `git_strategy.branch` if set; otherwise derive: `feat/<PARENT-ID>-<slug>`.
|
|
134
|
+
6. If `group.parent` is set AND parent card has `git_strategy.branch` → use it directly, no questions.
|
|
135
|
+
|
|
136
|
+
Branch name: `feat/<CARD-ID>-<slug>` (with card) or `feat/<slug>` (slug-only). Use `hotfix/` prefix if card specifies hotfix.
|
|
137
|
+
|
|
138
|
+
### 3. Create the worktree
|
|
139
|
+
|
|
140
|
+
Base the new worktree on `origin/develop` (the remote tip we just fetched in step 1) rather than the local `develop` branch — that way we never need the local `develop` to be checked out or up to date on the main repo.
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
# With card ID:
|
|
144
|
+
WORKTREE_PATH=".worktrees/feat-<CARD-ID>-<slug>"
|
|
145
|
+
git worktree add "$WORKTREE_PATH" -b "feat/<CARD-ID>-<slug>" origin/develop
|
|
146
|
+
|
|
147
|
+
# Slug-only (no card):
|
|
148
|
+
WORKTREE_PATH=".worktrees/feat-<slug>"
|
|
149
|
+
git worktree add "$WORKTREE_PATH" -b "feat/<slug>" origin/develop
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### 3b. Sync untracked backlog cards from main repo
|
|
153
|
+
|
|
154
|
+
Backlog cards created during `/prd` sessions may exist as untracked files in the main repo
|
|
155
|
+
but are NOT on `develop` yet. The worktree (branched from develop) won't have them.
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
MAIN_ROOT="$(git -C "$WORKTREE_PATH" rev-parse --show-superproject-working-tree 2>/dev/null || pwd)"
|
|
159
|
+
|
|
160
|
+
# For each card in the batch, check if its YAML exists in the main repo but not in the worktree
|
|
161
|
+
for CARD_FILE in $(ls "$MAIN_ROOT/${paths.backlog_dir:-backlog}"/*.yml 2>/dev/null); do
|
|
162
|
+
BASENAME=$(basename "$CARD_FILE")
|
|
163
|
+
if [ ! -f "$WORKTREE_PATH/${paths.backlog_dir:-backlog}/$BASENAME" ]; then
|
|
164
|
+
cp "$CARD_FILE" "$WORKTREE_PATH/${paths.backlog_dir:-backlog}/$BASENAME"
|
|
165
|
+
echo "Synced untracked card: $BASENAME"
|
|
166
|
+
fi
|
|
167
|
+
done
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
This prevents "File not found" errors when Phase 4 tries to mark cards as DONE.
|
|
171
|
+
|
|
172
|
+
### 4. Full isolation setup
|
|
173
|
+
|
|
174
|
+
Run ALL of these inside the worktree directory:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
cd "$WORKTREE_PATH"
|
|
178
|
+
|
|
179
|
+
# 1. Own node_modules (full independent install)
|
|
180
|
+
npm install
|
|
181
|
+
|
|
182
|
+
# 2. Own .next cache — already isolated since each worktree has its own
|
|
183
|
+
# directory tree. The default .next inside the worktree is sufficient.
|
|
184
|
+
|
|
185
|
+
# 3. Copy environment files from main repo root
|
|
186
|
+
# Build requires Firebase env vars — this copy is critical.
|
|
187
|
+
MAIN_ROOT="$(git -C .. rev-parse --show-toplevel 2>/dev/null || echo '../..')"
|
|
188
|
+
cp "$MAIN_ROOT/.env.local" .env.local 2>/dev/null || true
|
|
189
|
+
cp "$MAIN_ROOT/.env" .env 2>/dev/null || true
|
|
190
|
+
|
|
191
|
+
# 4. Pick a free dev server port (avoid 3000 used by main)
|
|
192
|
+
PORT=3001
|
|
193
|
+
while lsof -i :$PORT -sTCP:LISTEN >/dev/null 2>&1; do
|
|
194
|
+
PORT=$((PORT + 1))
|
|
195
|
+
if [ $PORT -gt 3099 ]; then echo "ERROR: No free port in 3001-3099" >&2; exit 1; fi
|
|
196
|
+
done
|
|
197
|
+
# Write PORT to .env.local (append or replace existing PORT line)
|
|
198
|
+
if grep -q "^PORT=" .env.local 2>/dev/null; then
|
|
199
|
+
sed -i '' "s/^PORT=.*/PORT=$PORT/" .env.local
|
|
200
|
+
else
|
|
201
|
+
echo "PORT=$PORT" >> .env.local
|
|
202
|
+
fi
|
|
203
|
+
|
|
204
|
+
# 5. Verify husky hooks work (they share via .git/commondir)
|
|
205
|
+
git config core.hooksPath || true
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### 5. Verify baseline
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
# TypeScript + lint (fast)
|
|
212
|
+
npx tsc --noEmit
|
|
213
|
+
npx eslint --max-warnings=0 src/
|
|
214
|
+
|
|
215
|
+
# Full build verification (required — confirms worktree is functional)
|
|
216
|
+
npm run build
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
If build fails → STOP and report. Do NOT continue — the worktree is broken.
|
|
220
|
+
If only tsc/lint fails → report but continue (develop should be clean, may be a transient issue).
|
|
221
|
+
|
|
222
|
+
### 6. Update registry
|
|
223
|
+
|
|
224
|
+
Add entry to `.worktrees/registry.json` with all fields: card, cards, groupParent, slug, branch, absolute path, port, `createdAt`, `envSyncedAt`, and `buildVerified`.
|
|
225
|
+
|
|
226
|
+
### 7. Auto-start dev server (if `--dev` flag or `/nw --dev`)
|
|
227
|
+
|
|
228
|
+
If the user passed `--dev` (e.g., `/nw --dev FEAT-0500 menu-fix`), start the dev server in background:
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
cd "$WORKTREE_PATH"
|
|
232
|
+
nohup npm run dev > .next/dev.log 2>&1 &
|
|
233
|
+
DEV_PID=$!
|
|
234
|
+
# Wait a few seconds and verify it's running
|
|
235
|
+
sleep 3
|
|
236
|
+
if kill -0 $DEV_PID 2>/dev/null; then
|
|
237
|
+
echo "Dev server started (PID: $DEV_PID) on port $PORT"
|
|
238
|
+
else
|
|
239
|
+
echo "WARNING: Dev server failed to start. Check .next/dev.log" >&2
|
|
240
|
+
fi
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### 8. Report to user
|
|
244
|
+
|
|
245
|
+
```
|
|
246
|
+
Worktree ready:
|
|
247
|
+
Path: <full-absolute-path>
|
|
248
|
+
Branch: feat/<CARD-ID>-<slug> (or feat/<slug> if no card)
|
|
249
|
+
Port: <PORT>
|
|
250
|
+
Card: <CARD-ID> (or "none" if slug-only)
|
|
251
|
+
Build: verified ✓
|
|
252
|
+
Dev: http://localhost:<PORT> (PID: <DEV_PID>) ← only if --dev
|
|
253
|
+
|
|
254
|
+
Start dev server: cd <path> && npm run dev ← only if NOT --dev
|
|
255
|
+
The worktree has its own node_modules and .next cache — fully independent.
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## /mw — Merge Worktree
|
|
261
|
+
|
|
262
|
+
Supports two modes:
|
|
263
|
+
- **Interactive** (user invokes `/mw`): full flow with PR creation + merge + cleanup
|
|
264
|
+
- **Programmatic** (called by `/new` orchestrator): can be invoked with specific worktree path and skip-checks flag if checks already passed in orchestrator pipeline
|
|
265
|
+
|
|
266
|
+
### 1. Identify worktree
|
|
267
|
+
|
|
268
|
+
Read `.worktrees/registry.json`. If multiple entries exist or user didn't specify, list them and ask which to merge.
|
|
269
|
+
|
|
270
|
+
Fallback: `git worktree list` if registry is missing.
|
|
271
|
+
|
|
272
|
+
Determine:
|
|
273
|
+
- `WORKTREE_PATH`, `BRANCH`, `CARD` (or `CARDS` for batch worktrees)
|
|
274
|
+
|
|
275
|
+
### 2. Env sync check
|
|
276
|
+
|
|
277
|
+
Compare main repo `.env.local` modification time with registry `envSyncedAt`.
|
|
278
|
+
If main `.env.local` is newer, WARN:
|
|
279
|
+
|
|
280
|
+
```
|
|
281
|
+
Warning: Main repo .env.local has changed since this worktree was created.
|
|
282
|
+
Consider updating the worktree's .env.local before merging.
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### 3. Pre-merge safety commit + checks inside the worktree
|
|
286
|
+
|
|
287
|
+
**CRITICAL — Safety commit (MUST run before anything else)**:
|
|
288
|
+
Files lost after rebase are unrecoverable. ALWAYS commit everything before proceeding.
|
|
289
|
+
|
|
290
|
+
```bash
|
|
291
|
+
cd "$WORKTREE_PATH"
|
|
292
|
+
|
|
293
|
+
# 1. Check for uncommitted changes (staged, unstaged, and untracked)
|
|
294
|
+
CHANGED=$(git diff --name-only HEAD 2>/dev/null)
|
|
295
|
+
UNTRACKED=$(git ls-files --others --exclude-standard 2>/dev/null)
|
|
296
|
+
|
|
297
|
+
if [ -n "$CHANGED" ] || [ -n "$UNTRACKED" ]; then
|
|
298
|
+
echo "⚠️ Uncommitted files detected — creating safety commit before merge"
|
|
299
|
+
|
|
300
|
+
# Stage all changed files by EXPLICIT name (never git add -A)
|
|
301
|
+
for f in $CHANGED $UNTRACKED; do
|
|
302
|
+
git add "$f"
|
|
303
|
+
done
|
|
304
|
+
|
|
305
|
+
# Verify what we staged
|
|
306
|
+
git diff --staged --name-only
|
|
307
|
+
|
|
308
|
+
# Safety commit
|
|
309
|
+
git commit -m "[safety] Auto-commit uncommitted files before merge
|
|
310
|
+
|
|
311
|
+
Files were uncommitted when /mw started. This safety commit
|
|
312
|
+
prevents file loss during rebase. Squash-merge will fold this
|
|
313
|
+
into the final commit on develop.
|
|
314
|
+
|
|
315
|
+
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>"
|
|
316
|
+
|
|
317
|
+
echo "✅ Safety commit created — all files preserved"
|
|
318
|
+
fi
|
|
319
|
+
|
|
320
|
+
# 2. Run quality checks
|
|
321
|
+
# Lint only changed files (vs develop)
|
|
322
|
+
npx eslint --max-warnings=0 $(git diff --name-only develop -- '*.ts' '*.tsx')
|
|
323
|
+
npx tsc --noEmit
|
|
324
|
+
|
|
325
|
+
# Full build (required before PR per AGENTS.md)
|
|
326
|
+
npm run build
|
|
327
|
+
|
|
328
|
+
# Tests
|
|
329
|
+
npm run test 2>/dev/null || true
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
If lint, tsc, or build fails → report and STOP. Do NOT proceed to PR.
|
|
333
|
+
|
|
334
|
+
**Programmatic mode**: If the orchestrator already ran these checks (Phase 2 self-healing + Phase 3.5 QA), it may pass `checksAlreadyPassed: true` to skip re-running quality checks. The safety commit step ALWAYS runs regardless — it is never skippable.
|
|
335
|
+
|
|
336
|
+
### 4. Commit & push
|
|
337
|
+
|
|
338
|
+
**Interactive mode**: Stage and commit all pending changes.
|
|
339
|
+
|
|
340
|
+
```bash
|
|
341
|
+
cd "$WORKTREE_PATH"
|
|
342
|
+
|
|
343
|
+
# Stage only changed files (explicit names, NEVER git add . or git add -A)
|
|
344
|
+
git add <list-changed-files-explicitly>
|
|
345
|
+
|
|
346
|
+
# Verify staged files
|
|
347
|
+
git diff --staged --name-only
|
|
348
|
+
|
|
349
|
+
# Commit directly — NO stash in worktrees (stashes are globally shared via refs/stash)
|
|
350
|
+
git commit -m "[<CARD-ID>] <description>"
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
**Programmatic mode**: The orchestrator handles per-card commits in Phase 4. `/mw` only needs to rebase and push (see steps 4b and 4c below).
|
|
354
|
+
|
|
355
|
+
### 4b. Rebase onto latest develop (MUST — prevents PR merge conflicts)
|
|
356
|
+
|
|
357
|
+
Before pushing, ALWAYS rebase the feature branch onto the latest develop to avoid merge conflicts at PR merge time.
|
|
358
|
+
|
|
359
|
+
```bash
|
|
360
|
+
cd "$WORKTREE_PATH"
|
|
361
|
+
|
|
362
|
+
# 1. Check for uncommitted changes BEFORE stashing
|
|
363
|
+
# If the safety commit in step 3 ran, this should be clean.
|
|
364
|
+
# But if called outside /mw flow, there might be leftovers.
|
|
365
|
+
DIRTY=$(git status --porcelain 2>/dev/null)
|
|
366
|
+
STASHED="false"
|
|
367
|
+
if [ -n "$DIRTY" ]; then
|
|
368
|
+
echo "⚠️ Dirty working tree before rebase — stashing"
|
|
369
|
+
STASH_MSG="pre-rebase-$(date +%s)"
|
|
370
|
+
git stash push --include-untracked -m "$STASH_MSG"
|
|
371
|
+
STASHED="true"
|
|
372
|
+
fi
|
|
373
|
+
|
|
374
|
+
# 2. Fetch latest develop
|
|
375
|
+
git fetch origin develop
|
|
376
|
+
|
|
377
|
+
# 3. Rebase onto origin/develop
|
|
378
|
+
git rebase origin/develop 2>&1
|
|
379
|
+
REBASE_EXIT=$?
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
**If rebase succeeds** (exit 0): restore stash and continue to push.
|
|
383
|
+
|
|
384
|
+
```bash
|
|
385
|
+
if [ "$STASHED" = "true" ]; then
|
|
386
|
+
STASH_NUM=$(git stash list | grep "$STASH_MSG" | sed -E 's/stash@\{([0-9]+)\}.*/\1/')
|
|
387
|
+
if [ -n "$STASH_NUM" ]; then
|
|
388
|
+
if ! git stash pop "stash@{$STASH_NUM}" 2>&1; then
|
|
389
|
+
echo "⚠️ STASH POP FAILED — files preserved in stash@{$STASH_NUM} ($STASH_MSG)"
|
|
390
|
+
echo "Run 'git stash show stash@{$STASH_NUM}' to see affected files"
|
|
391
|
+
echo "Run 'git stash pop stash@{$STASH_NUM}' to recover manually"
|
|
392
|
+
# DO NOT silently continue — report this to the user
|
|
393
|
+
fi
|
|
394
|
+
fi
|
|
395
|
+
fi
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
**If rebase fails with conflicts**: apply the auto-resolution protocol below.
|
|
399
|
+
|
|
400
|
+
#### Conflict auto-resolution protocol
|
|
401
|
+
|
|
402
|
+
```bash
|
|
403
|
+
CONFLICTED=$(git diff --name-only --diff-filter=U)
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
Categorize each conflicted file and resolve:
|
|
407
|
+
|
|
408
|
+
| Category | Patterns | Action |
|
|
409
|
+
|----------|----------|--------|
|
|
410
|
+
| **Docs/config** | `docs/**/*.md`, `backlog/*.yml`, `*.md` outside `src/`, `*.json`/`*.yml` outside `src/` | Auto-resolve: strip markers, keep both sides |
|
|
411
|
+
| **Code** | `src/**/*.ts`, `*.tsx`, `*.js`, `*.jsx` | STOP — abort rebase, report to user |
|
|
412
|
+
| **Tests** | `*.test.*`, `*.spec.*` | Manual only — report to user |
|
|
413
|
+
|
|
414
|
+
```bash
|
|
415
|
+
for FILE in $CONFLICTED; do
|
|
416
|
+
case "$FILE" in
|
|
417
|
+
src/*.ts|src/*.tsx|src/*.js|src/*.jsx|*.test.*|*.spec.*)
|
|
418
|
+
# Code or test conflict — abort and report
|
|
419
|
+
git rebase --abort
|
|
420
|
+
git stash pop 2>/dev/null || true
|
|
421
|
+
echo "CONFLICT in $FILE — cannot auto-resolve" >&2
|
|
422
|
+
exit 1 ;;
|
|
423
|
+
docs/*|backlog/*|*.md|*.json|*.yml)
|
|
424
|
+
# Doc/config conflict — auto-resolve keeping both sides
|
|
425
|
+
sed -i '' '/^<<<<<<< /d; /^=======/d; /^>>>>>>> /d' "$FILE"
|
|
426
|
+
git add "$FILE" ;;
|
|
427
|
+
esac
|
|
428
|
+
done
|
|
429
|
+
|
|
430
|
+
# Continue rebase + restore stash + verify build
|
|
431
|
+
git rebase --continue
|
|
432
|
+
git stash pop 2>/dev/null || true
|
|
433
|
+
npm run build
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
If build fails after rebase → STOP and report. The rebase introduced incompatibilities.
|
|
437
|
+
|
|
438
|
+
### 4c. Remote merge via GitHub PR (NO main-repo checkout)
|
|
439
|
+
|
|
440
|
+
**IMPORTANT — Remote merge only, NO local checkout/switch/branch on the main repo.** Consumer projects often share the main repo as a parallel resource across multiple terminals; running `git checkout develop` on it preempts whatever the other terminals are doing and breaks worktree-driven workflows. We therefore do the merge via the GitHub API (`gh pr create` + `gh pr merge`) — the main repo's `HEAD` is never touched.
|
|
441
|
+
|
|
442
|
+
The previous local-merge flow caused: (a) classifier-blocked `git checkout develop` in projects with terminal-isolation rules in CLAUDE.md, (b) silent failure of the orchestrator's merge phase.
|
|
443
|
+
|
|
444
|
+
```bash
|
|
445
|
+
MAIN=$(git -C "$WORKTREE_PATH" rev-parse --git-common-dir)/..
|
|
446
|
+
MAIN=$(cd "$MAIN" && pwd)
|
|
447
|
+
|
|
448
|
+
# 1. Push the feature branch to origin (force-with-lease in case of rebase in 4b).
|
|
449
|
+
git -C "$WORKTREE_PATH" push --force-with-lease origin "$BRANCH"
|
|
450
|
+
|
|
451
|
+
# 2. Open / find the PR.
|
|
452
|
+
PR_NUMBER=$(gh -R "$(gh repo view --json nameWithOwner -q .nameWithOwner)" pr list \
|
|
453
|
+
--head "$BRANCH" --state open --json number -q '.[0].number' 2>/dev/null || true)
|
|
454
|
+
|
|
455
|
+
if [ -z "$PR_NUMBER" ]; then
|
|
456
|
+
PR_URL=$(gh pr create \
|
|
457
|
+
--base develop \
|
|
458
|
+
--head "$BRANCH" \
|
|
459
|
+
--title "[<CARD-ID>] $(echo "$BRANCH" | sed 's|.*/||')" \
|
|
460
|
+
--body "Auto-merged by /mw after final review + QA passed." \
|
|
461
|
+
--repo "$(gh repo view --json nameWithOwner -q .nameWithOwner)")
|
|
462
|
+
PR_NUMBER=$(echo "$PR_URL" | grep -oE '[0-9]+$')
|
|
463
|
+
fi
|
|
464
|
+
echo "PR #$PR_NUMBER ready to merge."
|
|
465
|
+
|
|
466
|
+
# 3. Merge via gh CLI. --delete-branch removes the remote branch on success.
|
|
467
|
+
# The CLI may print a non-fatal warning if the LOCAL branch can't be deleted
|
|
468
|
+
# (e.g. "fatal: 'develop' is already used by worktree at ..." when develop is
|
|
469
|
+
# checked out in another worktree). The REMOTE merge happens regardless — we
|
|
470
|
+
# swallow the local-cleanup warning.
|
|
471
|
+
MERGE_OUTPUT=$(gh pr merge "$PR_NUMBER" --merge --delete-branch 2>&1) || MERGE_RC=$?
|
|
472
|
+
echo "$MERGE_OUTPUT"
|
|
473
|
+
|
|
474
|
+
# 3b. Fallback: if `gh pr merge` failed AND the PR is not yet merged, fall back
|
|
475
|
+
# to the REST API (works even when the CLI errors on local cleanup).
|
|
476
|
+
PR_STATE=$(gh pr view "$PR_NUMBER" --json state -q .state)
|
|
477
|
+
if [ "$PR_STATE" != "MERGED" ]; then
|
|
478
|
+
echo "Falling back to REST API merge..."
|
|
479
|
+
REPO=$(gh repo view --json nameWithOwner -q .nameWithOwner)
|
|
480
|
+
gh api -X PUT "repos/$REPO/pulls/$PR_NUMBER/merge" \
|
|
481
|
+
-f merge_method=merge \
|
|
482
|
+
-f commit_title="[<CARD-ID>] Merge $BRANCH into develop"
|
|
483
|
+
PR_STATE=$(gh pr view "$PR_NUMBER" --json state -q .state)
|
|
484
|
+
fi
|
|
485
|
+
|
|
486
|
+
if [ "$PR_STATE" != "MERGED" ]; then
|
|
487
|
+
echo "❌ PR #$PR_NUMBER did not merge. Inspect manually: $PR_URL"
|
|
488
|
+
exit 1
|
|
489
|
+
fi
|
|
490
|
+
echo "✅ PR #$PR_NUMBER merged to develop."
|
|
491
|
+
|
|
492
|
+
# 4. Sync local develop ONLY if the main repo's HEAD is already develop.
|
|
493
|
+
# NEVER `git checkout develop` here — that's the regression we're fixing.
|
|
494
|
+
# If the user (or another terminal) had develop checked out, ff-only updates
|
|
495
|
+
# it cleanly. Otherwise we leave their HEAD alone and they'll pull next time.
|
|
496
|
+
CURRENT_BRANCH=$(git -C "$MAIN" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "")
|
|
497
|
+
if [ "$CURRENT_BRANCH" = "develop" ]; then
|
|
498
|
+
git -C "$MAIN" pull --ff-only origin develop || \
|
|
499
|
+
echo "⚠️ Could not fast-forward main repo develop (uncommitted work?). Leaving as-is."
|
|
500
|
+
else
|
|
501
|
+
echo "ℹ️ Main repo HEAD is '$CURRENT_BRANCH' — not switching. Next manual `git pull` on develop will sync."
|
|
502
|
+
git -C "$MAIN" fetch origin develop --quiet
|
|
503
|
+
fi
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
If `gh` is not installed in the project, STOP and ask the user to install GitHub CLI (`brew install gh` or equivalent) and run `gh auth login`. Do NOT fall back to the legacy local-checkout flow — it violates terminal isolation in worktree-driven projects.
|
|
507
|
+
|
|
508
|
+
If both gh CLI and REST API merge fail → STOP and report. Do NOT attempt a local checkout as fallback.
|
|
509
|
+
|
|
510
|
+
### 5. Post-merge verification
|
|
511
|
+
|
|
512
|
+
```bash
|
|
513
|
+
npx tsc --noEmit
|
|
514
|
+
npm run build
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
If post-merge build fails → STOP and report. Do NOT cleanup worktree (may need to investigate).
|
|
518
|
+
|
|
519
|
+
### 6. Cleanup worktree
|
|
520
|
+
|
|
521
|
+
Only after post-merge verification passes:
|
|
522
|
+
|
|
523
|
+
Run each command INDIVIDUALLY (do NOT chain with `&&` or `;` — permission systems
|
|
524
|
+
may block destructive commands when chained):
|
|
525
|
+
|
|
526
|
+
```bash
|
|
527
|
+
# 1. Remove the worktree (this also unlocks the branch from worktree use)
|
|
528
|
+
git worktree remove "$WORKTREE_PATH" --force
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
```bash
|
|
532
|
+
# 2. Delete the local branch — use -d (safe delete, branch is already merged)
|
|
533
|
+
# NOT -D (force delete) which gets blocked by permission systems
|
|
534
|
+
git branch -d "$BRANCH"
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
```bash
|
|
538
|
+
# 3. Delete the remote branch (optional — may not exist if never pushed)
|
|
539
|
+
git push origin --delete "$BRANCH" 2>/dev/null || true
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
```bash
|
|
543
|
+
# 4. Prune stale references
|
|
544
|
+
git worktree prune
|
|
545
|
+
```
|
|
546
|
+
|
|
547
|
+
### 7. Update registry
|
|
548
|
+
|
|
549
|
+
Remove the entry from `.worktrees/registry.json`.
|
|
550
|
+
|
|
551
|
+
### 8. Report
|
|
552
|
+
|
|
553
|
+
```
|
|
554
|
+
Merge complete:
|
|
555
|
+
Card: <CARD-ID>
|
|
556
|
+
Branch: <BRANCH> (deleted on remote; local-cleanup may have skipped if checked out elsewhere)
|
|
557
|
+
PR: #<PR_NUMBER> merged via `gh pr merge`
|
|
558
|
+
Worktree: <WORKTREE_PATH> (removed)
|
|
559
|
+
develop: remote up to date; local main-repo synced only if HEAD was already develop
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
---
|
|
563
|
+
|
|
564
|
+
## /lw — List Worktrees
|
|
565
|
+
|
|
566
|
+
Show status of all active worktrees. Read `.worktrees/registry.json` and cross-reference with `git worktree list`.
|
|
567
|
+
|
|
568
|
+
For each worktree, display:
|
|
569
|
+
|
|
570
|
+
```
|
|
571
|
+
Active worktrees:
|
|
572
|
+
|
|
573
|
+
1. FEAT-0200 menu-ranking (batch: FEAT-0200, FEAT-0201)
|
|
574
|
+
Branch: feat/FEAT-0200-menu-ranking
|
|
575
|
+
Path: /abs/path/.worktrees/feat-FEAT-0200-menu-ranking
|
|
576
|
+
Port: 3001
|
|
577
|
+
Age: 2 days
|
|
578
|
+
Status: 3 uncommitted changes
|
|
579
|
+
Build: verified ✓
|
|
580
|
+
Env: in sync | STALE (main .env.local changed)
|
|
581
|
+
|
|
582
|
+
2. BUG-0500 fix-auth
|
|
583
|
+
Branch: feat/BUG-0500-fix-auth
|
|
584
|
+
Path: /abs/path/.worktrees/feat-BUG-0500-fix-auth
|
|
585
|
+
Port: 3002
|
|
586
|
+
Age: 8 days (stale — consider merging or cleaning up)
|
|
587
|
+
Status: clean
|
|
588
|
+
Build: verified ✓
|
|
589
|
+
Env: in sync
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
**Stale detection**: Worktrees older than 7 days get a warning.
|
|
593
|
+
**Merged detection**: If the branch has been merged into develop (`git branch -a --merged develop`), flag as "already merged — safe to /cw".
|
|
594
|
+
**Orphan detection**: Worktrees in `git worktree list` but NOT in registry get flagged as "unregistered".
|
|
595
|
+
|
|
596
|
+
---
|
|
597
|
+
|
|
598
|
+
## /cw — Cleanup Worktrees
|
|
599
|
+
|
|
600
|
+
Remove worktrees without the full PR/merge flow. Use for:
|
|
601
|
+
- Worktrees whose branches were already merged
|
|
602
|
+
- Abandoned worktrees
|
|
603
|
+
- Worktrees created outside this skill
|
|
604
|
+
|
|
605
|
+
### 1. Scan
|
|
606
|
+
|
|
607
|
+
```bash
|
|
608
|
+
git worktree list
|
|
609
|
+
```
|
|
610
|
+
|
|
611
|
+
Cross-reference with registry. For each worktree, check:
|
|
612
|
+
- Is the branch merged into develop? → "safe to remove"
|
|
613
|
+
- Is the branch pushed to remote? → "has remote backup"
|
|
614
|
+
- Are there uncommitted changes? → "has uncommitted work — DANGEROUS"
|
|
615
|
+
|
|
616
|
+
### 2. Present options
|
|
617
|
+
|
|
618
|
+
```
|
|
619
|
+
Worktrees available for cleanup:
|
|
620
|
+
|
|
621
|
+
1. feat/FEAT-0200-menu-ranking — merged into develop ✓ safe
|
|
622
|
+
2. feat/BUG-0300-old-fix — not merged, pushed to remote
|
|
623
|
+
3. feat/FEAT-0100-abandoned — not merged, uncommitted changes ✗ DANGEROUS
|
|
624
|
+
|
|
625
|
+
Remove which? (comma-separated numbers, or "all-safe" for merged-only)
|
|
626
|
+
```
|
|
627
|
+
|
|
628
|
+
### 3. Cleanup selected
|
|
629
|
+
|
|
630
|
+
For each selected worktree:
|
|
631
|
+
|
|
632
|
+
```bash
|
|
633
|
+
git worktree remove "<path>" --force
|
|
634
|
+
```
|
|
635
|
+
|
|
636
|
+
Also delete the remote branch if it exists:
|
|
637
|
+
|
|
638
|
+
```bash
|
|
639
|
+
git push origin --delete "<branch-name>" 2>/dev/null || true
|
|
640
|
+
```
|
|
641
|
+
|
|
642
|
+
If the worktree has uncommitted changes and user confirmed removal, proceed.
|
|
643
|
+
If user did NOT confirm, SKIP and warn.
|
|
644
|
+
|
|
645
|
+
After all removals:
|
|
646
|
+
|
|
647
|
+
```bash
|
|
648
|
+
git worktree prune
|
|
649
|
+
```
|
|
650
|
+
|
|
651
|
+
### 4. Update registry
|
|
652
|
+
|
|
653
|
+
Remove cleaned entries from `.worktrees/registry.json`.
|
|
654
|
+
|
|
655
|
+
### 5. Report
|
|
656
|
+
|
|
657
|
+
```
|
|
658
|
+
Cleanup complete:
|
|
659
|
+
Removed: feat/FEAT-0200-menu-ranking, feat/BUG-0300-old-fix
|
|
660
|
+
Skipped: feat/FEAT-0100-abandoned (uncommitted changes)
|
|
661
|
+
Registry: updated
|
|
662
|
+
```
|
|
663
|
+
|
|
664
|
+
---
|
|
665
|
+
|
|
666
|
+
## Safety Rules
|
|
667
|
+
|
|
668
|
+
- **NEVER `git checkout`, `git switch`, `git checkout -b`, or `git branch` on the main repo from inside `/mw` / `/nw` / `/cw`.** The main repo is a shared resource across parallel terminals; touching its `HEAD` preempts other agents and breaks worktree-driven workflows. Many consumer projects (e.g. mayo) declare this as an absolute rule in CLAUDE.md and Claude Code's classifier will pattern-match and block these commands preemptively. Use `gh pr create` + `gh pr merge` for develop merges and `git -C <main> pull --ff-only` (only when `HEAD = develop` already) for sync. See `/mw` step 4c.
|
|
669
|
+
- NEVER merge to `main` — only to `develop`, and only via `gh pr merge` (NOT local checkout).
|
|
670
|
+
- NEVER force push from a worktree (`--force-with-lease` on the feature branch after rebase is the only allowed force variant).
|
|
671
|
+
- NEVER `git add .` or `git add -A` — always explicit file names.
|
|
672
|
+
- NEVER remove a worktree with uncommitted changes without explicit user confirmation.
|
|
673
|
+
- NEVER delete a branch before successful merge verification.
|
|
674
|
+
- NEVER cleanup a worktree before confirming develop is stable post-merge.
|
|
675
|
+
- If build/lint/tsc fails during /mw, STOP and report. Do not skip checks.
|
|
676
|
+
- If merge conflicts during /mw, STOP and ask the user. Do not auto-resolve.
|
|
677
|
+
- Always verify `.worktrees/` is in `.gitignore` before creating (already done in this project).
|
|
678
|
+
- Commit lock protocol: Each worktree has its own `COMMIT_LOCK` in its git dir — no cross-worktree interference.
|
|
679
|
+
- Port persistence: On dev server restart, reuse the port from registry (grep .env.local for PORT=) instead of picking a new one.
|
|
680
|
+
- **NEVER use `git stash` in worktrees.** Stashes are globally shared across all worktrees (`refs/stash` via `git.commondir`). A stash created in one worktree or in the main repo can be popped in another, causing conflicts, data loss, and cascading merge failures (see FEAT-0522 incident). Use explicit file staging only — the file ownership map ensures no overlap between cards. The stash pattern in AGENTS.md/CLAUDE.md applies ONLY to the main repo working tree.
|