specweave 0.24.9 → 0.24.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +158 -10
- package/dist/plugins/specweave-github/lib/github-client-v2.d.ts +28 -0
- package/dist/plugins/specweave-github/lib/github-client-v2.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/github-client-v2.js +47 -0
- package/dist/plugins/specweave-github/lib/github-client-v2.js.map +1 -1
- package/dist/src/cli/commands/init.d.ts.map +1 -1
- package/dist/src/cli/commands/init.js +15 -7
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/github-multi-repo.d.ts.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/github-multi-repo.js +13 -1
- package/dist/src/cli/helpers/issue-tracker/github-multi-repo.js.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/index.js +4 -4
- package/dist/src/cli/helpers/issue-tracker/index.js.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/types.d.ts +1 -1
- package/dist/src/cli/helpers/issue-tracker/types.d.ts.map +1 -1
- package/dist/src/core/config/types.d.ts +46 -12
- package/dist/src/core/config/types.d.ts.map +1 -1
- package/dist/src/core/config/types.js +0 -5
- package/dist/src/core/config/types.js.map +1 -1
- package/dist/src/core/repo-structure/repo-bulk-discovery.d.ts.map +1 -1
- package/dist/src/core/repo-structure/repo-bulk-discovery.js +20 -5
- package/dist/src/core/repo-structure/repo-bulk-discovery.js.map +1 -1
- package/dist/src/core/repo-structure/repo-structure-manager.d.ts.map +1 -1
- package/dist/src/core/repo-structure/repo-structure-manager.js +29 -14
- package/dist/src/core/repo-structure/repo-structure-manager.js.map +1 -1
- package/dist/src/sync/format-preservation-sync.d.ts.map +1 -1
- package/dist/src/sync/format-preservation-sync.js +23 -5
- package/dist/src/sync/format-preservation-sync.js.map +1 -1
- package/dist/src/sync/frontmatter-updater.d.ts +57 -0
- package/dist/src/sync/frontmatter-updater.d.ts.map +1 -0
- package/dist/src/sync/frontmatter-updater.js +147 -0
- package/dist/src/sync/frontmatter-updater.js.map +1 -0
- package/dist/src/sync/sync-coordinator.d.ts +22 -1
- package/dist/src/sync/sync-coordinator.d.ts.map +1 -1
- package/dist/src/sync/sync-coordinator.js +268 -21
- package/dist/src/sync/sync-coordinator.js.map +1 -1
- package/dist/src/types/living-docs-us-file.d.ts +18 -0
- package/dist/src/types/living-docs-us-file.d.ts.map +1 -1
- package/dist/src/types/living-docs-us-file.js.map +1 -1
- package/package.json +1 -1
- package/plugins/specweave/.claude-plugin/plugin.json +17 -11
- package/plugins/specweave/agents/architect/AGENT.md +115 -45
- package/plugins/specweave/agents/test-aware-planner/AGENT.md +76 -6
- package/plugins/specweave/hooks/lib/update-status-line.sh +19 -0
- package/plugins/specweave/hooks/post-edit-write-consolidated.sh +335 -0
- package/plugins/specweave/hooks/post-metadata-change.sh +40 -6
- package/plugins/specweave/hooks/post-task-completion.sh +93 -9
- package/plugins/specweave/hooks/pre-edit-spec.sh +0 -11
- package/plugins/specweave/hooks/pre-edit-write-consolidated.sh +188 -0
- package/plugins/specweave/hooks/pre-task-completion.sh +11 -0
- package/plugins/specweave/hooks/pre-write-spec.sh +0 -11
- package/plugins/specweave/lib/hooks/consolidated-sync.js +61 -3
- package/plugins/specweave-github/hooks/.specweave/logs/hooks-debug.log +294 -0
- package/plugins/specweave-github/lib/github-client-v2.js +46 -0
- package/plugins/specweave-github/lib/github-client-v2.ts +65 -0
- package/plugins/specweave-release/commands/specweave-release-npm.md +130 -2
- package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +60 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format-preservation-sync.js","sourceRoot":"","sources":["../../../src/sync/format-preservation-sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAoB,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,MAAM,wDAAwD,CAAC;AACxF,OAAO,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AAC9D,OAAO,EAAU,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAgC3D,MAAM,OAAO,6BAA6B;IAIxC,YACE,SAAqB,EAAE,EACvB,UAA+B,EAAE;QAEjC,IAAI,CAAC,MAAM,GAAG;YACZ,sBAAsB,EAAE,MAAM,CAAC,sBAAsB,IAAI,KAAK;YAC9D,sBAAsB,EAAE,MAAM,CAAC,sBAAsB,IAAI,KAAK;YAC9D,eAAe,EAAE,MAAM,CAAC,eAAe,IAAI,KAAK;SACjD,CAAC;QACF,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,aAAa,CAAC;IAChD,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,aAAa,CACjB,MAAwB,EACxB,cAAqC,EACrC,cAAuD;QAEvD,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;QAEjC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,cAAc,MAAM,CAAC,EAAE,aAAa,MAAM,GAAG,CAAC,CAAC;QAE/D,IAAI,MAAM,KAAK,UAAU,EAAE,CAAC;YAC1B,oDAAoD;YACpD,MAAM,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,cAAc,EAAE,cAAc,CAAC,CAAC;QACpE,CAAC;aAAM,CAAC;YACN,0CAA0C;YAC1C,MAAM,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,cAAc,EAAE,cAAc,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;IAED;;;;OAIG;IACK,KAAK,CAAC,cAAc,CAC1B,MAAwB,EACxB,cAAqC,EACrC,cAAuD;QAEvD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,wDAAwD,CAAC,CAAC;QAE1E,2BAA2B;QAC3B,MAAM,OAAO,GAAG,IAAI,CAAC,sBAAsB,CAAC,cAAc,CAAC,CAAC;QAE5D,
|
|
1
|
+
{"version":3,"file":"format-preservation-sync.js","sourceRoot":"","sources":["../../../src/sync/format-preservation-sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAoB,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,MAAM,wDAAwD,CAAC;AACxF,OAAO,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AAC9D,OAAO,EAAU,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAgC3D,MAAM,OAAO,6BAA6B;IAIxC,YACE,SAAqB,EAAE,EACvB,UAA+B,EAAE;QAEjC,IAAI,CAAC,MAAM,GAAG;YACZ,sBAAsB,EAAE,MAAM,CAAC,sBAAsB,IAAI,KAAK;YAC9D,sBAAsB,EAAE,MAAM,CAAC,sBAAsB,IAAI,KAAK;YAC9D,eAAe,EAAE,MAAM,CAAC,eAAe,IAAI,KAAK;SACjD,CAAC;QACF,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,aAAa,CAAC;IAChD,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,aAAa,CACjB,MAAwB,EACxB,cAAqC,EACrC,cAAuD;QAEvD,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;QAEjC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,cAAc,MAAM,CAAC,EAAE,aAAa,MAAM,GAAG,CAAC,CAAC;QAE/D,IAAI,MAAM,KAAK,UAAU,EAAE,CAAC;YAC1B,oDAAoD;YACpD,MAAM,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,cAAc,EAAE,cAAc,CAAC,CAAC;QACpE,CAAC;aAAM,CAAC;YACN,0CAA0C;YAC1C,MAAM,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,cAAc,EAAE,cAAc,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;IAED;;;;OAIG;IACK,KAAK,CAAC,cAAc,CAC1B,MAAwB,EACxB,cAAqC,EACrC,cAAuD;QAEvD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,wDAAwD,CAAC,CAAC;QAE1E,2BAA2B;QAC3B,MAAM,OAAO,GAAG,IAAI,CAAC,sBAAsB,CAAC,cAAc,CAAC,CAAC;QAE5D,uDAAuD;QACvD,IAAI,cAAc,YAAY,cAAc,EAAE,CAAC;YAC7C,iEAAiE;YACjE,8FAA8F;YAC9F,MAAM,WAAW,GAAG,MAAM,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC,CAAC;YAE/D,gDAAgD;YAChD,MAAM,WAAW,GAAG,MAAM,cAAc,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;YAErE,IAAI,WAAW,IAAI,WAAW,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;gBAChD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;gBACrE,OAAO,CAAE,qCAAqC;YAChD,CAAC;YAED,MAAM,cAAc,CAAC,UAAU,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;YACtD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,yCAAyC,WAAW,EAAE,CAAC,CAAC;QAC1E,CAAC;aAAM,IAAI,cAAc,YAAY,UAAU,EAAE,CAAC;YAChD,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC;YAC1C,MAAM,cAAc,CAAC,UAAU,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACrD,CAAC;aAAM,IAAI,cAAc,YAAY,SAAS,EAAE,CAAC;YAC/C,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,WAAW,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC;YAC3D,MAAM,cAAc,CAAC,UAAU,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACvD,CAAC;QAED,oDAAoD;QACpD,IAAI,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC;YAChC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;YAC7C,sCAAsC;QACxC,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,qDAAqD,CAAC,CAAC;QACzE,CAAC;IACH,CAAC;IAED;;;;OAIG;IACK,KAAK,CAAC,cAAc,CAC1B,MAAwB,EACxB,cAAqC,EACrC,cAAuD;QAEvD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,+CAA+C,CAAC,CAAC;QAEjE,yDAAyD;QACzD,IAAI,IAAI,CAAC,MAAM,CAAC,sBAAsB,EAAE,CAAC;YACvC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;YAEhD,2BAA2B;YAC3B,MAAM,OAAO,GAAG,IAAI,CAAC,sBAAsB,CAAC,cAAc,CAAC,CAAC;YAE5D,sCAAsC;YACtC,IAAI,cAAc,YAAY,cAAc,EAAE,CAAC;gBAC7C,iEAAiE;gBACjE,MAAM,WAAW,GAAG,MAAM,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC,CAAC;gBAE/D,gDAAgD;gBAChD,MAAM,WAAW,GAAG,MAAM,cAAc,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;gBAErE,IAAI,WAAW,IAAI,WAAW,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;oBAChD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;gBACvE,CAAC;qBAAM,CAAC;oBACN,MAAM,cAAc,CAAC,UAAU,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;oBACtD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,yCAAyC,WAAW,EAAE,CAAC,CAAC;gBAC1E,CAAC;gBAED,qCAAqC;gBACrC,iDAAiD;YACnD,CAAC;iBAAM,IAAI,cAAc,YAAY,UAAU,EAAE,CAAC;gBAChD,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC;gBAC1C,MAAM,cAAc,CAAC,UAAU,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACrD,CAAC;iBAAM,IAAI,cAAc,YAAY,SAAS,EAAE,CAAC;gBAC/C,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,WAAW,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC;gBAC3D,MAAM,cAAc,CAAC,UAAU,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;YACvD,CAAC;YAED,2BAA2B;YAC3B,IAAI,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC;gBAChC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;gBAC7C,sCAAsC;YACxC,CAAC;QACH,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAC;QACnF,CAAC;IACH,CAAC;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH,sBAAsB,CAAC,IAA2B;QAChD,MAAM,KAAK,GAAa,EAAE,CAAC;QAE3B,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QACjC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAEf,kBAAkB;QAClB,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAC3D,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;YAClC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,KAAK,MAAM,IAAI,IAAI,cAAc,EAAE,CAAC;gBAClC,KAAK,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YACnD,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjB,CAAC;QAED,sBAAsB;QACtB,MAAM,YAAY,GAAG,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;QACxE,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5B,KAAK,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;YACtC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,KAAK,MAAM,EAAE,IAAI,YAAY,EAAE,CAAC;gBAC9B,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,IAAI,OAAO,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;YACtD,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjB,CAAC;QAED,mBAAmB;QACnB,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;QACrC,MAAM,SAAS,GAAG,cAAc,CAAC,MAAM,CAAC;QACxC,KAAK,CAAC,IAAI,CAAC,iBAAiB,SAAS,IAAI,UAAU,qBAAqB,IAAI,CAAC,kBAAkB,IAAI,CAAC,CAAC;QACrG,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAEf,mBAAmB;QACnB,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,KAAK,CAAC,IAAI,CAAC,sBAAsB,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC;QAC1D,CAAC;QAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAED;;;OAGG;IACK,kBAAkB,CAAC,UAAkB;QAC3C,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACzC,OAAO,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5C,CAAC;CACF"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Frontmatter Updater (Layer 1 Idempotency Backfill)
|
|
3
|
+
*
|
|
4
|
+
* Updates user story frontmatter with GitHub issue information
|
|
5
|
+
* after issues are created. This provides the fastest idempotency
|
|
6
|
+
* check (<1ms) for future syncs.
|
|
7
|
+
*
|
|
8
|
+
* Part of 3-layer idempotency strategy:
|
|
9
|
+
* - Layer 1: User story frontmatter (fastest, <1ms)
|
|
10
|
+
* - Layer 2: Increment metadata.json (fast, <5ms)
|
|
11
|
+
* - Layer 3: GitHub API query (slow, 500-2000ms)
|
|
12
|
+
*/
|
|
13
|
+
import { Logger } from '../utils/logger.js';
|
|
14
|
+
export interface GitHubIssueInfo {
|
|
15
|
+
number: number;
|
|
16
|
+
url: string;
|
|
17
|
+
createdAt: string;
|
|
18
|
+
}
|
|
19
|
+
export interface FrontmatterUpdateOptions {
|
|
20
|
+
projectRoot: string;
|
|
21
|
+
featureId: string;
|
|
22
|
+
userStoryId: string;
|
|
23
|
+
githubIssue: GitHubIssueInfo;
|
|
24
|
+
logger?: Logger;
|
|
25
|
+
}
|
|
26
|
+
export declare class FrontmatterUpdater {
|
|
27
|
+
private logger;
|
|
28
|
+
constructor(options?: {
|
|
29
|
+
logger?: Logger;
|
|
30
|
+
});
|
|
31
|
+
/**
|
|
32
|
+
* Update user story frontmatter with GitHub issue information
|
|
33
|
+
*
|
|
34
|
+
* CRITICAL: This is Layer 1 backfill for 3-layer idempotency
|
|
35
|
+
* Must be called after GitHub issue creation to cache issue number
|
|
36
|
+
*/
|
|
37
|
+
updateUserStoryFrontmatter(options: FrontmatterUpdateOptions): Promise<boolean>;
|
|
38
|
+
/**
|
|
39
|
+
* Batch update multiple user story frontmatters
|
|
40
|
+
*/
|
|
41
|
+
batchUpdateFrontmatters(projectRoot: string, featureId: string, updates: Array<{
|
|
42
|
+
userStoryId: string;
|
|
43
|
+
githubIssue: GitHubIssueInfo;
|
|
44
|
+
}>): Promise<{
|
|
45
|
+
success: number;
|
|
46
|
+
failed: number;
|
|
47
|
+
}>;
|
|
48
|
+
/**
|
|
49
|
+
* Get user story file path from project root, feature ID, and user story ID
|
|
50
|
+
*/
|
|
51
|
+
private getUserStoryPath;
|
|
52
|
+
/**
|
|
53
|
+
* Read GitHub issue info from user story frontmatter (Layer 1 check)
|
|
54
|
+
*/
|
|
55
|
+
getGitHubIssueFromFrontmatter(projectRoot: string, featureId: string, userStoryId: string): Promise<GitHubIssueInfo | null>;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=frontmatter-updater.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frontmatter-updater.d.ts","sourceRoot":"","sources":["../../../src/sync/frontmatter-updater.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,OAAO,EAAE,MAAM,EAAiB,MAAM,oBAAoB,CAAC;AAE3D,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,wBAAwB;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,eAAe,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,MAAM,CAAS;gBAEX,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAO;IAI7C;;;;;OAKG;IACG,0BAA0B,CAAC,OAAO,EAAE,wBAAwB,GAAG,OAAO,CAAC,OAAO,CAAC;IAmErF;;OAEG;IACG,uBAAuB,CAC3B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,KAAK,CAAC;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,eAAe,CAAA;KAAE,CAAC,GACpE,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAsB/C;;OAEG;YACW,gBAAgB;IAkC9B;;OAEG;IACG,6BAA6B,CACjC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;CAmCnC"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Frontmatter Updater (Layer 1 Idempotency Backfill)
|
|
3
|
+
*
|
|
4
|
+
* Updates user story frontmatter with GitHub issue information
|
|
5
|
+
* after issues are created. This provides the fastest idempotency
|
|
6
|
+
* check (<1ms) for future syncs.
|
|
7
|
+
*
|
|
8
|
+
* Part of 3-layer idempotency strategy:
|
|
9
|
+
* - Layer 1: User story frontmatter (fastest, <1ms)
|
|
10
|
+
* - Layer 2: Increment metadata.json (fast, <5ms)
|
|
11
|
+
* - Layer 3: GitHub API query (slow, 500-2000ms)
|
|
12
|
+
*/
|
|
13
|
+
import { readFile, writeFile, readdir } from 'fs/promises';
|
|
14
|
+
import { existsSync } from 'fs';
|
|
15
|
+
import path from 'path';
|
|
16
|
+
import yaml from 'yaml';
|
|
17
|
+
import { consoleLogger } from '../utils/logger.js';
|
|
18
|
+
export class FrontmatterUpdater {
|
|
19
|
+
constructor(options = {}) {
|
|
20
|
+
this.logger = options.logger ?? consoleLogger;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Update user story frontmatter with GitHub issue information
|
|
24
|
+
*
|
|
25
|
+
* CRITICAL: This is Layer 1 backfill for 3-layer idempotency
|
|
26
|
+
* Must be called after GitHub issue creation to cache issue number
|
|
27
|
+
*/
|
|
28
|
+
async updateUserStoryFrontmatter(options) {
|
|
29
|
+
try {
|
|
30
|
+
const { projectRoot, featureId, userStoryId, githubIssue } = options;
|
|
31
|
+
// Construct user story file path
|
|
32
|
+
const userStoryPath = await this.getUserStoryPath(projectRoot, featureId, userStoryId);
|
|
33
|
+
if (!existsSync(userStoryPath)) {
|
|
34
|
+
this.logger.log(`⚠️ User story file not found: ${userStoryPath}`);
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
// Read current content
|
|
38
|
+
const content = await readFile(userStoryPath, 'utf-8');
|
|
39
|
+
// Parse frontmatter
|
|
40
|
+
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
41
|
+
if (!frontmatterMatch) {
|
|
42
|
+
this.logger.log(`⚠️ No frontmatter found in ${userStoryPath}`);
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
const frontmatterText = frontmatterMatch[1];
|
|
46
|
+
const frontmatter = yaml.parse(frontmatterText);
|
|
47
|
+
// Check if already has GitHub info (avoid overwriting)
|
|
48
|
+
if (frontmatter.external_tools?.github?.number) {
|
|
49
|
+
this.logger.log(` ℹ️ ${userStoryId} frontmatter already has GitHub issue #${frontmatter.external_tools.github.number}`);
|
|
50
|
+
return true; // Already backfilled
|
|
51
|
+
}
|
|
52
|
+
// Add external_tools.github section
|
|
53
|
+
if (!frontmatter.external_tools) {
|
|
54
|
+
frontmatter.external_tools = {};
|
|
55
|
+
}
|
|
56
|
+
frontmatter.external_tools.github = {
|
|
57
|
+
number: githubIssue.number,
|
|
58
|
+
url: githubIssue.url,
|
|
59
|
+
created_at: githubIssue.createdAt,
|
|
60
|
+
};
|
|
61
|
+
// Serialize updated frontmatter
|
|
62
|
+
const newFrontmatter = yaml.stringify(frontmatter);
|
|
63
|
+
// Replace frontmatter in content
|
|
64
|
+
const newContent = content.replace(/^---\n[\s\S]*?\n---/, `---\n${newFrontmatter.trim()}\n---`);
|
|
65
|
+
// Write back to file
|
|
66
|
+
await writeFile(userStoryPath, newContent, 'utf-8');
|
|
67
|
+
this.logger.log(` ✅ Updated ${userStoryId} frontmatter with issue #${githubIssue.number}`);
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
this.logger.error(`❌ Failed to update frontmatter for ${options.userStoryId}:`, error);
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Batch update multiple user story frontmatters
|
|
77
|
+
*/
|
|
78
|
+
async batchUpdateFrontmatters(projectRoot, featureId, updates) {
|
|
79
|
+
let success = 0;
|
|
80
|
+
let failed = 0;
|
|
81
|
+
for (const update of updates) {
|
|
82
|
+
const result = await this.updateUserStoryFrontmatter({
|
|
83
|
+
projectRoot,
|
|
84
|
+
featureId,
|
|
85
|
+
userStoryId: update.userStoryId,
|
|
86
|
+
githubIssue: update.githubIssue,
|
|
87
|
+
});
|
|
88
|
+
if (result) {
|
|
89
|
+
success++;
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
failed++;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return { success, failed };
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Get user story file path from project root, feature ID, and user story ID
|
|
99
|
+
*/
|
|
100
|
+
async getUserStoryPath(projectRoot, featureId, userStoryId) {
|
|
101
|
+
// Convert user story ID to file name (US-001 → us-001-*.md)
|
|
102
|
+
const usPrefix = userStoryId.toLowerCase();
|
|
103
|
+
// Search in .specweave/docs/internal/specs/specweave/{featureId}/
|
|
104
|
+
const featurePath = path.join(projectRoot, '.specweave/docs/internal/specs/specweave', featureId);
|
|
105
|
+
if (!existsSync(featurePath)) {
|
|
106
|
+
throw new Error(`Feature directory not found: ${featurePath}`);
|
|
107
|
+
}
|
|
108
|
+
// Find file matching us-* pattern (use async readdir)
|
|
109
|
+
const files = await readdir(featurePath);
|
|
110
|
+
const matchingFile = files.find((file) => file.startsWith(usPrefix) && file.endsWith('.md'));
|
|
111
|
+
if (!matchingFile) {
|
|
112
|
+
throw new Error(`User story file not found for ${userStoryId} in ${featurePath}`);
|
|
113
|
+
}
|
|
114
|
+
return path.join(featurePath, matchingFile);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Read GitHub issue info from user story frontmatter (Layer 1 check)
|
|
118
|
+
*/
|
|
119
|
+
async getGitHubIssueFromFrontmatter(projectRoot, featureId, userStoryId) {
|
|
120
|
+
try {
|
|
121
|
+
const userStoryPath = await this.getUserStoryPath(projectRoot, featureId, userStoryId);
|
|
122
|
+
if (!existsSync(userStoryPath)) {
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
const content = await readFile(userStoryPath, 'utf-8');
|
|
126
|
+
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
127
|
+
if (!frontmatterMatch) {
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
const frontmatter = yaml.parse(frontmatterMatch[1]);
|
|
131
|
+
const githubInfo = frontmatter.external_tools?.github;
|
|
132
|
+
if (!githubInfo || !githubInfo.number) {
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
return {
|
|
136
|
+
number: githubInfo.number,
|
|
137
|
+
url: githubInfo.url,
|
|
138
|
+
createdAt: githubInfo.created_at || new Date().toISOString(),
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
this.logger.error(`Failed to read GitHub info from ${userStoryId} frontmatter:`, error);
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=frontmatter-updater.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frontmatter-updater.js","sourceRoot":"","sources":["../../../src/sync/frontmatter-updater.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* High-level coordinator that integrates FormatPreservationSyncService
|
|
5
5
|
* with living docs sync workflow. Called by post-task-completion hook.
|
|
6
6
|
*/
|
|
7
|
+
import { GitHubIssue } from '../../plugins/specweave-github/lib/types.js';
|
|
7
8
|
import { Logger } from '../utils/logger.js';
|
|
8
9
|
export interface SyncCoordinatorOptions {
|
|
9
10
|
projectRoot: string;
|
|
@@ -13,14 +14,34 @@ export interface SyncCoordinatorOptions {
|
|
|
13
14
|
export interface SyncResult {
|
|
14
15
|
success: boolean;
|
|
15
16
|
userStoriesSynced: number;
|
|
16
|
-
syncMode: 'comment-only' | 'full-sync' | 'read-only' | 'manual-only';
|
|
17
|
+
syncMode: 'comment-only' | 'full-sync' | 'read-only' | 'manual-only' | 'living-docs-only' | 'external-disabled';
|
|
17
18
|
errors: string[];
|
|
18
19
|
}
|
|
19
20
|
export declare class SyncCoordinator {
|
|
20
21
|
private projectRoot;
|
|
21
22
|
private incrementId;
|
|
22
23
|
private logger;
|
|
24
|
+
private frontmatterUpdater;
|
|
23
25
|
constructor(options: SyncCoordinatorOptions);
|
|
26
|
+
/**
|
|
27
|
+
* Create GitHub issues for all User Stories in the feature (NEW in v0.25.0)
|
|
28
|
+
*
|
|
29
|
+
* This is the AUTOMATIC GitHub sync that runs when increment completes.
|
|
30
|
+
* Creates issues for User Stories that don't have GitHub issues yet.
|
|
31
|
+
*
|
|
32
|
+
* Uses 3-layer idempotency:
|
|
33
|
+
* - Layer 1: Check user story frontmatter (fastest, <1ms)
|
|
34
|
+
* - Layer 2: Check increment metadata.json (fast, <5ms)
|
|
35
|
+
* - Layer 3: Query GitHub API (slow but authoritative, 500-2000ms)
|
|
36
|
+
*
|
|
37
|
+
* @param config - Project configuration
|
|
38
|
+
* @returns Array of created issues
|
|
39
|
+
*/
|
|
40
|
+
createGitHubIssuesForUserStories(config: any): Promise<GitHubIssue[]>;
|
|
41
|
+
/**
|
|
42
|
+
* Format user story content for GitHub issue body
|
|
43
|
+
*/
|
|
44
|
+
private formatUserStoryBody;
|
|
24
45
|
/**
|
|
25
46
|
* Sync increment completion to external tools using format preservation
|
|
26
47
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-coordinator.d.ts","sourceRoot":"","sources":["../../../src/sync/sync-coordinator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,OAAO,EAAE,MAAM,EAAiB,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"sync-coordinator.d.ts","sourceRoot":"","sources":["../../../src/sync/sync-coordinator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,OAAO,EAAE,WAAW,EAAE,MAAM,6CAA6C,CAAC;AAC1E,OAAO,EAAE,MAAM,EAAiB,MAAM,oBAAoB,CAAC;AAG3D,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,cAAc,GAAG,WAAW,GAAG,WAAW,GAAG,aAAa,GAAG,kBAAkB,GAAG,mBAAmB,CAAC;IAChH,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,kBAAkB,CAAqB;gBAEnC,OAAO,EAAE,sBAAsB;IAO3C;;;;;;;;;;;;;OAaG;IACG,gCAAgC,CAAC,MAAM,EAAE,GAAG,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAwN3E;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAuB3B;;OAEG;IACG,uBAAuB,IAAI,OAAO,CAAC,UAAU,CAAC;IA6HpD;;OAEG;YACW,aAAa;IAyD3B;;OAEG;YACW,kBAAkB;IAmEhC;;OAEG;YACW,2BAA2B;IAsEzC;;OAEG;YACW,UAAU;IAWxB;;OAEG;YACW,gBAAgB;CAyB/B"}
|