specweave 1.0.520 → 1.0.522
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/.claude-plugin/README.md +1 -1
- package/CLAUDE.md +1 -1
- package/README.md +1 -1
- package/bin/specweave.js +8 -8
- package/dist/plugins/specweave/lib/integrations/github/duplicate-detector.js +6 -6
- package/dist/plugins/specweave/lib/integrations/github/duplicate-detector.js.map +1 -1
- package/dist/plugins/specweave/lib/integrations/github/github-ac-comment-poster.d.ts.map +1 -1
- package/dist/plugins/specweave/lib/integrations/github/github-ac-comment-poster.js +34 -9
- package/dist/plugins/specweave/lib/integrations/github/github-ac-comment-poster.js.map +1 -1
- package/dist/plugins/specweave/lib/integrations/github/github-body-utils.d.ts +38 -0
- package/dist/plugins/specweave/lib/integrations/github/github-body-utils.d.ts.map +1 -0
- package/dist/plugins/specweave/lib/integrations/github/github-body-utils.js +50 -0
- package/dist/plugins/specweave/lib/integrations/github/github-body-utils.js.map +1 -0
- package/dist/plugins/specweave/lib/integrations/github/github-feature-sync.d.ts +0 -2
- package/dist/plugins/specweave/lib/integrations/github/github-feature-sync.d.ts.map +1 -1
- package/dist/plugins/specweave/lib/integrations/github/github-feature-sync.js +194 -173
- package/dist/plugins/specweave/lib/integrations/github/github-feature-sync.js.map +1 -1
- package/dist/src/adapters/codex/README.md +1 -1
- package/dist/src/adapters/gemini/README.md +1 -1
- package/dist/src/cli/commands/complete.d.ts +10 -7
- package/dist/src/cli/commands/complete.d.ts.map +1 -1
- package/dist/src/cli/commands/complete.js +60 -14
- package/dist/src/cli/commands/complete.js.map +1 -1
- package/dist/src/cli/commands/create-increment.d.ts.map +1 -1
- package/dist/src/cli/commands/create-increment.js +2 -10
- package/dist/src/cli/commands/create-increment.js.map +1 -1
- package/dist/src/cli/commands/evaluate-completion.d.ts.map +1 -1
- package/dist/src/cli/commands/evaluate-completion.js +8 -38
- package/dist/src/cli/commands/evaluate-completion.js.map +1 -1
- package/dist/src/cli/commands/init.d.ts.map +1 -1
- package/dist/src/cli/commands/init.js +25 -0
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/commands/save.js +1 -1
- package/dist/src/cli/commands/save.js.map +1 -1
- package/dist/src/cli/commands/sync-progress.d.ts.map +1 -1
- package/dist/src/cli/commands/sync-progress.js +10 -0
- package/dist/src/cli/commands/sync-progress.js.map +1 -1
- package/dist/src/cli/helpers/init/claude-settings-lsp.js +1 -1
- package/dist/src/cli/helpers/init/claude-settings-lsp.js.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/github-multi-repo.d.ts +1 -8
- package/dist/src/cli/helpers/issue-tracker/github-multi-repo.d.ts.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/github-multi-repo.js +57 -88
- package/dist/src/cli/helpers/issue-tracker/github-multi-repo.js.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/github.d.ts.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/github.js +1 -3
- package/dist/src/cli/helpers/issue-tracker/github.js.map +1 -1
- package/dist/src/core/increment/completion-validator.d.ts.map +1 -1
- package/dist/src/core/increment/completion-validator.js +2 -3
- package/dist/src/core/increment/completion-validator.js.map +1 -1
- package/dist/src/core/increment/increment-utils.d.ts +7 -7
- package/dist/src/core/increment/increment-utils.d.ts.map +1 -1
- package/dist/src/core/increment/increment-utils.js +19 -13
- package/dist/src/core/increment/increment-utils.js.map +1 -1
- package/dist/src/core/increment/status-change-sync-trigger.d.ts.map +1 -1
- package/dist/src/core/increment/status-change-sync-trigger.js +9 -0
- package/dist/src/core/increment/status-change-sync-trigger.js.map +1 -1
- package/dist/src/core/repo-structure/prompt-consolidator.d.ts +3 -17
- package/dist/src/core/repo-structure/prompt-consolidator.d.ts.map +1 -1
- package/dist/src/core/repo-structure/prompt-consolidator.js +1 -55
- package/dist/src/core/repo-structure/prompt-consolidator.js.map +1 -1
- package/dist/src/core/repo-structure/repo-structure-manager.d.ts.map +1 -1
- package/dist/src/core/repo-structure/repo-structure-manager.js +3 -1
- package/dist/src/core/repo-structure/repo-structure-manager.js.map +1 -1
- package/dist/src/core/repo-structure/setup-state-manager.d.ts.map +1 -1
- package/dist/src/core/repo-structure/setup-state-manager.js +2 -1
- package/dist/src/core/repo-structure/setup-state-manager.js.map +1 -1
- package/dist/src/core/repo-structure/setup-summary.js +1 -1
- package/dist/src/core/repo-structure/setup-summary.js.map +1 -1
- package/dist/src/core/sync-throttle.d.ts +49 -0
- package/dist/src/core/sync-throttle.d.ts.map +1 -0
- package/dist/src/core/sync-throttle.js +94 -0
- package/dist/src/core/sync-throttle.js.map +1 -0
- package/dist/src/dashboard/server/dashboard-server.js +1 -1
- package/dist/src/dashboard/server/dashboard-server.js.map +1 -1
- package/dist/src/hooks/auto-create-external-issue.js +11 -0
- package/dist/src/hooks/auto-create-external-issue.js.map +1 -1
- package/dist/src/init/InitFlow.d.ts.map +1 -1
- package/dist/src/init/InitFlow.js +4 -8
- package/dist/src/init/InitFlow.js.map +1 -1
- package/dist/src/init/research/src/config/ConfigManager.js +1 -1
- package/dist/src/init/research/src/config/ConfigManager.js.map +1 -1
- package/dist/src/init/research/src/config/types.d.ts +0 -1
- package/dist/src/init/research/src/config/types.d.ts.map +1 -1
- package/dist/src/init/research/src/config/types.js +1 -1
- package/dist/src/init/research/src/config/types.js.map +1 -1
- package/dist/src/locales/de/cli.json +1 -1
- package/dist/src/locales/en/cli.json +1 -1
- package/dist/src/locales/es/cli.json +1 -1
- package/dist/src/locales/fr/cli.json +1 -1
- package/dist/src/locales/ja/cli.json +1 -1
- package/dist/src/locales/ko/cli.json +1 -1
- package/dist/src/locales/pt/cli.json +1 -1
- package/dist/src/locales/ru/cli.json +1 -1
- package/dist/src/locales/zh/cli.json +1 -1
- package/dist/src/utils/resolve-increment-id.d.ts +24 -0
- package/dist/src/utils/resolve-increment-id.d.ts.map +1 -0
- package/dist/src/utils/resolve-increment-id.js +53 -0
- package/dist/src/utils/resolve-increment-id.js.map +1 -0
- package/package.json +1 -1
- package/plugins/specweave/.claude-plugin/plugin.json +2 -2
- package/plugins/specweave/commands/import-external.md +4 -4
- package/plugins/specweave/lib/integrations/github/duplicate-detector.js +1 -1
- package/plugins/specweave/lib/integrations/github/duplicate-detector.ts +6 -6
- package/plugins/specweave/lib/integrations/github/github-ac-comment-poster.js +39 -13
- package/plugins/specweave/lib/integrations/github/github-ac-comment-poster.ts +43 -13
- package/plugins/specweave/lib/integrations/github/github-body-utils.js +15 -0
- package/plugins/specweave/lib/integrations/github/github-body-utils.ts +52 -0
- package/plugins/specweave/lib/integrations/github/github-feature-sync.js +160 -136
- package/plugins/specweave/lib/integrations/github/github-feature-sync.ts +49 -29
- package/plugins/specweave/skills/increment/SKILL.md +45 -88
- package/plugins/specweave/skills/team-lead/SKILL.md +68 -4
- package/scripts/check-node-version.js +1 -1
- package/src/templates/lsp-plugin/plugin.json +1 -1
- package/dist/src/core/migration/consolidation-engine.d.ts +0 -59
- package/dist/src/core/migration/consolidation-engine.d.ts.map +0 -1
- package/dist/src/core/migration/consolidation-engine.js +0 -177
- package/dist/src/core/migration/consolidation-engine.js.map +0 -1
- package/dist/src/core/migration/spec-project-mapper.d.ts +0 -51
- package/dist/src/core/migration/spec-project-mapper.d.ts.map +0 -1
- package/dist/src/core/migration/spec-project-mapper.js +0 -299
- package/dist/src/core/migration/spec-project-mapper.js.map +0 -1
- package/dist/src/core/migration/types.d.ts +0 -132
- package/dist/src/core/migration/types.d.ts.map +0 -1
- package/dist/src/core/migration/types.js +0 -10
- package/dist/src/core/migration/types.js.map +0 -1
- package/dist/src/core/migration/umbrella-migrator.d.ts +0 -58
- package/dist/src/core/migration/umbrella-migrator.d.ts.map +0 -1
- package/dist/src/core/migration/umbrella-migrator.js +0 -617
- package/dist/src/core/migration/umbrella-migrator.js.map +0 -1
|
@@ -45,12 +45,12 @@ Increment planning produces specs, plans, and task breakdowns that require user
|
|
|
45
45
|
STEP 0A: Discipline Check (BLOCKING)
|
|
46
46
|
STEP 0B: WIP Enforcement
|
|
47
47
|
STEP 0C: Tech Stack Detection
|
|
48
|
-
STEP 0D: Structure Resolution (if deferred from init)
|
|
49
48
|
STEP 1: Pre-flight (TDD mode, multi-project, Deep Interview check)
|
|
50
49
|
STEP 2: Project Context (resolve project/board)
|
|
51
50
|
STEP 3: Create Increment (via Template API) ← folder + ID exist after this
|
|
52
51
|
STEP 3a: Deep Interview (if enabled) ← runs AFTER folder exists
|
|
53
|
-
STEP 4:
|
|
52
|
+
STEP 4: Direct Specification Writing (universal, CLI-first)
|
|
53
|
+
STEP 4a: Enhanced: Team-Based Delegation (optional, Claude Code only)
|
|
54
54
|
STEP 5: Post-Creation Sync
|
|
55
55
|
STEP 6: Execution Strategy Recommendation
|
|
56
56
|
```
|
|
@@ -116,31 +116,6 @@ Auto-detect from project files:
|
|
|
116
116
|
|
|
117
117
|
If detection fails, ask user.
|
|
118
118
|
|
|
119
|
-
## Step 0D: Structure Resolution (if deferred)
|
|
120
|
-
|
|
121
|
-
Check if the user deferred their repository structure decision during init (greenfield projects):
|
|
122
|
-
|
|
123
|
-
```bash
|
|
124
|
-
DEFERRED=$(jq -r '.project.structureDeferred // false' .specweave/config.json 2>/dev/null)
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
If `DEFERRED` is `true`, this is the user's **first increment** and they need to define their project structure.
|
|
128
|
-
|
|
129
|
-
Based on the user's feature description and what you've learned from tech stack detection:
|
|
130
|
-
|
|
131
|
-
1. **Ask the user** about their repository structure:
|
|
132
|
-
- **Single repo** — one repository (monorepo or standard project)
|
|
133
|
-
- **Multiple repos** — microservices, EDA, parent/child architecture
|
|
134
|
-
|
|
135
|
-
2. **Run the resolve command** based on their answer:
|
|
136
|
-
```bash
|
|
137
|
-
specweave resolve-structure --type single
|
|
138
|
-
# OR
|
|
139
|
-
specweave resolve-structure --type multiple
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
3. This clears the deferred flag and configures the project accordingly. Continue with the normal increment flow.
|
|
143
|
-
|
|
144
119
|
## Step 1: Pre-flight Checks
|
|
145
120
|
|
|
146
121
|
```bash
|
|
@@ -170,7 +145,7 @@ Every US MUST have `**Project**:` field. For 2-level structures, also `**Board**
|
|
|
170
145
|
|
|
171
146
|
### 3a. Determine Increment Location
|
|
172
147
|
|
|
173
|
-
**
|
|
148
|
+
**Determine where increments are stored:**
|
|
174
149
|
|
|
175
150
|
```bash
|
|
176
151
|
# Check umbrella mode
|
|
@@ -188,7 +163,7 @@ elif [ -d "repositories" ]; then
|
|
|
188
163
|
echo "Organization: $ORG"
|
|
189
164
|
ls -d repositories/*/* 2>/dev/null | head -20
|
|
190
165
|
else
|
|
191
|
-
echo "
|
|
166
|
+
echo "WORKSPACE: Use .specweave/increments/"
|
|
192
167
|
fi
|
|
193
168
|
```
|
|
194
169
|
|
|
@@ -202,7 +177,7 @@ fi
|
|
|
202
177
|
- Each repository has its OWN `.specweave/increments/` directory
|
|
203
178
|
- Run `specweave init` in each repo if `.specweave/` doesn't exist
|
|
204
179
|
|
|
205
|
-
### 3b. Create Increment
|
|
180
|
+
### 3b. Create Increment
|
|
206
181
|
|
|
207
182
|
```bash
|
|
208
183
|
specweave create-increment --auto-id --name "your-feature-name" --title "Feature Title" --description "Brief description" --project "my-app"
|
|
@@ -212,20 +187,9 @@ This atomically reserves the next available ID and creates the increment directo
|
|
|
212
187
|
|
|
213
188
|
**Optional flags**: `--type hotfix` | `--priority P1` | `--board "team-name"` | `--json`
|
|
214
189
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
```bash
|
|
218
|
-
# Step 1: Get the next available increment ID
|
|
219
|
-
NEXT_ID=$(specweave next-id --name "your-feature-name")
|
|
220
|
-
# Returns e.g. "0579-your-feature-name"
|
|
221
|
-
|
|
222
|
-
# Step 2: Create with explicit ID
|
|
223
|
-
specweave create-increment --id "$NEXT_ID" --title "Feature Title" --description "Brief description" --project "my-app"
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
**Note**: The two-step approach has a TOCTOU race — another process can claim the ID between steps. Prefer `--auto-id` for concurrent environments.
|
|
190
|
+
For diagnostic purposes, `specweave next-id` is available to preview the next number.
|
|
227
191
|
|
|
228
|
-
###
|
|
192
|
+
### 3c. Create manually (if CLI unavailable)
|
|
229
193
|
|
|
230
194
|
```bash
|
|
231
195
|
mkdir -p .specweave/increments/XXXX-name
|
|
@@ -273,31 +237,50 @@ Create files in order: metadata.json FIRST, then spec.md, plan.md, tasks.md.
|
|
|
273
237
|
|
|
274
238
|
## Critical Rules
|
|
275
239
|
|
|
276
|
-
1. **
|
|
240
|
+
1. **Prefer team-based delegation when TeamCreate is available**; write spec files directly otherwise
|
|
277
241
|
2. **Project field is MANDATORY** — Every US MUST have `**Project**:` field
|
|
278
242
|
3. **Use Template Creator CLI** (REQUIRED): `specweave create-increment --auto-id --name "name" --title "Title" --description "Desc" --project "my-app"`
|
|
279
|
-
4. **Team-based delegation is the
|
|
243
|
+
4. **Team-based delegation is the preferred path** when TeamCreate is available — but direct spec writing is the universal default that works with ALL AI tools
|
|
280
244
|
5. **Increment naming** — Format: `####-descriptive-kebab-case`
|
|
281
245
|
6. **Umbrella mode** — When `umbrella.enabled: true`, ALL increments go in the umbrella root `.specweave/increments/`. The `**Project**:` field per user story routes sync to child repos. Do NOT create increments in child repos.
|
|
282
246
|
|
|
283
|
-
##
|
|
247
|
+
## Step 3a: Deep Interview Mode (if enabled)
|
|
248
|
+
|
|
249
|
+
**IMPORTANT**: This step runs AFTER the increment folder is created (Step 3), so the
|
|
250
|
+
interview state file can reference the real increment ID.
|
|
284
251
|
|
|
285
|
-
|
|
286
|
-
|
|
252
|
+
**If deep interview is enabled, delegate to PM subagent (if Agent tool available) or conduct inline:**
|
|
253
|
+
|
|
254
|
+
```typescript
|
|
255
|
+
Agent({ subagent_type: "sw:sw-pm", prompt: "Deep interview for increment XXXX-name: <user description>. Increment path: <path>", description: "PM deep interview" })
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
The PM agent will:
|
|
259
|
+
1. Assess complexity and determine question count (trivial: 0-3, small: 4-8, medium: 9-18, large: 19-40)
|
|
260
|
+
2. Interview the user across relevant categories
|
|
261
|
+
3. Write interview state to `.specweave/state/interview-{increment-id}.json`
|
|
262
|
+
4. Return interview summary for spec.md creation
|
|
263
|
+
|
|
264
|
+
**After PM agent returns**, read the interview state file to confirm all categories are covered
|
|
265
|
+
before proceeding to spec.md creation (especially when `enforcement: "strict"`).
|
|
266
|
+
|
|
267
|
+
## Step 4: Direct Specification Writing (Universal — works with ALL AI tools)
|
|
268
|
+
|
|
269
|
+
**After increment folder + metadata.json are created, write the spec files using CLI commands and templates.**
|
|
270
|
+
|
|
271
|
+
This is the default path. It works with Claude Code, Cursor, OpenCode, Copilot, Aider, and any other AI tool.
|
|
287
272
|
|
|
288
|
-
**Fallback: Direct spec writing**
|
|
289
273
|
1. Create the increment: `specweave create-increment --auto-id --name "feature-name" --title "Title" --description "Desc" --project "my-app"`
|
|
290
|
-
2. Write spec.md
|
|
291
|
-
3. Write plan.md with architecture decisions
|
|
292
|
-
4. Write tasks.md with BDD test plans for each AC
|
|
274
|
+
2. Write `spec.md` with user stories and acceptance criteria (use the User Story Format above)
|
|
275
|
+
3. Write `plan.md` with architecture decisions and ADR references
|
|
276
|
+
4. Write `tasks.md` with BDD test plans (Given/When/Then) for each AC
|
|
293
277
|
5. Run: `specweave sync-living-docs {increment-id}`
|
|
294
278
|
|
|
295
|
-
|
|
279
|
+
Proceed to Step 5 after writing all files.
|
|
296
280
|
|
|
297
|
-
|
|
281
|
+
### Step 4a: Enhanced — Team-Based Delegation (Optional, Claude Code only)
|
|
298
282
|
|
|
299
|
-
**
|
|
300
|
-
Delegate via TeamCreate + team-scoped Agent() calls. Each agent gets its own tmux pane for user visibility.
|
|
283
|
+
**If TeamCreate is available**, use team-based delegation for better quality. This provides isolated context, persistent memory, resumability, auto-compaction, and tmux pane visibility for each agent.
|
|
301
284
|
|
|
302
285
|
**Team lifecycle:**
|
|
303
286
|
1. `TeamCreate({ team_name: "plan-XXXX-name", description: "Planning: <feature>" })`
|
|
@@ -317,7 +300,7 @@ Delegate via TeamCreate + team-scoped Agent() calls. Each agent gets its own tmu
|
|
|
317
300
|
fi
|
|
318
301
|
```
|
|
319
302
|
|
|
320
|
-
**
|
|
303
|
+
**Agents to spawn:**
|
|
321
304
|
|
|
322
305
|
| File | Agent | Invocation |
|
|
323
306
|
|------|-------|------------|
|
|
@@ -325,7 +308,7 @@ Delegate via TeamCreate + team-scoped Agent() calls. Each agent gets its own tmu
|
|
|
325
308
|
| plan.md | sw:sw-architect | `Agent({ team_name: "plan-XXXX-name", name: "architect", subagent_type: "sw:sw-architect", mode: "bypassPermissions", prompt: "...", description: "Architect writes plan.md" })` |
|
|
326
309
|
| tasks.md | sw:sw-planner | `Agent({ team_name: "plan-XXXX-name", name: "planner", subagent_type: "sw:sw-planner", mode: "bypassPermissions", prompt: "...", description: "Planner writes tasks.md" })` |
|
|
327
310
|
|
|
328
|
-
**DO NOT:**
|
|
311
|
+
**DO NOT (when using team-based delegation):**
|
|
329
312
|
- Write user stories, architecture, or tasks inline
|
|
330
313
|
- Copy/paste spec content into Write() calls
|
|
331
314
|
- "Summarize" what an agent would produce
|
|
@@ -333,33 +316,7 @@ Delegate via TeamCreate + team-scoped Agent() calls. Each agent gets its own tmu
|
|
|
333
316
|
- Use standalone Agent() without team_name for Phase 1/2 delegation — agents MUST be in a team for tmux visibility (exception: Deep Interview in Step 3a is standalone because it's interactive + sequential)
|
|
334
317
|
- Use Skill() for these — team agents provide memory + resumability + visibility
|
|
335
318
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
**IMPORTANT**: This step runs AFTER the increment folder is created (Step 3), so the
|
|
339
|
-
interview state file can reference the real increment ID.
|
|
340
|
-
|
|
341
|
-
**If deep interview is enabled, delegate to PM subagent:**
|
|
342
|
-
|
|
343
|
-
```typescript
|
|
344
|
-
Agent({ subagent_type: "sw:sw-pm", prompt: "Deep interview for increment XXXX-name: <user description>. Increment path: <path>", description: "PM deep interview" })
|
|
345
|
-
```
|
|
346
|
-
|
|
347
|
-
The PM agent will:
|
|
348
|
-
1. Assess complexity and determine question count (trivial: 0-3, small: 4-8, medium: 9-18, large: 19-40)
|
|
349
|
-
2. Interview the user across relevant categories
|
|
350
|
-
3. Write interview state to `.specweave/state/interview-{increment-id}.json`
|
|
351
|
-
4. Return interview summary for spec.md creation
|
|
352
|
-
|
|
353
|
-
**After PM agent returns**, read the interview state file to confirm all categories are covered
|
|
354
|
-
before proceeding to spec.md creation (especially when `enforcement: "strict"`).
|
|
355
|
-
|
|
356
|
-
## Step 4: Delegation (MANDATORY - Team-Based)
|
|
357
|
-
|
|
358
|
-
**After increment folder + metadata.json are created, create a planning team and spawn agents using a 2-phase overlap strategy.**
|
|
359
|
-
|
|
360
|
-
Each agent runs in its own tmux pane for visibility. Agents preload their corresponding skill (with full domain logic, phases, templates), providing: isolated context, persistent memory, resumability, auto-compaction.
|
|
361
|
-
|
|
362
|
-
### 4a. Create Planning Team (REQUIRED — before spawning any agents)
|
|
319
|
+
#### 4a-i. Create Planning Team (before spawning any agents)
|
|
363
320
|
|
|
364
321
|
**Cleanup first** — if you previously created a planning team in this session, shut down those agents before proceeding:
|
|
365
322
|
```typescript
|
|
@@ -377,7 +334,7 @@ TeamCreate({ team_name: "plan-XXXX-name", description: "Planning: <feature descr
|
|
|
377
334
|
|
|
378
335
|
**team_name prefix `plan-*`** bypasses the increment-existence-guard (planning doesn't require an active increment).
|
|
379
336
|
|
|
380
|
-
|
|
337
|
+
#### 4a-ii. Spawn PM and Architect IN PARALLEL
|
|
381
338
|
|
|
382
339
|
PM and Architect run concurrently in separate tmux panes. Architect starts codebase exploration immediately while PM writes spec.md. Architect polls for spec.md and reads it once available, then produces plan.md.
|
|
383
340
|
|
|
@@ -394,7 +351,7 @@ Agent({ team_name: "plan-XXXX-name", name: "architect", subagent_type: "sw:sw-ar
|
|
|
394
351
|
|
|
395
352
|
**IMPORTANT**: Use parallel Agent() tool calls — call PM and Architect in the SAME message so they start concurrently.
|
|
396
353
|
|
|
397
|
-
|
|
354
|
+
#### 4a-iii. Spawn Planner (after PM + Architect complete)
|
|
398
355
|
```typescript
|
|
399
356
|
Agent({ team_name: "plan-XXXX-name", name: "planner", subagent_type: "sw:sw-planner", mode: "bypassPermissions", prompt: "Generate tasks for increment XXXX-name. Read spec.md at .specweave/increments/XXXX-name/spec.md and plan.md at .specweave/increments/XXXX-name/plan.md", description: "Planner writes tasks.md" })
|
|
400
357
|
```
|
|
@@ -403,7 +360,7 @@ Agent({ team_name: "plan-XXXX-name", name: "planner", subagent_type: "sw:sw-plan
|
|
|
403
360
|
Architect explores the codebase while PM writes spec.md, then reads spec.md to produce plan.md.
|
|
404
361
|
Planner needs both spec.md AND plan.md, so it must wait for Phase 1 to finish.
|
|
405
362
|
|
|
406
|
-
|
|
363
|
+
#### 4a-iv. Team Cleanup (after Planner completes)
|
|
407
364
|
|
|
408
365
|
```typescript
|
|
409
366
|
SendMessage({ type: "shutdown_request", recipient: "pm" })
|
|
@@ -111,7 +111,30 @@ Skip increment pre-flight entirely. Brainstorm doesn't need a spec — it explor
|
|
|
111
111
|
1. Create team: `TeamCreate({ team_name: "brainstorm-{slug}", description: "Brainstorm: {topic}" })`
|
|
112
112
|
2. Read agent templates from `agents/brainstorm-advocate.md`, `agents/brainstorm-critic.md`, `agents/brainstorm-pragmatist.md`
|
|
113
113
|
3. Replace `[BRAINSTORM_QUESTION]` with the user's question/topic
|
|
114
|
-
4. Spawn all 3 agents in parallel
|
|
114
|
+
4. Spawn all 3 agents in parallel — each call MUST include `team_name` so agents join the team (and get tmux panes):
|
|
115
|
+
```
|
|
116
|
+
Task({
|
|
117
|
+
team_name: "brainstorm-{slug}",
|
|
118
|
+
name: "brainstorm-advocate",
|
|
119
|
+
subagent_type: "general-purpose",
|
|
120
|
+
mode: "bypassPermissions",
|
|
121
|
+
prompt: <replaced brainstorm-advocate.md content>
|
|
122
|
+
})
|
|
123
|
+
Task({
|
|
124
|
+
team_name: "brainstorm-{slug}",
|
|
125
|
+
name: "brainstorm-critic",
|
|
126
|
+
subagent_type: "general-purpose",
|
|
127
|
+
mode: "bypassPermissions",
|
|
128
|
+
prompt: <replaced brainstorm-critic.md content>
|
|
129
|
+
})
|
|
130
|
+
Task({
|
|
131
|
+
team_name: "brainstorm-{slug}",
|
|
132
|
+
name: "brainstorm-pragmatist",
|
|
133
|
+
subagent_type: "general-purpose",
|
|
134
|
+
mode: "bypassPermissions",
|
|
135
|
+
prompt: <replaced brainstorm-pragmatist.md content>
|
|
136
|
+
})
|
|
137
|
+
```
|
|
115
138
|
5. **PASSIVE WAIT (CRITICAL)**: Do NOT apply §8b stuck detection to brainstorm agents.
|
|
116
139
|
Brainstorm agents send `STATUS:` heartbeats (not task-granularity `T-{N}/{total}`).
|
|
117
140
|
Wait patiently for `PERSPECTIVE_COMPLETE:` messages — expected 2-5 minutes per agent.
|
|
@@ -144,7 +167,23 @@ Planning mode runs PM and Architect agents in parallel for richer, faster spec c
|
|
|
144
167
|
2. **Spawn PM + Architect in parallel** (TRUE parallelism):
|
|
145
168
|
- Read `agents/pm.md`, replace `[INCREMENT_ID]`, `[MASTER_INCREMENT_PATH]`, `[FEATURE_DESCRIPTION]`
|
|
146
169
|
- Read `agents/architect.md`, replace `[INCREMENT_ID]`, `[MASTER_INCREMENT_PATH]`
|
|
147
|
-
- **Spawn BOTH
|
|
170
|
+
- **Spawn BOTH in a single step — each call MUST include `team_name`:**
|
|
171
|
+
```
|
|
172
|
+
Task({
|
|
173
|
+
team_name: "plan-{feature-slug}",
|
|
174
|
+
name: "pm-agent",
|
|
175
|
+
subagent_type: "general-purpose",
|
|
176
|
+
mode: "bypassPermissions",
|
|
177
|
+
prompt: <replaced pm.md content>
|
|
178
|
+
})
|
|
179
|
+
Task({
|
|
180
|
+
team_name: "plan-{feature-slug}",
|
|
181
|
+
name: "architect-agent",
|
|
182
|
+
subagent_type: "general-purpose",
|
|
183
|
+
mode: "bypassPermissions",
|
|
184
|
+
prompt: <replaced architect.md content>
|
|
185
|
+
})
|
|
186
|
+
```
|
|
148
187
|
- PM writes spec.md with user stories and ACs
|
|
149
188
|
- Architect starts codebase exploration immediately (does NOT need spec.md for this)
|
|
150
189
|
- Architect polls for spec.md, reads it when PM finishes, then designs architecture
|
|
@@ -196,7 +235,16 @@ Skip increment pre-flight. Research is exploratory — no spec needed.
|
|
|
196
235
|
- Multi-faceted topic: spawn 2-3 researchers with different scopes
|
|
197
236
|
(e.g., "research auth" → one agent on OAuth providers, one on session management, one on security best practices)
|
|
198
237
|
3. Replace `[RESEARCH_TOPIC]` and `[RESEARCH_SCOPE]` in each agent prompt
|
|
199
|
-
4. Spawn all researchers in parallel
|
|
238
|
+
4. Spawn all researchers in parallel — each call MUST include `team_name`:
|
|
239
|
+
```
|
|
240
|
+
Task({
|
|
241
|
+
team_name: "research-{slug}",
|
|
242
|
+
name: "researcher-{scope}",
|
|
243
|
+
subagent_type: "general-purpose",
|
|
244
|
+
mode: "bypassPermissions",
|
|
245
|
+
prompt: <replaced researcher.md content>
|
|
246
|
+
})
|
|
247
|
+
```
|
|
200
248
|
5. Collect `RESEARCH_COMPLETE:` messages
|
|
201
249
|
6. Merge findings into a unified research report:
|
|
202
250
|
- Cross-reference findings between agents
|
|
@@ -223,7 +271,23 @@ Testing mode requires an increment (it needs to know WHAT to test).
|
|
|
223
271
|
- **Unit test agent**: read `agents/testing.md`, override scope to unit tests only
|
|
224
272
|
- **E2E test agent**: read `agents/testing.md`, override scope to E2E tests only
|
|
225
273
|
- Split scope via the agent prompt, not via separate templates
|
|
226
|
-
4. Spawn both in parallel
|
|
274
|
+
4. Spawn both in parallel — each call MUST include `team_name`:
|
|
275
|
+
```
|
|
276
|
+
Task({
|
|
277
|
+
team_name: "test-{id}",
|
|
278
|
+
name: "unit-test-agent",
|
|
279
|
+
subagent_type: "general-purpose",
|
|
280
|
+
mode: "bypassPermissions",
|
|
281
|
+
prompt: <replaced testing.md content with unit-test scope>
|
|
282
|
+
})
|
|
283
|
+
Task({
|
|
284
|
+
team_name: "test-{id}",
|
|
285
|
+
name: "e2e-test-agent",
|
|
286
|
+
subagent_type: "general-purpose",
|
|
287
|
+
mode: "bypassPermissions",
|
|
288
|
+
prompt: <replaced testing.md content with e2e scope>
|
|
289
|
+
})
|
|
290
|
+
```
|
|
227
291
|
5. Collect `COMPLETION:` messages
|
|
228
292
|
6. Run test suites to verify: `npx vitest run` + `npx playwright test`
|
|
229
293
|
7. Report results: pass/fail counts, coverage, uncovered ACs
|
|
@@ -116,7 +116,7 @@ if (!isVersionSatisfied(CURRENT_NODE_VERSION, MIN_NODE_VERSION)) {
|
|
|
116
116
|
console.error(getUpgradeInstructions());
|
|
117
117
|
console.error('');
|
|
118
118
|
console.error(`${BOLD}Full guide:${RESET}`);
|
|
119
|
-
console.error(` ${CYAN}${UNDERLINE}https://
|
|
119
|
+
console.error(` ${CYAN}${UNDERLINE}https://spec-weave.com/docs/guides/troubleshooting/common-errors#node-version-error${RESET}`);
|
|
120
120
|
console.error('');
|
|
121
121
|
console.error(`${DIM}After upgrading, run: npm install -g specweave${RESET}`);
|
|
122
122
|
console.error('');
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"description": "Auto-configured LSP servers for code intelligence (go-to-definition, find-references, hover)",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "SpecWeave",
|
|
7
|
-
"url": "https://
|
|
7
|
+
"url": "https://spec-weave.com"
|
|
8
8
|
},
|
|
9
9
|
"keywords": ["lsp", "typescript", "python", "code-intelligence"]
|
|
10
10
|
}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Consolidation Engine
|
|
3
|
-
*
|
|
4
|
-
* Scans nested repo `.specweave/` directories for orphaned increments
|
|
5
|
-
* and living docs, then consolidates them into the umbrella root.
|
|
6
|
-
*
|
|
7
|
-
* Used by `migrate-to-umbrella --consolidate` CLI command.
|
|
8
|
-
*
|
|
9
|
-
* @module core/migration/consolidation-engine
|
|
10
|
-
*/
|
|
11
|
-
/**
|
|
12
|
-
* A planned move operation
|
|
13
|
-
*/
|
|
14
|
-
export interface ConsolidationMove {
|
|
15
|
-
/** Source path (absolute) */
|
|
16
|
-
from: string;
|
|
17
|
-
/** Destination path (absolute) */
|
|
18
|
-
to: string;
|
|
19
|
-
/** Type of item being moved */
|
|
20
|
-
type: 'increment' | 'living-doc';
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* A planned deletion operation
|
|
24
|
-
*/
|
|
25
|
-
export interface ConsolidationDeletion {
|
|
26
|
-
/** Path to delete (absolute) */
|
|
27
|
-
path: string;
|
|
28
|
-
/** Reason for deletion */
|
|
29
|
-
reason: 'duplicate';
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* Plan produced by scanForOrphans(), consumed by executeConsolidation()
|
|
33
|
-
*/
|
|
34
|
-
export interface ConsolidationPlan {
|
|
35
|
-
moves: ConsolidationMove[];
|
|
36
|
-
deletions: ConsolidationDeletion[];
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Scan nested repos for orphaned increments and living docs.
|
|
40
|
-
*
|
|
41
|
-
* For each `repositories/{org}/{repo}/.specweave/increments/{id}/`:
|
|
42
|
-
* - If the same increment ID exists in umbrella root → schedule deletion (duplicate)
|
|
43
|
-
* - If not → schedule move to umbrella root
|
|
44
|
-
*
|
|
45
|
-
* For each `repositories/{org}/{repo}/.specweave/docs/{...}`:
|
|
46
|
-
* - Schedule move to umbrella root docs
|
|
47
|
-
*
|
|
48
|
-
* @param umbrellaRoot - Absolute path to umbrella root directory
|
|
49
|
-
* @returns ConsolidationPlan with moves and deletions
|
|
50
|
-
*/
|
|
51
|
-
export declare function scanForOrphans(umbrellaRoot: string): Promise<ConsolidationPlan>;
|
|
52
|
-
/**
|
|
53
|
-
* Execute a consolidation plan: move orphans and delete duplicates.
|
|
54
|
-
*
|
|
55
|
-
* @param plan - ConsolidationPlan from scanForOrphans()
|
|
56
|
-
* @param _umbrellaRoot - Umbrella root path (reserved for future use)
|
|
57
|
-
*/
|
|
58
|
-
export declare function executeConsolidation(plan: ConsolidationPlan, _umbrellaRoot: string): Promise<void>;
|
|
59
|
-
//# sourceMappingURL=consolidation-engine.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"consolidation-engine.d.ts","sourceRoot":"","sources":["../../../../src/core/migration/consolidation-engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,6BAA6B;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,kCAAkC;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,+BAA+B;IAC/B,IAAI,EAAE,WAAW,GAAG,YAAY,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,gCAAgC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,0BAA0B;IAC1B,MAAM,EAAE,WAAW,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,iBAAiB,EAAE,CAAC;IAC3B,SAAS,EAAE,qBAAqB,EAAE,CAAC;CACpC;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAkDrF;AAED;;;;;GAKG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,iBAAiB,EACvB,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC,CAwBf"}
|
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Consolidation Engine
|
|
3
|
-
*
|
|
4
|
-
* Scans nested repo `.specweave/` directories for orphaned increments
|
|
5
|
-
* and living docs, then consolidates them into the umbrella root.
|
|
6
|
-
*
|
|
7
|
-
* Used by `migrate-to-umbrella --consolidate` CLI command.
|
|
8
|
-
*
|
|
9
|
-
* @module core/migration/consolidation-engine
|
|
10
|
-
*/
|
|
11
|
-
import * as fs from 'fs';
|
|
12
|
-
import * as path from 'path';
|
|
13
|
-
/**
|
|
14
|
-
* Scan nested repos for orphaned increments and living docs.
|
|
15
|
-
*
|
|
16
|
-
* For each `repositories/{org}/{repo}/.specweave/increments/{id}/`:
|
|
17
|
-
* - If the same increment ID exists in umbrella root → schedule deletion (duplicate)
|
|
18
|
-
* - If not → schedule move to umbrella root
|
|
19
|
-
*
|
|
20
|
-
* For each `repositories/{org}/{repo}/.specweave/docs/{...}`:
|
|
21
|
-
* - Schedule move to umbrella root docs
|
|
22
|
-
*
|
|
23
|
-
* @param umbrellaRoot - Absolute path to umbrella root directory
|
|
24
|
-
* @returns ConsolidationPlan with moves and deletions
|
|
25
|
-
*/
|
|
26
|
-
export async function scanForOrphans(umbrellaRoot) {
|
|
27
|
-
const plan = { moves: [], deletions: [] };
|
|
28
|
-
const reposDir = path.join(umbrellaRoot, 'repositories');
|
|
29
|
-
if (!fs.existsSync(reposDir)) {
|
|
30
|
-
return plan;
|
|
31
|
-
}
|
|
32
|
-
// Collect all nested repo paths: repositories/{org}/{repo}
|
|
33
|
-
const nestedRepoPaths = collectNestedRepoPaths(reposDir);
|
|
34
|
-
// Get umbrella root increment IDs for duplicate detection
|
|
35
|
-
const umbrellaIncrementsDir = path.join(umbrellaRoot, '.specweave', 'increments');
|
|
36
|
-
const umbrellaIncrementIds = listDirectoryNames(umbrellaIncrementsDir);
|
|
37
|
-
for (const repoPath of nestedRepoPaths) {
|
|
38
|
-
// Scan increments
|
|
39
|
-
const nestedIncDir = path.join(repoPath, '.specweave', 'increments');
|
|
40
|
-
if (fs.existsSync(nestedIncDir)) {
|
|
41
|
-
const nestedIncrements = listDirectoryNames(nestedIncDir);
|
|
42
|
-
for (const incName of nestedIncrements) {
|
|
43
|
-
const nestedIncPath = path.join(nestedIncDir, incName);
|
|
44
|
-
const umbrellaIncPath = path.join(umbrellaIncrementsDir, incName);
|
|
45
|
-
if (umbrellaIncrementIds.has(incName)) {
|
|
46
|
-
// Duplicate — schedule deletion of nested copy
|
|
47
|
-
plan.deletions.push({
|
|
48
|
-
path: nestedIncPath,
|
|
49
|
-
reason: 'duplicate',
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
else {
|
|
53
|
-
// Orphan — schedule move
|
|
54
|
-
plan.moves.push({
|
|
55
|
-
from: nestedIncPath,
|
|
56
|
-
to: umbrellaIncPath,
|
|
57
|
-
type: 'increment',
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
// Scan docs
|
|
63
|
-
const nestedDocsDir = path.join(repoPath, '.specweave', 'docs');
|
|
64
|
-
if (fs.existsSync(nestedDocsDir)) {
|
|
65
|
-
const umbrellaDocsDir = path.join(umbrellaRoot, '.specweave', 'docs');
|
|
66
|
-
scanDocsRecursive(nestedDocsDir, umbrellaDocsDir, plan);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
return plan;
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Execute a consolidation plan: move orphans and delete duplicates.
|
|
73
|
-
*
|
|
74
|
-
* @param plan - ConsolidationPlan from scanForOrphans()
|
|
75
|
-
* @param _umbrellaRoot - Umbrella root path (reserved for future use)
|
|
76
|
-
*/
|
|
77
|
-
export async function executeConsolidation(plan, _umbrellaRoot) {
|
|
78
|
-
// Execute moves
|
|
79
|
-
for (const move of plan.moves) {
|
|
80
|
-
// Ensure parent directory exists
|
|
81
|
-
const parentDir = path.dirname(move.to);
|
|
82
|
-
await fs.promises.mkdir(parentDir, { recursive: true });
|
|
83
|
-
// Move via rename; fall back to copy+delete if across filesystems (EXDEV)
|
|
84
|
-
try {
|
|
85
|
-
await fs.promises.rename(move.from, move.to);
|
|
86
|
-
}
|
|
87
|
-
catch (e) {
|
|
88
|
-
if (e.code === 'EXDEV') {
|
|
89
|
-
await fs.promises.cp(move.from, move.to, { recursive: true });
|
|
90
|
-
await fs.promises.rm(move.from, { recursive: true, force: true });
|
|
91
|
-
}
|
|
92
|
-
else {
|
|
93
|
-
throw e;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
// Execute deletions
|
|
98
|
-
for (const deletion of plan.deletions) {
|
|
99
|
-
await fs.promises.rm(deletion.path, { recursive: true, force: true });
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
// ---------------------------------------------------------------------------
|
|
103
|
-
// Internal helpers
|
|
104
|
-
// ---------------------------------------------------------------------------
|
|
105
|
-
/**
|
|
106
|
-
* Collect all nested repo paths under repositories/{org}/{repo}
|
|
107
|
-
*/
|
|
108
|
-
function collectNestedRepoPaths(reposDir) {
|
|
109
|
-
const repoPaths = [];
|
|
110
|
-
try {
|
|
111
|
-
const orgEntries = fs.readdirSync(reposDir, { withFileTypes: true });
|
|
112
|
-
for (const orgEntry of orgEntries) {
|
|
113
|
-
if (!orgEntry.isDirectory())
|
|
114
|
-
continue;
|
|
115
|
-
const orgDir = path.join(reposDir, orgEntry.name);
|
|
116
|
-
const repoEntries = fs.readdirSync(orgDir, { withFileTypes: true });
|
|
117
|
-
for (const repoEntry of repoEntries) {
|
|
118
|
-
if (!repoEntry.isDirectory())
|
|
119
|
-
continue;
|
|
120
|
-
repoPaths.push(path.join(orgDir, repoEntry.name));
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
catch {
|
|
125
|
-
// Ignore read errors
|
|
126
|
-
}
|
|
127
|
-
return repoPaths;
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* List directory names (non-recursive) as a Set
|
|
131
|
-
*/
|
|
132
|
-
function listDirectoryNames(dirPath) {
|
|
133
|
-
const names = new Set();
|
|
134
|
-
if (!fs.existsSync(dirPath))
|
|
135
|
-
return names;
|
|
136
|
-
try {
|
|
137
|
-
const entries = fs.readdirSync(dirPath, { withFileTypes: true });
|
|
138
|
-
for (const entry of entries) {
|
|
139
|
-
if (entry.isDirectory()) {
|
|
140
|
-
names.add(entry.name);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
catch {
|
|
145
|
-
// Ignore read errors
|
|
146
|
-
}
|
|
147
|
-
return names;
|
|
148
|
-
}
|
|
149
|
-
/**
|
|
150
|
-
* Recursively scan a nested docs directory for leaf directories to move.
|
|
151
|
-
* Finds the deepest directories containing files and schedules moves.
|
|
152
|
-
*/
|
|
153
|
-
function scanDocsRecursive(nestedDocsDir, umbrellaDocsDir, plan) {
|
|
154
|
-
try {
|
|
155
|
-
const entries = fs.readdirSync(nestedDocsDir, { withFileTypes: true });
|
|
156
|
-
const hasFiles = entries.some(e => e.isFile());
|
|
157
|
-
const subdirs = entries.filter(e => e.isDirectory());
|
|
158
|
-
if (hasFiles) {
|
|
159
|
-
// This directory has files — schedule move
|
|
160
|
-
// umbrellaDocsDir already has the correct target path via recursion
|
|
161
|
-
plan.moves.push({
|
|
162
|
-
from: nestedDocsDir,
|
|
163
|
-
to: umbrellaDocsDir,
|
|
164
|
-
type: 'living-doc',
|
|
165
|
-
});
|
|
166
|
-
return; // Don't recurse further — moving the whole directory
|
|
167
|
-
}
|
|
168
|
-
// Recurse into subdirectories
|
|
169
|
-
for (const subdir of subdirs) {
|
|
170
|
-
scanDocsRecursive(path.join(nestedDocsDir, subdir.name), path.join(umbrellaDocsDir, subdir.name), plan);
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
catch {
|
|
174
|
-
// Ignore read errors
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
//# sourceMappingURL=consolidation-engine.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"consolidation-engine.js","sourceRoot":"","sources":["../../../../src/core/migration/consolidation-engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Spec Project Mapper
|
|
3
|
-
*
|
|
4
|
-
* Maps FS-XXX feature spec folders to their owning project(s) by scanning
|
|
5
|
-
* increment metadata and spec.md **Project**: fields. Used by the
|
|
6
|
-
* --reorganize-specs flag of migrate-to-umbrella.
|
|
7
|
-
*
|
|
8
|
-
* @module core/migration/spec-project-mapper
|
|
9
|
-
*/
|
|
10
|
-
export interface ReorgOperation {
|
|
11
|
-
featureId: string;
|
|
12
|
-
source: string;
|
|
13
|
-
destination: string;
|
|
14
|
-
type: 'move' | 'copy';
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Builds a map of FS-XXX feature IDs to their owning project(s).
|
|
18
|
-
*
|
|
19
|
-
* Strategy:
|
|
20
|
-
* 1. Scan all increments for feature_id in metadata.json (explicit link)
|
|
21
|
-
* 2. Fall back to numeric matching: FS-282 → glob 0282-*
|
|
22
|
-
* 3. Parse increment spec.md for **Project**: lines
|
|
23
|
-
* 4. Default to current project folder name when no Project field found
|
|
24
|
-
*
|
|
25
|
-
* @param projectRoot - Root of the umbrella workspace
|
|
26
|
-
* @returns Map of featureId (e.g. "FS-282") to project IDs (e.g. ["vskill-platform"])
|
|
27
|
-
*/
|
|
28
|
-
export declare function buildFeatureProjectMap(projectRoot: string): Promise<Map<string, string[]>>;
|
|
29
|
-
/**
|
|
30
|
-
* Generates a list of move/copy operations to reorganize FS-XXX folders
|
|
31
|
-
* from a centralized project directory to per-project directories.
|
|
32
|
-
*
|
|
33
|
-
* @param featureMap - Map from buildFeatureProjectMap()
|
|
34
|
-
* @param specsDir - Path to .specweave/docs/internal/specs/
|
|
35
|
-
* @param currentProject - Name of the current (centralized) project folder
|
|
36
|
-
* @returns List of move/copy operations
|
|
37
|
-
*/
|
|
38
|
-
export declare function generateReorganizationPlan(featureMap: Map<string, string[]>, specsDir: string, currentProject: string): Promise<ReorgOperation[]>;
|
|
39
|
-
export interface ReorganizeOptions {
|
|
40
|
-
execute: boolean;
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Executes a reorganization plan: moves/copies FS-XXX folders to per-project
|
|
44
|
-
* directories and enables multiProject mode in config.json.
|
|
45
|
-
*
|
|
46
|
-
* @param plan - List of move/copy operations from generateReorganizationPlan()
|
|
47
|
-
* @param configPath - Path to .specweave/config.json
|
|
48
|
-
* @param options - { execute: true } to apply changes, false for dry-run
|
|
49
|
-
*/
|
|
50
|
-
export declare function reorganizeSpecs(plan: ReorgOperation[], configPath: string, options: ReorganizeOptions): Promise<void>;
|
|
51
|
-
//# sourceMappingURL=spec-project-mapper.d.ts.map
|