specweave 1.0.326 → 1.0.327
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-github/lib/github-feature-sync.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/github-feature-sync.js +23 -8
- package/dist/plugins/specweave-github/lib/github-feature-sync.js.map +1 -1
- package/dist/plugins/specweave-github/lib/github-us-auto-closer.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/github-us-auto-closer.js +2 -0
- package/dist/plugins/specweave-github/lib/github-us-auto-closer.js.map +1 -1
- package/dist/src/metrics/report-generator.js +5 -5
- package/dist/src/metrics/utils/tier-classifier.d.ts +9 -7
- package/dist/src/metrics/utils/tier-classifier.d.ts.map +1 -1
- package/dist/src/metrics/utils/tier-classifier.js +15 -13
- package/dist/src/metrics/utils/tier-classifier.js.map +1 -1
- package/package.json +1 -1
- package/plugins/specweave/hooks/v2/handlers/ac-sync-dispatcher.sh +29 -4
- package/plugins/specweave-github/hooks/github-auto-create-handler.sh +23 -4
- package/plugins/specweave-github/hooks/post-task-completion.sh +25 -8
- package/plugins/specweave-github/lib/github-feature-sync.js +18 -7
- package/plugins/specweave-github/lib/github-feature-sync.ts +22 -8
- package/plugins/specweave-github/lib/github-us-auto-closer.js +5 -0
- package/plugins/specweave-github/lib/github-us-auto-closer.ts +6 -0
- package/src/templates/AGENTS.md.template +96 -751
|
@@ -82,7 +82,15 @@ const _GitHubFeatureSync = class _GitHubFeatureSync {
|
|
|
82
82
|
\u{1F504} Syncing Feature ${featureId} to GitHub...`);
|
|
83
83
|
const featureFolder = await this.findFeatureFolder(featureId);
|
|
84
84
|
if (!featureFolder) {
|
|
85
|
-
|
|
85
|
+
console.log(` \u26A0\uFE0F Feature ${featureId} not found in ${this.specsDir} (no living docs and auto-create failed)`);
|
|
86
|
+
console.log(` \u{1F4A1} Run /sw:sync-docs or /sw:living-docs to generate living docs first`);
|
|
87
|
+
return {
|
|
88
|
+
milestoneNumber: 0,
|
|
89
|
+
milestoneUrl: "",
|
|
90
|
+
issuesCreated: 0,
|
|
91
|
+
issuesUpdated: 0,
|
|
92
|
+
userStoriesProcessed: 0
|
|
93
|
+
};
|
|
86
94
|
}
|
|
87
95
|
const featurePath = path.join(featureFolder, "FEATURE.md");
|
|
88
96
|
const featureData = await this.parseFeatureMd(featurePath);
|
|
@@ -246,16 +254,19 @@ const _GitHubFeatureSync = class _GitHubFeatureSync {
|
|
|
246
254
|
}
|
|
247
255
|
const specContent = await readFile(specPath, "utf-8");
|
|
248
256
|
const fmMatch = specContent.match(/^---\n([\s\S]*?)\n---/);
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
257
|
+
let frontmatter = {};
|
|
258
|
+
if (fmMatch) {
|
|
259
|
+
try {
|
|
260
|
+
frontmatter = yaml.parse(fmMatch[1]) || {};
|
|
261
|
+
} catch {
|
|
262
|
+
}
|
|
252
263
|
}
|
|
253
|
-
const
|
|
254
|
-
const title = frontmatter.title ||
|
|
264
|
+
const incrementBasename = path.basename(incrementFolder);
|
|
265
|
+
const title = frontmatter.title || specContent.match(/^#\s+(.+)/m)?.[1]?.trim() || incrementBasename.replace(/^\d+-/, "").replace(/-/g, " ");
|
|
255
266
|
const status = frontmatter.status || "active";
|
|
256
267
|
const priority = frontmatter.priority || "P2";
|
|
257
268
|
const created = frontmatter.created || (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
258
|
-
const incrementId = frontmatter.increment ||
|
|
269
|
+
const incrementId = frontmatter.increment || incrementBasename;
|
|
259
270
|
let targetProjectFolder = projectFolders[0];
|
|
260
271
|
const projectMatch = specContent.match(/\*\*Project\*\*:\s*(\S+)/);
|
|
261
272
|
if (projectMatch) {
|
|
@@ -154,7 +154,15 @@ export class GitHubFeatureSync {
|
|
|
154
154
|
// 1. Load Feature FEATURE.md
|
|
155
155
|
const featureFolder = await this.findFeatureFolder(featureId);
|
|
156
156
|
if (!featureFolder) {
|
|
157
|
-
|
|
157
|
+
console.log(` ⚠️ Feature ${featureId} not found in ${this.specsDir} (no living docs and auto-create failed)`);
|
|
158
|
+
console.log(` 💡 Run /sw:sync-docs or /sw:living-docs to generate living docs first`);
|
|
159
|
+
return {
|
|
160
|
+
milestoneNumber: 0,
|
|
161
|
+
milestoneUrl: '',
|
|
162
|
+
issuesCreated: 0,
|
|
163
|
+
issuesUpdated: 0,
|
|
164
|
+
userStoriesProcessed: 0,
|
|
165
|
+
};
|
|
158
166
|
}
|
|
159
167
|
|
|
160
168
|
const featurePath = path.join(featureFolder, 'FEATURE.md');
|
|
@@ -407,19 +415,25 @@ export class GitHubFeatureSync {
|
|
|
407
415
|
|
|
408
416
|
const specContent = await readFile(specPath, 'utf-8');
|
|
409
417
|
|
|
410
|
-
// Parse frontmatter
|
|
418
|
+
// Parse frontmatter (optional — many specs don't have YAML frontmatter)
|
|
411
419
|
const fmMatch = specContent.match(/^---\n([\s\S]*?)\n---/);
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
420
|
+
let frontmatter: Record<string, string> = {};
|
|
421
|
+
if (fmMatch) {
|
|
422
|
+
try {
|
|
423
|
+
frontmatter = yaml.parse(fmMatch[1]) || {};
|
|
424
|
+
} catch {
|
|
425
|
+
// Invalid YAML — proceed without frontmatter
|
|
426
|
+
}
|
|
415
427
|
}
|
|
416
428
|
|
|
417
|
-
const
|
|
418
|
-
const title = frontmatter.title
|
|
429
|
+
const incrementBasename = path.basename(incrementFolder);
|
|
430
|
+
const title = frontmatter.title
|
|
431
|
+
|| specContent.match(/^#\s+(.+)/m)?.[1]?.trim()
|
|
432
|
+
|| incrementBasename.replace(/^\d+-/, '').replace(/-/g, ' ');
|
|
419
433
|
const status = frontmatter.status || 'active';
|
|
420
434
|
const priority = frontmatter.priority || 'P2';
|
|
421
435
|
const created = frontmatter.created || new Date().toISOString().split('T')[0];
|
|
422
|
-
const incrementId = frontmatter.increment ||
|
|
436
|
+
const incrementId = frontmatter.increment || incrementBasename;
|
|
423
437
|
|
|
424
438
|
// Determine target project folder from spec.md user stories or first available
|
|
425
439
|
let targetProjectFolder = projectFolders[0]; // Default: first project folder
|
|
@@ -60,6 +60,11 @@ async function autoCloseCompletedUserStories(incrementId, affectedUSIds, specPat
|
|
|
60
60
|
execOpts
|
|
61
61
|
);
|
|
62
62
|
if (closeResult.success) {
|
|
63
|
+
await execFileNoThrow(
|
|
64
|
+
"gh",
|
|
65
|
+
["issue", "edit", issueNum, "--remove-label", "status:active", "--add-label", "status:completed", "-R", repoSlug],
|
|
66
|
+
execOpts
|
|
67
|
+
);
|
|
63
68
|
result.closed.push({ usId, issueNumber: link.issueNumber });
|
|
64
69
|
} else {
|
|
65
70
|
result.errors.push({
|
|
@@ -130,6 +130,12 @@ export async function autoCloseCompletedUserStories(
|
|
|
130
130
|
);
|
|
131
131
|
|
|
132
132
|
if (closeResult.success) {
|
|
133
|
+
// Update labels: remove status:active, add status:completed
|
|
134
|
+
await execFileNoThrow(
|
|
135
|
+
'gh',
|
|
136
|
+
['issue', 'edit', issueNum, '--remove-label', 'status:active', '--add-label', 'status:completed', '-R', repoSlug],
|
|
137
|
+
execOpts,
|
|
138
|
+
);
|
|
133
139
|
result.closed.push({ usId, issueNumber: link.issueNumber });
|
|
134
140
|
} else {
|
|
135
141
|
result.errors.push({
|