specweave 0.30.9 → 0.30.11
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/dist/plugins/specweave-ado/lib/ado-client-v2.d.ts.map +1 -1
- package/dist/plugins/specweave-ado/lib/ado-client-v2.js +46 -12
- package/dist/plugins/specweave-ado/lib/ado-client-v2.js.map +1 -1
- package/dist/plugins/specweave-github/lib/github-feature-sync.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/github-feature-sync.js +14 -4
- package/dist/plugins/specweave-github/lib/github-feature-sync.js.map +1 -1
- package/dist/plugins/specweave-github/lib/user-story-content-builder.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/user-story-content-builder.js +5 -1
- package/dist/plugins/specweave-github/lib/user-story-content-builder.js.map +1 -1
- package/dist/plugins/specweave-github/lib/user-story-issue-builder.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/user-story-issue-builder.js +9 -2
- package/dist/plugins/specweave-github/lib/user-story-issue-builder.js.map +1 -1
- package/dist/src/cli/helpers/init/repository-setup.d.ts.map +1 -1
- package/dist/src/cli/helpers/init/repository-setup.js +64 -2
- package/dist/src/cli/helpers/init/repository-setup.js.map +1 -1
- package/dist/src/cli/helpers/project-count-fetcher.js +33 -2
- package/dist/src/cli/helpers/project-count-fetcher.js.map +1 -1
- package/dist/src/core/living-docs/living-docs-sync.d.ts +9 -0
- package/dist/src/core/living-docs/living-docs-sync.d.ts.map +1 -1
- package/dist/src/core/living-docs/living-docs-sync.js +170 -6
- package/dist/src/core/living-docs/living-docs-sync.js.map +1 -1
- package/dist/src/integrations/ado/ado-client.d.ts +22 -0
- package/dist/src/integrations/ado/ado-client.d.ts.map +1 -1
- package/dist/src/integrations/ado/ado-client.js +89 -37
- package/dist/src/integrations/ado/ado-client.js.map +1 -1
- package/package.json +1 -1
- package/plugins/specweave/commands/specweave-sync-specs.md +46 -37
- package/plugins/specweave-ado/lib/ado-client-v2.js +43 -8
- package/plugins/specweave-ado/lib/ado-client-v2.ts +52 -12
- package/plugins/specweave-github/lib/github-feature-sync.js +11 -3
- package/plugins/specweave-github/lib/github-feature-sync.ts +16 -4
- package/plugins/specweave-github/lib/user-story-content-builder.js +3 -1
- package/plugins/specweave-github/lib/user-story-content-builder.ts +5 -1
- package/plugins/specweave-github/lib/user-story-issue-builder.js +6 -2
- package/plugins/specweave-github/lib/user-story-issue-builder.ts +10 -2
- package/plugins/specweave-github/skills/github-issue-standard/SKILL.md +10 -8
|
@@ -277,10 +277,22 @@ export class GitHubFeatureSync {
|
|
|
277
277
|
* Find Feature folder in specs directory
|
|
278
278
|
*/
|
|
279
279
|
private async findFeatureFolder(featureId: string): Promise<string | null> {
|
|
280
|
-
//
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
280
|
+
// v5.0.0+: NO _features folder - features live in project folders
|
|
281
|
+
// Search all project folders for the feature
|
|
282
|
+
const projectFolders = await this.findProjectFolders();
|
|
283
|
+
|
|
284
|
+
for (const projectFolder of projectFolders) {
|
|
285
|
+
const featureFolder = path.join(projectFolder, featureId);
|
|
286
|
+
if (existsSync(featureFolder) && existsSync(path.join(featureFolder, 'FEATURE.md'))) {
|
|
287
|
+
return featureFolder;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// Legacy fallback: Check _features folder (for brownfield migration)
|
|
292
|
+
const legacyFolder = path.join(this.specsDir, '_features', featureId);
|
|
293
|
+
if (existsSync(legacyFolder)) {
|
|
294
|
+
console.log(` ⚠️ Found feature in legacy _features folder - consider migrating to project folder`);
|
|
295
|
+
return legacyFolder;
|
|
284
296
|
}
|
|
285
297
|
|
|
286
298
|
return null;
|
|
@@ -43,7 +43,9 @@ class UserStoryContentBuilder {
|
|
|
43
43
|
const priority = this.extractPriorityFromACs(content.acceptanceCriteria);
|
|
44
44
|
const repo = githubRepo || await this.detectGitHubRepo();
|
|
45
45
|
if (repo) {
|
|
46
|
-
|
|
46
|
+
const pathMatch = this.userStoryPath.match(/specs\/([^/]+)\/FS-\d+\//);
|
|
47
|
+
const projectFolder = pathMatch ? pathMatch[1] : "default";
|
|
48
|
+
body += `**Feature**: [${content.featureId}](https://github.com/${repo}/tree/develop/.specweave/docs/internal/specs/${projectFolder}/${content.featureId})
|
|
47
49
|
`;
|
|
48
50
|
} else {
|
|
49
51
|
body += `**Feature**: ${content.featureId}
|
|
@@ -123,8 +123,12 @@ export class UserStoryContentBuilder {
|
|
|
123
123
|
const repo = githubRepo || await this.detectGitHubRepo();
|
|
124
124
|
|
|
125
125
|
// Header with metadata
|
|
126
|
+
// v5.0.0+: Features live in project folders, NOT _features
|
|
127
|
+
// Extract project from path: specs/{project}/FS-XXX/us-*.md
|
|
126
128
|
if (repo) {
|
|
127
|
-
|
|
129
|
+
const pathMatch = this.userStoryPath.match(/specs\/([^/]+)\/FS-\d+\//);
|
|
130
|
+
const projectFolder = pathMatch ? pathMatch[1] : 'default';
|
|
131
|
+
body += `**Feature**: [${content.featureId}](https://github.com/${repo}/tree/develop/.specweave/docs/internal/specs/${projectFolder}/${content.featureId})\n`;
|
|
128
132
|
} else {
|
|
129
133
|
body += `**Feature**: ${content.featureId}\n`;
|
|
130
134
|
}
|
|
@@ -329,7 +329,9 @@ User Story ID: ${frontmatter.id}`
|
|
|
329
329
|
sections.push("");
|
|
330
330
|
if (this.repoOwner && this.repoName) {
|
|
331
331
|
const baseUrl = `https://github.com/${this.repoOwner}/${this.repoName}/blob/${this.branch}`;
|
|
332
|
-
|
|
332
|
+
const pathMatch = this.userStoryPath.match(/specs\/([^/]+)\/FS-\d+\//);
|
|
333
|
+
const projectFolder = pathMatch ? pathMatch[1] : "default";
|
|
334
|
+
sections.push(`- **Feature Spec**: [${this.featureId}](${baseUrl}/.specweave/docs/internal/specs/${projectFolder}/${this.featureId}/FEATURE.md)`);
|
|
333
335
|
const relativeUSPath = path.relative(this.projectRoot, this.userStoryPath);
|
|
334
336
|
sections.push(`- **User Story File**: [${path.basename(this.userStoryPath)}](${baseUrl}/${relativeUSPath})`);
|
|
335
337
|
const incrementMatch = implMatch?.[1]?.match(/\*\*Increment\*\*:\s*\[([^\]]+)\]/);
|
|
@@ -338,7 +340,9 @@ User Story ID: ${frontmatter.id}`
|
|
|
338
340
|
sections.push(`- **Increment**: [${incrementId}](${baseUrl}/.specweave/increments/${incrementId})`);
|
|
339
341
|
}
|
|
340
342
|
} else {
|
|
341
|
-
|
|
343
|
+
const pathMatch = this.userStoryPath.match(/specs\/([^/]+)\/FS-\d+\//);
|
|
344
|
+
const projectFolder = pathMatch ? pathMatch[1] : "default";
|
|
345
|
+
sections.push(`- **Feature Spec**: [${this.featureId}](../.specweave/docs/internal/specs/${projectFolder}/${this.featureId}/FEATURE.md)`);
|
|
342
346
|
sections.push(`- **User Story File**: [${path.basename(this.userStoryPath)}](${this.userStoryPath})`);
|
|
343
347
|
}
|
|
344
348
|
sections.push("");
|
|
@@ -525,11 +525,16 @@ export class UserStoryIssueBuilder {
|
|
|
525
525
|
sections.push('');
|
|
526
526
|
|
|
527
527
|
// Generate proper GitHub blob URLs
|
|
528
|
+
// v5.0.0+: Features live in project folders, NOT _features
|
|
528
529
|
if (this.repoOwner && this.repoName) {
|
|
529
530
|
const baseUrl = `https://github.com/${this.repoOwner}/${this.repoName}/blob/${this.branch}`;
|
|
530
531
|
|
|
532
|
+
// Extract project from user story path: specs/{project}/FS-XXX/us-*.md
|
|
533
|
+
const pathMatch = this.userStoryPath.match(/specs\/([^/]+)\/FS-\d+\//);
|
|
534
|
+
const projectFolder = pathMatch ? pathMatch[1] : 'default';
|
|
535
|
+
|
|
531
536
|
// Feature Spec link
|
|
532
|
-
sections.push(`- **Feature Spec**: [${this.featureId}](${baseUrl}/.specweave/docs/internal/specs
|
|
537
|
+
sections.push(`- **Feature Spec**: [${this.featureId}](${baseUrl}/.specweave/docs/internal/specs/${projectFolder}/${this.featureId}/FEATURE.md)`);
|
|
533
538
|
|
|
534
539
|
// User Story File link (relative to project root)
|
|
535
540
|
const relativeUSPath = path.relative(this.projectRoot, this.userStoryPath);
|
|
@@ -543,7 +548,10 @@ export class UserStoryIssueBuilder {
|
|
|
543
548
|
}
|
|
544
549
|
} else {
|
|
545
550
|
// Fallback to relative links if repo info not provided
|
|
546
|
-
|
|
551
|
+
// v5.0.0+: Features live in project folders, NOT _features
|
|
552
|
+
const pathMatch = this.userStoryPath.match(/specs\/([^/]+)\/FS-\d+\//);
|
|
553
|
+
const projectFolder = pathMatch ? pathMatch[1] : 'default';
|
|
554
|
+
sections.push(`- **Feature Spec**: [${this.featureId}](../.specweave/docs/internal/specs/${projectFolder}/${this.featureId}/FEATURE.md)`);
|
|
547
555
|
sections.push(`- **User Story File**: [${path.basename(this.userStoryPath)}](${this.userStoryPath})`);
|
|
548
556
|
}
|
|
549
557
|
|
|
@@ -70,12 +70,14 @@ Every GitHub issue MUST include:
|
|
|
70
70
|
- Use GitHub task checkbox format
|
|
71
71
|
- Example: `- [x] [T-008: Title](https://github.com/owner/repo/tree/develop/.specweave/increments/0031/tasks.md#t-008-title)`
|
|
72
72
|
|
|
73
|
-
3. **Working GitHub URLs**
|
|
74
|
-
- Feature links: `https://github.com/owner/repo/tree/develop/.specweave/docs/internal/specs/
|
|
75
|
-
- User story links: `https://github.com/owner/repo/tree/develop/.specweave/docs/internal/specs/
|
|
73
|
+
3. **Working GitHub URLs** (v5.0.0+ - NO _features folder)
|
|
74
|
+
- Feature links: `https://github.com/owner/repo/tree/develop/.specweave/docs/internal/specs/{project}/FS-031`
|
|
75
|
+
- User story links: `https://github.com/owner/repo/tree/develop/.specweave/docs/internal/specs/{project}/FS-031/us-004-*.md`
|
|
76
76
|
- Task links: `https://github.com/owner/repo/tree/develop/.specweave/increments/0031/tasks.md#task-anchor`
|
|
77
77
|
- Increment links: `https://github.com/owner/repo/tree/develop/.specweave/increments/0031`
|
|
78
78
|
|
|
79
|
+
**Note**: Feature ID is DERIVED from increment (0031 → FS-031)
|
|
80
|
+
|
|
79
81
|
4. **Extracted Priority**
|
|
80
82
|
- Extract from ACs (highest priority wins: P1 > P2 > P3)
|
|
81
83
|
- Show ONLY if priority exists (don't show "undefined")
|
|
@@ -87,7 +89,7 @@ Every GitHub issue MUST include:
|
|
|
87
89
|
|
|
88
90
|
### ❌ Never Use
|
|
89
91
|
|
|
90
|
-
- ❌ Relative paths (`../../
|
|
92
|
+
- ❌ Relative paths (`../../{project}/FS-031`)
|
|
91
93
|
- ❌ Undefined values (`**Priority**: undefined`)
|
|
92
94
|
- ❌ Project field in metadata
|
|
93
95
|
- ❌ Plain bullet points for ACs (must be checkboxes)
|
|
@@ -112,8 +114,8 @@ private async detectGitHubRepo(): Promise<string | null>
|
|
|
112
114
|
// 3. Extract priority from ACs
|
|
113
115
|
private extractPriorityFromACs(criteria: AcceptanceCriterion[]): string | null
|
|
114
116
|
|
|
115
|
-
// 4. Generate GitHub URLs (not relative)
|
|
116
|
-
const featureUrl = `https://github.com/${repo}/tree/develop/.specweave/docs/internal/specs
|
|
117
|
+
// 4. Generate GitHub URLs (not relative) - v5.0.0+: No _features folder
|
|
118
|
+
const featureUrl = `https://github.com/${repo}/tree/develop/.specweave/docs/internal/specs/${project}/${featureId}`;
|
|
117
119
|
|
|
118
120
|
// 5. Convert task links to GitHub URLs
|
|
119
121
|
if (repo && taskLink.startsWith('../../')) {
|
|
@@ -125,7 +127,7 @@ if (repo && taskLink.startsWith('../../')) {
|
|
|
125
127
|
### Template
|
|
126
128
|
|
|
127
129
|
```markdown
|
|
128
|
-
**Feature**: [FS-031](https://github.com/owner/repo/tree/develop/.specweave/docs/internal/specs/
|
|
130
|
+
**Feature**: [FS-031](https://github.com/owner/repo/tree/develop/.specweave/docs/internal/specs/{project}/FS-031)
|
|
129
131
|
**Status**: complete
|
|
130
132
|
**Priority**: P1
|
|
131
133
|
|
|
@@ -137,7 +139,7 @@ if (repo && taskLink.startsWith('../../')) {
|
|
|
137
139
|
**I want** feature
|
|
138
140
|
**So that** benefit
|
|
139
141
|
|
|
140
|
-
📄 View full story: [`us-004-name.md`](https://github.com/owner/repo/tree/develop/.specweave/docs/internal/specs/
|
|
142
|
+
📄 View full story: [`us-004-name.md`](https://github.com/owner/repo/tree/develop/.specweave/docs/internal/specs/{project}/FS-031/us-004-name.md)
|
|
141
143
|
|
|
142
144
|
---
|
|
143
145
|
|