specweave 0.17.16 → 0.18.0
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.md +405 -2495
- package/README.md +92 -2
- package/dist/plugins/specweave/lib/hooks/sync-living-docs.d.ts.map +1 -1
- package/dist/plugins/specweave/lib/hooks/sync-living-docs.js +188 -36
- package/dist/plugins/specweave/lib/hooks/sync-living-docs.js.map +1 -1
- package/dist/plugins/specweave-ado/lib/ado-status-sync.d.ts +54 -0
- package/dist/plugins/specweave-ado/lib/ado-status-sync.d.ts.map +1 -0
- package/dist/plugins/specweave-ado/lib/ado-status-sync.js +86 -0
- package/dist/plugins/specweave-ado/lib/ado-status-sync.js.map +1 -0
- package/dist/plugins/specweave-github/lib/duplicate-detector.d.ts +139 -0
- package/dist/plugins/specweave-github/lib/duplicate-detector.d.ts.map +1 -0
- package/dist/plugins/specweave-github/lib/duplicate-detector.js +389 -0
- package/dist/plugins/specweave-github/lib/duplicate-detector.js.map +1 -0
- package/dist/plugins/specweave-github/lib/enhanced-github-sync.d.ts +26 -0
- package/dist/plugins/specweave-github/lib/enhanced-github-sync.d.ts.map +1 -0
- package/dist/plugins/specweave-github/lib/enhanced-github-sync.js +249 -0
- package/dist/plugins/specweave-github/lib/enhanced-github-sync.js.map +1 -0
- package/dist/plugins/specweave-github/lib/github-client.d.ts +1 -1
- package/dist/plugins/specweave-github/lib/github-client.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/github-client.js +25 -13
- package/dist/plugins/specweave-github/lib/github-client.js.map +1 -1
- package/dist/plugins/specweave-github/lib/github-epic-sync.d.ts +83 -0
- package/dist/plugins/specweave-github/lib/github-epic-sync.d.ts.map +1 -0
- package/dist/plugins/specweave-github/lib/github-epic-sync.js +451 -0
- package/dist/plugins/specweave-github/lib/github-epic-sync.js.map +1 -0
- package/dist/plugins/specweave-github/lib/github-status-sync.d.ts +43 -0
- package/dist/plugins/specweave-github/lib/github-status-sync.d.ts.map +1 -0
- package/dist/plugins/specweave-github/lib/github-status-sync.js +82 -0
- package/dist/plugins/specweave-github/lib/github-status-sync.js.map +1 -0
- package/dist/plugins/specweave-github/lib/task-sync.d.ts +5 -0
- package/dist/plugins/specweave-github/lib/task-sync.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/task-sync.js +38 -2
- package/dist/plugins/specweave-github/lib/task-sync.js.map +1 -1
- package/dist/plugins/specweave-jira/lib/jira-epic-sync.d.ts +66 -0
- package/dist/plugins/specweave-jira/lib/jira-epic-sync.d.ts.map +1 -0
- package/dist/plugins/specweave-jira/lib/jira-epic-sync.js +274 -0
- package/dist/plugins/specweave-jira/lib/jira-epic-sync.js.map +1 -0
- package/dist/plugins/specweave-jira/lib/jira-status-sync.d.ts +56 -0
- package/dist/plugins/specweave-jira/lib/jira-status-sync.d.ts.map +1 -0
- package/dist/plugins/specweave-jira/lib/jira-status-sync.js +93 -0
- package/dist/plugins/specweave-jira/lib/jira-status-sync.js.map +1 -0
- package/dist/src/cli/helpers/issue-tracker/index.d.ts.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/index.js +48 -3
- package/dist/src/cli/helpers/issue-tracker/index.js.map +1 -1
- package/dist/src/core/living-docs/hierarchy-mapper.d.ts +142 -0
- package/dist/src/core/living-docs/hierarchy-mapper.d.ts.map +1 -0
- package/dist/src/core/living-docs/hierarchy-mapper.js +453 -0
- package/dist/src/core/living-docs/hierarchy-mapper.js.map +1 -0
- package/dist/src/core/living-docs/index.d.ts +10 -84
- package/dist/src/core/living-docs/index.d.ts.map +1 -1
- package/dist/src/core/living-docs/index.js +10 -164
- package/dist/src/core/living-docs/index.js.map +1 -1
- package/dist/src/core/living-docs/spec-distributor.d.ts +106 -0
- package/dist/src/core/living-docs/spec-distributor.d.ts.map +1 -0
- package/dist/src/core/living-docs/spec-distributor.js +823 -0
- package/dist/src/core/living-docs/spec-distributor.js.map +1 -0
- package/dist/src/core/living-docs/types.d.ts +201 -0
- package/dist/src/core/living-docs/types.d.ts.map +1 -0
- package/dist/src/core/living-docs/types.js +15 -0
- package/dist/src/core/living-docs/types.js.map +1 -0
- package/dist/src/core/logging/prompt-logger.d.ts +70 -0
- package/dist/src/core/logging/prompt-logger.d.ts.map +1 -0
- package/dist/src/core/logging/prompt-logger.js +247 -0
- package/dist/src/core/logging/prompt-logger.js.map +1 -0
- package/dist/src/core/status-line/status-line-manager.d.ts +15 -24
- package/dist/src/core/status-line/status-line-manager.d.ts.map +1 -1
- package/dist/src/core/status-line/status-line-manager.js +33 -70
- package/dist/src/core/status-line/status-line-manager.js.map +1 -1
- package/dist/src/core/status-line/types.d.ts +19 -31
- package/dist/src/core/status-line/types.d.ts.map +1 -1
- package/dist/src/core/status-line/types.js +5 -9
- package/dist/src/core/status-line/types.js.map +1 -1
- package/dist/src/core/sync/conflict-resolver.d.ts +66 -0
- package/dist/src/core/sync/conflict-resolver.d.ts.map +1 -0
- package/dist/src/core/sync/conflict-resolver.js +108 -0
- package/dist/src/core/sync/conflict-resolver.js.map +1 -0
- package/dist/src/core/sync/enhanced-content-builder.d.ts +77 -0
- package/dist/src/core/sync/enhanced-content-builder.d.ts.map +1 -0
- package/dist/src/core/sync/enhanced-content-builder.js +199 -0
- package/dist/src/core/sync/enhanced-content-builder.js.map +1 -0
- package/dist/src/core/sync/label-detector.d.ts +66 -0
- package/dist/src/core/sync/label-detector.d.ts.map +1 -0
- package/dist/src/core/sync/label-detector.js +211 -0
- package/dist/src/core/sync/label-detector.js.map +1 -0
- package/dist/src/core/sync/retry-logic.d.ts +64 -0
- package/dist/src/core/sync/retry-logic.d.ts.map +1 -0
- package/dist/src/core/sync/retry-logic.js +165 -0
- package/dist/src/core/sync/retry-logic.js.map +1 -0
- package/dist/src/core/sync/spec-increment-mapper.d.ts +100 -0
- package/dist/src/core/sync/spec-increment-mapper.d.ts.map +1 -0
- package/dist/src/core/sync/spec-increment-mapper.js +424 -0
- package/dist/src/core/sync/spec-increment-mapper.js.map +1 -0
- package/dist/src/core/sync/status-cache.d.ts +91 -0
- package/dist/src/core/sync/status-cache.d.ts.map +1 -0
- package/dist/src/core/sync/status-cache.js +140 -0
- package/dist/src/core/sync/status-cache.js.map +1 -0
- package/dist/src/core/sync/status-mapper.d.ts +69 -0
- package/dist/src/core/sync/status-mapper.d.ts.map +1 -0
- package/dist/src/core/sync/status-mapper.js +90 -0
- package/dist/src/core/sync/status-mapper.js.map +1 -0
- package/dist/src/core/sync/status-sync-engine.d.ts +162 -0
- package/dist/src/core/sync/status-sync-engine.d.ts.map +1 -0
- package/dist/src/core/sync/status-sync-engine.js +347 -0
- package/dist/src/core/sync/status-sync-engine.js.map +1 -0
- package/dist/src/core/sync/sync-event-logger.d.ts +99 -0
- package/dist/src/core/sync/sync-event-logger.d.ts.map +1 -0
- package/dist/src/core/sync/sync-event-logger.js +103 -0
- package/dist/src/core/sync/sync-event-logger.js.map +1 -0
- package/dist/src/core/sync/workflow-detector.d.ts +95 -0
- package/dist/src/core/sync/workflow-detector.d.ts.map +1 -0
- package/dist/src/core/sync/workflow-detector.js +175 -0
- package/dist/src/core/sync/workflow-detector.js.map +1 -0
- package/dist/src/core/types/config.d.ts.map +1 -1
- package/dist/src/core/types/config.js +31 -0
- package/dist/src/core/types/config.js.map +1 -1
- package/dist/src/utils/github-url.d.ts +53 -0
- package/dist/src/utils/github-url.d.ts.map +1 -0
- package/dist/src/utils/github-url.js +90 -0
- package/dist/src/utils/github-url.js.map +1 -0
- package/dist/src/utils/spec-parser.d.ts +145 -0
- package/dist/src/utils/spec-parser.d.ts.map +1 -0
- package/dist/src/utils/spec-parser.js +640 -0
- package/dist/src/utils/spec-parser.js.map +1 -0
- package/package.json +1 -1
- package/plugins/specweave/agents/pm/AGENT.md +1 -1
- package/plugins/specweave/agents/pm/templates/increment-spec.md +158 -0
- package/plugins/specweave/agents/pm/templates/living-docs-spec.md +113 -0
- package/plugins/specweave/commands/specweave-done.md +163 -0
- package/plugins/specweave/hooks/lib/update-status-line.sh +79 -111
- package/plugins/specweave/hooks/post-increment-planning.sh +107 -35
- package/plugins/specweave/lib/hooks/sync-living-docs.js +139 -34
- package/plugins/specweave/lib/hooks/sync-living-docs.ts +234 -38
- package/plugins/specweave/skills/SKILLS-INDEX.md +4 -24
- package/plugins/specweave/skills/increment-planner/SKILL.md +94 -0
- package/plugins/specweave/skills/increment-work-router/SKILL.md +466 -0
- package/plugins/specweave-ado/lib/ado-status-sync.js +80 -0
- package/plugins/specweave-ado/lib/ado-status-sync.ts +121 -0
- package/plugins/specweave-github/commands/specweave-github-cleanup-duplicates.md +205 -0
- package/plugins/specweave-github/commands/specweave-github-sync-epic.md +248 -0
- package/plugins/specweave-github/lib/duplicate-detector.js +370 -0
- package/plugins/specweave-github/lib/duplicate-detector.ts +525 -0
- package/plugins/specweave-github/lib/enhanced-github-sync.js +220 -0
- package/plugins/specweave-github/lib/enhanced-github-sync.ts +322 -0
- package/plugins/specweave-github/lib/github-client.js +21 -10
- package/plugins/specweave-github/lib/github-client.ts +27 -16
- package/plugins/specweave-github/lib/github-epic-sync.js +489 -0
- package/plugins/specweave-github/lib/github-epic-sync.ts +690 -0
- package/plugins/specweave-github/lib/github-status-sync.js +71 -0
- package/plugins/specweave-github/lib/github-status-sync.ts +107 -0
- package/plugins/specweave-github/lib/task-sync.js +33 -2
- package/plugins/specweave-github/lib/task-sync.ts +44 -2
- package/plugins/specweave-jira/commands/specweave-jira-sync-epic.md +267 -0
- package/plugins/specweave-jira/lib/enhanced-jira-sync.ts.disabled +222 -0
- package/plugins/specweave-jira/lib/jira-epic-sync.js +304 -0
- package/plugins/specweave-jira/lib/jira-epic-sync.ts +459 -0
- package/plugins/specweave-jira/lib/jira-status-sync.js +79 -0
- package/plugins/specweave-jira/lib/jira-status-sync.ts +139 -0
- package/src/templates/AGENTS.md.template +88 -1
- package/src/templates/CLAUDE.md.template +49 -0
- package/plugins/specweave/skills/increment-quality-judge/SKILL.md +0 -524
- package/plugins/specweave/skills/plugin-installer/SKILL.md +0 -353
|
@@ -87,10 +87,11 @@ async function syncLivingDocs(incrementId: string): Promise<void> {
|
|
|
87
87
|
specCopied = result.success;
|
|
88
88
|
changedDocs = result.changedFiles;
|
|
89
89
|
} else {
|
|
90
|
-
//
|
|
91
|
-
console.log('
|
|
92
|
-
|
|
93
|
-
|
|
90
|
+
// Hierarchical distribution mode: Epic + User Stories (v2.1)
|
|
91
|
+
console.log('📊 Using hierarchical distribution mode (v2.1 - Epic + User Stories)');
|
|
92
|
+
const result = await hierarchicalDistribution(incrementId);
|
|
93
|
+
specCopied = result.success;
|
|
94
|
+
changedDocs = result.changedFiles;
|
|
94
95
|
}
|
|
95
96
|
|
|
96
97
|
if (changedDocs.length === 0 && !specCopied) {
|
|
@@ -113,58 +114,81 @@ async function syncLivingDocs(incrementId: string): Promise<void> {
|
|
|
113
114
|
|
|
114
115
|
/**
|
|
115
116
|
* Intelligent sync using the new architecture (v0.18.0+)
|
|
117
|
+
*
|
|
118
|
+
* NOTE: syncIncrement not yet implemented, fallback to hierarchical distribution
|
|
116
119
|
*/
|
|
117
120
|
async function intelligentSyncLivingDocs(
|
|
118
121
|
incrementId: string,
|
|
119
122
|
config: Config
|
|
123
|
+
): Promise<{ success: boolean; changedFiles: string[] }> {
|
|
124
|
+
console.log(' ⚠️ Intelligent sync not yet fully implemented');
|
|
125
|
+
console.log(' Falling back to hierarchical distribution mode...');
|
|
126
|
+
|
|
127
|
+
// Fallback to hierarchical distribution
|
|
128
|
+
return await hierarchicalDistribution(incrementId);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Hierarchical distribution using new architecture (v2.1 - Epic + User Stories)
|
|
133
|
+
*
|
|
134
|
+
* Distributes increment spec into hierarchical structure:
|
|
135
|
+
* - Epic file (SPEC-###.md) - High-level summary (50-80 lines)
|
|
136
|
+
* - User story files (us-###.md) - Detailed requirements (80-120 lines each)
|
|
137
|
+
* - Links to tasks.md for implementation details
|
|
138
|
+
*/
|
|
139
|
+
async function hierarchicalDistribution(
|
|
140
|
+
incrementId: string
|
|
120
141
|
): Promise<{ success: boolean; changedFiles: string[] }> {
|
|
121
142
|
try {
|
|
122
143
|
// Dynamic import to avoid circular dependencies
|
|
123
|
-
const {
|
|
124
|
-
|
|
125
|
-
console.log('
|
|
126
|
-
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
preserveCodeBlocks: true,
|
|
132
|
-
preserveLinks: true,
|
|
133
|
-
preserveImages: true,
|
|
134
|
-
},
|
|
135
|
-
distributor: {
|
|
136
|
-
generateFrontmatter: true,
|
|
137
|
-
preserveOriginal: config.livingDocs?.intelligent?.preserveOriginal ?? true,
|
|
138
|
-
},
|
|
139
|
-
linker: {
|
|
140
|
-
generateBacklinks: config.livingDocs?.intelligent?.generateCrossLinks ?? true,
|
|
141
|
-
updateExisting: true,
|
|
142
|
-
},
|
|
144
|
+
const { SpecDistributor } = await import('../../../../src/core/living-docs/index.js');
|
|
145
|
+
|
|
146
|
+
console.log(' 📊 Parsing and distributing spec into hierarchical structure...');
|
|
147
|
+
|
|
148
|
+
const projectRoot = process.cwd();
|
|
149
|
+
const distributor = new SpecDistributor(projectRoot, {
|
|
150
|
+
overwriteExisting: false,
|
|
151
|
+
createBackups: true,
|
|
143
152
|
});
|
|
144
153
|
|
|
154
|
+
const result = await distributor.distribute(incrementId);
|
|
155
|
+
|
|
156
|
+
if (!result.success) {
|
|
157
|
+
console.error(` ❌ Distribution failed with errors:`);
|
|
158
|
+
for (const error of result.errors) {
|
|
159
|
+
console.error(` - ${error}`);
|
|
160
|
+
}
|
|
161
|
+
return { success: false, changedFiles: [] };
|
|
162
|
+
}
|
|
163
|
+
|
|
145
164
|
// Log summary
|
|
146
|
-
console.log(` ✅
|
|
147
|
-
console.log(`
|
|
148
|
-
console.log(`
|
|
149
|
-
console.log(` Files
|
|
150
|
-
console.log(`
|
|
151
|
-
console.log(`
|
|
165
|
+
console.log(` ✅ Hierarchical distribution complete:`);
|
|
166
|
+
console.log(` Epic ID: ${result.specId}`);
|
|
167
|
+
console.log(` User Stories: ${result.totalStories}`);
|
|
168
|
+
console.log(` Files created: ${result.totalFiles}`);
|
|
169
|
+
console.log(` Epic: ${path.basename(result.epicPath)}`);
|
|
170
|
+
console.log(` User story files: ${result.userStoryPaths.length}`);
|
|
171
|
+
|
|
172
|
+
if (result.warnings.length > 0) {
|
|
173
|
+
console.log(` ⚠️ Warnings:`);
|
|
174
|
+
for (const warning of result.warnings) {
|
|
175
|
+
console.log(` - ${warning}`);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
152
178
|
|
|
153
179
|
// Collect changed file paths
|
|
154
|
-
const changedFiles = [
|
|
155
|
-
...result.distribution.created.map((f) => f.path),
|
|
156
|
-
...result.distribution.updated.map((f) => f.path),
|
|
157
|
-
];
|
|
180
|
+
const changedFiles = [result.epicPath, ...result.userStoryPaths];
|
|
158
181
|
|
|
159
182
|
return {
|
|
160
|
-
success:
|
|
183
|
+
success: true,
|
|
161
184
|
changedFiles,
|
|
162
185
|
};
|
|
163
186
|
} catch (error) {
|
|
164
|
-
console.error(` ❌
|
|
165
|
-
console.error(
|
|
187
|
+
console.error(` ❌ Hierarchical distribution failed: ${error}`);
|
|
188
|
+
console.error((error as Error).stack);
|
|
166
189
|
|
|
167
190
|
// Fallback to simple mode
|
|
191
|
+
console.error(' Falling back to simple sync mode...');
|
|
168
192
|
const copied = await copyIncrementSpecToLivingDocs(incrementId);
|
|
169
193
|
return {
|
|
170
194
|
success: copied,
|
|
@@ -174,10 +198,182 @@ async function intelligentSyncLivingDocs(
|
|
|
174
198
|
}
|
|
175
199
|
|
|
176
200
|
/**
|
|
177
|
-
*
|
|
201
|
+
* Extract and merge living docs (v2.0 - NO DUPLICATION!)
|
|
202
|
+
*
|
|
203
|
+
* NEW ARCHITECTURE:
|
|
204
|
+
* - Living docs = Permanent EPIC (GitHub Project, Jira Epic, ADO Feature)
|
|
205
|
+
* - Increment spec = Temporary ITERATION (GitHub Issue, Jira Story, ADO User Story)
|
|
206
|
+
*
|
|
207
|
+
* What this does:
|
|
208
|
+
* 1. Parse increment spec (extract user stories ONLY)
|
|
209
|
+
* 2. Check if living docs spec exists
|
|
210
|
+
* 3. If exists: Merge new user stories (avoid duplicates)
|
|
211
|
+
* 4. If not: Create new living docs spec
|
|
212
|
+
* 5. Generate links to architecture/ADRs (NO duplication!)
|
|
213
|
+
* 6. Update implementation history
|
|
214
|
+
*
|
|
215
|
+
* What this DOESN'T do:
|
|
216
|
+
* - ❌ Copy architecture details (those live in architecture/)
|
|
217
|
+
* - ❌ Copy ADR content (those live in architecture/adr/)
|
|
218
|
+
* - ❌ Copy success metrics (those live in increment reports)
|
|
219
|
+
* - ❌ Copy future enhancements (those live in roadmap)
|
|
220
|
+
*
|
|
221
|
+
* Returns true if living docs updated, false if skipped
|
|
222
|
+
*/
|
|
223
|
+
async function extractAndMergeLivingDocs(incrementId: string): Promise<boolean> {
|
|
224
|
+
try {
|
|
225
|
+
// Import parser utilities
|
|
226
|
+
const {
|
|
227
|
+
parseIncrementSpec,
|
|
228
|
+
parseLivingDocsSpec,
|
|
229
|
+
extractSpecId,
|
|
230
|
+
mergeUserStories,
|
|
231
|
+
generateRelatedDocsLinks,
|
|
232
|
+
writeLivingDocsSpec,
|
|
233
|
+
} = await import('../../../../src/utils/spec-parser.js');
|
|
234
|
+
|
|
235
|
+
const projectRoot = process.cwd();
|
|
236
|
+
const incrementSpecPath = path.join(projectRoot, '.specweave', 'increments', incrementId, 'spec.md');
|
|
237
|
+
|
|
238
|
+
// Check if increment spec exists
|
|
239
|
+
if (!fs.existsSync(incrementSpecPath)) {
|
|
240
|
+
console.log(`⚠️ Increment spec not found: ${incrementSpecPath}`);
|
|
241
|
+
return false;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
console.log(` 📖 Parsing increment spec: ${incrementId}`);
|
|
245
|
+
|
|
246
|
+
// 1. Parse increment spec (extract user stories)
|
|
247
|
+
const incrementSpec = await parseIncrementSpec(incrementSpecPath);
|
|
248
|
+
|
|
249
|
+
if (incrementSpec.userStories.length === 0) {
|
|
250
|
+
console.log(`ℹ️ No user stories found in increment spec, skipping sync`);
|
|
251
|
+
return false;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
console.log(` ✅ Found ${incrementSpec.userStories.length} user stories in increment`);
|
|
255
|
+
|
|
256
|
+
// 2. Determine living docs spec ID
|
|
257
|
+
const specId = incrementSpec.implementsSpec || extractSpecId(incrementId);
|
|
258
|
+
const livingDocsDir = path.join(projectRoot, '.specweave', 'docs', 'internal', 'specs', 'default');
|
|
259
|
+
const livingDocsPath = path.join(livingDocsDir, `${specId}-${incrementId.replace(/^\d+-/, '')}.md`);
|
|
260
|
+
|
|
261
|
+
// 3. Check if living docs spec exists
|
|
262
|
+
const livingDocsExists = fs.existsSync(livingDocsPath);
|
|
263
|
+
|
|
264
|
+
if (livingDocsExists) {
|
|
265
|
+
console.log(` 📚 Living docs spec exists, merging user stories...`);
|
|
266
|
+
|
|
267
|
+
// MERGE MODE: Add new user stories to existing spec
|
|
268
|
+
const livingSpec = await parseLivingDocsSpec(livingDocsPath);
|
|
269
|
+
|
|
270
|
+
// Merge user stories (adds new, updates existing)
|
|
271
|
+
const mergedStories = mergeUserStories(
|
|
272
|
+
livingSpec.userStories,
|
|
273
|
+
incrementSpec.userStories,
|
|
274
|
+
incrementId
|
|
275
|
+
);
|
|
276
|
+
|
|
277
|
+
const newStoriesCount = mergedStories.length - livingSpec.userStories.length;
|
|
278
|
+
|
|
279
|
+
// Update implementation history
|
|
280
|
+
const existingEntry = livingSpec.implementationHistory.find(e => e.increment === incrementId);
|
|
281
|
+
|
|
282
|
+
if (!existingEntry) {
|
|
283
|
+
livingSpec.implementationHistory.push({
|
|
284
|
+
increment: incrementId,
|
|
285
|
+
stories: incrementSpec.userStories.map(s => s.id),
|
|
286
|
+
status: 'complete',
|
|
287
|
+
date: new Date().toISOString().split('T')[0],
|
|
288
|
+
});
|
|
289
|
+
} else {
|
|
290
|
+
// Update existing entry
|
|
291
|
+
existingEntry.status = 'complete';
|
|
292
|
+
existingEntry.date = new Date().toISOString().split('T')[0];
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// Update user stories
|
|
296
|
+
livingSpec.userStories = mergedStories;
|
|
297
|
+
|
|
298
|
+
// Update last_updated
|
|
299
|
+
livingSpec.lastUpdated = new Date().toISOString().split('T')[0];
|
|
300
|
+
|
|
301
|
+
// Write updated spec
|
|
302
|
+
await writeLivingDocsSpec(livingDocsPath, livingSpec);
|
|
303
|
+
|
|
304
|
+
console.log(` ✅ Merged ${newStoriesCount} new user stories into living docs`);
|
|
305
|
+
console.log(` ✅ Updated implementation history for ${incrementId}`);
|
|
306
|
+
|
|
307
|
+
} else {
|
|
308
|
+
console.log(` 📝 Creating new living docs spec: ${specId}`);
|
|
309
|
+
|
|
310
|
+
// CREATE MODE: First increment for this spec
|
|
311
|
+
const relatedDocs = generateRelatedDocsLinks(incrementSpec, projectRoot);
|
|
312
|
+
|
|
313
|
+
const livingSpec = {
|
|
314
|
+
id: specId,
|
|
315
|
+
title: incrementSpec.title,
|
|
316
|
+
featureArea: extractFeatureArea(incrementSpec.title),
|
|
317
|
+
overview: incrementSpec.overview,
|
|
318
|
+
userStories: incrementSpec.userStories.map(story => ({
|
|
319
|
+
...story,
|
|
320
|
+
implementedIn: incrementId,
|
|
321
|
+
status: 'complete' as const,
|
|
322
|
+
})),
|
|
323
|
+
implementationHistory: [
|
|
324
|
+
{
|
|
325
|
+
increment: incrementId,
|
|
326
|
+
stories: incrementSpec.userStories.map(s => s.id),
|
|
327
|
+
status: 'complete' as const,
|
|
328
|
+
date: new Date().toISOString().split('T')[0],
|
|
329
|
+
},
|
|
330
|
+
],
|
|
331
|
+
relatedDocs,
|
|
332
|
+
externalLinks: {} as { github?: string; jira?: string; ado?: string },
|
|
333
|
+
priority: incrementSpec.priority,
|
|
334
|
+
status: 'active',
|
|
335
|
+
created: new Date().toISOString().split('T')[0],
|
|
336
|
+
lastUpdated: new Date().toISOString().split('T')[0],
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
// Ensure directory exists
|
|
340
|
+
await fs.ensureDir(livingDocsDir);
|
|
341
|
+
|
|
342
|
+
// Write new spec
|
|
343
|
+
await writeLivingDocsSpec(livingDocsPath, livingSpec);
|
|
344
|
+
|
|
345
|
+
console.log(` ✅ Created new living docs spec: ${specId}`);
|
|
346
|
+
console.log(` ✅ Added ${incrementSpec.userStories.length} user stories`);
|
|
347
|
+
console.log(` ✅ Generated links to ${relatedDocs.architecture.length} architecture docs`);
|
|
348
|
+
console.log(` ✅ Generated links to ${relatedDocs.adrs.length} ADRs`);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
return true;
|
|
352
|
+
|
|
353
|
+
} catch (error) {
|
|
354
|
+
console.error(`❌ Error extracting/merging living docs: ${error}`);
|
|
355
|
+
console.error((error as Error).stack);
|
|
356
|
+
return false;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* Extract feature area from title
|
|
362
|
+
*/
|
|
363
|
+
function extractFeatureArea(title: string): string {
|
|
364
|
+
// Simple heuristic: Use title as feature area
|
|
365
|
+
// Can be customized later based on keywords
|
|
366
|
+
return title.replace(/^(Increment \d+:\s*)?/, '').trim();
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* Copy increment spec to living docs (DEPRECATED - use extractAndMergeLivingDocs instead)
|
|
178
371
|
* Returns true if spec was copied, false if skipped
|
|
179
372
|
*/
|
|
180
373
|
async function copyIncrementSpecToLivingDocs(incrementId: string): Promise<boolean> {
|
|
374
|
+
console.warn('⚠️ Using deprecated copyIncrementSpecToLivingDocs (simple mode)');
|
|
375
|
+
console.warn(' Consider enabling intelligent mode to avoid duplication');
|
|
376
|
+
|
|
181
377
|
try {
|
|
182
378
|
const incrementSpecPath = path.join(process.cwd(), '.specweave', 'increments', incrementId, 'spec.md');
|
|
183
379
|
const livingDocsPath = path.join(process.cwd(), '.specweave', 'docs', 'internal', 'specs', `spec-${incrementId}.md`);
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
**Purpose**: Quick reference for all available skills. Read this file BEFORE starting any task.
|
|
4
4
|
|
|
5
|
-
**Last Updated**: 2025-11-
|
|
5
|
+
**Last Updated**: 2025-11-13 (removed deprecated skills: plugin-installer, increment-quality-judge v1)
|
|
6
6
|
|
|
7
|
-
**Total Skills**:
|
|
7
|
+
**Total Skills**: 18
|
|
8
8
|
|
|
9
9
|
---
|
|
10
10
|
|
|
@@ -37,16 +37,6 @@ Step 4: Execute → Follow the increment planning workflow
|
|
|
37
37
|
|
|
38
38
|
### Framework Core
|
|
39
39
|
|
|
40
|
-
#### plugin-installer
|
|
41
|
-
|
|
42
|
-
**Description**: Proactive just-in-time plugin installation. Auto-detects when specialized plugins are needed (frontend, kubernetes, ML, payments, testing, etc.) and installs them automatically before use. Activates for React, Next.js, K8s, Kubernetes, Helm, TensorFlow, PyTorch, ML model, Stripe, billing, payment, Playwright, E2E testing, Figma, design system, ADO, Azure DevOps, infrastructure, Prometheus, Grafana, monitoring, Node.js, Python backend, REST API, cloud deployment, diagram, Mermaid, C4, architecture diagram.
|
|
43
|
-
|
|
44
|
-
**Activates for**: React, Next.js, frontend, UI component, K8s, Kubernetes, deploy, TensorFlow, ML model, Stripe, billing, E2E testing, Figma, diagram, architecture diagram
|
|
45
|
-
|
|
46
|
-
**Location**: `.claude/skills/plugin-installer/SKILL.md`
|
|
47
|
-
|
|
48
|
-
---
|
|
49
|
-
|
|
50
40
|
#### plugin-expert
|
|
51
41
|
|
|
52
42
|
**Description**: Expert knowledge of Claude Code's plugin system, marketplace management, and installation commands. Activates for plugin installation, marketplace setup, plugin troubleshooting, plugin commands. Keywords plugin install, plugin marketplace, claude code plugins, plugin management, plugin errors, marketplace add, plugin list.
|
|
@@ -85,16 +75,6 @@ Step 4: Execute → Follow the increment planning workflow
|
|
|
85
75
|
|
|
86
76
|
---
|
|
87
77
|
|
|
88
|
-
#### increment-quality-judge
|
|
89
|
-
|
|
90
|
-
**Description**: Optional AI-powered quality assessment for specifications, plans, and tests. Goes beyond rule-based validation to evaluate clarity, testability, edge cases, and architecture soundness. Activates for validate quality, quality check, assess spec, evaluate increment, spec review, quality score.
|
|
91
|
-
|
|
92
|
-
**Location**: `.claude/skills/increment-quality-judge/SKILL.md`
|
|
93
|
-
|
|
94
|
-
**Allowed tools**: Read, Grep, Glob
|
|
95
|
-
|
|
96
|
-
---
|
|
97
|
-
|
|
98
78
|
#### specweave-detector
|
|
99
79
|
|
|
100
80
|
**Description**: Detects SpecWeave context (.specweave/ directory exists) and provides workflow documentation. Explains available slash commands and workflow. Keywords slash commands, /specweave:increment, /increment, /specweave:do, /specweave:progress, /specweave:validate, /specweave:done, specweave commands, workflow help, specweave folder.
|
|
@@ -202,13 +182,13 @@ Step 4: Execute → Follow the increment planning workflow
|
|
|
202
182
|
|
|
203
183
|
| Your Task | Relevant Skill | Keywords |
|
|
204
184
|
|-----------|---------------|----------|
|
|
205
|
-
| "Preview internal docs" | `plugin-installer` | "preview docs", "Docusaurus", "documentation UI" |
|
|
206
185
|
| "Plan a new feature" | `increment-planner` | "feature planning", "create increment" |
|
|
186
|
+
| "Implement feature" | `increment-work-router` | "implement", "complete", "build", "work on" |
|
|
207
187
|
| "Sync to JIRA" | `jira-sync` | "JIRA sync", "create JIRA issue" |
|
|
208
188
|
| "Create diagram" | `diagrams-architect` | "architecture diagram", "C4 diagram" |
|
|
209
189
|
| "Build React UI" | `frontend` | "React", "components", "UI" |
|
|
210
190
|
| "Deploy to cloud" | `hetzner-provisioner` | "deploy", "infrastructure" |
|
|
211
|
-
| "Quality check" | `increment-quality-judge` | "quality check", "assess spec" |
|
|
191
|
+
| "Quality check" | `increment-quality-judge-v2` | "quality check", "assess spec", "risk assessment" |
|
|
212
192
|
| "E2E testing" | `e2e-playwright` | "E2E test", "browser test" |
|
|
213
193
|
| "Generate docs site" | `docusaurus` | "documentation site", "docs" |
|
|
214
194
|
|
|
@@ -34,6 +34,56 @@ The increment-planner skill automates the creation of implementation plans for A
|
|
|
34
34
|
- Separation of WHAT/WHY (spec) from HOW (plan) from STEPS (tasks with test plans)
|
|
35
35
|
- **v0.7.0+**: Test-Aware Planning (bidirectional AC↔Task↔Test linking)
|
|
36
36
|
- **v0.8.0+**: Multi-Project Support (specs organized by project/team)
|
|
37
|
+
- **v0.18.0+**: Bidirectional Task↔User Story Linking (automatic during `/specweave:done`)
|
|
38
|
+
|
|
39
|
+
## Bidirectional Linking (v0.18.0+)
|
|
40
|
+
|
|
41
|
+
**CRITICAL FEATURE**: When you create tasks, ensure they have **AC**: fields so bidirectional links can be created automatically.
|
|
42
|
+
|
|
43
|
+
### How It Works
|
|
44
|
+
|
|
45
|
+
1. **During Planning**: Create tasks with AC-IDs
|
|
46
|
+
```markdown
|
|
47
|
+
## T-001: Implement User Login
|
|
48
|
+
|
|
49
|
+
**AC**: AC-US1-01, AC-US1-02, AC-US1-03 ← CRITICAL!
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
2. **During Completion**: `/specweave:done` automatically:
|
|
53
|
+
- Extracts user stories to `.specweave/docs/internal/specs/{project}/{feature}/`
|
|
54
|
+
- Parses tasks.md for AC-IDs
|
|
55
|
+
- **Injects bidirectional links** into tasks.md
|
|
56
|
+
- Creates complete traceability (Tasks ↔ User Stories)
|
|
57
|
+
|
|
58
|
+
3. **Result**: Tasks now link back to user stories:
|
|
59
|
+
```markdown
|
|
60
|
+
## T-001: Implement User Login
|
|
61
|
+
|
|
62
|
+
**User Story**: [US-001: User Authentication](../../docs/internal/specs/default/auth-service/us-001-user-authentication.md)
|
|
63
|
+
|
|
64
|
+
**AC**: AC-US1-01, AC-US1-02, AC-US1-03
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Requirements
|
|
68
|
+
|
|
69
|
+
**MUST HAVE** for bidirectional linking:
|
|
70
|
+
- ✅ Tasks with **AC**: field
|
|
71
|
+
- ✅ AC-IDs in format: `AC-US{number}-{criteria}` (e.g., `AC-US1-01`)
|
|
72
|
+
- ✅ Matching user stories in spec.md (e.g., `### US-001:` or `#### US-001:`)
|
|
73
|
+
|
|
74
|
+
**Multi-Project Support**:
|
|
75
|
+
- Works with `specs/default/`, `specs/backend/`, `specs/frontend/`, etc.
|
|
76
|
+
- Paths automatically adapt to project structure
|
|
77
|
+
- No additional configuration needed
|
|
78
|
+
|
|
79
|
+
### Benefits
|
|
80
|
+
|
|
81
|
+
- ✅ **Complete Traceability**: Navigate from tasks to user stories and back
|
|
82
|
+
- ✅ **Automatic**: Zero manual linking during `/specweave:done`
|
|
83
|
+
- ✅ **LLM-Friendly**: AI can understand relationships bidirectionally
|
|
84
|
+
- ✅ **Multi-Project Aware**: Works across all projects
|
|
85
|
+
|
|
86
|
+
**For complete details**: See `.specweave/docs/public/guides/bidirectional-linking.md`
|
|
37
87
|
|
|
38
88
|
## Increment Types (v0.7.0+)
|
|
39
89
|
|
|
@@ -80,6 +130,50 @@ Do NOT activate if:
|
|
|
80
130
|
- ❌ User is already in an active increment planning workflow
|
|
81
131
|
- ❌ Increment files (spec.md, plan.md, tasks.md) are currently being created
|
|
82
132
|
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## Increment Naming Convention
|
|
136
|
+
|
|
137
|
+
**CRITICAL**: All increments MUST use descriptive names, not just numbers.
|
|
138
|
+
|
|
139
|
+
**Format**: `####-descriptive-kebab-case-name`
|
|
140
|
+
|
|
141
|
+
**Examples**:
|
|
142
|
+
- ✅ `0001-core-framework`
|
|
143
|
+
- ✅ `0002-core-enhancements`
|
|
144
|
+
- ✅ `0003-intelligent-model-selection`
|
|
145
|
+
- ❌ `0003` (too generic, rejected)
|
|
146
|
+
- ❌ `0004` (no description, rejected)
|
|
147
|
+
|
|
148
|
+
**Rationale**:
|
|
149
|
+
- **Clear intent at a glance** - "0003-intelligent-model-selection" tells you exactly what it does
|
|
150
|
+
- **Easy to reference** - "the model selection increment" vs "increment 3"
|
|
151
|
+
- **Better git history** - Commit messages naturally include feature name
|
|
152
|
+
- **Searchable by feature** - `git log --grep="model-selection"` works
|
|
153
|
+
- **Self-documenting** - Increment folders are readable without opening files
|
|
154
|
+
|
|
155
|
+
**Rules**:
|
|
156
|
+
- `####` = Zero-padded 4-digit number (0001, 0002, 0003, ...)
|
|
157
|
+
- `-descriptive-name` = Kebab-case description (lowercase, hyphens)
|
|
158
|
+
- Max 50 chars total (for readability)
|
|
159
|
+
- No special characters except hyphens
|
|
160
|
+
|
|
161
|
+
**When Creating Increments**:
|
|
162
|
+
```bash
|
|
163
|
+
# ❌ Wrong
|
|
164
|
+
/specweave:increment "0004"
|
|
165
|
+
|
|
166
|
+
# ✅ Correct
|
|
167
|
+
/specweave:increment "0004-cost-optimization"
|
|
168
|
+
/specweave:increment "0005-github-sync-enhancements"
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
**Enforcement**:
|
|
172
|
+
- `/specweave:increment` command validates naming (rejects bare numbers)
|
|
173
|
+
- Code review requirement (descriptive names mandatory)
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
83
177
|
## 🔗 External Sync Architecture (CRITICAL)
|
|
84
178
|
|
|
85
179
|
**Source of Truth**: `.specweave/docs/specs/` (LOCAL) is the permanent source of truth. External tools (GitHub, Jira, ADO) are **MIRRORS**.
|