specweave 0.17.15 → 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.
Files changed (166) hide show
  1. package/CLAUDE.md +405 -2495
  2. package/README.md +92 -2
  3. package/dist/plugins/specweave/lib/hooks/sync-living-docs.d.ts.map +1 -1
  4. package/dist/plugins/specweave/lib/hooks/sync-living-docs.js +188 -36
  5. package/dist/plugins/specweave/lib/hooks/sync-living-docs.js.map +1 -1
  6. package/dist/plugins/specweave-ado/lib/ado-status-sync.d.ts +54 -0
  7. package/dist/plugins/specweave-ado/lib/ado-status-sync.d.ts.map +1 -0
  8. package/dist/plugins/specweave-ado/lib/ado-status-sync.js +86 -0
  9. package/dist/plugins/specweave-ado/lib/ado-status-sync.js.map +1 -0
  10. package/dist/plugins/specweave-github/lib/duplicate-detector.d.ts +139 -0
  11. package/dist/plugins/specweave-github/lib/duplicate-detector.d.ts.map +1 -0
  12. package/dist/plugins/specweave-github/lib/duplicate-detector.js +389 -0
  13. package/dist/plugins/specweave-github/lib/duplicate-detector.js.map +1 -0
  14. package/dist/plugins/specweave-github/lib/enhanced-github-sync.d.ts +26 -0
  15. package/dist/plugins/specweave-github/lib/enhanced-github-sync.d.ts.map +1 -0
  16. package/dist/plugins/specweave-github/lib/enhanced-github-sync.js +249 -0
  17. package/dist/plugins/specweave-github/lib/enhanced-github-sync.js.map +1 -0
  18. package/dist/plugins/specweave-github/lib/github-client.d.ts +1 -1
  19. package/dist/plugins/specweave-github/lib/github-client.d.ts.map +1 -1
  20. package/dist/plugins/specweave-github/lib/github-client.js +25 -13
  21. package/dist/plugins/specweave-github/lib/github-client.js.map +1 -1
  22. package/dist/plugins/specweave-github/lib/github-epic-sync.d.ts +83 -0
  23. package/dist/plugins/specweave-github/lib/github-epic-sync.d.ts.map +1 -0
  24. package/dist/plugins/specweave-github/lib/github-epic-sync.js +451 -0
  25. package/dist/plugins/specweave-github/lib/github-epic-sync.js.map +1 -0
  26. package/dist/plugins/specweave-github/lib/github-status-sync.d.ts +43 -0
  27. package/dist/plugins/specweave-github/lib/github-status-sync.d.ts.map +1 -0
  28. package/dist/plugins/specweave-github/lib/github-status-sync.js +82 -0
  29. package/dist/plugins/specweave-github/lib/github-status-sync.js.map +1 -0
  30. package/dist/plugins/specweave-github/lib/task-sync.d.ts +5 -0
  31. package/dist/plugins/specweave-github/lib/task-sync.d.ts.map +1 -1
  32. package/dist/plugins/specweave-github/lib/task-sync.js +38 -2
  33. package/dist/plugins/specweave-github/lib/task-sync.js.map +1 -1
  34. package/dist/plugins/specweave-jira/lib/jira-epic-sync.d.ts +66 -0
  35. package/dist/plugins/specweave-jira/lib/jira-epic-sync.d.ts.map +1 -0
  36. package/dist/plugins/specweave-jira/lib/jira-epic-sync.js +274 -0
  37. package/dist/plugins/specweave-jira/lib/jira-epic-sync.js.map +1 -0
  38. package/dist/plugins/specweave-jira/lib/jira-status-sync.d.ts +56 -0
  39. package/dist/plugins/specweave-jira/lib/jira-status-sync.d.ts.map +1 -0
  40. package/dist/plugins/specweave-jira/lib/jira-status-sync.js +93 -0
  41. package/dist/plugins/specweave-jira/lib/jira-status-sync.js.map +1 -0
  42. package/dist/src/cli/helpers/issue-tracker/index.d.ts.map +1 -1
  43. package/dist/src/cli/helpers/issue-tracker/index.js +48 -3
  44. package/dist/src/cli/helpers/issue-tracker/index.js.map +1 -1
  45. package/dist/src/core/living-docs/hierarchy-mapper.d.ts +142 -0
  46. package/dist/src/core/living-docs/hierarchy-mapper.d.ts.map +1 -0
  47. package/dist/src/core/living-docs/hierarchy-mapper.js +453 -0
  48. package/dist/src/core/living-docs/hierarchy-mapper.js.map +1 -0
  49. package/dist/src/core/living-docs/index.d.ts +10 -84
  50. package/dist/src/core/living-docs/index.d.ts.map +1 -1
  51. package/dist/src/core/living-docs/index.js +10 -164
  52. package/dist/src/core/living-docs/index.js.map +1 -1
  53. package/dist/src/core/living-docs/spec-distributor.d.ts +106 -0
  54. package/dist/src/core/living-docs/spec-distributor.d.ts.map +1 -0
  55. package/dist/src/core/living-docs/spec-distributor.js +823 -0
  56. package/dist/src/core/living-docs/spec-distributor.js.map +1 -0
  57. package/dist/src/core/living-docs/types.d.ts +201 -0
  58. package/dist/src/core/living-docs/types.d.ts.map +1 -0
  59. package/dist/src/core/living-docs/types.js +15 -0
  60. package/dist/src/core/living-docs/types.js.map +1 -0
  61. package/dist/src/core/logging/prompt-logger.d.ts +70 -0
  62. package/dist/src/core/logging/prompt-logger.d.ts.map +1 -0
  63. package/dist/src/core/logging/prompt-logger.js +247 -0
  64. package/dist/src/core/logging/prompt-logger.js.map +1 -0
  65. package/dist/src/core/status-line/status-line-manager.d.ts +15 -24
  66. package/dist/src/core/status-line/status-line-manager.d.ts.map +1 -1
  67. package/dist/src/core/status-line/status-line-manager.js +33 -70
  68. package/dist/src/core/status-line/status-line-manager.js.map +1 -1
  69. package/dist/src/core/status-line/types.d.ts +19 -31
  70. package/dist/src/core/status-line/types.d.ts.map +1 -1
  71. package/dist/src/core/status-line/types.js +5 -9
  72. package/dist/src/core/status-line/types.js.map +1 -1
  73. package/dist/src/core/sync/conflict-resolver.d.ts +66 -0
  74. package/dist/src/core/sync/conflict-resolver.d.ts.map +1 -0
  75. package/dist/src/core/sync/conflict-resolver.js +108 -0
  76. package/dist/src/core/sync/conflict-resolver.js.map +1 -0
  77. package/dist/src/core/sync/enhanced-content-builder.d.ts +77 -0
  78. package/dist/src/core/sync/enhanced-content-builder.d.ts.map +1 -0
  79. package/dist/src/core/sync/enhanced-content-builder.js +199 -0
  80. package/dist/src/core/sync/enhanced-content-builder.js.map +1 -0
  81. package/dist/src/core/sync/label-detector.d.ts +66 -0
  82. package/dist/src/core/sync/label-detector.d.ts.map +1 -0
  83. package/dist/src/core/sync/label-detector.js +211 -0
  84. package/dist/src/core/sync/label-detector.js.map +1 -0
  85. package/dist/src/core/sync/retry-logic.d.ts +64 -0
  86. package/dist/src/core/sync/retry-logic.d.ts.map +1 -0
  87. package/dist/src/core/sync/retry-logic.js +165 -0
  88. package/dist/src/core/sync/retry-logic.js.map +1 -0
  89. package/dist/src/core/sync/spec-increment-mapper.d.ts +100 -0
  90. package/dist/src/core/sync/spec-increment-mapper.d.ts.map +1 -0
  91. package/dist/src/core/sync/spec-increment-mapper.js +424 -0
  92. package/dist/src/core/sync/spec-increment-mapper.js.map +1 -0
  93. package/dist/src/core/sync/status-cache.d.ts +91 -0
  94. package/dist/src/core/sync/status-cache.d.ts.map +1 -0
  95. package/dist/src/core/sync/status-cache.js +140 -0
  96. package/dist/src/core/sync/status-cache.js.map +1 -0
  97. package/dist/src/core/sync/status-mapper.d.ts +69 -0
  98. package/dist/src/core/sync/status-mapper.d.ts.map +1 -0
  99. package/dist/src/core/sync/status-mapper.js +90 -0
  100. package/dist/src/core/sync/status-mapper.js.map +1 -0
  101. package/dist/src/core/sync/status-sync-engine.d.ts +162 -0
  102. package/dist/src/core/sync/status-sync-engine.d.ts.map +1 -0
  103. package/dist/src/core/sync/status-sync-engine.js +347 -0
  104. package/dist/src/core/sync/status-sync-engine.js.map +1 -0
  105. package/dist/src/core/sync/sync-event-logger.d.ts +99 -0
  106. package/dist/src/core/sync/sync-event-logger.d.ts.map +1 -0
  107. package/dist/src/core/sync/sync-event-logger.js +103 -0
  108. package/dist/src/core/sync/sync-event-logger.js.map +1 -0
  109. package/dist/src/core/sync/workflow-detector.d.ts +95 -0
  110. package/dist/src/core/sync/workflow-detector.d.ts.map +1 -0
  111. package/dist/src/core/sync/workflow-detector.js +175 -0
  112. package/dist/src/core/sync/workflow-detector.js.map +1 -0
  113. package/dist/src/core/types/config.d.ts.map +1 -1
  114. package/dist/src/core/types/config.js +31 -0
  115. package/dist/src/core/types/config.js.map +1 -1
  116. package/dist/src/utils/github-url.d.ts +53 -0
  117. package/dist/src/utils/github-url.d.ts.map +1 -0
  118. package/dist/src/utils/github-url.js +90 -0
  119. package/dist/src/utils/github-url.js.map +1 -0
  120. package/dist/src/utils/plugin-validator.d.ts +9 -0
  121. package/dist/src/utils/plugin-validator.d.ts.map +1 -1
  122. package/dist/src/utils/plugin-validator.js +86 -19
  123. package/dist/src/utils/plugin-validator.js.map +1 -1
  124. package/dist/src/utils/spec-parser.d.ts +145 -0
  125. package/dist/src/utils/spec-parser.d.ts.map +1 -0
  126. package/dist/src/utils/spec-parser.js +640 -0
  127. package/dist/src/utils/spec-parser.js.map +1 -0
  128. package/package.json +1 -1
  129. package/plugins/specweave/agents/pm/AGENT.md +1 -1
  130. package/plugins/specweave/agents/pm/templates/increment-spec.md +158 -0
  131. package/plugins/specweave/agents/pm/templates/living-docs-spec.md +113 -0
  132. package/plugins/specweave/commands/specweave-done.md +163 -0
  133. package/plugins/specweave/hooks/lib/update-status-line.sh +79 -111
  134. package/plugins/specweave/hooks/post-increment-planning.sh +107 -35
  135. package/plugins/specweave/lib/hooks/sync-living-docs.js +139 -34
  136. package/plugins/specweave/lib/hooks/sync-living-docs.ts +234 -38
  137. package/plugins/specweave/skills/SKILLS-INDEX.md +4 -24
  138. package/plugins/specweave/skills/increment-planner/SKILL.md +94 -0
  139. package/plugins/specweave/skills/increment-work-router/SKILL.md +466 -0
  140. package/plugins/specweave/skills/plugin-validator/SKILL.md +16 -13
  141. package/plugins/specweave-ado/lib/ado-status-sync.js +80 -0
  142. package/plugins/specweave-ado/lib/ado-status-sync.ts +121 -0
  143. package/plugins/specweave-github/commands/specweave-github-cleanup-duplicates.md +205 -0
  144. package/plugins/specweave-github/commands/specweave-github-sync-epic.md +248 -0
  145. package/plugins/specweave-github/lib/duplicate-detector.js +370 -0
  146. package/plugins/specweave-github/lib/duplicate-detector.ts +525 -0
  147. package/plugins/specweave-github/lib/enhanced-github-sync.js +220 -0
  148. package/plugins/specweave-github/lib/enhanced-github-sync.ts +322 -0
  149. package/plugins/specweave-github/lib/github-client.js +21 -10
  150. package/plugins/specweave-github/lib/github-client.ts +27 -16
  151. package/plugins/specweave-github/lib/github-epic-sync.js +489 -0
  152. package/plugins/specweave-github/lib/github-epic-sync.ts +690 -0
  153. package/plugins/specweave-github/lib/github-status-sync.js +71 -0
  154. package/plugins/specweave-github/lib/github-status-sync.ts +107 -0
  155. package/plugins/specweave-github/lib/task-sync.js +33 -2
  156. package/plugins/specweave-github/lib/task-sync.ts +44 -2
  157. package/plugins/specweave-jira/commands/specweave-jira-sync-epic.md +267 -0
  158. package/plugins/specweave-jira/lib/enhanced-jira-sync.ts.disabled +222 -0
  159. package/plugins/specweave-jira/lib/jira-epic-sync.js +304 -0
  160. package/plugins/specweave-jira/lib/jira-epic-sync.ts +459 -0
  161. package/plugins/specweave-jira/lib/jira-status-sync.js +79 -0
  162. package/plugins/specweave-jira/lib/jira-status-sync.ts +139 -0
  163. package/src/templates/AGENTS.md.template +88 -1
  164. package/src/templates/CLAUDE.md.template +49 -0
  165. package/plugins/specweave/skills/increment-quality-judge/SKILL.md +0 -524
  166. package/plugins/specweave/skills/plugin-installer/SKILL.md +0 -353
