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
|
@@ -0,0 +1,453 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SpecWeave Hierarchy Mapper
|
|
3
|
+
*
|
|
4
|
+
* Maps increments to Feature Spec (FS-*) folders following Universal Hierarchy architecture.
|
|
5
|
+
*
|
|
6
|
+
* Supports three complexity levels:
|
|
7
|
+
* 1. Simple: Increment → Issue/Epic/Feature (flat)
|
|
8
|
+
* 2. Standard: FS-* (Epic) → US-* (User Stories) → T-* (Tasks)
|
|
9
|
+
* 3. Enterprise: Domain → FS-* (Epic) → US-* → T-*
|
|
10
|
+
*
|
|
11
|
+
* @author SpecWeave Team
|
|
12
|
+
* @version 3.0.0
|
|
13
|
+
*/
|
|
14
|
+
import fs from 'fs-extra';
|
|
15
|
+
import path from 'path';
|
|
16
|
+
/**
|
|
17
|
+
* HierarchyMapper - Maps increments to feature folders (named by concept, not increment number)
|
|
18
|
+
*
|
|
19
|
+
* NEW ARCHITECTURE (v0.18.0+):
|
|
20
|
+
* - Features are PERMANENT (named by concept: "release-management", "external-tool-sync")
|
|
21
|
+
* - Increments are TEMPORARY (named by execution: "0023-release-management-enhancements")
|
|
22
|
+
* - Multiple increments can contribute to same feature
|
|
23
|
+
* - No FS-### prefix (features aren't numbered)
|
|
24
|
+
*/
|
|
25
|
+
export class HierarchyMapper {
|
|
26
|
+
constructor(projectRoot, config) {
|
|
27
|
+
this.projectRoot = projectRoot;
|
|
28
|
+
const projectId = config?.projectId || 'default';
|
|
29
|
+
this.config = {
|
|
30
|
+
level: 'standard', // SpecWeave uses Standard level by default
|
|
31
|
+
specsBaseDir: path.join(projectRoot, '.specweave', 'docs', 'internal', 'specs', projectId),
|
|
32
|
+
projectId,
|
|
33
|
+
featureFolderPattern: '{name}', // Feature-based naming (no FS- prefix)
|
|
34
|
+
userStoriesSubdir: '', // User stories go directly in feature folder, not subfolder
|
|
35
|
+
detectFeatureFrom: ['frontmatter', 'increment-name', 'config'],
|
|
36
|
+
fallbackFeature: undefined,
|
|
37
|
+
...config,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Detect which feature folder this increment belongs to
|
|
42
|
+
*
|
|
43
|
+
* NEW: Features are named by CONCEPT (release-management), not INCREMENT NUMBER (FS-023)
|
|
44
|
+
*/
|
|
45
|
+
async detectFeatureMapping(incrementId) {
|
|
46
|
+
const specPath = path.join(this.projectRoot, '.specweave', 'increments', incrementId, 'spec.md');
|
|
47
|
+
if (!fs.existsSync(specPath)) {
|
|
48
|
+
throw new Error(`Increment spec not found: ${specPath}`);
|
|
49
|
+
}
|
|
50
|
+
const content = await fs.readFile(specPath, 'utf-8');
|
|
51
|
+
// Try each detection method in order
|
|
52
|
+
for (const method of this.config.detectFeatureFrom) {
|
|
53
|
+
let mapping = null;
|
|
54
|
+
switch (method) {
|
|
55
|
+
case 'frontmatter':
|
|
56
|
+
mapping = await this.detectFromFrontmatter(content, incrementId);
|
|
57
|
+
break;
|
|
58
|
+
case 'increment-name':
|
|
59
|
+
mapping = await this.detectFromIncrementName(incrementId);
|
|
60
|
+
break;
|
|
61
|
+
case 'config':
|
|
62
|
+
mapping = await this.detectFromConfig(incrementId);
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
if (mapping && mapping.confidence >= 80) {
|
|
66
|
+
return mapping;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// Fallback: Extract feature name from increment ID
|
|
70
|
+
return await this.createFallbackMapping(incrementId);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Legacy alias for backward compatibility
|
|
74
|
+
*/
|
|
75
|
+
async detectEpicMapping(incrementId) {
|
|
76
|
+
return this.detectFeatureMapping(incrementId);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Detect feature from frontmatter (epic: feature-name)
|
|
80
|
+
*
|
|
81
|
+
* FORMAT (v0.18.1+): Accepts simple feature names (external-tool-status-sync)
|
|
82
|
+
* LEGACY: Also accepts old FS-### format (FS-001) - extracts from increment name instead
|
|
83
|
+
*/
|
|
84
|
+
async detectFromFrontmatter(content, incrementId) {
|
|
85
|
+
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
86
|
+
if (!frontmatterMatch)
|
|
87
|
+
return null;
|
|
88
|
+
try {
|
|
89
|
+
const yaml = await import('yaml');
|
|
90
|
+
const frontmatter = yaml.parse(frontmatterMatch[1]);
|
|
91
|
+
// Check for explicit epic field
|
|
92
|
+
if (frontmatter.epic && typeof frontmatter.epic === 'string') {
|
|
93
|
+
const epicValue = frontmatter.epic;
|
|
94
|
+
// Handle LEGACY numeric format (FS-001, FS-031) → extract from increment name
|
|
95
|
+
if (epicValue.match(/^FS-\d+$/)) {
|
|
96
|
+
console.log(` ⚠️ Legacy FS-### format detected (${epicValue}), extracting feature name from increment...`);
|
|
97
|
+
return await this.detectFromIncrementName(incrementId);
|
|
98
|
+
}
|
|
99
|
+
// NEW FORMAT: FS-25-11-14-feature-name (date-based) OR plain feature-name
|
|
100
|
+
const featureFolder = await this.findFeatureFolder(epicValue);
|
|
101
|
+
if (featureFolder) {
|
|
102
|
+
return {
|
|
103
|
+
featureId: featureFolder, // ID = folder name
|
|
104
|
+
featureFolder,
|
|
105
|
+
featurePath: path.join(this.config.specsBaseDir, featureFolder),
|
|
106
|
+
userStoriesPath: path.join(this.config.specsBaseDir, featureFolder, this.config.userStoriesSubdir),
|
|
107
|
+
confidence: 100,
|
|
108
|
+
detectionMethod: 'frontmatter',
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
console.warn(` ⚠️ Failed to parse frontmatter: ${error}`);
|
|
115
|
+
}
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Detect feature from increment NAME
|
|
120
|
+
*
|
|
121
|
+
* FORMAT (v0.18.1+): Simple descriptive names (no date prefixes)
|
|
122
|
+
*
|
|
123
|
+
* Extracts the descriptive part of increment ID and normalizes it to feature name
|
|
124
|
+
* Examples:
|
|
125
|
+
* 0023-release-management-enhancements → release-management (new or existing)
|
|
126
|
+
* 0031-external-tool-status-sync → external-tool-status-sync
|
|
127
|
+
*/
|
|
128
|
+
async detectFromIncrementName(incrementId) {
|
|
129
|
+
// Extract name part (after number: 0023-release-management-enhancements → release-management-enhancements)
|
|
130
|
+
const nameMatch = incrementId.match(/^\d+-(.+)/);
|
|
131
|
+
if (!nameMatch)
|
|
132
|
+
return null;
|
|
133
|
+
const fullName = nameMatch[1]; // release-management-enhancements
|
|
134
|
+
// Extract core feature name (remove suffixes like -enhancements, -improvements, -fixes)
|
|
135
|
+
const suffixesToRemove = ['-enhancements', '-improvements', '-fixes', '-updates', '-v2', '-v3'];
|
|
136
|
+
let featureName = fullName;
|
|
137
|
+
for (const suffix of suffixesToRemove) {
|
|
138
|
+
if (featureName.endsWith(suffix)) {
|
|
139
|
+
featureName = featureName.slice(0, -suffix.length);
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
// Try to find existing feature folder (legacy or new format)
|
|
144
|
+
let featureFolder = await this.findFeatureFolder(featureName);
|
|
145
|
+
// If not found, try with full name
|
|
146
|
+
if (!featureFolder) {
|
|
147
|
+
featureFolder = await this.findFeatureFolder(fullName);
|
|
148
|
+
}
|
|
149
|
+
// If not found, use simple feature name (no date prefix, no FS- prefix)
|
|
150
|
+
if (!featureFolder) {
|
|
151
|
+
featureFolder = featureName; // Simple: external-tool-status-sync
|
|
152
|
+
console.log(` ✨ Creating new feature folder: ${featureFolder}`);
|
|
153
|
+
}
|
|
154
|
+
return {
|
|
155
|
+
featureId: featureFolder, // ID = folder name (for consistency)
|
|
156
|
+
featureFolder,
|
|
157
|
+
featurePath: path.join(this.config.specsBaseDir, featureFolder),
|
|
158
|
+
userStoriesPath: path.join(this.config.specsBaseDir, featureFolder, this.config.userStoriesSubdir),
|
|
159
|
+
confidence: 90,
|
|
160
|
+
detectionMethod: 'increment-name',
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Detect feature from config mapping (explicit increment → feature mapping)
|
|
165
|
+
*/
|
|
166
|
+
async detectFromConfig(incrementId) {
|
|
167
|
+
// Load config to check for explicit mapping
|
|
168
|
+
const configPath = path.join(this.projectRoot, '.specweave', 'config.json');
|
|
169
|
+
if (!fs.existsSync(configPath))
|
|
170
|
+
return null;
|
|
171
|
+
try {
|
|
172
|
+
const config = JSON.parse(await fs.readFile(configPath, 'utf-8'));
|
|
173
|
+
const featureMapping = config.livingDocs?.hierarchyMapping?.incrementToFeature?.[incrementId];
|
|
174
|
+
if (featureMapping && typeof featureMapping === 'string') {
|
|
175
|
+
const featureFolder = await this.findFeatureFolder(featureMapping);
|
|
176
|
+
if (featureFolder) {
|
|
177
|
+
return {
|
|
178
|
+
featureId: featureMapping,
|
|
179
|
+
featureFolder,
|
|
180
|
+
featurePath: path.join(this.config.specsBaseDir, featureFolder),
|
|
181
|
+
userStoriesPath: path.join(this.config.specsBaseDir, featureFolder, this.config.userStoriesSubdir),
|
|
182
|
+
confidence: 100,
|
|
183
|
+
detectionMethod: 'config',
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
catch (error) {
|
|
189
|
+
console.warn(` ⚠️ Failed to load config: ${error}`);
|
|
190
|
+
}
|
|
191
|
+
return null;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Create fallback mapping (extract feature name from increment ID)
|
|
195
|
+
*
|
|
196
|
+
* FORMAT (v0.18.1+): Simple descriptive names (no prefixes)
|
|
197
|
+
* - Uses core feature name extracted from increment ID
|
|
198
|
+
* - No date prefixes (removed to prevent duplicates)
|
|
199
|
+
* - No FS- prefixes (features are not numbered)
|
|
200
|
+
*
|
|
201
|
+
* Example: 0023-release-management-enhancements → release-management
|
|
202
|
+
*/
|
|
203
|
+
async createFallbackMapping(incrementId) {
|
|
204
|
+
// Extract name from increment ID
|
|
205
|
+
const nameMatch = incrementId.match(/^\d+-(.+)/);
|
|
206
|
+
const fullName = nameMatch ? nameMatch[1] : 'unknown';
|
|
207
|
+
// Remove common suffixes to get core feature name
|
|
208
|
+
const suffixesToRemove = ['-enhancements', '-improvements', '-fixes', '-updates', '-v2', '-v3'];
|
|
209
|
+
let featureName = fullName;
|
|
210
|
+
for (const suffix of suffixesToRemove) {
|
|
211
|
+
if (featureName.endsWith(suffix)) {
|
|
212
|
+
featureName = featureName.slice(0, -suffix.length);
|
|
213
|
+
break;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
// Use simple feature name (no date prefix, no FS- prefix)
|
|
217
|
+
const featureFolder = featureName; // Simple: external-tool-status-sync
|
|
218
|
+
const featurePath = path.join(this.config.specsBaseDir, featureFolder);
|
|
219
|
+
const userStoriesPath = path.join(featurePath, this.config.userStoriesSubdir);
|
|
220
|
+
// Create folder if it doesn't exist
|
|
221
|
+
if (!fs.existsSync(featurePath)) {
|
|
222
|
+
console.log(` 📁 Creating new feature folder: ${featureFolder}`);
|
|
223
|
+
await fs.ensureDir(featurePath);
|
|
224
|
+
}
|
|
225
|
+
return {
|
|
226
|
+
featureId: featureFolder, // ID = folder name (external-tool-status-sync)
|
|
227
|
+
featureFolder,
|
|
228
|
+
featurePath,
|
|
229
|
+
userStoriesPath,
|
|
230
|
+
confidence: 80,
|
|
231
|
+
detectionMethod: 'fallback',
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Get increment creation date in yy-mm-dd format
|
|
236
|
+
* Tries: metadata.json → spec.md frontmatter → current date
|
|
237
|
+
*/
|
|
238
|
+
async getIncrementCreationDate(incrementId) {
|
|
239
|
+
// Try metadata.json
|
|
240
|
+
const metadataPath = path.join(this.projectRoot, '.specweave', 'increments', incrementId, 'metadata.json');
|
|
241
|
+
if (fs.existsSync(metadataPath)) {
|
|
242
|
+
try {
|
|
243
|
+
const metadata = JSON.parse(await fs.readFile(metadataPath, 'utf-8'));
|
|
244
|
+
if (metadata.created) {
|
|
245
|
+
return this.formatDateShort(metadata.created);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
catch (error) {
|
|
249
|
+
// Fall through to next method
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
// Try spec.md frontmatter
|
|
253
|
+
const specPath = path.join(this.projectRoot, '.specweave', 'increments', incrementId, 'spec.md');
|
|
254
|
+
if (fs.existsSync(specPath)) {
|
|
255
|
+
try {
|
|
256
|
+
const content = await fs.readFile(specPath, 'utf-8');
|
|
257
|
+
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
258
|
+
if (frontmatterMatch) {
|
|
259
|
+
const yaml = await import('yaml');
|
|
260
|
+
const frontmatter = yaml.parse(frontmatterMatch[1]);
|
|
261
|
+
if (frontmatter.created) {
|
|
262
|
+
return this.formatDateShort(frontmatter.created);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
catch (error) {
|
|
267
|
+
// Fall through to current date
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
// Fallback: current date
|
|
271
|
+
return this.formatDateShort(new Date().toISOString());
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Format date as yy-mm-dd
|
|
275
|
+
* Input: "2025-11-14" or "2025-11-14T12:00:00Z"
|
|
276
|
+
* Output: "25-11-14"
|
|
277
|
+
*/
|
|
278
|
+
formatDateShort(dateString) {
|
|
279
|
+
const date = new Date(dateString);
|
|
280
|
+
const yy = String(date.getFullYear()).slice(-2);
|
|
281
|
+
const mm = String(date.getMonth() + 1).padStart(2, '0');
|
|
282
|
+
const dd = String(date.getDate()).padStart(2, '0');
|
|
283
|
+
return `${yy}-${mm}-${dd}`;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* NEW: Find feature folder by name (exact match or fuzzy match)
|
|
287
|
+
*
|
|
288
|
+
* Examples:
|
|
289
|
+
* release-management → release-management/
|
|
290
|
+
* external-tool-sync → external-tool-status-sync/ (fuzzy match)
|
|
291
|
+
*/
|
|
292
|
+
async findFeatureFolder(featureName) {
|
|
293
|
+
try {
|
|
294
|
+
const folders = await fs.readdir(this.config.specsBaseDir);
|
|
295
|
+
// First: Try exact match
|
|
296
|
+
if (folders.includes(featureName)) {
|
|
297
|
+
const folderPath = path.join(this.config.specsBaseDir, featureName);
|
|
298
|
+
const stats = await fs.stat(folderPath);
|
|
299
|
+
if (stats.isDirectory()) {
|
|
300
|
+
return featureName;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
// Second: Try fuzzy match (feature name is substring of folder name)
|
|
304
|
+
for (const folder of folders) {
|
|
305
|
+
if (folder.startsWith(featureName) || folder.includes(featureName)) {
|
|
306
|
+
const folderPath = path.join(this.config.specsBaseDir, folder);
|
|
307
|
+
const stats = await fs.stat(folderPath);
|
|
308
|
+
if (stats.isDirectory() && folder !== 'README.md') {
|
|
309
|
+
return folder;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
catch (error) {
|
|
315
|
+
console.warn(` ⚠️ Failed to find feature folder for ${featureName}: ${error}`);
|
|
316
|
+
}
|
|
317
|
+
return null;
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* LEGACY: Find FS-* epic folder (for backward compatibility)
|
|
321
|
+
*/
|
|
322
|
+
async findEpicFolder(epicId) {
|
|
323
|
+
return this.findFeatureFolder(epicId);
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Get all feature folders (NEW: no FS- prefix filtering)
|
|
327
|
+
*/
|
|
328
|
+
async getAllFeatureFolders() {
|
|
329
|
+
try {
|
|
330
|
+
const folders = await fs.readdir(this.config.specsBaseDir);
|
|
331
|
+
const featureFolders = [];
|
|
332
|
+
for (const folder of folders) {
|
|
333
|
+
// Skip special files/folders
|
|
334
|
+
if (folder === 'README.md' || folder.startsWith('.') || folder.startsWith('_')) {
|
|
335
|
+
continue;
|
|
336
|
+
}
|
|
337
|
+
const folderPath = path.join(this.config.specsBaseDir, folder);
|
|
338
|
+
const stats = await fs.stat(folderPath);
|
|
339
|
+
if (stats.isDirectory()) {
|
|
340
|
+
featureFolders.push(folder);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
return featureFolders.sort();
|
|
344
|
+
}
|
|
345
|
+
catch (error) {
|
|
346
|
+
console.warn(` ⚠️ Failed to get feature folders: ${error}`);
|
|
347
|
+
return [];
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* LEGACY: Get all epic folders (for backward compatibility)
|
|
352
|
+
*/
|
|
353
|
+
async getAllEpicFolders() {
|
|
354
|
+
return this.getAllFeatureFolders();
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Validate feature folder structure (NEW: checks for FEATURE.md)
|
|
358
|
+
*/
|
|
359
|
+
async validateFeatureFolder(featureFolder) {
|
|
360
|
+
const featurePath = path.join(this.config.specsBaseDir, featureFolder);
|
|
361
|
+
const missing = [];
|
|
362
|
+
// Check FEATURE.md exists (feature overview)
|
|
363
|
+
if (!fs.existsSync(path.join(featurePath, 'FEATURE.md'))) {
|
|
364
|
+
missing.push('FEATURE.md');
|
|
365
|
+
}
|
|
366
|
+
// Note: User stories (us-*.md) go directly in feature folder, no validation needed here
|
|
367
|
+
return {
|
|
368
|
+
valid: missing.length === 0,
|
|
369
|
+
missing,
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* LEGACY: Validate epic folder structure (for backward compatibility)
|
|
374
|
+
*/
|
|
375
|
+
async validateEpicFolder(epicFolder) {
|
|
376
|
+
return this.validateFeatureFolder(epicFolder);
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Create feature folder structure if missing (NEW: creates FEATURE.md)
|
|
380
|
+
*/
|
|
381
|
+
async createFeatureFolderStructure(featureFolder, title) {
|
|
382
|
+
const featurePath = path.join(this.config.specsBaseDir, featureFolder);
|
|
383
|
+
// Create feature directory (user stories go directly here, no subfolder)
|
|
384
|
+
await fs.ensureDir(featurePath);
|
|
385
|
+
// Create FEATURE.md if missing (feature overview - high-level summary)
|
|
386
|
+
const featureFilePath = path.join(featurePath, 'FEATURE.md');
|
|
387
|
+
if (!fs.existsSync(featureFilePath)) {
|
|
388
|
+
// ID = folder name (e.g., FS-25-11-14-release-management)
|
|
389
|
+
const featureContent = `---
|
|
390
|
+
id: ${featureFolder}
|
|
391
|
+
title: "${title}"
|
|
392
|
+
type: feature
|
|
393
|
+
status: in-progress
|
|
394
|
+
priority: P1
|
|
395
|
+
created: ${new Date().toISOString().split('T')[0]}
|
|
396
|
+
last_updated: ${new Date().toISOString().split('T')[0]}
|
|
397
|
+
# External Tool Mapping
|
|
398
|
+
external_tools:
|
|
399
|
+
github:
|
|
400
|
+
type: project
|
|
401
|
+
id: null
|
|
402
|
+
url: null
|
|
403
|
+
jira:
|
|
404
|
+
type: epic
|
|
405
|
+
key: null
|
|
406
|
+
url: null
|
|
407
|
+
ado:
|
|
408
|
+
type: epic
|
|
409
|
+
id: null
|
|
410
|
+
url: null
|
|
411
|
+
---
|
|
412
|
+
|
|
413
|
+
# ${featureFolder}: ${title}
|
|
414
|
+
|
|
415
|
+
## Overview
|
|
416
|
+
|
|
417
|
+
[High-level description of this feature - what it does and why it matters]
|
|
418
|
+
|
|
419
|
+
## Business Value
|
|
420
|
+
|
|
421
|
+
[Add business value and impact]
|
|
422
|
+
|
|
423
|
+
## User Stories
|
|
424
|
+
|
|
425
|
+
User stories are in this folder as \`us-*.md\` files:
|
|
426
|
+
- us-001-*.md
|
|
427
|
+
- us-002-*.md
|
|
428
|
+
- ...
|
|
429
|
+
|
|
430
|
+
## Implementation History
|
|
431
|
+
|
|
432
|
+
| Increment | Stories Implemented | Status | Completion Date |
|
|
433
|
+
|-----------|-------------------|--------|----------------|
|
|
434
|
+
| [TBD]() | TBD | 🚧 In Progress | TBD |
|
|
435
|
+
|
|
436
|
+
## External Tool Integration
|
|
437
|
+
|
|
438
|
+
**GitHub Project**: Not yet synced
|
|
439
|
+
**Jira Epic**: Not yet synced
|
|
440
|
+
**Azure DevOps Epic**: Not yet synced
|
|
441
|
+
`;
|
|
442
|
+
await fs.writeFile(featureFilePath, featureContent, 'utf-8');
|
|
443
|
+
console.log(` ✅ Created FEATURE.md for ${featureFolder}`);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* LEGACY: Create epic folder structure (for backward compatibility)
|
|
448
|
+
*/
|
|
449
|
+
async createEpicFolderStructure(epicFolder, title) {
|
|
450
|
+
return this.createFeatureFolderStructure(epicFolder, title);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
//# sourceMappingURL=hierarchy-mapper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hierarchy-mapper.js","sourceRoot":"","sources":["../../../../src/core/living-docs/hierarchy-mapper.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,89 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Living Docs Distribution Module
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Exports:
|
|
5
|
+
* - SpecDistributor: Distributes increment specs into hierarchical living docs
|
|
6
|
+
* - HierarchyMapper: Maps increments to FS-* epic folders (Universal Hierarchy)
|
|
7
|
+
* - Types: TypeScript interfaces for living docs structure
|
|
5
8
|
*
|
|
6
|
-
* @
|
|
9
|
+
* @author SpecWeave Team
|
|
10
|
+
* @version 3.0.0
|
|
7
11
|
*/
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
import { ContentDistributor, DistributionResult, DistributorOptions } from './content-distributor.js';
|
|
12
|
-
import { CrossLinker, CrossLink, LinkerOptions } from './cross-linker.js';
|
|
13
|
-
/**
|
|
14
|
-
* Intelligent Sync options
|
|
15
|
-
*/
|
|
16
|
-
export interface IntelligentSyncOptions {
|
|
17
|
-
parser?: ParserOptions;
|
|
18
|
-
detector?: DetectorOptions;
|
|
19
|
-
distributor?: DistributorOptions;
|
|
20
|
-
linker?: LinkerOptions;
|
|
21
|
-
dryRun?: boolean;
|
|
22
|
-
verbose?: boolean;
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Complete sync result
|
|
26
|
-
*/
|
|
27
|
-
export interface IntelligentSyncResult {
|
|
28
|
-
incrementId: string;
|
|
29
|
-
project: ProjectContext;
|
|
30
|
-
spec: ParsedSpec;
|
|
31
|
-
classifications: ClassificationResult[];
|
|
32
|
-
distribution: DistributionResult;
|
|
33
|
-
links: CrossLink[];
|
|
34
|
-
duration: number;
|
|
35
|
-
success: boolean;
|
|
36
|
-
errors: string[];
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Intelligent Living Docs Sync Orchestrator
|
|
40
|
-
*/
|
|
41
|
-
export declare class IntelligentLivingDocsSync {
|
|
42
|
-
private parser;
|
|
43
|
-
private classifier;
|
|
44
|
-
private detector;
|
|
45
|
-
private distributor;
|
|
46
|
-
private linker;
|
|
47
|
-
private options;
|
|
48
|
-
constructor(options?: IntelligentSyncOptions);
|
|
49
|
-
/**
|
|
50
|
-
* Sync increment spec to living docs
|
|
51
|
-
*/
|
|
52
|
-
syncIncrement(incrementId: string): Promise<IntelligentSyncResult>;
|
|
53
|
-
/**
|
|
54
|
-
* Load and parse increment spec
|
|
55
|
-
*/
|
|
56
|
-
private loadAndParseSpec;
|
|
57
|
-
/**
|
|
58
|
-
* Generate index files for categories
|
|
59
|
-
*/
|
|
60
|
-
private generateIndexFiles;
|
|
61
|
-
/**
|
|
62
|
-
* Logging helper
|
|
63
|
-
*/
|
|
64
|
-
private log;
|
|
65
|
-
/**
|
|
66
|
-
* Get component instances (for testing/advanced usage)
|
|
67
|
-
*/
|
|
68
|
-
getComponents(): {
|
|
69
|
-
parser: ContentParser;
|
|
70
|
-
classifier: ContentClassifier;
|
|
71
|
-
detector: ProjectDetector;
|
|
72
|
-
distributor: ContentDistributor;
|
|
73
|
-
linker: CrossLinker;
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* Factory function to create sync orchestrator
|
|
78
|
-
*/
|
|
79
|
-
export declare function createIntelligentSync(options?: IntelligentSyncOptions): IntelligentLivingDocsSync;
|
|
80
|
-
/**
|
|
81
|
-
* Convenience function to sync an increment
|
|
82
|
-
*/
|
|
83
|
-
export declare function syncIncrement(incrementId: string, options?: IntelligentSyncOptions): Promise<IntelligentSyncResult>;
|
|
84
|
-
export * from './content-parser.js';
|
|
85
|
-
export * from './content-classifier.js';
|
|
86
|
-
export * from './project-detector.js';
|
|
87
|
-
export * from './content-distributor.js';
|
|
88
|
-
export * from './cross-linker.js';
|
|
12
|
+
export { SpecDistributor } from './spec-distributor.js';
|
|
13
|
+
export { HierarchyMapper } from './hierarchy-mapper.js';
|
|
14
|
+
export * from './types.js';
|
|
89
15
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/core/living-docs/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/core/living-docs/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,cAAc,YAAY,CAAC"}
|