specweave 1.0.301 → 1.0.304
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-ac-comment-poster.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/github-ac-comment-poster.js +44 -25
- package/dist/plugins/specweave-github/lib/github-ac-comment-poster.js.map +1 -1
- package/dist/plugins/specweave-github/lib/github-feature-sync-cli.js +6 -0
- package/dist/plugins/specweave-github/lib/github-feature-sync-cli.js.map +1 -1
- package/dist/plugins/specweave-github/lib/github-feature-sync.d.ts +36 -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 +266 -5
- 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 +2 -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 +6 -4
- 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 +37 -17
- package/dist/plugins/specweave-github/lib/user-story-issue-builder.js.map +1 -1
- package/dist/src/cli/commands/refresh-plugins.d.ts.map +1 -1
- package/dist/src/cli/commands/refresh-plugins.js +9 -0
- package/dist/src/cli/commands/refresh-plugins.js.map +1 -1
- package/dist/src/cli/commands/sync-progress.d.ts.map +1 -1
- package/dist/src/cli/commands/sync-progress.js +72 -2
- package/dist/src/cli/commands/sync-progress.js.map +1 -1
- package/dist/src/config/types.d.ts +2 -2
- package/dist/src/core/increment/increment-utils.d.ts +27 -4
- package/dist/src/core/increment/increment-utils.d.ts.map +1 -1
- package/dist/src/core/increment/increment-utils.js +44 -17
- package/dist/src/core/increment/increment-utils.js.map +1 -1
- package/dist/src/core/increment/template-creator.d.ts +26 -0
- package/dist/src/core/increment/template-creator.d.ts.map +1 -1
- package/dist/src/core/increment/template-creator.js +179 -20
- package/dist/src/core/increment/template-creator.js.map +1 -1
- package/dist/src/importers/import-to-increment.d.ts +111 -0
- package/dist/src/importers/import-to-increment.d.ts.map +1 -0
- package/dist/src/importers/import-to-increment.js +223 -0
- package/dist/src/importers/import-to-increment.js.map +1 -0
- package/dist/src/importers/increment-external-ref-detector.d.ts +78 -0
- package/dist/src/importers/increment-external-ref-detector.d.ts.map +1 -0
- package/dist/src/importers/increment-external-ref-detector.js +130 -0
- package/dist/src/importers/increment-external-ref-detector.js.map +1 -0
- package/dist/src/init/research/types.d.ts +1 -1
- package/dist/src/sync/external-issue-auto-creator.d.ts.map +1 -1
- package/dist/src/sync/external-issue-auto-creator.js +28 -1
- package/dist/src/sync/external-issue-auto-creator.js.map +1 -1
- package/dist/src/sync/sync-coordinator.d.ts +6 -0
- package/dist/src/sync/sync-coordinator.d.ts.map +1 -1
- package/dist/src/sync/sync-coordinator.js +42 -2
- package/dist/src/sync/sync-coordinator.js.map +1 -1
- package/package.json +1 -1
- package/plugins/specweave/hooks/lib/update-active-increment.sh +2 -2
- package/plugins/specweave/hooks/lib/update-status-line.sh +2 -2
- package/plugins/specweave/hooks/stop-auto-v5.sh +28 -8
- package/plugins/specweave/hooks/stop-sync.sh +10 -5
- package/plugins/specweave/hooks/universal/fail-fast-wrapper.sh +8 -4
- package/plugins/specweave/hooks/user-prompt-submit.sh +130 -112
- package/plugins/specweave/hooks/v2/handlers/github-sync-handler.sh +6 -3
- package/plugins/specweave/hooks/v2/handlers/project-bridge-handler.sh +4 -3
- package/plugins/specweave/skills/auto/SKILL.md +5 -3
- package/plugins/specweave/skills/done/SKILL.md +9 -3
- package/plugins/specweave/skills/import/SKILL.md +186 -0
- package/plugins/specweave/skills/increment/SKILL.md +30 -16
- package/plugins/specweave/skills/pm/SKILL.md +29 -2
- package/plugins/specweave/skills/pm/phases/00-deep-interview.md +12 -0
- package/plugins/specweave/skills/team-lead/SKILL.md +4 -2
- package/plugins/specweave/skills/team-merge/SKILL.md +2 -2
- package/plugins/specweave-github/lib/github-ac-comment-poster.js +31 -19
- package/plugins/specweave-github/lib/github-ac-comment-poster.ts +44 -27
- package/plugins/specweave-github/lib/github-feature-sync-cli.js +5 -0
- package/plugins/specweave-github/lib/github-feature-sync-cli.ts +7 -1
- package/plugins/specweave-github/lib/github-feature-sync.js +274 -6
- package/plugins/specweave-github/lib/github-feature-sync.ts +353 -5
- package/plugins/specweave-github/lib/user-story-content-builder.js +6 -4
- package/plugins/specweave-github/lib/user-story-content-builder.ts +6 -4
- package/plugins/specweave-github/lib/user-story-issue-builder.js +26 -11
- package/plugins/specweave-github/lib/user-story-issue-builder.ts +37 -19
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"github-ac-comment-poster.d.ts","sourceRoot":"","sources":["../../../../plugins/specweave-github/lib/github-ac-comment-poster.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"github-ac-comment-poster.d.ts","sourceRoot":"","sources":["../../../../plugins/specweave-github/lib/github-ac-comment-poster.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AASH,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACrD,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAChD;AAaD;;;;;;;;;;GAUG;AACH,wBAAsB,sBAAsB,CAC1C,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,EAAE,EACvB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,iBAAiB,CAAC,CA8D5B"}
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
* @module github-ac-comment-poster
|
|
9
9
|
*/
|
|
10
10
|
import { readFile } from 'fs/promises';
|
|
11
|
+
import { existsSync } from 'fs';
|
|
12
|
+
import * as path from 'path';
|
|
11
13
|
import { execFileNoThrow } from '../../../src/utils/execFileNoThrow.js';
|
|
12
14
|
import { pushSyncUserStories } from './github-push-sync.js';
|
|
13
15
|
/**
|
|
@@ -37,7 +39,7 @@ export async function postACProgressComments(incrementId, affectedUSIds, specPat
|
|
|
37
39
|
});
|
|
38
40
|
return result;
|
|
39
41
|
}
|
|
40
|
-
const issueLinks = parseIssueLinks(
|
|
42
|
+
const issueLinks = await parseIssueLinks(specPath);
|
|
41
43
|
const repoSlug = `${options.owner}/${options.repo}`;
|
|
42
44
|
const env = options.token ? { GH_TOKEN: options.token } : undefined;
|
|
43
45
|
for (const usId of affectedUSIds) {
|
|
@@ -75,33 +77,50 @@ export async function postACProgressComments(incrementId, affectedUSIds, specPat
|
|
|
75
77
|
return result;
|
|
76
78
|
}
|
|
77
79
|
/**
|
|
78
|
-
* Parse issue links from
|
|
79
|
-
*
|
|
80
|
+
* Parse issue links from metadata.json (sibling of spec.md).
|
|
81
|
+
*
|
|
82
|
+
* Supports TWO formats:
|
|
83
|
+
* - OLD: metadata.github.issues[] with { userStory, number, url }
|
|
84
|
+
* - NEW: metadata.externalLinks.github.issues with { [US-XXX]: { issueNumber, issueUrl } }
|
|
85
|
+
*
|
|
86
|
+
* Falls back to empty if metadata.json is missing or invalid.
|
|
80
87
|
*/
|
|
81
|
-
function parseIssueLinks(
|
|
88
|
+
async function parseIssueLinks(specPath) {
|
|
82
89
|
const links = {};
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
if (idMatch && numMatch) {
|
|
100
|
-
links[idMatch[1]] = {
|
|
101
|
-
issueNumber: parseInt(numMatch[1], 10),
|
|
102
|
-
issueUrl: urlMatch ? urlMatch[1] : '',
|
|
103
|
-
};
|
|
90
|
+
try {
|
|
91
|
+
const metadataPath = path.join(path.dirname(specPath), 'metadata.json');
|
|
92
|
+
if (!existsSync(metadataPath))
|
|
93
|
+
return links;
|
|
94
|
+
const raw = await readFile(metadataPath, 'utf-8');
|
|
95
|
+
const metadata = JSON.parse(raw);
|
|
96
|
+
// OLD format: metadata.github.issues[] array
|
|
97
|
+
if (metadata.github?.issues && Array.isArray(metadata.github.issues)) {
|
|
98
|
+
for (const entry of metadata.github.issues) {
|
|
99
|
+
if (entry.userStory && entry.number) {
|
|
100
|
+
links[entry.userStory] = {
|
|
101
|
+
issueNumber: entry.number,
|
|
102
|
+
issueUrl: entry.url || '',
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
}
|
|
104
106
|
}
|
|
107
|
+
// NEW format: metadata.externalLinks.github.issues object
|
|
108
|
+
if (metadata.externalLinks?.github?.issues) {
|
|
109
|
+
const issues = metadata.externalLinks.github.issues;
|
|
110
|
+
for (const [usId, data] of Object.entries(issues)) {
|
|
111
|
+
const issueData = data;
|
|
112
|
+
if (issueData.issueNumber) {
|
|
113
|
+
// NEW format entries override OLD format for the same US
|
|
114
|
+
links[usId] = {
|
|
115
|
+
issueNumber: issueData.issueNumber,
|
|
116
|
+
issueUrl: issueData.issueUrl || '',
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
// Graceful fallback: return empty if metadata.json is missing or invalid
|
|
105
124
|
}
|
|
106
125
|
return links;
|
|
107
126
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"github-ac-comment-poster.js","sourceRoot":"","sources":["../../../../plugins/specweave-github/lib/github-ac-comment-poster.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AACxE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAyB5D;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,WAAmB,EACnB,aAAuB,EACvB,QAAgB,EAChB,OAA2B;IAE3B,MAAM,MAAM,GAAsB,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IAE7D,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC9C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;YACjB,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC;YACtB,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;SACxD,CAAC,CAAC;QACH,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,UAAU,GAAG,eAAe,CAAC,
|
|
1
|
+
{"version":3,"file":"github-ac-comment-poster.js","sourceRoot":"","sources":["../../../../plugins/specweave-github/lib/github-ac-comment-poster.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AACxE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAyB5D;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,WAAmB,EACnB,aAAuB,EACvB,QAAgB,EAChB,OAA2B;IAE3B,MAAM,MAAM,GAAsB,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IAE7D,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC9C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;YACjB,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC;YACtB,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;SACxD,CAAC,CAAC;QACH,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,eAAe,CAAC,QAAQ,CAAC,CAAC;IACnD,MAAM,QAAQ,GAAG,GAAG,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;IACpD,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IAEpE,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;QACjC,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;QAC9B,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,SAAS;QACX,CAAC;QAED,MAAM,QAAQ,GAAG,kBAAkB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACnD,MAAM,WAAW,GAAG,yBAAyB,CAAC,WAAW,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;QAE3E,MAAM,UAAU,GAAG,MAAM,eAAe,CACtC,IAAI,EACJ,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE,QAAQ,CAAC,EACrF,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CACnB,CAAC;QAEF,IAAI,UAAU,CAAC,OAAO,EAAE,CAAC;YACvB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;QAC9D,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;gBACjB,IAAI;gBACJ,KAAK,EAAE,UAAU,CAAC,MAAM,IAAI,+BAA+B;aAC5D,CAAC,CAAC;QACL,CAAC;QAED,+DAA+D;QAC/D,MAAM,SAAS,GAAG,qBAAqB,CAAC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;QAC9E,IAAI,SAAS,EAAE,CAAC;YACd,IAAI,CAAC;gBACH,MAAM,mBAAmB,CAAC,CAAC,SAAS,CAAC,EAAE;oBACrC,KAAK,EAAE,OAAO,CAAC,KAAK;oBACpB,IAAI,EAAE,OAAO,CAAC,IAAI;oBAClB,KAAK,EAAE,OAAO,CAAC,KAAK;iBACrB,CAAC,CAAC;YACL,CAAC;YAAC,MAAM,CAAC;gBACP,oCAAoC;YACtC,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;GAQG;AACH,KAAK,UAAU,eAAe,CAAC,QAAgB;IAC7C,MAAM,KAAK,GAAsC,EAAE,CAAC;IAEpD,IAAI,CAAC;QACH,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,eAAe,CAAC,CAAC;QACxE,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC;YAAE,OAAO,KAAK,CAAC;QAE5C,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QAClD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAEjC,6CAA6C;QAC7C,IAAI,QAAQ,CAAC,MAAM,EAAE,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;YACrE,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;gBAC3C,IAAI,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;oBACpC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG;wBACvB,WAAW,EAAE,KAAK,CAAC,MAAM;wBACzB,QAAQ,EAAE,KAAK,CAAC,GAAG,IAAI,EAAE;qBAC1B,CAAC;gBACJ,CAAC;YACH,CAAC;QACH,CAAC;QAED,0DAA0D;QAC1D,IAAI,QAAQ,CAAC,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;YAC3C,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC;YACpD,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBAClD,MAAM,SAAS,GAAG,IAAmD,CAAC;gBACtE,IAAI,SAAS,CAAC,WAAW,EAAE,CAAC;oBAC1B,yDAAyD;oBACzD,KAAK,CAAC,IAAI,CAAC,GAAG;wBACZ,WAAW,EAAE,SAAS,CAAC,WAAW;wBAClC,QAAQ,EAAE,SAAS,CAAC,QAAQ,IAAI,EAAE;qBACnC,CAAC;gBACJ,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,yEAAyE;IAC3E,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,SAAS,kBAAkB,CAAC,OAAe,EAAE,IAAY;IACvD,MAAM,MAAM,GAAoB,EAAE,CAAC;IACnC,oDAAoD;IACpD,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IAE5D,MAAM,SAAS,GAAG,IAAI,MAAM,CAC1B,6BAA6B,KAAK,wBAAwB,EAC1D,GAAG,CACJ,CAAC;IAEF,IAAI,KAAK,CAAC;IACV,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QAClD,MAAM,CAAC,IAAI,CAAC;YACV,EAAE,EAAE,QAAQ,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE;YAC/B,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;YAC5B,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG;SAC5B,CAAC,CAAC;IACL,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,SAAS,qBAAqB,CAC5B,OAAe,EACf,IAAY,EACZ,QAAyB,EACzB,WAAmB;IAEnB,gCAAgC;IAChC,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC7E,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,UAAU,KAAK,WAAW,CAAC,CAAC,CAAC;IACzE,MAAM,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAEvD,OAAO;QACL,EAAE,EAAE,IAAI;QACR,KAAK;QACL,WAAW,EAAE,EAAE;QACf,QAAQ,EAAE,IAAI;QACd,MAAM,EAAE,aAAa;QACrB,kBAAkB,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;YACtC,EAAE,EAAE,EAAE,CAAC,EAAE;YACT,WAAW,EAAE,EAAE,CAAC,WAAW;YAC3B,SAAS,EAAE,EAAE,CAAC,SAAS;SACxB,CAAC,CAAC;QACH,MAAM,EAAE,WAAW;KACpB,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,yBAAyB,CAChC,WAAmB,EACnB,IAAY,EACZ,QAAyB;IAEzB,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC;IAC9B,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC;IAC7D,MAAM,UAAU,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,SAAS,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAEzE,IAAI,OAAO,GAAG,yBAAyB,IAAI,eAAe,WAAW,OAAO,CAAC;IAC7E,OAAO,IAAI,eAAe,SAAS,IAAI,KAAK,kBAAkB,UAAU,QAAQ,CAAC;IAEjF,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;QAClB,OAAO,IAAI,kBAAkB,CAAC;QAC9B,KAAK,MAAM,EAAE,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC;YACnD,OAAO,IAAI,WAAW,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,WAAW,IAAI,CAAC;QACvD,CAAC;QACD,OAAO,IAAI,IAAI,CAAC;IAClB,CAAC;IAED,IAAI,SAAS,GAAG,KAAK,EAAE,CAAC;QACtB,OAAO,IAAI,kBAAkB,CAAC;QAC9B,KAAK,MAAM,EAAE,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC;YACpD,OAAO,IAAI,WAAW,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,WAAW,IAAI,CAAC;QACvD,CAAC;QACD,OAAO,IAAI,IAAI,CAAC;IAClB,CAAC;IAED,OAAO,IAAI,OAAO,CAAC;IACnB,OAAO,IAAI,8BAA8B,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAEpF,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -168,12 +168,18 @@ async function main() {
|
|
|
168
168
|
process.exit(0);
|
|
169
169
|
}
|
|
170
170
|
catch (error) {
|
|
171
|
+
// FIXED (v1.0.302): Write errors to stdout too, since stderr may be suppressed
|
|
172
|
+
// by run_with_timeout() in shell handlers. This ensures errors appear in throttle.log.
|
|
173
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
174
|
+
console.log(`\n[ERROR] Sync failed for ${featureId}: ${msg}`);
|
|
171
175
|
console.error(`\n❌ Sync failed:`, error);
|
|
172
176
|
process.exit(1);
|
|
173
177
|
}
|
|
174
178
|
}
|
|
175
179
|
// Run CLI
|
|
176
180
|
main().catch(error => {
|
|
181
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
182
|
+
console.log(`[FATAL] ${msg}`);
|
|
177
183
|
console.error('Fatal error:', error);
|
|
178
184
|
process.exit(1);
|
|
179
185
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"github-feature-sync-cli.js","sourceRoot":"","sources":["../../../../plugins/specweave-github/lib/github-feature-sync-cli.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"github-feature-sync-cli.js","sourceRoot":"","sources":["../../../../plugins/specweave-github/lib/github-feature-sync-cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,9 +16,16 @@ export declare class GitHubFeatureSync {
|
|
|
16
16
|
private projectRoot;
|
|
17
17
|
private calculator;
|
|
18
18
|
private token?;
|
|
19
|
+
private defaultBranch;
|
|
19
20
|
private static syncLocks;
|
|
20
21
|
private static readonly LOCK_DURATION_MS;
|
|
21
22
|
constructor(client: GitHubClientV2, specsDir: string, projectRoot: string);
|
|
23
|
+
/**
|
|
24
|
+
* Detect the default branch from the GitHub API.
|
|
25
|
+
* Caches the result per sync session to avoid repeated API calls.
|
|
26
|
+
* Falls back to 'main' if API call fails.
|
|
27
|
+
*/
|
|
28
|
+
private detectDefaultBranch;
|
|
22
29
|
/**
|
|
23
30
|
* Get environment object with GH_TOKEN for gh CLI commands.
|
|
24
31
|
* This ensures the token from .env is passed to all gh operations,
|
|
@@ -42,9 +49,37 @@ export declare class GitHubFeatureSync {
|
|
|
42
49
|
userStoriesProcessed: number;
|
|
43
50
|
}>;
|
|
44
51
|
/**
|
|
45
|
-
* Find Feature folder in specs directory
|
|
52
|
+
* Find Feature folder in specs directory.
|
|
53
|
+
* Falls back to auto-creating from increment spec.md if living docs don't exist.
|
|
46
54
|
*/
|
|
47
55
|
private findFeatureFolder;
|
|
56
|
+
/**
|
|
57
|
+
* Find the increment folder for a given feature ID.
|
|
58
|
+
* Converts FS-271 -> finds 0271-xxx-xxx/ in .specweave/increments/
|
|
59
|
+
*/
|
|
60
|
+
private findIncrementFolder;
|
|
61
|
+
/**
|
|
62
|
+
* Auto-create a feature folder (FEATURE.md + us-NNN.md files) from an
|
|
63
|
+
* increment's spec.md. This enables GitHub sync even when the living docs
|
|
64
|
+
* builder hasn't run yet.
|
|
65
|
+
*/
|
|
66
|
+
private createFeatureFolderFromSpec;
|
|
67
|
+
/**
|
|
68
|
+
* Parse user stories from spec.md markdown content.
|
|
69
|
+
*/
|
|
70
|
+
private parseUserStoriesFromSpec;
|
|
71
|
+
/**
|
|
72
|
+
* Build FEATURE.md content matching the living docs format.
|
|
73
|
+
*/
|
|
74
|
+
private buildFeatureMd;
|
|
75
|
+
/**
|
|
76
|
+
* Build us-NNN.md content matching the living docs format.
|
|
77
|
+
*/
|
|
78
|
+
private buildUserStoryMd;
|
|
79
|
+
/**
|
|
80
|
+
* Convert a title to a URL-safe slug.
|
|
81
|
+
*/
|
|
82
|
+
private slugify;
|
|
48
83
|
/**
|
|
49
84
|
* Backfill increment metadata.json with GitHub issue reference (v1.0.240)
|
|
50
85
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"github-feature-sync.d.ts","sourceRoot":"","sources":["../../../../plugins/specweave-github/lib/github-feature-sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAiCvD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,KAAK,CAAC,CAAS;
|
|
1
|
+
{"version":3,"file":"github-feature-sync.d.ts","sourceRoot":"","sources":["../../../../plugins/specweave-github/lib/github-feature-sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAiCvD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,KAAK,CAAC,CAAS;IAGvB,OAAO,CAAC,aAAa,CAAuB;IAI5C,OAAO,CAAC,MAAM,CAAC,SAAS,CAAkC;IAC1D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAS;gBAErC,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;IASzE;;;;OAIG;YACW,mBAAmB;IAsBjC;;;;OAIG;IACH,OAAO,CAAC,QAAQ;IAMhB;;;;;;;;OAQG;IACG,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;QACpD,eAAe,EAAE,MAAM,CAAC;QACxB,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,MAAM,CAAC;QACtB,aAAa,EAAE,MAAM,CAAC;QACtB,oBAAoB,EAAE,MAAM,CAAC;KAC9B,CAAC;IA2MF;;;OAGG;YACW,iBAAiB;IA+B/B;;;OAGG;YACW,mBAAmB;IAiBjC;;;;OAIG;YACW,2BAA2B;IA2EzC;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAwEhC;;OAEG;IACH,OAAO,CAAC,cAAc;IAuCtB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IA8CxB;;OAEG;IACH,OAAO,CAAC,OAAO;IAQf;;;;;OAKG;YACW,yBAAyB;IAmDvC;;OAEG;YACW,cAAc;IAW5B;;OAEG;YACW,eAAe;IA4C7B;;OAEG;YACW,kBAAkB;IAgBhC;;OAEG;YACW,eAAe;IAgE7B;;;;;;OAMG;YACW,oBAAoB;IA6DlC;;;;;;;;OAQG;YACW,oBAAoB;IAmElC;;;;;;;OAOG;YACW,kBAAkB;IAqHhC;;;;;;;;;;;;;;OAcG;YACW,4BAA4B;IA+D1C;;OAEG;YACW,eAAe;IA+B7B;;OAEG;YACW,0BAA0B;CA8BzC"}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* This implements the Universal Hierarchy architecture for GitHub sync.
|
|
10
10
|
* Creates ONE issue PER user story file from specs/{project}/FS-XXX/us-*.md
|
|
11
11
|
*/
|
|
12
|
-
import { readdir, readFile, writeFile } from 'fs/promises';
|
|
12
|
+
import { readdir, readFile, writeFile, mkdir } from 'fs/promises';
|
|
13
13
|
import { existsSync } from 'fs';
|
|
14
14
|
import * as path from 'path';
|
|
15
15
|
import * as yaml from 'yaml';
|
|
@@ -20,6 +20,8 @@ import { execFileNoThrow } from '../../../src/utils/execFileNoThrow.js';
|
|
|
20
20
|
import { getGitHubAuthFromProject } from '../../../src/utils/auth-helpers.js';
|
|
21
21
|
export class GitHubFeatureSync {
|
|
22
22
|
constructor(client, specsDir, projectRoot) {
|
|
23
|
+
// Cached default branch for the sync session (one API call per session)
|
|
24
|
+
this.defaultBranch = null;
|
|
23
25
|
this.client = client;
|
|
24
26
|
this.specsDir = specsDir;
|
|
25
27
|
this.projectRoot = projectRoot;
|
|
@@ -27,6 +29,29 @@ export class GitHubFeatureSync {
|
|
|
27
29
|
// Get token from .env for gh CLI passthrough
|
|
28
30
|
this.token = getGitHubAuthFromProject(projectRoot).token;
|
|
29
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* Detect the default branch from the GitHub API.
|
|
34
|
+
* Caches the result per sync session to avoid repeated API calls.
|
|
35
|
+
* Falls back to 'main' if API call fails.
|
|
36
|
+
*/
|
|
37
|
+
async detectDefaultBranch() {
|
|
38
|
+
if (this.defaultBranch) {
|
|
39
|
+
return this.defaultBranch;
|
|
40
|
+
}
|
|
41
|
+
const owner = this.client.getOwner();
|
|
42
|
+
const repo = this.client.getRepo();
|
|
43
|
+
const result = await execFileNoThrow('gh', [
|
|
44
|
+
'api', `repos/${owner}/${repo}`, '--jq', '.default_branch'
|
|
45
|
+
], { env: this.getGhEnv() });
|
|
46
|
+
if (result.exitCode === 0 && result.stdout.trim()) {
|
|
47
|
+
this.defaultBranch = result.stdout.trim();
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
console.warn(` ⚠️ Failed to detect default branch, falling back to 'main': ${result.stderr}`);
|
|
51
|
+
this.defaultBranch = 'main';
|
|
52
|
+
}
|
|
53
|
+
return this.defaultBranch;
|
|
54
|
+
}
|
|
30
55
|
/**
|
|
31
56
|
* Get environment object with GH_TOKEN for gh CLI commands.
|
|
32
57
|
* This ensures the token from .env is passed to all gh operations,
|
|
@@ -104,13 +129,16 @@ export class GitHubFeatureSync {
|
|
|
104
129
|
// 4. Sync each User Story as GitHub Issue
|
|
105
130
|
let issuesCreated = 0;
|
|
106
131
|
let issuesUpdated = 0;
|
|
132
|
+
// Detect default branch once per sync session
|
|
133
|
+
const detectedBranch = await this.detectDefaultBranch();
|
|
134
|
+
console.log(` 🌿 Default branch: ${detectedBranch}`);
|
|
107
135
|
for (const userStory of userStories) {
|
|
108
136
|
console.log(`\n 🔹 Processing ${userStory.id}: ${userStory.title}`);
|
|
109
137
|
// Build issue content using UserStoryIssueBuilder
|
|
110
138
|
const repoInfo = {
|
|
111
139
|
owner: this.client.getOwner(),
|
|
112
140
|
repo: this.client.getRepo(),
|
|
113
|
-
branch:
|
|
141
|
+
branch: detectedBranch
|
|
114
142
|
};
|
|
115
143
|
const builder = new UserStoryIssueBuilder(userStory.filePath, this.projectRoot, featureId, repoInfo);
|
|
116
144
|
const issueContent = await builder.buildIssueBody();
|
|
@@ -211,7 +239,8 @@ export class GitHubFeatureSync {
|
|
|
211
239
|
};
|
|
212
240
|
}
|
|
213
241
|
/**
|
|
214
|
-
* Find Feature folder in specs directory
|
|
242
|
+
* Find Feature folder in specs directory.
|
|
243
|
+
* Falls back to auto-creating from increment spec.md if living docs don't exist.
|
|
215
244
|
*/
|
|
216
245
|
async findFeatureFolder(featureId) {
|
|
217
246
|
// v5.0.0+: NO _features folder - features live in project folders
|
|
@@ -229,8 +258,217 @@ export class GitHubFeatureSync {
|
|
|
229
258
|
console.log(` ⚠️ Found feature in legacy _features folder - consider migrating to project folder`);
|
|
230
259
|
return legacyFolder;
|
|
231
260
|
}
|
|
261
|
+
// FALLBACK (v1.0.302): Auto-create feature folder from increment spec.md
|
|
262
|
+
// Most increments never get living docs created, so sync silently fails.
|
|
263
|
+
// This makes sync self-healing by creating minimal living docs on-the-fly.
|
|
264
|
+
console.log(` ℹ️ Feature folder not found in living docs, attempting auto-create from spec.md...`);
|
|
265
|
+
const created = await this.createFeatureFolderFromSpec(featureId, projectFolders);
|
|
266
|
+
if (created) {
|
|
267
|
+
return created;
|
|
268
|
+
}
|
|
232
269
|
return null;
|
|
233
270
|
}
|
|
271
|
+
/**
|
|
272
|
+
* Find the increment folder for a given feature ID.
|
|
273
|
+
* Converts FS-271 -> finds 0271-xxx-xxx/ in .specweave/increments/
|
|
274
|
+
*/
|
|
275
|
+
async findIncrementFolder(featureId) {
|
|
276
|
+
const numMatch = featureId.match(/FS-0*(\d+)E?/i);
|
|
277
|
+
if (!numMatch)
|
|
278
|
+
return null;
|
|
279
|
+
const num = parseInt(numMatch[1], 10);
|
|
280
|
+
const paddedNum = String(num).padStart(4, '0');
|
|
281
|
+
const incrementsDir = path.join(this.projectRoot, '.specweave/increments');
|
|
282
|
+
if (!existsSync(incrementsDir))
|
|
283
|
+
return null;
|
|
284
|
+
const entries = await readdir(incrementsDir);
|
|
285
|
+
const match = entries.find(e => e.startsWith(paddedNum + '-'));
|
|
286
|
+
if (!match)
|
|
287
|
+
return null;
|
|
288
|
+
return path.join(incrementsDir, match);
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Auto-create a feature folder (FEATURE.md + us-NNN.md files) from an
|
|
292
|
+
* increment's spec.md. This enables GitHub sync even when the living docs
|
|
293
|
+
* builder hasn't run yet.
|
|
294
|
+
*/
|
|
295
|
+
async createFeatureFolderFromSpec(featureId, projectFolders) {
|
|
296
|
+
try {
|
|
297
|
+
const incrementFolder = await this.findIncrementFolder(featureId);
|
|
298
|
+
if (!incrementFolder) {
|
|
299
|
+
console.log(` ⚠️ No increment folder found for ${featureId}`);
|
|
300
|
+
return null;
|
|
301
|
+
}
|
|
302
|
+
const specPath = path.join(incrementFolder, 'spec.md');
|
|
303
|
+
if (!existsSync(specPath)) {
|
|
304
|
+
console.log(` ⚠️ No spec.md found in ${path.basename(incrementFolder)}`);
|
|
305
|
+
return null;
|
|
306
|
+
}
|
|
307
|
+
const specContent = await readFile(specPath, 'utf-8');
|
|
308
|
+
// Parse frontmatter
|
|
309
|
+
const fmMatch = specContent.match(/^---\n([\s\S]*?)\n---/);
|
|
310
|
+
if (!fmMatch) {
|
|
311
|
+
console.log(` ⚠️ spec.md has no YAML frontmatter`);
|
|
312
|
+
return null;
|
|
313
|
+
}
|
|
314
|
+
const frontmatter = yaml.parse(fmMatch[1]);
|
|
315
|
+
const title = frontmatter.title || path.basename(incrementFolder).replace(/^\d+-/, '');
|
|
316
|
+
const status = frontmatter.status || 'active';
|
|
317
|
+
const priority = frontmatter.priority || 'P2';
|
|
318
|
+
const created = frontmatter.created || new Date().toISOString().split('T')[0];
|
|
319
|
+
const incrementId = frontmatter.increment || path.basename(incrementFolder);
|
|
320
|
+
// Determine target project folder from spec.md user stories or first available
|
|
321
|
+
let targetProjectFolder = projectFolders[0]; // Default: first project folder
|
|
322
|
+
const projectMatch = specContent.match(/\*\*Project\*\*:\s*(\S+)/);
|
|
323
|
+
if (projectMatch) {
|
|
324
|
+
const projectName = projectMatch[1];
|
|
325
|
+
const matchingFolder = projectFolders.find(f => path.basename(f) === projectName);
|
|
326
|
+
if (matchingFolder) {
|
|
327
|
+
targetProjectFolder = matchingFolder;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
if (!targetProjectFolder) {
|
|
331
|
+
console.log(` ⚠️ No project folder available for feature creation`);
|
|
332
|
+
return null;
|
|
333
|
+
}
|
|
334
|
+
// Create feature folder
|
|
335
|
+
const featureFolder = path.join(targetProjectFolder, featureId);
|
|
336
|
+
await mkdir(featureFolder, { recursive: true });
|
|
337
|
+
// Parse user stories from spec.md body
|
|
338
|
+
const userStories = this.parseUserStoriesFromSpec(specContent, featureId);
|
|
339
|
+
// Create FEATURE.md
|
|
340
|
+
const featureMd = this.buildFeatureMd(featureId, title, status, priority, created, incrementId, userStories);
|
|
341
|
+
await writeFile(path.join(featureFolder, 'FEATURE.md'), featureMd, 'utf-8');
|
|
342
|
+
// Create us-NNN.md files
|
|
343
|
+
for (const us of userStories) {
|
|
344
|
+
const usFilename = `us-${us.id.replace('US-', '').padStart(3, '0')}-${this.slugify(us.title)}.md`;
|
|
345
|
+
const usMd = this.buildUserStoryMd(us, featureId, incrementId);
|
|
346
|
+
await writeFile(path.join(featureFolder, usFilename), usMd, 'utf-8');
|
|
347
|
+
}
|
|
348
|
+
console.log(` ✅ Auto-created feature folder with ${userStories.length} user stories`);
|
|
349
|
+
return featureFolder;
|
|
350
|
+
}
|
|
351
|
+
catch (error) {
|
|
352
|
+
console.log(` ⚠️ Failed to auto-create feature folder: ${error.message}`);
|
|
353
|
+
return null;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Parse user stories from spec.md markdown content.
|
|
358
|
+
*/
|
|
359
|
+
parseUserStoriesFromSpec(specContent, featureId) {
|
|
360
|
+
const stories = [];
|
|
361
|
+
// Match ### US-NNN: Title (Priority) sections
|
|
362
|
+
const usRegex = /### (US-\d+):\s*(.+?)(?:\s*\((P\d)\))?\s*\n([\s\S]*?)(?=\n### US-|\n## |\n---\s*\n### US-|$)/g;
|
|
363
|
+
let match;
|
|
364
|
+
while ((match = usRegex.exec(specContent)) !== null) {
|
|
365
|
+
const usId = match[1];
|
|
366
|
+
const rawTitle = match[2].trim();
|
|
367
|
+
const priority = match[3] || 'P2';
|
|
368
|
+
const body = match[4];
|
|
369
|
+
// Skip template placeholders
|
|
370
|
+
if (rawTitle === '[Story Title]')
|
|
371
|
+
continue;
|
|
372
|
+
// Extract project
|
|
373
|
+
const projectMatch = body.match(/\*\*Project\*\*:\s*(\S+)/);
|
|
374
|
+
const project = projectMatch ? projectMatch[1] : 'specweave';
|
|
375
|
+
// Extract story text (As a... I want... So that...)
|
|
376
|
+
const storyMatch = body.match(/\*\*As a\*\*\s+([\s\S]*?)(?=\n\*\*Acceptance Criteria|$)/);
|
|
377
|
+
const storyText = storyMatch ? storyMatch[1].trim() : '';
|
|
378
|
+
// Extract acceptance criteria
|
|
379
|
+
const acs = [];
|
|
380
|
+
const acRegex = /- \[[ x]\] \*\*AC-[^*]+\*\*:\s*(.+)/g;
|
|
381
|
+
let acMatch;
|
|
382
|
+
while ((acMatch = acRegex.exec(body)) !== null) {
|
|
383
|
+
acs.push(acMatch[0]);
|
|
384
|
+
}
|
|
385
|
+
// Determine status from ACs
|
|
386
|
+
const totalAcs = acs.length;
|
|
387
|
+
const completedAcs = acs.filter(ac => ac.startsWith('- [x]')).length;
|
|
388
|
+
let status = 'not-started';
|
|
389
|
+
if (totalAcs > 0 && completedAcs === totalAcs)
|
|
390
|
+
status = 'complete';
|
|
391
|
+
else if (completedAcs > 0)
|
|
392
|
+
status = 'active';
|
|
393
|
+
stories.push({
|
|
394
|
+
id: usId,
|
|
395
|
+
title: rawTitle,
|
|
396
|
+
priority,
|
|
397
|
+
project,
|
|
398
|
+
storyText,
|
|
399
|
+
acceptanceCriteria: acs,
|
|
400
|
+
status,
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
return stories;
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* Build FEATURE.md content matching the living docs format.
|
|
407
|
+
*/
|
|
408
|
+
buildFeatureMd(featureId, title, status, priority, created, incrementId, userStories) {
|
|
409
|
+
const now = new Date().toISOString().split('T')[0];
|
|
410
|
+
const mappedStatus = status === 'planned' ? 'planning'
|
|
411
|
+
: status === 'completed' || status === 'done' ? 'complete'
|
|
412
|
+
: status === 'active' || status === 'in-progress' ? 'active'
|
|
413
|
+
: 'planning';
|
|
414
|
+
const fm = {
|
|
415
|
+
id: featureId,
|
|
416
|
+
title,
|
|
417
|
+
type: 'feature',
|
|
418
|
+
status: mappedStatus,
|
|
419
|
+
priority,
|
|
420
|
+
created,
|
|
421
|
+
lastUpdated: now,
|
|
422
|
+
tldr: title,
|
|
423
|
+
complexity: 'medium',
|
|
424
|
+
auto_created: true,
|
|
425
|
+
};
|
|
426
|
+
const yamlFm = yaml.stringify(fm);
|
|
427
|
+
let body = `\n# ${title}\n\n## TL;DR\n\n**What**: ${title}\n**Status**: ${mappedStatus} | **Priority**: ${priority}\n**User Stories**: ${userStories.length}\n\n## Overview\n\n${title}\n\n## Implementation History\n\n| Increment | Status |\n|-----------|--------|\n| [${incrementId}](../../../../../increments/${incrementId}/spec.md) | ${mappedStatus} |\n\n## User Stories\n`;
|
|
428
|
+
for (const us of userStories) {
|
|
429
|
+
body += `\n- [${us.id}: ${us.title}](./${us.id.toLowerCase()}.md)`;
|
|
430
|
+
}
|
|
431
|
+
return `---\n${yamlFm}---${body}\n`;
|
|
432
|
+
}
|
|
433
|
+
/**
|
|
434
|
+
* Build us-NNN.md content matching the living docs format.
|
|
435
|
+
*/
|
|
436
|
+
buildUserStoryMd(us, featureId, incrementId) {
|
|
437
|
+
const now = new Date().toISOString().split('T')[0];
|
|
438
|
+
const fm = {
|
|
439
|
+
id: us.id,
|
|
440
|
+
feature: featureId,
|
|
441
|
+
title: us.title,
|
|
442
|
+
status: us.status,
|
|
443
|
+
priority: us.priority,
|
|
444
|
+
created: now,
|
|
445
|
+
project: us.project,
|
|
446
|
+
};
|
|
447
|
+
const yamlFm = yaml.stringify(fm);
|
|
448
|
+
let body = `\n# ${us.id}: ${us.title}\n\n**Feature**: [${featureId}](./FEATURE.md)\n\n`;
|
|
449
|
+
if (us.storyText) {
|
|
450
|
+
body += `${us.storyText}\n\n`;
|
|
451
|
+
}
|
|
452
|
+
body += `---\n\n## Acceptance Criteria\n\n`;
|
|
453
|
+
if (us.acceptanceCriteria.length > 0) {
|
|
454
|
+
body += us.acceptanceCriteria.join('\n') + '\n';
|
|
455
|
+
}
|
|
456
|
+
else {
|
|
457
|
+
body += `- [ ] **AC-${us.id.replace('US-', 'US')}-01**: Pending specification\n`;
|
|
458
|
+
}
|
|
459
|
+
body += `\n---\n\n## Implementation\n\n**Increment**: [${incrementId}](../../../../../increments/${incrementId}/spec.md)\n`;
|
|
460
|
+
return `---\n${yamlFm}---${body}\n`;
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* Convert a title to a URL-safe slug.
|
|
464
|
+
*/
|
|
465
|
+
slugify(text) {
|
|
466
|
+
return text
|
|
467
|
+
.toLowerCase()
|
|
468
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
469
|
+
.replace(/^-+|-+$/g, '')
|
|
470
|
+
.substring(0, 60);
|
|
471
|
+
}
|
|
234
472
|
/**
|
|
235
473
|
* Backfill increment metadata.json with GitHub issue reference (v1.0.240)
|
|
236
474
|
*
|
|
@@ -351,9 +589,12 @@ export class GitHubFeatureSync {
|
|
|
351
589
|
// CRITICAL: Check if milestone already exists before creating
|
|
352
590
|
// NOTE: Must use per_page=100 to handle repos with 30+ milestones (GitHub default is 30)
|
|
353
591
|
// BUG FIX: Without pagination, milestone #31+ won't be found → false "not found" → HTTP 422 duplicate error
|
|
592
|
+
// FIX (v1.0.302): Use explicit owner/repo from config, not :owner/:repo which resolves from git remote
|
|
593
|
+
const owner = this.client.getOwner();
|
|
594
|
+
const repo = this.client.getRepo();
|
|
354
595
|
const existingResult = await execFileNoThrow('gh', [
|
|
355
596
|
'api',
|
|
356
|
-
|
|
597
|
+
`repos/${owner}/${repo}/milestones?per_page=100&state=all`,
|
|
357
598
|
'--jq',
|
|
358
599
|
`.[] | select(.title == "${title}") | {number, html_url}`,
|
|
359
600
|
], { env: this.getGhEnv() });
|
|
@@ -375,7 +616,7 @@ export class GitHubFeatureSync {
|
|
|
375
616
|
const description = `Feature ${featureData.id}\n\nStatus: ${featureData.status}\nCreated: ${featureData.created}`;
|
|
376
617
|
const result = await execFileNoThrow('gh', [
|
|
377
618
|
'api',
|
|
378
|
-
|
|
619
|
+
`repos/${owner}/${repo}/milestones`,
|
|
379
620
|
'-X',
|
|
380
621
|
'POST',
|
|
381
622
|
'-f',
|
|
@@ -587,6 +828,26 @@ export class GitHubFeatureSync {
|
|
|
587
828
|
else {
|
|
588
829
|
console.warn(` ⚠️ Failed to add label ${newStatusLabel}: ${result.stderr}`);
|
|
589
830
|
}
|
|
831
|
+
// Step 3: Auto-close issue when status:complete and issue still OPEN
|
|
832
|
+
// This ensures closure happens atomically with the label update,
|
|
833
|
+
// preventing issues like #1198 where label is applied but issue stays open
|
|
834
|
+
if (newStatusLabel === 'status:complete' && issueData.state.toLowerCase() !== 'closed') {
|
|
835
|
+
try {
|
|
836
|
+
const completionComment = this.calculator.buildCompletionComment(completion);
|
|
837
|
+
await execFileNoThrow('gh', [
|
|
838
|
+
'issue',
|
|
839
|
+
'close',
|
|
840
|
+
issueNumber.toString(),
|
|
841
|
+
'--comment',
|
|
842
|
+
completionComment,
|
|
843
|
+
], { env: this.getGhEnv() });
|
|
844
|
+
console.log(` ✅ Auto-closed issue #${issueNumber} (status:complete)`);
|
|
845
|
+
}
|
|
846
|
+
catch (closeError) {
|
|
847
|
+
// Non-blocking: close failure shouldn't break sync
|
|
848
|
+
console.warn(` ⚠️ Failed to auto-close issue #${issueNumber}: ${closeError.message}`);
|
|
849
|
+
}
|
|
850
|
+
}
|
|
590
851
|
}
|
|
591
852
|
catch (error) {
|
|
592
853
|
// Non-blocking: Label update failure shouldn't break sync
|