specweave 0.34.4 → 0.34.6
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/bin/fix-marketplace-errors.sh +55 -7
- package/dist/plugins/specweave-github/lib/github-feature-sync.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/github-feature-sync.js +3 -1
- package/dist/plugins/specweave-github/lib/github-feature-sync.js.map +1 -1
- package/dist/src/cli/commands/init.d.ts.map +1 -1
- package/dist/src/cli/commands/init.js +11 -2
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/commands/living-docs.js +4 -4
- package/dist/src/cli/commands/living-docs.js.map +1 -1
- package/dist/src/cli/helpers/init/brownfield-analysis.js +15 -15
- package/dist/src/cli/helpers/init/brownfield-analysis.js.map +1 -1
- package/dist/src/cli/helpers/init/living-docs-preflight.js +7 -7
- package/dist/src/cli/helpers/init/living-docs-preflight.js.map +1 -1
- package/dist/src/cli/helpers/init/plugin-installer.d.ts.map +1 -1
- package/dist/src/cli/helpers/init/plugin-installer.js +61 -9
- package/dist/src/cli/helpers/init/plugin-installer.js.map +1 -1
- package/dist/src/core/background/types.d.ts +3 -0
- package/dist/src/core/background/types.d.ts.map +1 -1
- package/dist/src/core/living-docs/delivery/delivery-generator.d.ts +58 -0
- package/dist/src/core/living-docs/delivery/delivery-generator.d.ts.map +1 -0
- package/dist/src/core/living-docs/delivery/delivery-generator.js +501 -0
- package/dist/src/core/living-docs/delivery/delivery-generator.js.map +1 -0
- package/dist/src/core/living-docs/delivery/index.d.ts +8 -0
- package/dist/src/core/living-docs/delivery/index.d.ts.map +1 -0
- package/dist/src/core/living-docs/delivery/index.js +7 -0
- package/dist/src/core/living-docs/delivery/index.js.map +1 -0
- package/dist/src/core/living-docs/diagrams/index.d.ts +8 -0
- package/dist/src/core/living-docs/diagrams/index.d.ts.map +1 -0
- package/dist/src/core/living-docs/diagrams/index.js +7 -0
- package/dist/src/core/living-docs/diagrams/index.js.map +1 -0
- package/dist/src/core/living-docs/diagrams/mermaid-generator.d.ts +103 -0
- package/dist/src/core/living-docs/diagrams/mermaid-generator.d.ts.map +1 -0
- package/dist/src/core/living-docs/diagrams/mermaid-generator.js +515 -0
- package/dist/src/core/living-docs/diagrams/mermaid-generator.js.map +1 -0
- package/dist/src/core/living-docs/enterprise/enterprise-generator.d.ts +85 -0
- package/dist/src/core/living-docs/enterprise/enterprise-generator.d.ts.map +1 -0
- package/dist/src/core/living-docs/enterprise/enterprise-generator.js +556 -0
- package/dist/src/core/living-docs/enterprise/enterprise-generator.js.map +1 -0
- package/dist/src/core/living-docs/enterprise/history-analyzer.d.ts +91 -0
- package/dist/src/core/living-docs/enterprise/history-analyzer.d.ts.map +1 -0
- package/dist/src/core/living-docs/enterprise/history-analyzer.js +321 -0
- package/dist/src/core/living-docs/enterprise/history-analyzer.js.map +1 -0
- package/dist/src/core/living-docs/enterprise/index.d.ts +18 -0
- package/dist/src/core/living-docs/enterprise/index.d.ts.map +1 -0
- package/dist/src/core/living-docs/enterprise/index.js +14 -0
- package/dist/src/core/living-docs/enterprise/index.js.map +1 -0
- package/dist/src/core/living-docs/enterprise/relationship-mapper.d.ts +58 -0
- package/dist/src/core/living-docs/enterprise/relationship-mapper.d.ts.map +1 -0
- package/dist/src/core/living-docs/enterprise/relationship-mapper.js +227 -0
- package/dist/src/core/living-docs/enterprise/relationship-mapper.js.map +1 -0
- package/dist/src/core/living-docs/enterprise/spec-loader.d.ts +161 -0
- package/dist/src/core/living-docs/enterprise/spec-loader.d.ts.map +1 -0
- package/dist/src/core/living-docs/enterprise/spec-loader.js +470 -0
- package/dist/src/core/living-docs/enterprise/spec-loader.js.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/inconsistency-detector.d.ts +31 -1
- package/dist/src/core/living-docs/intelligent-analyzer/inconsistency-detector.d.ts.map +1 -1
- package/dist/src/core/living-docs/intelligent-analyzer/inconsistency-detector.js +626 -14
- package/dist/src/core/living-docs/intelligent-analyzer/inconsistency-detector.js.map +1 -1
- package/dist/src/core/living-docs/intelligent-analyzer/index.d.ts +8 -0
- package/dist/src/core/living-docs/intelligent-analyzer/index.d.ts.map +1 -1
- package/dist/src/core/living-docs/intelligent-analyzer/index.js +87 -4
- package/dist/src/core/living-docs/intelligent-analyzer/index.js.map +1 -1
- package/dist/src/core/living-docs/intelligent-analyzer/types.d.ts +3 -1
- package/dist/src/core/living-docs/intelligent-analyzer/types.d.ts.map +1 -1
- package/dist/src/core/living-docs/operations/index.d.ts +8 -0
- package/dist/src/core/living-docs/operations/index.d.ts.map +1 -0
- package/dist/src/core/living-docs/operations/index.js +7 -0
- package/dist/src/core/living-docs/operations/index.js.map +1 -0
- package/dist/src/core/living-docs/operations/ops-generator.d.ts +53 -0
- package/dist/src/core/living-docs/operations/ops-generator.d.ts.map +1 -0
- package/dist/src/core/living-docs/operations/ops-generator.js +462 -0
- package/dist/src/core/living-docs/operations/ops-generator.js.map +1 -0
- package/package.json +1 -1
- package/plugins/specweave/commands/living-docs.md +168 -39
- package/plugins/specweave-github/lib/github-feature-sync.js +1 -1
- package/plugins/specweave-github/lib/github-feature-sync.ts +3 -1
|
@@ -0,0 +1,470 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enhanced Spec Loader
|
|
3
|
+
*
|
|
4
|
+
* Loads ALL specifications from living docs with full details:
|
|
5
|
+
* - Feature hierarchies (FS-XXX -> US-XXX)
|
|
6
|
+
* - User story details with acceptance criteria
|
|
7
|
+
* - Status and completion information
|
|
8
|
+
* - External tool references (GitHub/JIRA/ADO)
|
|
9
|
+
* - Related increments
|
|
10
|
+
*/
|
|
11
|
+
import * as fs from 'fs';
|
|
12
|
+
import * as path from 'path';
|
|
13
|
+
import { glob } from 'glob';
|
|
14
|
+
import { consoleLogger } from '../../../utils/logger.js';
|
|
15
|
+
/**
|
|
16
|
+
* Enhanced spec loader that extracts full details from all specs
|
|
17
|
+
*/
|
|
18
|
+
export class EnhancedSpecLoader {
|
|
19
|
+
constructor(options) {
|
|
20
|
+
this.projectPath = options.projectPath;
|
|
21
|
+
this.logger = options.logger ?? consoleLogger;
|
|
22
|
+
this.includeArchived = options.includeArchived ?? true;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Load all specifications with full details
|
|
26
|
+
*/
|
|
27
|
+
async loadAllSpecs() {
|
|
28
|
+
const specsPath = path.join(this.projectPath, '.specweave/docs/internal/specs');
|
|
29
|
+
if (!fs.existsSync(specsPath)) {
|
|
30
|
+
this.logger.warn('Specs directory not found');
|
|
31
|
+
return this.createEmptyCatalog();
|
|
32
|
+
}
|
|
33
|
+
const features = [];
|
|
34
|
+
// Find all FEATURE.md files (including in archives if enabled)
|
|
35
|
+
const pattern = this.includeArchived
|
|
36
|
+
? '**/FS-*/FEATURE.md'
|
|
37
|
+
: '**/FS-*/FEATURE.md';
|
|
38
|
+
const featureFiles = await glob(pattern, {
|
|
39
|
+
cwd: specsPath,
|
|
40
|
+
nodir: true,
|
|
41
|
+
ignore: this.includeArchived ? [] : ['**/_archive/**']
|
|
42
|
+
});
|
|
43
|
+
this.logger.info(`Found ${featureFiles.length} feature files`);
|
|
44
|
+
for (const featureFile of featureFiles) {
|
|
45
|
+
try {
|
|
46
|
+
const feature = await this.loadFeature(specsPath, featureFile);
|
|
47
|
+
if (feature) {
|
|
48
|
+
features.push(feature);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
catch (err) {
|
|
52
|
+
this.logger.warn(`Failed to load feature ${featureFile}: ${err.message}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return this.buildCatalog(features);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Load a single feature with all its user stories
|
|
59
|
+
*/
|
|
60
|
+
async loadFeature(specsPath, featureFilePath) {
|
|
61
|
+
const fullPath = path.join(specsPath, featureFilePath);
|
|
62
|
+
const featureDir = path.dirname(fullPath);
|
|
63
|
+
const featureId = path.basename(featureDir);
|
|
64
|
+
// Read FEATURE.md
|
|
65
|
+
const content = fs.readFileSync(fullPath, 'utf-8');
|
|
66
|
+
// Extract feature metadata
|
|
67
|
+
const featureName = this.extractTitle(content) || featureId;
|
|
68
|
+
const description = this.extractDescription(content);
|
|
69
|
+
const isArchived = featureFilePath.includes('_archive');
|
|
70
|
+
// Load all user stories in this feature folder
|
|
71
|
+
const userStories = await this.loadUserStories(featureDir);
|
|
72
|
+
// Calculate completion
|
|
73
|
+
const totalACs = userStories.reduce((sum, us) => sum + us.acceptanceCriteria.length, 0);
|
|
74
|
+
const completedACs = userStories.reduce((sum, us) => sum + us.acceptanceCriteria.filter(ac => ac.completed).length, 0);
|
|
75
|
+
const completionPercentage = totalACs > 0 ? Math.round((completedACs / totalACs) * 100) : 0;
|
|
76
|
+
// Determine status
|
|
77
|
+
let status = 'active';
|
|
78
|
+
if (isArchived) {
|
|
79
|
+
status = 'archived';
|
|
80
|
+
}
|
|
81
|
+
else if (completionPercentage === 100 && totalACs > 0) {
|
|
82
|
+
status = 'completed';
|
|
83
|
+
}
|
|
84
|
+
// Extract external references from user stories
|
|
85
|
+
const externalRefs = userStories
|
|
86
|
+
.filter(us => us.externalRef)
|
|
87
|
+
.map(us => us.externalRef);
|
|
88
|
+
// Find related increments
|
|
89
|
+
const relatedIncrements = this.findRelatedIncrements(featureId);
|
|
90
|
+
// Extract project/board from first user story or feature content
|
|
91
|
+
const project = userStories[0]?.project || this.extractField(content, 'project');
|
|
92
|
+
const board = userStories[0]?.board || this.extractField(content, 'board');
|
|
93
|
+
return {
|
|
94
|
+
featureId,
|
|
95
|
+
featureName,
|
|
96
|
+
description,
|
|
97
|
+
userStories,
|
|
98
|
+
status,
|
|
99
|
+
createdAt: this.getFileCreatedDate(fullPath),
|
|
100
|
+
completedAt: status === 'completed' ? this.getFileModifiedDate(fullPath) : undefined,
|
|
101
|
+
externalRefs,
|
|
102
|
+
relatedIncrements,
|
|
103
|
+
project,
|
|
104
|
+
board,
|
|
105
|
+
folderPath: featureDir,
|
|
106
|
+
totalACs,
|
|
107
|
+
completedACs,
|
|
108
|
+
completionPercentage,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Load all user stories in a feature folder
|
|
113
|
+
*/
|
|
114
|
+
async loadUserStories(featureDir) {
|
|
115
|
+
const userStories = [];
|
|
116
|
+
const usFiles = await glob('us-*.md', { cwd: featureDir, nodir: true });
|
|
117
|
+
for (const usFile of usFiles) {
|
|
118
|
+
try {
|
|
119
|
+
const us = this.loadUserStory(path.join(featureDir, usFile));
|
|
120
|
+
if (us) {
|
|
121
|
+
userStories.push(us);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
catch (err) {
|
|
125
|
+
this.logger.debug(`Failed to load user story ${usFile}: ${err.message}`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return userStories.sort((a, b) => a.id.localeCompare(b.id));
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Load a single user story with acceptance criteria
|
|
132
|
+
*/
|
|
133
|
+
loadUserStory(filePath) {
|
|
134
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
135
|
+
const fileName = path.basename(filePath, '.md');
|
|
136
|
+
// Extract US ID from filename or content
|
|
137
|
+
const idMatch = fileName.match(/us-(\d+)/i) || content.match(/US-(\d+)/i);
|
|
138
|
+
const id = idMatch ? `US-${idMatch[1].padStart(3, '0')}` : fileName;
|
|
139
|
+
// Extract title
|
|
140
|
+
const title = this.extractTitle(content) || fileName;
|
|
141
|
+
// Extract description (the "As a... I want... So that..." pattern)
|
|
142
|
+
const description = this.extractUserStoryDescription(content);
|
|
143
|
+
// Extract acceptance criteria
|
|
144
|
+
const acceptanceCriteria = this.extractAcceptanceCriteria(content, id);
|
|
145
|
+
// Extract priority from title or content
|
|
146
|
+
const priority = this.extractPriority(content, title);
|
|
147
|
+
// Extract status from frontmatter or checkboxes
|
|
148
|
+
const status = this.determineUserStoryStatus(content, acceptanceCriteria);
|
|
149
|
+
// Extract project/board from frontmatter
|
|
150
|
+
const frontmatter = this.extractFrontmatter(content);
|
|
151
|
+
const project = frontmatter.project || this.extractField(content, 'Project');
|
|
152
|
+
const board = frontmatter.board || this.extractField(content, 'Board');
|
|
153
|
+
// Extract external reference
|
|
154
|
+
const externalRef = this.extractExternalRef(content, frontmatter);
|
|
155
|
+
return {
|
|
156
|
+
id,
|
|
157
|
+
title,
|
|
158
|
+
description,
|
|
159
|
+
acceptanceCriteria,
|
|
160
|
+
priority,
|
|
161
|
+
status,
|
|
162
|
+
project,
|
|
163
|
+
board,
|
|
164
|
+
externalRef,
|
|
165
|
+
filePath,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Extract acceptance criteria from user story content
|
|
170
|
+
*/
|
|
171
|
+
extractAcceptanceCriteria(content, usId) {
|
|
172
|
+
const criteria = [];
|
|
173
|
+
// Match patterns like:
|
|
174
|
+
// - [x] **AC-US001-01**: Description
|
|
175
|
+
// - [ ] **AC-US001-02**: Description
|
|
176
|
+
// - [x] AC-US001-03: Description
|
|
177
|
+
const acPattern = /- \[([ x])\]\s*\*?\*?(?:AC-)?([A-Z0-9-]+)(?:\*?\*?):\s*(.+)/gi;
|
|
178
|
+
let match;
|
|
179
|
+
while ((match = acPattern.exec(content)) !== null) {
|
|
180
|
+
const completed = match[1].toLowerCase() === 'x';
|
|
181
|
+
let acId = match[2];
|
|
182
|
+
const description = match[3].trim();
|
|
183
|
+
// Normalize AC ID format
|
|
184
|
+
if (!acId.startsWith('AC-')) {
|
|
185
|
+
acId = `AC-${acId}`;
|
|
186
|
+
}
|
|
187
|
+
criteria.push({
|
|
188
|
+
id: acId,
|
|
189
|
+
description,
|
|
190
|
+
completed,
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
// Also try simpler checkbox patterns with numbered items
|
|
194
|
+
if (criteria.length === 0) {
|
|
195
|
+
const simplePattern = /- \[([ x])\]\s*(.+)/g;
|
|
196
|
+
let acNum = 1;
|
|
197
|
+
while ((match = simplePattern.exec(content)) !== null) {
|
|
198
|
+
const completed = match[1].toLowerCase() === 'x';
|
|
199
|
+
const description = match[2].trim();
|
|
200
|
+
// Skip if it looks like a task, not an AC
|
|
201
|
+
if (description.startsWith('T-') || description.match(/^Task/i))
|
|
202
|
+
continue;
|
|
203
|
+
criteria.push({
|
|
204
|
+
id: `AC-${usId.replace('US-', '')}-${String(acNum++).padStart(2, '0')}`,
|
|
205
|
+
description,
|
|
206
|
+
completed,
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return criteria;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Extract priority from content or title
|
|
214
|
+
*/
|
|
215
|
+
extractPriority(content, title) {
|
|
216
|
+
const combined = `${title} ${content}`;
|
|
217
|
+
if (combined.match(/\(P0\)|P0:|Priority:\s*P0|Critical/i))
|
|
218
|
+
return 'P0';
|
|
219
|
+
if (combined.match(/\(P1\)|P1:|Priority:\s*P1|High/i))
|
|
220
|
+
return 'P1';
|
|
221
|
+
if (combined.match(/\(P2\)|P2:|Priority:\s*P2|Medium/i))
|
|
222
|
+
return 'P2';
|
|
223
|
+
if (combined.match(/\(P3\)|P3:|Priority:\s*P3|Low/i))
|
|
224
|
+
return 'P3';
|
|
225
|
+
return null;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Determine user story status from content
|
|
229
|
+
*/
|
|
230
|
+
determineUserStoryStatus(content, acs) {
|
|
231
|
+
// Check frontmatter status
|
|
232
|
+
const frontmatter = this.extractFrontmatter(content);
|
|
233
|
+
if (frontmatter.status) {
|
|
234
|
+
return frontmatter.status;
|
|
235
|
+
}
|
|
236
|
+
// Determine from ACs
|
|
237
|
+
if (acs.length === 0)
|
|
238
|
+
return 'draft';
|
|
239
|
+
const completedCount = acs.filter(ac => ac.completed).length;
|
|
240
|
+
if (completedCount === acs.length)
|
|
241
|
+
return 'completed';
|
|
242
|
+
if (completedCount > 0)
|
|
243
|
+
return 'in_progress';
|
|
244
|
+
return 'ready';
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Extract external reference (GitHub/JIRA/ADO)
|
|
248
|
+
*/
|
|
249
|
+
extractExternalRef(content, frontmatter) {
|
|
250
|
+
// Check frontmatter first
|
|
251
|
+
if (frontmatter.external_ref || frontmatter.externalRef) {
|
|
252
|
+
const ref = frontmatter.external_ref || frontmatter.externalRef;
|
|
253
|
+
return {
|
|
254
|
+
provider: ref.provider || 'github',
|
|
255
|
+
id: ref.id || ref.number || '',
|
|
256
|
+
url: ref.url,
|
|
257
|
+
status: ref.status,
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
// Look for GitHub issue links
|
|
261
|
+
const ghMatch = content.match(/github\.com\/[^/]+\/[^/]+\/issues\/(\d+)/i);
|
|
262
|
+
if (ghMatch) {
|
|
263
|
+
return {
|
|
264
|
+
provider: 'github',
|
|
265
|
+
id: ghMatch[1],
|
|
266
|
+
url: ghMatch[0],
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
// Look for JIRA links
|
|
270
|
+
const jiraMatch = content.match(/([A-Z]+-\d+)/);
|
|
271
|
+
if (jiraMatch && content.includes('atlassian.net') || content.includes('jira')) {
|
|
272
|
+
return {
|
|
273
|
+
provider: 'jira',
|
|
274
|
+
id: jiraMatch[1],
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
// Look for ADO links
|
|
278
|
+
const adoMatch = content.match(/dev\.azure\.com\/[^/]+\/[^/]+\/_workitems\/edit\/(\d+)/i);
|
|
279
|
+
if (adoMatch) {
|
|
280
|
+
return {
|
|
281
|
+
provider: 'ado',
|
|
282
|
+
id: adoMatch[1],
|
|
283
|
+
url: adoMatch[0],
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
return undefined;
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Find increments related to a feature
|
|
290
|
+
*/
|
|
291
|
+
findRelatedIncrements(featureId) {
|
|
292
|
+
const incrementsPath = path.join(this.projectPath, '.specweave/increments');
|
|
293
|
+
const relatedIncrements = [];
|
|
294
|
+
if (!fs.existsSync(incrementsPath))
|
|
295
|
+
return relatedIncrements;
|
|
296
|
+
// Check all increment directories
|
|
297
|
+
const dirs = ['', '_archive', '_paused', '_abandoned'];
|
|
298
|
+
for (const subdir of dirs) {
|
|
299
|
+
const checkPath = subdir ? path.join(incrementsPath, subdir) : incrementsPath;
|
|
300
|
+
if (!fs.existsSync(checkPath))
|
|
301
|
+
continue;
|
|
302
|
+
const entries = fs.readdirSync(checkPath, { withFileTypes: true });
|
|
303
|
+
for (const entry of entries) {
|
|
304
|
+
if (!entry.isDirectory())
|
|
305
|
+
continue;
|
|
306
|
+
if (entry.name.startsWith('_'))
|
|
307
|
+
continue;
|
|
308
|
+
// Check if increment references this feature
|
|
309
|
+
const specPath = path.join(checkPath, entry.name, 'spec.md');
|
|
310
|
+
if (fs.existsSync(specPath)) {
|
|
311
|
+
const content = fs.readFileSync(specPath, 'utf-8');
|
|
312
|
+
if (content.includes(featureId)) {
|
|
313
|
+
relatedIncrements.push(entry.name);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
return relatedIncrements;
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Extract frontmatter from markdown
|
|
322
|
+
*/
|
|
323
|
+
extractFrontmatter(content) {
|
|
324
|
+
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
325
|
+
if (!match)
|
|
326
|
+
return {};
|
|
327
|
+
const frontmatter = {};
|
|
328
|
+
const lines = match[1].split('\n');
|
|
329
|
+
for (const line of lines) {
|
|
330
|
+
const [key, ...valueParts] = line.split(':');
|
|
331
|
+
if (key && valueParts.length > 0) {
|
|
332
|
+
frontmatter[key.trim()] = valueParts.join(':').trim();
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
return frontmatter;
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Extract title from markdown (first H1)
|
|
339
|
+
*/
|
|
340
|
+
extractTitle(content) {
|
|
341
|
+
const match = content.match(/^#\s+(.+)/m);
|
|
342
|
+
return match ? match[1].trim() : null;
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Extract description (first paragraph after title)
|
|
346
|
+
*/
|
|
347
|
+
extractDescription(content) {
|
|
348
|
+
// Remove frontmatter
|
|
349
|
+
const withoutFrontmatter = content.replace(/^---[\s\S]*?---\n?/, '');
|
|
350
|
+
// Find first paragraph after title
|
|
351
|
+
const lines = withoutFrontmatter.split('\n');
|
|
352
|
+
let afterTitle = false;
|
|
353
|
+
let description = '';
|
|
354
|
+
for (const line of lines) {
|
|
355
|
+
if (line.startsWith('#')) {
|
|
356
|
+
afterTitle = true;
|
|
357
|
+
continue;
|
|
358
|
+
}
|
|
359
|
+
if (afterTitle && line.trim() && !line.startsWith('#')) {
|
|
360
|
+
description = line.trim();
|
|
361
|
+
break;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
return description;
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Extract user story description ("As a... I want... So that...")
|
|
368
|
+
*/
|
|
369
|
+
extractUserStoryDescription(content) {
|
|
370
|
+
const asAMatch = content.match(/\*?\*?As an?\*?\*?\s+([^,\n]+)/i);
|
|
371
|
+
const wantMatch = content.match(/\*?\*?I want\*?\*?\s+([^,\n]+)/i);
|
|
372
|
+
const soThatMatch = content.match(/\*?\*?So that\*?\*?\s+([^,\n]+)/i);
|
|
373
|
+
if (asAMatch || wantMatch) {
|
|
374
|
+
return [
|
|
375
|
+
asAMatch ? `As a ${asAMatch[1].trim()}` : '',
|
|
376
|
+
wantMatch ? `I want ${wantMatch[1].trim()}` : '',
|
|
377
|
+
soThatMatch ? `So that ${soThatMatch[1].trim()}` : '',
|
|
378
|
+
].filter(Boolean).join(', ');
|
|
379
|
+
}
|
|
380
|
+
return this.extractDescription(content);
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Extract a specific field like **Project**: value
|
|
384
|
+
*/
|
|
385
|
+
extractField(content, fieldName) {
|
|
386
|
+
const pattern = new RegExp(`\\*\\*${fieldName}\\*\\*:\\s*(.+)`, 'i');
|
|
387
|
+
const match = content.match(pattern);
|
|
388
|
+
return match ? match[1].trim() : undefined;
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* Get file creation date
|
|
392
|
+
*/
|
|
393
|
+
getFileCreatedDate(filePath) {
|
|
394
|
+
try {
|
|
395
|
+
const stats = fs.statSync(filePath);
|
|
396
|
+
return stats.birthtime.toISOString();
|
|
397
|
+
}
|
|
398
|
+
catch {
|
|
399
|
+
return new Date().toISOString();
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Get file modification date
|
|
404
|
+
*/
|
|
405
|
+
getFileModifiedDate(filePath) {
|
|
406
|
+
try {
|
|
407
|
+
const stats = fs.statSync(filePath);
|
|
408
|
+
return stats.mtime.toISOString();
|
|
409
|
+
}
|
|
410
|
+
catch {
|
|
411
|
+
return new Date().toISOString();
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* Build the full catalog from loaded features
|
|
416
|
+
*/
|
|
417
|
+
buildCatalog(features) {
|
|
418
|
+
const byProject = new Map();
|
|
419
|
+
const byStatus = new Map();
|
|
420
|
+
for (const feature of features) {
|
|
421
|
+
// Group by project
|
|
422
|
+
const projectKey = feature.project || 'default';
|
|
423
|
+
if (!byProject.has(projectKey)) {
|
|
424
|
+
byProject.set(projectKey, []);
|
|
425
|
+
}
|
|
426
|
+
byProject.get(projectKey).push(feature);
|
|
427
|
+
// Group by status
|
|
428
|
+
if (!byStatus.has(feature.status)) {
|
|
429
|
+
byStatus.set(feature.status, []);
|
|
430
|
+
}
|
|
431
|
+
byStatus.get(feature.status).push(feature);
|
|
432
|
+
}
|
|
433
|
+
const totalACs = features.reduce((sum, f) => sum + f.totalACs, 0);
|
|
434
|
+
const completedACs = features.reduce((sum, f) => sum + f.completedACs, 0);
|
|
435
|
+
return {
|
|
436
|
+
features: features.sort((a, b) => a.featureId.localeCompare(b.featureId)),
|
|
437
|
+
totalFeatures: features.length,
|
|
438
|
+
activeFeatures: byStatus.get('active')?.length || 0,
|
|
439
|
+
completedFeatures: byStatus.get('completed')?.length || 0,
|
|
440
|
+
archivedFeatures: byStatus.get('archived')?.length || 0,
|
|
441
|
+
totalUserStories: features.reduce((sum, f) => sum + f.userStories.length, 0),
|
|
442
|
+
totalACs,
|
|
443
|
+
completedACs,
|
|
444
|
+
overallCompletion: totalACs > 0 ? Math.round((completedACs / totalACs) * 100) : 0,
|
|
445
|
+
byProject,
|
|
446
|
+
byStatus,
|
|
447
|
+
loadedAt: new Date().toISOString(),
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* Create empty catalog
|
|
452
|
+
*/
|
|
453
|
+
createEmptyCatalog() {
|
|
454
|
+
return {
|
|
455
|
+
features: [],
|
|
456
|
+
totalFeatures: 0,
|
|
457
|
+
activeFeatures: 0,
|
|
458
|
+
completedFeatures: 0,
|
|
459
|
+
archivedFeatures: 0,
|
|
460
|
+
totalUserStories: 0,
|
|
461
|
+
totalACs: 0,
|
|
462
|
+
completedACs: 0,
|
|
463
|
+
overallCompletion: 0,
|
|
464
|
+
byProject: new Map(),
|
|
465
|
+
byStatus: new Map(),
|
|
466
|
+
loadedAt: new Date().toISOString(),
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
//# sourceMappingURL=spec-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec-loader.js","sourceRoot":"","sources":["../../../../../src/core/living-docs/enterprise/spec-loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,15 +3,45 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Finds inconsistencies, duplicates, ownership gaps,
|
|
5
5
|
* and generates questions for CTO/PO.
|
|
6
|
+
*
|
|
7
|
+
* Enhanced with:
|
|
8
|
+
* - Severity categorization (P0-P3)
|
|
9
|
+
* - Broken link detection
|
|
10
|
+
* - Spec-code gap detection
|
|
11
|
+
* - Orphaned document detection
|
|
6
12
|
*/
|
|
7
13
|
import type { RepoAnalysis, DetectedIssue, TechDebtItem, LLMProvider, ProgressCallback } from './types.js';
|
|
8
14
|
import type { OrganizationSynthesisResult } from './organization-synthesizer.js';
|
|
15
|
+
export type IssueSeverity = 'P0' | 'P1' | 'P2' | 'P3';
|
|
16
|
+
export interface EnhancedIssue extends DetectedIssue {
|
|
17
|
+
priority: IssueSeverity;
|
|
18
|
+
remediation: string[];
|
|
19
|
+
category: 'inconsistency' | 'duplicate' | 'ownership' | 'broken-link' | 'spec-gap' | 'orphaned';
|
|
20
|
+
}
|
|
9
21
|
export interface InconsistencyResult {
|
|
10
22
|
issues: DetectedIssue[];
|
|
23
|
+
enhancedIssues: EnhancedIssue[];
|
|
11
24
|
techDebt: TechDebtItem[];
|
|
12
25
|
questionsForCTO: string[];
|
|
13
26
|
questionsForPO: string[];
|
|
27
|
+
byPriority: Map<IssueSeverity, EnhancedIssue[]>;
|
|
28
|
+
brokenLinks: BrokenLink[];
|
|
29
|
+
specCodeGaps: SpecCodeGap[];
|
|
30
|
+
orphanedDocs: string[];
|
|
31
|
+
}
|
|
32
|
+
export interface BrokenLink {
|
|
33
|
+
file: string;
|
|
34
|
+
line: number;
|
|
35
|
+
link: string;
|
|
36
|
+
reason: string;
|
|
37
|
+
}
|
|
38
|
+
export interface SpecCodeGap {
|
|
39
|
+
specId: string;
|
|
40
|
+
specFile: string;
|
|
41
|
+
type: 'ghost_completion' | 'missing_impl' | 'outdated_spec';
|
|
42
|
+
confidence: number;
|
|
43
|
+
details: string;
|
|
14
44
|
}
|
|
15
|
-
export declare function detectInconsistencies(repoAnalyses: Map<string, RepoAnalysis>, orgResult: OrganizationSynthesisResult, llmProvider: LLMProvider | null, onProgress: ProgressCallback, log: (msg: string) => void): Promise<InconsistencyResult>;
|
|
45
|
+
export declare function detectInconsistencies(repoAnalyses: Map<string, RepoAnalysis>, orgResult: OrganizationSynthesisResult, llmProvider: LLMProvider | null, onProgress: ProgressCallback, log: (msg: string) => void, projectPath?: string): Promise<InconsistencyResult>;
|
|
16
46
|
export declare function saveReviewNeeded(projectPath: string, result: InconsistencyResult): Promise<string[]>;
|
|
17
47
|
//# sourceMappingURL=inconsistency-detector.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inconsistency-detector.d.ts","sourceRoot":"","sources":["../../../../../src/core/living-docs/intelligent-analyzer/inconsistency-detector.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"inconsistency-detector.d.ts","sourceRoot":"","sources":["../../../../../src/core/living-docs/intelligent-analyzer/inconsistency-detector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,WAAW,EACX,gBAAgB,EACjB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,+BAA+B,CAAC;AAEjF,MAAM,MAAM,aAAa,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAEtD,MAAM,WAAW,aAAc,SAAQ,aAAa;IAClD,QAAQ,EAAE,aAAa,CAAC;IACxB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,EAAE,eAAe,GAAG,WAAW,GAAG,WAAW,GAAG,aAAa,GAAG,UAAU,GAAG,UAAU,CAAC;CACjG;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,cAAc,EAAE,aAAa,EAAE,CAAC;IAChC,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,UAAU,EAAE,GAAG,CAAC,aAAa,EAAE,aAAa,EAAE,CAAC,CAAC;IAChD,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,kBAAkB,GAAG,cAAc,GAAG,eAAe,CAAC;IAC5D,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,qBAAqB,CACzC,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,EACvC,SAAS,EAAE,2BAA2B,EACtC,WAAW,EAAE,WAAW,GAAG,IAAI,EAC/B,UAAU,EAAE,gBAAgB,EAC5B,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,EAC1B,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,mBAAmB,CAAC,CA8G9B;AA2mBD,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,mBAAmB,GAC1B,OAAO,CAAC,MAAM,EAAE,CAAC,CA0TnB"}
|