@@ -0,0 +1,451 @@
1
+ /**
2
+ * GitHub Epic Sync - Hierarchical synchronization for Epic folder structure
3
+ *
4
+ * Architecture:
5
+ * - Epic (FS-001) → GitHub Milestone
6
+ * - Increment (0001-core-framework) → GitHub Issue (linked to Milestone)
7
+ *
8
+ * This implements the Universal Hierarchy architecture for GitHub.
9
+ */
10
+ import { readdir, readFile, writeFile } from 'fs/promises';
11
+ import { existsSync } from 'fs';
12
+ import * as path from 'path';
13
+ import * as yaml from 'yaml';
14
+ import { execFileNoThrow } from '../../../src/utils/execFileNoThrow.js';
15
+ import { DuplicateDetector } from './duplicate-detector.js';
16
+ export class GitHubEpicSync {
17
+ constructor(client, specsDir) {
18
+ this.client = client;
19
+ this.specsDir = specsDir;
20
+ }
21
+ /**
22
+ * Sync Epic folder to GitHub (Milestone + Issues)
23
+ */
24
+ async syncEpicToGitHub(epicId) {
25
+ console.log(`\n🔄 Syncing Epic ${epicId} to GitHub...`);
26
+ // 1. Load Epic FEATURE.md
27
+ const epicFolder = await this.findEpicFolder(epicId);
28
+ if (!epicFolder) {
29
+ throw new Error(`Epic ${epicId} not found in ${this.specsDir}`);
30
+ }
31
+ const readmePath = path.join(epicFolder, 'FEATURE.md');
32
+ const epicData = await this.parseEpicReadme(readmePath);
33
+ console.log(` 📦 Epic: ${epicData.title}`);
34
+ console.log(` 📊 Increments: ${epicData.total_increments}`);
35
+ // 2. Create or update GitHub Milestone
36
+ let milestoneNumber = epicData.external_tools.github.id;
37
+ let milestoneUrl = epicData.external_tools.github.url;
38
+ if (!milestoneNumber) {
39
+ console.log(` 🚀 Creating GitHub Milestone...`);
40
+ const milestone = await this.createMilestone(epicData);
41
+ milestoneNumber = milestone.number;
42
+ milestoneUrl = milestone.url;
43
+ console.log(` ✅ Created Milestone #${milestoneNumber}`);
44
+ // Update Epic README with Milestone ID
45
+ await this.updateEpicReadme(readmePath, {
46
+ type: 'milestone',
47
+ id: milestoneNumber,
48
+ url: milestoneUrl,
49
+ });
50
+ }
51
+ else {
52
+ console.log(` ♻️ Updating existing Milestone #${milestoneNumber}...`);
53
+ await this.updateMilestone(milestoneNumber, epicData);
54
+ console.log(` ✅ Updated Milestone #${milestoneNumber}`);
55
+ }
56
+ // 3. Sync each increment as GitHub Issue (WITH DUPLICATE DETECTION!)
57
+ let issuesCreated = 0;
58
+ let issuesUpdated = 0;
59
+ let duplicatesDetected = 0;
60
+ console.log(`\n 📝 Syncing ${epicData.increments.length} increments...`);
61
+ for (const increment of epicData.increments) {
62
+ const incrementFile = path.join(epicFolder, `${increment.id}.md`);
63
+ if (!existsSync(incrementFile)) {
64
+ console.log(` ⚠️ Increment file not found: ${increment.id}.md`);
65
+ continue;
66
+ }
67
+ const incrementData = await this.parseIncrementFile(incrementFile);
68
+ const existingIssue = increment.external.github;
69
+ if (!existingIssue) {
70
+ // NEW: Check GitHub FIRST before creating (duplicate detection!)
71
+ console.log(` 🔍 Checking GitHub for existing issue: ${increment.id}...`);
72
+ const githubIssue = await this.findExistingIssue(epicData.id, increment.id);
73
+ if (githubIssue) {
74
+ // Found existing issue! Re-link it instead of creating duplicate
75
+ console.log(` ♻️ Found existing Issue #${githubIssue} for ${increment.id} (self-healing)`);
76
+ await this.updateIncrementExternalLink(readmePath, incrementFile, increment.id, githubIssue);
77
+ issuesUpdated++;
78
+ duplicatesDetected++;
79
+ }
80
+ else {
81
+ // Truly new issue - create it
82
+ const issueNumber = await this.createIssue(epicData.id, incrementData, milestoneNumber);
83
+ issuesCreated++;
84
+ console.log(` ✅ Created Issue #${issueNumber} for ${increment.id}`);
85
+ // Update Epic README and Increment file
86
+ await this.updateIncrementExternalLink(readmePath, incrementFile, increment.id, issueNumber);
87
+ }
88
+ }
89
+ else {
90
+ // Update existing issue
91
+ await this.updateIssue(epicData.id, existingIssue, incrementData, milestoneNumber);
92
+ issuesUpdated++;
93
+ console.log(` ♻️ Updated Issue #${existingIssue} for ${increment.id}`);
94
+ }
95
+ }
96
+ console.log(`\n✅ Epic sync complete!`);
97
+ console.log(` Milestone: ${milestoneUrl}`);
98
+ console.log(` Issues created: ${issuesCreated}`);
99
+ console.log(` Issues updated: ${issuesUpdated}`);
100
+ if (duplicatesDetected > 0) {
101
+ console.log(` 🔗 Self-healed: ${duplicatesDetected} (found existing issues)`);
102
+ }
103
+ // 4. Post-sync validation: Check for duplicates
104
+ console.log(`\n🔍 Post-sync validation...`);
105
+ const validation = await this.validateSync(epicData.id);
106
+ if (validation.duplicatesFound > 0) {
107
+ console.warn(`\n⚠️ WARNING: ${validation.duplicatesFound} duplicate(s) detected!`);
108
+ console.warn(` This may indicate a previous sync created duplicates.`);
109
+ console.warn(` Run cleanup command to resolve:`);
110
+ console.warn(` /specweave-github:cleanup-duplicates ${epicData.id}`);
111
+ console.warn(`\n Duplicate groups:`);
112
+ for (const [title, numbers] of validation.duplicateGroups) {
113
+ console.warn(` - "${title}": Issues #${numbers.join(', #')}`);
114
+ }
115
+ }
116
+ else {
117
+ console.log(` ✅ No duplicates found`);
118
+ }
119
+ return {
120
+ milestoneNumber: milestoneNumber,
121
+ milestoneUrl: milestoneUrl,
122
+ issuesCreated,
123
+ issuesUpdated,
124
+ duplicatesDetected,
125
+ };
126
+ }
127
+ /**
128
+ * Validate sync results - check for duplicate issues
129
+ *
130
+ * Searches GitHub for all issues with the Epic ID and detects duplicates
131
+ * (multiple issues with the same title).
132
+ *
133
+ * @param epicId - Epic ID (e.g., FS-031)
134
+ * @returns Validation result with duplicate count and groups
135
+ */
136
+ async validateSync(epicId) {
137
+ try {
138
+ // Search for all issues with Epic ID in title
139
+ const titlePattern = `[${epicId}]`;
140
+ const result = await execFileNoThrow('gh', [
141
+ 'issue',
142
+ 'list',
143
+ '--search',
144
+ `"${titlePattern}" in:title`,
145
+ '--json',
146
+ 'number,title,state',
147
+ '--limit',
148
+ '100', // Check up to 100 issues
149
+ '--state',
150
+ 'all', // Include both open and closed
151
+ ]);
152
+ if (result.exitCode !== 0 || !result.stdout) {
153
+ console.warn(` ⚠️ Validation failed: ${result.stderr || 'unknown error'}`);
154
+ return { totalIssues: 0, duplicatesFound: 0, duplicateGroups: [] };
155
+ }
156
+ const issues = JSON.parse(result.stdout);
157
+ // Group issues by title
158
+ const titleGroups = new Map();
159
+ for (const issue of issues) {
160
+ const title = issue.title;
161
+ if (!titleGroups.has(title)) {
162
+ titleGroups.set(title, []);
163
+ }
164
+ titleGroups.get(title).push(issue.number);
165
+ }
166
+ // Find duplicates (titles with more than one issue)
167
+ const duplicateGroups = [];
168
+ for (const [title, numbers] of titleGroups.entries()) {
169
+ if (numbers.length > 1) {
170
+ duplicateGroups.push([title, numbers]);
171
+ }
172
+ }
173
+ return {
174
+ totalIssues: issues.length,
175
+ duplicatesFound: duplicateGroups.length,
176
+ duplicateGroups,
177
+ };
178
+ }
179
+ catch (error) {
180
+ console.warn(` ⚠️ Validation error: ${error}`);
181
+ return { totalIssues: 0, duplicatesFound: 0, duplicateGroups: [] };
182
+ }
183
+ }
184
+ /**
185
+ * Find existing GitHub issue for increment (duplicate detection!)
186
+ *
187
+ * Searches GitHub for issues matching the Epic ID and Increment ID.
188
+ * This prevents creating duplicates when frontmatter is lost/corrupted.
189
+ *
190
+ * @param epicId - Epic ID (e.g., FS-031)
191
+ * @param incrementId - Increment ID (e.g., 0031-feature-name)
192
+ * @returns GitHub issue number if found, null otherwise
193
+ */
194
+ async findExistingIssue(epicId, incrementId) {
195
+ try {
196
+ // Search GitHub for issues with Epic ID in title
197
+ // Pattern: "[FS-031] Title" or "[INC-0031] Title"
198
+ const titlePattern = `[${epicId}]`;
199
+ const result = await execFileNoThrow('gh', [
200
+ 'issue',
201
+ 'list',
202
+ '--search',
203
+ `"${titlePattern}" in:title`,
204
+ '--json',
205
+ 'number,title,body',
206
+ '--limit',
207
+ '50', // Check up to 50 issues (should cover most Epics)
208
+ ]);
209
+ if (result.exitCode !== 0 || !result.stdout) {
210
+ console.warn(` ⚠️ GitHub search failed: ${result.stderr || 'unknown error'}`);
211
+ return null;
212
+ }
213
+ const issues = JSON.parse(result.stdout);
214
+ if (issues.length === 0) {
215
+ return null; // No issues found for this Epic
216
+ }
217
+ // Find issue that mentions this increment ID in body
218
+ // Look for patterns like "**Increment**: 0031-feature-name"
219
+ for (const issue of issues) {
220
+ if (issue.body && issue.body.includes(`**Increment**: ${incrementId}`)) {
221
+ console.log(` 🔗 Found existing issue #${issue.number} for ${incrementId}`);
222
+ return issue.number;
223
+ }
224
+ }
225
+ // Fallback: Check if increment ID is in title
226
+ // Pattern: "[INC-0031-feature-name] Title"
227
+ for (const issue of issues) {
228
+ if (issue.title.toLowerCase().includes(incrementId.toLowerCase())) {
229
+ console.log(` 🔗 Found existing issue #${issue.number} for ${incrementId} (title match)`);
230
+ return issue.number;
231
+ }
232
+ }
233
+ return null; // No matching issue found
234
+ }
235
+ catch (error) {
236
+ console.warn(` ⚠️ Error searching for existing issue: ${error}`);
237
+ return null; // Fail gracefully - continue with sync
238
+ }
239
+ }
240
+ /**
241
+ * Find Epic folder by ID (FS-001 or just 001)
242
+ */
243
+ async findEpicFolder(epicId) {
244
+ const normalizedId = epicId.startsWith('FS-')
245
+ ? epicId
246
+ : `FS-${epicId.padStart(3, '0')}`;
247
+ const folders = await readdir(this.specsDir);
248
+ for (const folder of folders) {
249
+ if (folder.startsWith(normalizedId)) {
250
+ return path.join(this.specsDir, folder);
251
+ }
252
+ }
253
+ return null;
254
+ }
255
+ /**
256
+ * Parse Epic FEATURE.md to extract frontmatter
257
+ */
258
+ async parseEpicReadme(readmePath) {
259
+ const content = await readFile(readmePath, 'utf-8');
260
+ const match = content.match(/^---\n([\s\S]*?)\n---/);
261
+ if (!match) {
262
+ throw new Error('Epic FEATURE.md missing YAML frontmatter');
263
+ }
264
+ const frontmatter = yaml.parse(match[1]);
265
+ return frontmatter;
266
+ }
267
+ /**
268
+ * Parse increment file to extract title and overview
269
+ */
270
+ async parseIncrementFile(filePath) {
271
+ const content = await readFile(filePath, 'utf-8');
272
+ const match = content.match(/^---\n([\s\S]*?)\n---/);
273
+ let frontmatter = { id: '', epic: '' };
274
+ let bodyContent = content;
275
+ if (match) {
276
+ frontmatter = yaml.parse(match[1]);
277
+ bodyContent = content.slice(match[0].length).trim();
278
+ }
279
+ // Extract title
280
+ const titleMatch = bodyContent.match(/^#\s+(.+)$/m);
281
+ const title = titleMatch
282
+ ? titleMatch[1].trim()
283
+ : frontmatter.id || path.basename(filePath, '.md');
284
+ // Extract overview (first paragraph after title)
285
+ const overviewMatch = bodyContent.match(/^#[^\n]+\n+([^\n]+)/);
286
+ const overview = overviewMatch
287
+ ? overviewMatch[1].trim()
288
+ : 'No overview available';
289
+ return {
290
+ id: frontmatter.id,
291
+ title,
292
+ overview,
293
+ content: bodyContent,
294
+ frontmatter,
295
+ };
296
+ }
297
+ /**
298
+ * Create GitHub Milestone
299
+ */
300
+ async createMilestone(epic) {
301
+ const title = `[${epic.id}] ${epic.title}`;
302
+ const description = `Epic: ${epic.title}\n\nProgress: ${epic.completed_increments}/${epic.total_increments} increments (${epic.progress})\n\nPriority: ${epic.priority}\nStatus: ${epic.status}`;
303
+ // Determine milestone state
304
+ const state = epic.status === 'complete' ? 'closed' : 'open';
305
+ // Use GitHub CLI to create milestone
306
+ const result = await execFileNoThrow('gh', [
307
+ 'api',
308
+ '/repos/{owner}/{repo}/milestones',
309
+ '-X',
310
+ 'POST',
311
+ '-f',
312
+ `title=${title}`,
313
+ '-f',
314
+ `description=${description}`,
315
+ '-f',
316
+ `state=${state}`,
317
+ ]);
318
+ if (result.exitCode !== 0) {
319
+ throw new Error(`Failed to create GitHub Milestone: ${result.stderr || result.stdout}`);
320
+ }
321
+ const milestone = JSON.parse(result.stdout);
322
+ return {
323
+ number: milestone.number,
324
+ url: milestone.html_url,
325
+ };
326
+ }
327
+ /**
328
+ * Update GitHub Milestone
329
+ */
330
+ async updateMilestone(milestoneNumber, epic) {
331
+ const title = `[${epic.id}] ${epic.title}`;
332
+ const description = `Epic: ${epic.title}\n\nProgress: ${epic.completed_increments}/${epic.total_increments} increments (${epic.progress})\n\nPriority: ${epic.priority}\nStatus: ${epic.status}`;
333
+ const state = epic.status === 'complete' ? 'closed' : 'open';
334
+ const result = await execFileNoThrow('gh', [
335
+ 'api',
336
+ `/repos/{owner}/{repo}/milestones/${milestoneNumber}`,
337
+ '-X',
338
+ 'PATCH',
339
+ '-f',
340
+ `title=${title}`,
341
+ '-f',
342
+ `description=${description}`,
343
+ '-f',
344
+ `state=${state}`,
345
+ ]);
346
+ if (result.exitCode !== 0) {
347
+ throw new Error(`Failed to update GitHub Milestone: ${result.stderr || result.stdout}`);
348
+ }
349
+ }
350
+ /**
351
+ * Create GitHub Issue for increment with FULL DUPLICATE PROTECTION
352
+ */
353
+ async createIssue(epicId, increment, milestoneNumber) {
354
+ const title = `[${epicId}] ${increment.title}`;
355
+ const body = `# ${increment.title}\n\n${increment.overview}\n\n---\n\n**Increment**: ${increment.id}\n**Epic**: ${epicId}\n**Milestone**: See milestone for Epic progress\n\n🤖 Auto-created by SpecWeave Epic Sync`;
356
+ try {
357
+ // Use DuplicateDetector for full 3-phase protection
358
+ const result = await DuplicateDetector.createWithProtection({
359
+ title,
360
+ body,
361
+ titlePattern: `[${epicId}]`,
362
+ incrementId: increment.id, // For body matching
363
+ labels: ['increment', 'epic-sync'],
364
+ milestone: milestoneNumber.toString()
365
+ });
366
+ // Log duplicate detection results
367
+ if (result.wasReused) {
368
+ console.log(` ♻️ Reused existing issue #${result.issue.number} (duplicate prevention)`);
369
+ }
370
+ if (result.duplicatesFound > 0) {
371
+ console.log(` 🛡️ Duplicates: ${result.duplicatesFound} found, ${result.duplicatesClosed} closed`);
372
+ }
373
+ return result.issue.number;
374
+ }
375
+ catch (error) {
376
+ throw new Error(`Failed to create GitHub Issue: ${error.message}`);
377
+ }
378
+ }
379
+ /**
380
+ * Update GitHub Issue for increment
381
+ */
382
+ async updateIssue(epicId, issueNumber, increment, milestoneNumber) {
383
+ const title = `[${epicId}] ${increment.title}`;
384
+ const body = `# ${increment.title}\n\n${increment.overview}\n\n---\n\n**Increment**: ${increment.id}\n**Epic**: ${epicId}\n**Milestone**: See milestone for Epic progress\n\n🤖 Auto-updated by SpecWeave Epic Sync`;
385
+ const result = await execFileNoThrow('gh', [
386
+ 'issue',
387
+ 'edit',
388
+ issueNumber.toString(),
389
+ '--title',
390
+ title,
391
+ '--body',
392
+ body,
393
+ '--milestone',
394
+ milestoneNumber.toString(),
395
+ ]);
396
+ if (result.exitCode !== 0) {
397
+ throw new Error(`Failed to update GitHub Issue: ${result.stderr || result.stdout}`);
398
+ }
399
+ }
400
+ /**
401
+ * Update Epic FEATURE.md with GitHub Milestone ID
402
+ */
403
+ async updateEpicReadme(readmePath, github) {
404
+ const content = await readFile(readmePath, 'utf-8');
405
+ const match = content.match(/^---\n([\s\S]*?)\n---/);
406
+ if (!match) {
407
+ throw new Error('Epic FEATURE.md missing YAML frontmatter');
408
+ }
409
+ const frontmatter = yaml.parse(match[1]);
410
+ frontmatter.external_tools.github = github;
411
+ const newFrontmatter = yaml.stringify(frontmatter);
412
+ const newContent = content.replace(/^---\n[\s\S]*?\n---/, `---\n${newFrontmatter}---`);
413
+ await writeFile(readmePath, newContent, 'utf-8');
414
+ }
415
+ /**
416
+ * Update increment external link in both Epic README and increment file
417
+ */
418
+ async updateIncrementExternalLink(readmePath, incrementFile, incrementId, issueNumber) {
419
+ const issueUrl = `https://github.com/{owner}/{repo}/issues/${issueNumber}`;
420
+ // 1. Update Epic FEATURE.md
421
+ const readmeContent = await readFile(readmePath, 'utf-8');
422
+ const readmeMatch = readmeContent.match(/^---\n([\s\S]*?)\n---/);
423
+ if (readmeMatch) {
424
+ const frontmatter = yaml.parse(readmeMatch[1]);
425
+ const increment = frontmatter.increments.find((inc) => inc.id === incrementId);
426
+ if (increment) {
427
+ increment.external.github = issueNumber;
428
+ const newFrontmatter = yaml.stringify(frontmatter);
429
+ const newContent = readmeContent.replace(/^---\n[\s\S]*?\n---/, `---\n${newFrontmatter}---`);
430
+ await writeFile(readmePath, newContent, 'utf-8');
431
+ }
432
+ }
433
+ // 2. Update increment file frontmatter
434
+ const incrementContent = await readFile(incrementFile, 'utf-8');
435
+ const incrementMatch = incrementContent.match(/^---\n([\s\S]*?)\n---/);
436
+ if (incrementMatch) {
437
+ const frontmatter = yaml.parse(incrementMatch[1]);
438
+ if (!frontmatter.external) {
439
+ frontmatter.external = {};
440
+ }
441
+ frontmatter.external.github = {
442
+ issue: issueNumber,
443
+ url: issueUrl,
444
+ };
445
+ const newFrontmatter = yaml.stringify(frontmatter);
446
+ const newContent = incrementContent.replace(/^---\n[\s\S]*?\n---/, `---\n${newFrontmatter}---`);
447
+ await writeFile(incrementFile, newContent, 'utf-8');
448
+ }
449
+ }
450
+ }
451
+ //# sourceMappingURL=github-epic-sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-epic-sync.js","sourceRoot":"","sources":["../../../../plugins/specweave-github/lib/github-epic-sync.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * GitHub Status Sync
3
+ *
4
+ * Synchronizes SpecWeave increment statuses with GitHub issues.
5
+ *
6
+ * Responsibilities:
7
+ * - Get current status from GitHub issue
8
+ * - Update GitHub issue state and labels
9
+ * - Post status change comments
10
+ */
11
+ export interface ExternalStatus {
12
+ state: string;
13
+ labels?: string[];
14
+ }
15
+ export declare class GitHubStatusSync {
16
+ private octokit;
17
+ private owner;
18
+ private repo;
19
+ constructor(token: string, owner: string, repo: string);
20
+ /**
21
+ * Get current status from GitHub issue
22
+ *
23
+ * @param issueNumber - GitHub issue number
24
+ * @returns External status with state and labels
25
+ */
26
+ getStatus(issueNumber: number): Promise<ExternalStatus>;
27
+ /**
28
+ * Update GitHub issue status
29
+ *
30
+ * @param issueNumber - GitHub issue number
31
+ * @param status - New status (state and labels)
32
+ */
33
+ updateStatus(issueNumber: number, status: ExternalStatus): Promise<void>;
34
+ /**
35
+ * Post status change comment to GitHub issue
36
+ *
37
+ * @param issueNumber - GitHub issue number
38
+ * @param oldStatus - Previous SpecWeave status
39
+ * @param newStatus - New SpecWeave status
40
+ */
41
+ postStatusComment(issueNumber: number, oldStatus: string, newStatus: string): Promise<void>;
42
+ }
43
+ //# sourceMappingURL=github-status-sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-status-sync.d.ts","sourceRoot":"","sources":["../../../../plugins/specweave-github/lib/github-status-sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,IAAI,CAAS;gBAET,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IAMtD;;;;;OAKG;IACU,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAiBpE;;;;;OAKG;IACU,YAAY,CACvB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,IAAI,CAAC;IAgBhB;;;;;;OAMG;IACU,iBAAiB,CAC5B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC;CAkBjB"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * GitHub Status Sync
3
+ *
4
+ * Synchronizes SpecWeave increment statuses with GitHub issues.
5
+ *
6
+ * Responsibilities:
7
+ * - Get current status from GitHub issue
8
+ * - Update GitHub issue state and labels
9
+ * - Post status change comments
10
+ */
11
+ import { Octokit } from '@octokit/rest';
12
+ export class GitHubStatusSync {
13
+ constructor(token, owner, repo) {
14
+ this.octokit = new Octokit({ auth: token });
15
+ this.owner = owner;
16
+ this.repo = repo;
17
+ }
18
+ /**
19
+ * Get current status from GitHub issue
20
+ *
21
+ * @param issueNumber - GitHub issue number
22
+ * @returns External status with state and labels
23
+ */
24
+ async getStatus(issueNumber) {
25
+ const response = await this.octokit.rest.issues.get({
26
+ owner: this.owner,
27
+ repo: this.repo,
28
+ issue_number: issueNumber
29
+ });
30
+ const labels = response.data.labels
31
+ .map((label) => (typeof label === 'string' ? label : label.name))
32
+ .filter(Boolean);
33
+ return {
34
+ state: response.data.state,
35
+ labels
36
+ };
37
+ }
38
+ /**
39
+ * Update GitHub issue status
40
+ *
41
+ * @param issueNumber - GitHub issue number
42
+ * @param status - New status (state and labels)
43
+ */
44
+ async updateStatus(issueNumber, status) {
45
+ const updateData = {
46
+ owner: this.owner,
47
+ repo: this.repo,
48
+ issue_number: issueNumber,
49
+ state: status.state
50
+ };
51
+ // Add labels if provided
52
+ if (status.labels && status.labels.length > 0) {
53
+ updateData.labels = status.labels;
54
+ }
55
+ await this.octokit.rest.issues.update(updateData);
56
+ }
57
+ /**
58
+ * Post status change comment to GitHub issue
59
+ *
60
+ * @param issueNumber - GitHub issue number
61
+ * @param oldStatus - Previous SpecWeave status
62
+ * @param newStatus - New SpecWeave status
63
+ */
64
+ async postStatusComment(issueNumber, oldStatus, newStatus) {
65
+ const timestamp = new Date().toISOString();
66
+ const body = `🔄 **Status Update**
67
+
68
+ SpecWeave increment status changed:
69
+ - **From**: ${oldStatus}
70
+ - **To**: ${newStatus}
71
+ - **When**: ${timestamp}
72
+
73
+ This update was automatically synchronized by SpecWeave.`;
74
+ await this.octokit.rest.issues.createComment({
75
+ owner: this.owner,
76
+ repo: this.repo,
77
+ issue_number: issueNumber,
78
+ body
79
+ });
80
+ }
81
+ }
82
+ //# sourceMappingURL=github-status-sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-status-sync.js","sourceRoot":"","sources":["../../../../plugins/specweave-github/lib/github-status-sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAOxC,MAAM,OAAO,gBAAgB;IAK3B,YAAY,KAAa,EAAE,KAAa,EAAE,IAAY;QACpD,IAAI,CAAC,OAAO,GAAG,IAAI,OAAO,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAC5C,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED;;;;;OAKG;IACI,KAAK,CAAC,SAAS,CAAC,WAAmB;QACxC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;YAClD,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,YAAY,EAAE,WAAW;SAC1B,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM;aAChC,GAAG,CAAC,CAAC,KAAU,EAAE,EAAE,CAAC,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;aACrE,MAAM,CAAC,OAAO,CAAC,CAAC;QAEnB,OAAO;YACL,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,KAAK;YAC1B,MAAM;SACP,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACI,KAAK,CAAC,YAAY,CACvB,WAAmB,EACnB,MAAsB;QAEtB,MAAM,UAAU,GAAQ;YACtB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,YAAY,EAAE,WAAW;YACzB,KAAK,EAAE,MAAM,CAAC,KAAK;SACpB,CAAC;QAEF,yBAAyB;QACzB,IAAI,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9C,UAAU,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QACpC,CAAC;QAED,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IACpD,CAAC;IAED;;;;;;OAMG;IACI,KAAK,CAAC,iBAAiB,CAC5B,WAAmB,EACnB,SAAiB,EACjB,SAAiB;QAEjB,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC3C,MAAM,IAAI,GAAG;;;cAGH,SAAS;YACX,SAAS;cACP,SAAS;;yDAEkC,CAAC;QAEtD,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC;YAC3C,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,YAAY,EAAE,WAAW;YACzB,IAAI;SACL,CAAC,CAAC;IACL,CAAC;CACF"}
@@ -27,6 +27,11 @@ export declare class TaskSync {
27
27
  * Save increment metadata
28
28
  */
29
29
  private saveIncrementMetadata;
30
+ /**
31
+ * Get issue prefix from metadata.json (with created date)
32
+ * Returns FS-YY-MM-DD format or fallback to FS-UNKNOWN
33
+ */
34
+ private getIssuePrefix;
30
35
  /**
31
36
  * Save sync mapping
32
37
  */
@@ -1 +1 @@
1
- {"version":3,"file":"task-sync.d.ts","sourceRoot":"","sources":["../../../../plugins/specweave-github/lib/task-sync.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,EAA2B,UAAU,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEjF,qBAAa,QAAQ;IACnB,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,aAAa,CAAS;gBAElB,aAAa,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM;IAKhD;;OAEG;IACG,SAAS,CAAC,OAAO,GAAE,iBAAsB,GAAG,OAAO,CAAC,UAAU,CAAC;IAkKrE;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAsDxB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IA+DxB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IA8B7B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAK7B;;OAEG;IACH,OAAO,CAAC,eAAe;IAKvB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAIzB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAUxB;;OAEG;IACH,OAAO,CAAC,OAAO;IAOf;;OAEG;IACH,OAAO,CAAC,kBAAkB;CAU3B"}
1
+ {"version":3,"file":"task-sync.d.ts","sourceRoot":"","sources":["../../../../plugins/specweave-github/lib/task-sync.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,EAA2B,UAAU,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEjF,qBAAa,QAAQ;IACnB,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,aAAa,CAAS;gBAElB,aAAa,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM;IAKhD;;OAEG;IACG,SAAS,CAAC,OAAO,GAAE,iBAAsB,GAAG,OAAO,CAAC,UAAU,CAAC;IAsKrE;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAsDxB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IA+DxB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IA8B7B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAK7B;;;OAGG;IACH,OAAO,CAAC,cAAc;IAiCtB;;OAEG;IACH,OAAO,CAAC,eAAe;IAKvB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAIzB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAUxB;;OAEG;IACH,OAAO,CAAC,OAAO;IAOf;;OAEG;IACH,OAAO,CAAC,kBAAkB;CAW3B"}