specweave 1.0.235 → 1.0.239

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 (196) hide show
  1. package/README.md +89 -193
  2. package/dist/plugins/specweave-github/lib/github-ac-comment-poster.d.ts +37 -0
  3. package/dist/plugins/specweave-github/lib/github-ac-comment-poster.d.ts.map +1 -0
  4. package/dist/plugins/specweave-github/lib/github-ac-comment-poster.js +176 -0
  5. package/dist/plugins/specweave-github/lib/github-ac-comment-poster.js.map +1 -0
  6. package/dist/plugins/specweave-github/lib/github-batch-sync.d.ts +36 -0
  7. package/dist/plugins/specweave-github/lib/github-batch-sync.d.ts.map +1 -0
  8. package/dist/plugins/specweave-github/lib/github-batch-sync.js +115 -0
  9. package/dist/plugins/specweave-github/lib/github-batch-sync.js.map +1 -0
  10. package/dist/plugins/specweave-github/lib/github-board-resolver-v2.d.ts +37 -0
  11. package/dist/plugins/specweave-github/lib/github-board-resolver-v2.d.ts.map +1 -0
  12. package/dist/plugins/specweave-github/lib/github-board-resolver-v2.js +56 -0
  13. package/dist/plugins/specweave-github/lib/github-board-resolver-v2.js.map +1 -0
  14. package/dist/plugins/specweave-github/lib/github-conflict-resolver.d.ts +68 -0
  15. package/dist/plugins/specweave-github/lib/github-conflict-resolver.d.ts.map +1 -0
  16. package/dist/plugins/specweave-github/lib/github-conflict-resolver.js +102 -0
  17. package/dist/plugins/specweave-github/lib/github-conflict-resolver.js.map +1 -0
  18. package/dist/plugins/specweave-github/lib/github-cross-repo-sync.d.ts +64 -0
  19. package/dist/plugins/specweave-github/lib/github-cross-repo-sync.d.ts.map +1 -0
  20. package/dist/plugins/specweave-github/lib/github-cross-repo-sync.js +162 -0
  21. package/dist/plugins/specweave-github/lib/github-cross-repo-sync.js.map +1 -0
  22. package/dist/plugins/specweave-github/lib/github-field-sync.d.ts +50 -0
  23. package/dist/plugins/specweave-github/lib/github-field-sync.d.ts.map +1 -0
  24. package/dist/plugins/specweave-github/lib/github-field-sync.js +107 -0
  25. package/dist/plugins/specweave-github/lib/github-field-sync.js.map +1 -0
  26. package/dist/plugins/specweave-github/lib/github-graphql-client.d.ts +53 -0
  27. package/dist/plugins/specweave-github/lib/github-graphql-client.d.ts.map +1 -0
  28. package/dist/plugins/specweave-github/lib/github-graphql-client.js +138 -0
  29. package/dist/plugins/specweave-github/lib/github-graphql-client.js.map +1 -0
  30. package/dist/plugins/specweave-github/lib/github-issue-body-generator.d.ts +40 -0
  31. package/dist/plugins/specweave-github/lib/github-issue-body-generator.d.ts.map +1 -0
  32. package/dist/plugins/specweave-github/lib/github-issue-body-generator.js +50 -0
  33. package/dist/plugins/specweave-github/lib/github-issue-body-generator.js.map +1 -0
  34. package/dist/plugins/specweave-github/lib/github-issue-body-parser.d.ts +30 -0
  35. package/dist/plugins/specweave-github/lib/github-issue-body-parser.d.ts.map +1 -0
  36. package/dist/plugins/specweave-github/lib/github-issue-body-parser.js +75 -0
  37. package/dist/plugins/specweave-github/lib/github-issue-body-parser.js.map +1 -0
  38. package/dist/plugins/specweave-github/lib/github-pull-sync.d.ts +94 -0
  39. package/dist/plugins/specweave-github/lib/github-pull-sync.d.ts.map +1 -0
  40. package/dist/plugins/specweave-github/lib/github-pull-sync.js +232 -0
  41. package/dist/plugins/specweave-github/lib/github-pull-sync.js.map +1 -0
  42. package/dist/plugins/specweave-github/lib/github-push-sync.d.ts +50 -0
  43. package/dist/plugins/specweave-github/lib/github-push-sync.d.ts.map +1 -0
  44. package/dist/plugins/specweave-github/lib/github-push-sync.js +114 -0
  45. package/dist/plugins/specweave-github/lib/github-push-sync.js.map +1 -0
  46. package/dist/plugins/specweave-github/lib/github-rate-limiter.d.ts +53 -0
  47. package/dist/plugins/specweave-github/lib/github-rate-limiter.d.ts.map +1 -0
  48. package/dist/plugins/specweave-github/lib/github-rate-limiter.js +109 -0
  49. package/dist/plugins/specweave-github/lib/github-rate-limiter.js.map +1 -0
  50. package/dist/plugins/specweave-github/lib/github-spec-frontmatter-updater.d.ts +21 -0
  51. package/dist/plugins/specweave-github/lib/github-spec-frontmatter-updater.d.ts.map +1 -0
  52. package/dist/plugins/specweave-github/lib/github-spec-frontmatter-updater.js +161 -0
  53. package/dist/plugins/specweave-github/lib/github-spec-frontmatter-updater.js.map +1 -0
  54. package/dist/plugins/specweave-github/lib/github-sync-orchestrator.d.ts +46 -0
  55. package/dist/plugins/specweave-github/lib/github-sync-orchestrator.d.ts.map +1 -0
  56. package/dist/plugins/specweave-github/lib/github-sync-orchestrator.js +99 -0
  57. package/dist/plugins/specweave-github/lib/github-sync-orchestrator.js.map +1 -0
  58. package/dist/plugins/specweave-github/lib/github-us-auto-closer.d.ts +43 -0
  59. package/dist/plugins/specweave-github/lib/github-us-auto-closer.d.ts.map +1 -0
  60. package/dist/plugins/specweave-github/lib/github-us-auto-closer.js +153 -0
  61. package/dist/plugins/specweave-github/lib/github-us-auto-closer.js.map +1 -0
  62. package/dist/plugins/specweave-github/lib/index.d.ts +1 -4
  63. package/dist/plugins/specweave-github/lib/index.d.ts.map +1 -1
  64. package/dist/plugins/specweave-github/lib/index.js +1 -4
  65. package/dist/plugins/specweave-github/lib/index.js.map +1 -1
  66. package/dist/plugins/specweave-testing/lib/playwright-ci-defaults.d.ts +7 -0
  67. package/dist/plugins/specweave-testing/lib/playwright-ci-defaults.d.ts.map +1 -0
  68. package/dist/plugins/specweave-testing/lib/playwright-ci-defaults.js +15 -0
  69. package/dist/plugins/specweave-testing/lib/playwright-ci-defaults.js.map +1 -0
  70. package/dist/plugins/specweave-testing/lib/playwright-cli-detector.d.ts +10 -0
  71. package/dist/plugins/specweave-testing/lib/playwright-cli-detector.d.ts.map +1 -0
  72. package/dist/plugins/specweave-testing/lib/playwright-cli-detector.js +36 -0
  73. package/dist/plugins/specweave-testing/lib/playwright-cli-detector.js.map +1 -0
  74. package/dist/plugins/specweave-testing/lib/playwright-cli-runner.d.ts +25 -0
  75. package/dist/plugins/specweave-testing/lib/playwright-cli-runner.d.ts.map +1 -0
  76. package/dist/plugins/specweave-testing/lib/playwright-cli-runner.js +57 -0
  77. package/dist/plugins/specweave-testing/lib/playwright-cli-runner.js.map +1 -0
  78. package/dist/plugins/specweave-testing/lib/playwright-routing.d.ts +7 -0
  79. package/dist/plugins/specweave-testing/lib/playwright-routing.d.ts.map +1 -0
  80. package/dist/plugins/specweave-testing/lib/playwright-routing.js +17 -0
  81. package/dist/plugins/specweave-testing/lib/playwright-routing.js.map +1 -0
  82. package/dist/src/cli/commands/auto.d.ts.map +1 -1
  83. package/dist/src/cli/commands/auto.js +1 -2
  84. package/dist/src/cli/commands/auto.js.map +1 -1
  85. package/dist/src/cli/commands/cancel-auto.js +1 -2
  86. package/dist/src/cli/commands/cancel-auto.js.map +1 -1
  87. package/dist/src/cli/commands/living-docs.js +2 -2
  88. package/dist/src/cli/commands/living-docs.js.map +1 -1
  89. package/dist/src/cli/commands/update.d.ts.map +1 -1
  90. package/dist/src/cli/commands/update.js +1 -2
  91. package/dist/src/cli/commands/update.js.map +1 -1
  92. package/dist/src/core/config/types.d.ts +8 -0
  93. package/dist/src/core/config/types.d.ts.map +1 -1
  94. package/dist/src/core/config/types.js +3 -0
  95. package/dist/src/core/config/types.js.map +1 -1
  96. package/dist/src/core/types/sync-profile.d.ts +72 -0
  97. package/dist/src/core/types/sync-profile.d.ts.map +1 -1
  98. package/dist/src/core/types/sync-profile.js +6 -0
  99. package/dist/src/core/types/sync-profile.js.map +1 -1
  100. package/package.json +2 -2
  101. package/plugins/specweave/hooks/hooks.json +2 -2
  102. package/plugins/specweave/hooks/startup-health-check.sh +1 -1
  103. package/plugins/specweave/hooks/stop-auto-v5.sh +166 -0
  104. package/plugins/specweave/hooks/user-prompt-submit.sh +10 -0
  105. package/plugins/specweave/hooks/v2/dispatchers/post-tool-use.sh +21 -1
  106. package/plugins/specweave/hooks/v2/dispatchers/session-start.sh +1 -1
  107. package/plugins/specweave/skills/auto/SKILL.md +71 -251
  108. package/plugins/specweave/skills/team-build/SKILL.md +370 -0
  109. package/plugins/specweave/skills/team-merge/SKILL.md +123 -0
  110. package/plugins/specweave/skills/team-orchestrate/SKILL.md +800 -0
  111. package/plugins/specweave/skills/team-status/SKILL.md +89 -0
  112. package/plugins/specweave-github/MULTI-PROJECT-SYNC-ARCHITECTURE.md +94 -8
  113. package/plugins/specweave-github/commands/sync.md +17 -3
  114. package/plugins/specweave-github/hooks/github-ac-sync-handler.sh +255 -0
  115. package/plugins/specweave-github/hooks/github-auto-create-handler.sh +455 -0
  116. package/plugins/specweave-github/lib/github-ac-comment-poster.js +150 -0
  117. package/plugins/specweave-github/lib/github-ac-comment-poster.ts +245 -0
  118. package/plugins/specweave-github/lib/github-batch-sync.js +93 -0
  119. package/plugins/specweave-github/lib/github-batch-sync.ts +152 -0
  120. package/plugins/specweave-github/lib/github-board-resolver-v2.js +47 -0
  121. package/plugins/specweave-github/lib/github-board-resolver-v2.ts +73 -0
  122. package/plugins/specweave-github/lib/github-conflict-resolver.js +90 -0
  123. package/plugins/specweave-github/lib/github-conflict-resolver.ts +154 -0
  124. package/plugins/specweave-github/lib/github-cross-repo-sync.js +168 -0
  125. package/plugins/specweave-github/lib/github-cross-repo-sync.ts +252 -0
  126. package/plugins/specweave-github/lib/github-field-sync.js +116 -0
  127. package/plugins/specweave-github/lib/github-field-sync.ts +165 -0
  128. package/plugins/specweave-github/lib/github-graphql-client.js +129 -0
  129. package/plugins/specweave-github/lib/github-graphql-client.ts +181 -0
  130. package/plugins/specweave-github/lib/github-issue-body-generator.js +30 -0
  131. package/plugins/specweave-github/lib/github-issue-body-generator.ts +76 -0
  132. package/plugins/specweave-github/lib/github-issue-body-parser.js +55 -0
  133. package/plugins/specweave-github/lib/github-issue-body-parser.ts +92 -0
  134. package/plugins/specweave-github/lib/github-pull-sync.js +185 -0
  135. package/plugins/specweave-github/lib/github-pull-sync.ts +343 -0
  136. package/plugins/specweave-github/lib/github-push-sync.js +119 -0
  137. package/plugins/specweave-github/lib/github-push-sync.ts +174 -0
  138. package/plugins/specweave-github/lib/github-rate-limiter.js +96 -0
  139. package/plugins/specweave-github/lib/github-rate-limiter.ts +143 -0
  140. package/plugins/specweave-github/lib/github-spec-frontmatter-updater.js +117 -0
  141. package/plugins/specweave-github/lib/github-spec-frontmatter-updater.ts +180 -0
  142. package/plugins/specweave-github/lib/github-sync-orchestrator.js +84 -0
  143. package/plugins/specweave-github/lib/github-sync-orchestrator.ts +156 -0
  144. package/plugins/specweave-github/lib/github-us-auto-closer.js +134 -0
  145. package/plugins/specweave-github/lib/github-us-auto-closer.ts +226 -0
  146. package/plugins/specweave-github/lib/index.js +1 -7
  147. package/plugins/specweave-github/lib/index.ts +1 -4
  148. package/plugins/specweave-github/skills/github-sync/SKILL.md +76 -4
  149. package/plugins/specweave-testing/commands/e2e-setup.md +18 -0
  150. package/plugins/specweave-testing/commands/ui-automate.md +2 -0
  151. package/plugins/specweave-testing/commands/ui-inspect.md +8 -0
  152. package/plugins/specweave-testing/lib/playwright-ci-defaults.d.ts +6 -0
  153. package/plugins/specweave-testing/lib/playwright-ci-defaults.js +14 -0
  154. package/plugins/specweave-testing/lib/playwright-ci-defaults.ts +24 -0
  155. package/plugins/specweave-testing/lib/playwright-cli-detector.js +33 -0
  156. package/plugins/specweave-testing/lib/playwright-cli-detector.ts +48 -0
  157. package/plugins/specweave-testing/lib/playwright-cli-runner.js +58 -0
  158. package/plugins/specweave-testing/lib/playwright-cli-runner.ts +80 -0
  159. package/plugins/specweave-testing/lib/playwright-routing.js +16 -0
  160. package/plugins/specweave-testing/lib/playwright-routing.ts +38 -0
  161. package/plugins/specweave-testing/skills/e2e-testing/SKILL.md +38 -0
  162. package/src/templates/CLAUDE.md.template +7 -0
  163. package/src/templates/config.json.template +9 -1
  164. package/dist/plugins/specweave-github/lib/subtask-sync.d.ts +0 -51
  165. package/dist/plugins/specweave-github/lib/subtask-sync.d.ts.map +0 -1
  166. package/dist/plugins/specweave-github/lib/subtask-sync.js +0 -147
  167. package/dist/plugins/specweave-github/lib/subtask-sync.js.map +0 -1
  168. package/dist/plugins/specweave-github/lib/task-parser.d.ts +0 -37
  169. package/dist/plugins/specweave-github/lib/task-parser.d.ts.map +0 -1
  170. package/dist/plugins/specweave-github/lib/task-parser.js +0 -211
  171. package/dist/plugins/specweave-github/lib/task-parser.js.map +0 -1
  172. package/dist/plugins/specweave-github/lib/task-sync.d.ts +0 -56
  173. package/dist/plugins/specweave-github/lib/task-sync.d.ts.map +0 -1
  174. package/dist/plugins/specweave-github/lib/task-sync.js +0 -375
  175. package/dist/plugins/specweave-github/lib/task-sync.js.map +0 -1
  176. package/plugins/specweave/hooks/validate-completion-conditions.sh +0 -474
  177. package/plugins/specweave-github/lib/subtask-sync.d.ts +0 -51
  178. package/plugins/specweave-github/lib/subtask-sync.d.ts.map +0 -1
  179. package/plugins/specweave-github/lib/subtask-sync.js +0 -154
  180. package/plugins/specweave-github/lib/subtask-sync.js.map +0 -1
  181. package/plugins/specweave-github/lib/subtask-sync.ts +0 -225
  182. package/plugins/specweave-github/lib/task-parser.d.js +0 -0
  183. package/plugins/specweave-github/lib/task-parser.d.ts +0 -37
  184. package/plugins/specweave-github/lib/task-parser.d.ts.map +0 -1
  185. package/plugins/specweave-github/lib/task-parser.js +0 -195
  186. package/plugins/specweave-github/lib/task-parser.js.map +0 -1
  187. package/plugins/specweave-github/lib/task-parser.ts +0 -246
  188. package/plugins/specweave-github/lib/task-sync.d.js +0 -0
  189. package/plugins/specweave-github/lib/task-sync.d.ts +0 -51
  190. package/plugins/specweave-github/lib/task-sync.d.ts.map +0 -1
  191. package/plugins/specweave-github/lib/task-sync.js +0 -415
  192. package/plugins/specweave-github/lib/task-sync.js.map +0 -1
  193. package/plugins/specweave-github/lib/task-sync.ts +0 -451
  194. package/plugins/specweave-github/skills/github-issue-tracker/SKILL.md +0 -496
  195. /package/plugins/specweave/hooks/{stop-auto.sh → _archive/stop-auto-v4-legacy.sh} +0 -0
  196. /package/plugins/{specweave-github/lib/subtask-sync.d.js → specweave-testing/lib/playwright-ci-defaults.d.js} +0 -0
@@ -0,0 +1,94 @@
1
+ /**
2
+ * GitHub Pull Sync — GitHub Issues → Spec
3
+ *
4
+ * Fetches GitHub issue state and compares with spec acceptance criteria
5
+ * to detect changes, conflicts, and apply updates.
6
+ *
7
+ * @module github-pull-sync
8
+ */
9
+ import type { GitHubUserStoryLink } from '../../../src/core/types/sync-profile.js';
10
+ export interface PullSyncOptions {
11
+ owner: string;
12
+ repo: string;
13
+ token?: string;
14
+ dryRun?: boolean;
15
+ }
16
+ export interface PullSyncChange {
17
+ userStoryId: string;
18
+ field: string;
19
+ specValue: string;
20
+ githubValue: string;
21
+ applied: boolean;
22
+ }
23
+ export interface PullSyncConflict {
24
+ userStoryId: string;
25
+ field: string;
26
+ specValue: string;
27
+ githubValue: string;
28
+ }
29
+ export interface PullSyncResult {
30
+ changes: PullSyncChange[];
31
+ conflicts: PullSyncConflict[];
32
+ errors: Array<{
33
+ userStoryId: string;
34
+ error: string;
35
+ }>;
36
+ }
37
+ /**
38
+ * Pull sync from GitHub — fetch issue state and compare with spec ACs.
39
+ *
40
+ * For each linked user story:
41
+ * 1. Fetch issue via `gh issue view`
42
+ * 2. Parse body to extract AC checkbox states
43
+ * 3. Compare with spec AC states
44
+ * 4. Report changes and conflicts
45
+ */
46
+ export declare function pullSyncFromGitHub(userStoryLinks: Record<string, GitHubUserStoryLink>, specAcceptanceCriteria: Record<string, Array<{
47
+ id: string;
48
+ completed: boolean;
49
+ }>>, options: PullSyncOptions): Promise<PullSyncResult>;
50
+ export interface MultiRepoPullSyncOptions extends PullSyncOptions {
51
+ }
52
+ export interface MultiRepoDisagreement {
53
+ userStoryId: string;
54
+ field: string;
55
+ repoStates: Record<string, boolean>;
56
+ }
57
+ export interface MultiRepoPullSyncResult {
58
+ changes: PullSyncChange[];
59
+ conflicts: PullSyncConflict[];
60
+ disagreements: MultiRepoDisagreement[];
61
+ errors: Array<{
62
+ userStoryId?: string;
63
+ repo?: string;
64
+ error: string;
65
+ }>;
66
+ }
67
+ interface RepoConfig {
68
+ owner: string;
69
+ repo: string;
70
+ relevantStories: string[];
71
+ }
72
+ interface MultiRepoUserStoryLinks {
73
+ [usId: string]: Record<string, {
74
+ issueNumber: number;
75
+ }>;
76
+ }
77
+ /**
78
+ * Pull sync from multiple repos with all-repos-must-agree consensus.
79
+ *
80
+ * For shared user stories (appearing in 2+ repos):
81
+ * - AC is marked done ONLY if ALL repos agree it is done
82
+ * - Disagreements are recorded separately
83
+ *
84
+ * For repo-specific user stories (1 repo):
85
+ * - Standard single-repo logic applies
86
+ *
87
+ * Repo errors are non-blocking: erroring repos are excluded from consensus.
88
+ */
89
+ export declare function pullSyncMultiRepo(repos: RepoConfig[], userStoryLinks: MultiRepoUserStoryLinks, specAcceptanceCriteria: Record<string, Array<{
90
+ id: string;
91
+ completed: boolean;
92
+ }>>, options: MultiRepoPullSyncOptions): Promise<MultiRepoPullSyncResult>;
93
+ export {};
94
+ //# sourceMappingURL=github-pull-sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-pull-sync.d.ts","sourceRoot":"","sources":["../../../../plugins/specweave-github/lib/github-pull-sync.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AAEnF,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,SAAS,EAAE,gBAAgB,EAAE,CAAC;IAC9B,MAAM,EAAE,KAAK,CAAC;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACvD;AAED;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,CACtC,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,EACnD,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC,EACjF,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,cAAc,CAAC,CA+BzB;AA+FD,MAAM,WAAW,wBAAyB,SAAQ,eAAe;CAAG;AAEpE,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,SAAS,EAAE,gBAAgB,EAAE,CAAC;IAC9B,aAAa,EAAE,qBAAqB,EAAE,CAAC;IACvC,MAAM,EAAE,KAAK,CAAC;QAAE,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACvE;AAED,UAAU,UAAU;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,UAAU,uBAAuB;IAC/B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACzD;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,UAAU,EAAE,EACnB,cAAc,EAAE,uBAAuB,EACvC,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC,EACjF,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,uBAAuB,CAAC,CAwHlC"}
@@ -0,0 +1,232 @@
1
+ /**
2
+ * GitHub Pull Sync — GitHub Issues → Spec
3
+ *
4
+ * Fetches GitHub issue state and compares with spec acceptance criteria
5
+ * to detect changes, conflicts, and apply updates.
6
+ *
7
+ * @module github-pull-sync
8
+ */
9
+ import { execFileNoThrow } from '../../../src/utils/execFileNoThrow.js';
10
+ import { parseIssueBody } from './github-issue-body-parser.js';
11
+ /**
12
+ * Pull sync from GitHub — fetch issue state and compare with spec ACs.
13
+ *
14
+ * For each linked user story:
15
+ * 1. Fetch issue via `gh issue view`
16
+ * 2. Parse body to extract AC checkbox states
17
+ * 3. Compare with spec AC states
18
+ * 4. Report changes and conflicts
19
+ */
20
+ export async function pullSyncFromGitHub(userStoryLinks, specAcceptanceCriteria, options) {
21
+ const result = { changes: [], conflicts: [], errors: [] };
22
+ const entries = Object.entries(userStoryLinks);
23
+ if (entries.length === 0) {
24
+ return result;
25
+ }
26
+ const env = getEnv(options.token);
27
+ const repoSlug = `${options.owner}/${options.repo}`;
28
+ for (const [usId, link] of entries) {
29
+ try {
30
+ const issueData = await fetchIssue(link.issueNumber, repoSlug, env);
31
+ const parsed = parseIssueBody(issueData.body || '');
32
+ const specACs = specAcceptanceCriteria[usId] || [];
33
+ // Compare AC checkbox states
34
+ compareACStates(usId, specACs, parsed.acceptanceCriteria, options.dryRun ?? false, result);
35
+ // Compare issue state (open/closed)
36
+ compareIssueState(usId, issueData.state, specACs, result, options.dryRun ?? false);
37
+ }
38
+ catch (err) {
39
+ result.errors.push({
40
+ userStoryId: usId,
41
+ error: err instanceof Error ? err.message : String(err),
42
+ });
43
+ }
44
+ }
45
+ return result;
46
+ }
47
+ function compareACStates(usId, specACs, githubACs, dryRun, result) {
48
+ for (const specAC of specACs) {
49
+ const ghAC = githubACs[specAC.id];
50
+ if (!ghAC)
51
+ continue;
52
+ const specValue = String(specAC.completed);
53
+ const githubValue = String(ghAC.checked);
54
+ if (specValue !== githubValue) {
55
+ // Both changed from a baseline? That's a conflict.
56
+ // Simple heuristic: if spec says true and GitHub says false, it's a conflict
57
+ // (someone completed on spec side, but GitHub unchecked it)
58
+ if (specAC.completed && !ghAC.checked) {
59
+ result.conflicts.push({
60
+ userStoryId: usId,
61
+ field: specAC.id,
62
+ specValue,
63
+ githubValue,
64
+ });
65
+ }
66
+ else {
67
+ // GitHub is ahead — record as a change
68
+ result.changes.push({
69
+ userStoryId: usId,
70
+ field: specAC.id,
71
+ specValue,
72
+ githubValue,
73
+ applied: !dryRun,
74
+ });
75
+ }
76
+ }
77
+ }
78
+ }
79
+ function compareIssueState(usId, githubState, specACs, result, dryRun) {
80
+ // Normalize GitHub state
81
+ const normalizedState = githubState.toLowerCase() === 'closed' ? 'closed' : 'open';
82
+ // Check if spec is effectively "complete" (all ACs done) or "open"
83
+ const allDone = specACs.length > 0 && specACs.every(ac => ac.completed);
84
+ const specState = allDone ? 'closed' : 'open';
85
+ if (specState !== normalizedState) {
86
+ result.changes.push({
87
+ userStoryId: usId,
88
+ field: 'status',
89
+ specValue: specState,
90
+ githubValue: normalizedState,
91
+ applied: !dryRun,
92
+ });
93
+ }
94
+ }
95
+ async function fetchIssue(issueNumber, repoSlug, env) {
96
+ const res = await execFileNoThrow('gh', [
97
+ 'issue', 'view', String(issueNumber),
98
+ '--repo', repoSlug,
99
+ '--json', 'title,body,state,labels',
100
+ ], { env });
101
+ if (!res.success) {
102
+ throw new Error(res.stderr || 'Failed to fetch issue');
103
+ }
104
+ return JSON.parse(res.stdout);
105
+ }
106
+ function getEnv(token) {
107
+ if (token) {
108
+ return { ...process.env, GH_TOKEN: token };
109
+ }
110
+ return process.env;
111
+ }
112
+ /**
113
+ * Pull sync from multiple repos with all-repos-must-agree consensus.
114
+ *
115
+ * For shared user stories (appearing in 2+ repos):
116
+ * - AC is marked done ONLY if ALL repos agree it is done
117
+ * - Disagreements are recorded separately
118
+ *
119
+ * For repo-specific user stories (1 repo):
120
+ * - Standard single-repo logic applies
121
+ *
122
+ * Repo errors are non-blocking: erroring repos are excluded from consensus.
123
+ */
124
+ export async function pullSyncMultiRepo(repos, userStoryLinks, specAcceptanceCriteria, options) {
125
+ const result = {
126
+ changes: [],
127
+ conflicts: [],
128
+ disagreements: [],
129
+ errors: [],
130
+ };
131
+ if (repos.length === 0) {
132
+ return result;
133
+ }
134
+ const env = getEnv(options.token);
135
+ // Step 1: Fetch per-repo AC states
136
+ // Map: usId → acId → repoSlug → checked
137
+ const perRepoACStates = {};
138
+ const failedRepos = new Set();
139
+ for (const repo of repos) {
140
+ const repoSlug = `${repo.owner}/${repo.repo}`;
141
+ for (const usId of repo.relevantStories) {
142
+ const links = userStoryLinks[usId];
143
+ if (!links || !links[repoSlug])
144
+ continue;
145
+ const issueNumber = links[repoSlug].issueNumber;
146
+ try {
147
+ const issueData = await fetchIssue(issueNumber, repoSlug, env);
148
+ const parsed = parseIssueBody(issueData.body || '');
149
+ // Record AC states for this repo
150
+ if (!perRepoACStates[usId]) {
151
+ perRepoACStates[usId] = {};
152
+ }
153
+ const specACs = specAcceptanceCriteria[usId] || [];
154
+ for (const specAC of specACs) {
155
+ const ghAC = parsed.acceptanceCriteria[specAC.id];
156
+ if (!ghAC)
157
+ continue;
158
+ if (!perRepoACStates[usId][specAC.id]) {
159
+ perRepoACStates[usId][specAC.id] = {};
160
+ }
161
+ perRepoACStates[usId][specAC.id][repoSlug] = ghAC.checked;
162
+ }
163
+ }
164
+ catch (err) {
165
+ failedRepos.add(repoSlug);
166
+ result.errors.push({
167
+ userStoryId: usId,
168
+ repo: repoSlug,
169
+ error: err instanceof Error ? err.message : String(err),
170
+ });
171
+ }
172
+ }
173
+ }
174
+ // Step 2: Build consensus per AC
175
+ for (const [usId, acMap] of Object.entries(perRepoACStates)) {
176
+ const specACs = specAcceptanceCriteria[usId] || [];
177
+ // Determine how many repos this US should appear in (excluding failed)
178
+ const usLinks = userStoryLinks[usId] || {};
179
+ const expectedRepos = Object.keys(usLinks).filter(r => !failedRepos.has(r));
180
+ for (const specAC of specACs) {
181
+ const repoStates = acMap[specAC.id];
182
+ if (!repoStates)
183
+ continue;
184
+ // Filter out failed repos
185
+ const validStates = Object.entries(repoStates).filter(([repo]) => !failedRepos.has(repo));
186
+ if (validStates.length === 0)
187
+ continue;
188
+ const allChecked = validStates.every(([, checked]) => checked);
189
+ const allUnchecked = validStates.every(([, checked]) => !checked);
190
+ const isShared = expectedRepos.length > 1;
191
+ if (isShared) {
192
+ // All-repos-must-agree consensus
193
+ if (allChecked && !specAC.completed) {
194
+ result.changes.push({
195
+ userStoryId: usId,
196
+ field: specAC.id,
197
+ specValue: String(specAC.completed),
198
+ githubValue: 'true',
199
+ applied: true,
200
+ });
201
+ }
202
+ else if (!allChecked && !allUnchecked && !specAC.completed) {
203
+ // Disagreement
204
+ const stateMap = {};
205
+ for (const [repo, checked] of validStates) {
206
+ stateMap[repo] = checked;
207
+ }
208
+ result.disagreements.push({
209
+ userStoryId: usId,
210
+ field: specAC.id,
211
+ repoStates: stateMap,
212
+ });
213
+ }
214
+ }
215
+ else {
216
+ // Single-repo: use directly
217
+ const [, checked] = validStates[0];
218
+ if (checked && !specAC.completed) {
219
+ result.changes.push({
220
+ userStoryId: usId,
221
+ field: specAC.id,
222
+ specValue: String(specAC.completed),
223
+ githubValue: 'true',
224
+ applied: true,
225
+ });
226
+ }
227
+ }
228
+ }
229
+ }
230
+ return result;
231
+ }
232
+ //# sourceMappingURL=github-pull-sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-pull-sync.js","sourceRoot":"","sources":["../../../../plugins/specweave-github/lib/github-pull-sync.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * GitHub Push Sync — User Stories → GitHub Issues
3
+ *
4
+ * Creates or updates GitHub issues from SpecWeave user stories.
5
+ * Uses `gh` CLI for all operations (no direct HTTP).
6
+ *
7
+ * @module github-push-sync
8
+ */
9
+ export interface UserStoryForSync {
10
+ id: string;
11
+ title: string;
12
+ description: string;
13
+ priority: string;
14
+ status: string;
15
+ acceptanceCriteria: Array<{
16
+ id: string;
17
+ description: string;
18
+ completed: boolean;
19
+ }>;
20
+ specId?: string;
21
+ }
22
+ export interface PushSyncOptions {
23
+ owner: string;
24
+ repo: string;
25
+ token?: string;
26
+ dryRun?: boolean;
27
+ }
28
+ export interface PushSyncResult {
29
+ created: Array<{
30
+ userStoryId: string;
31
+ issueNumber: number;
32
+ issueUrl: string;
33
+ issueNodeId: string;
34
+ }>;
35
+ updated: Array<{
36
+ userStoryId: string;
37
+ issueNumber: number;
38
+ issueUrl: string;
39
+ }>;
40
+ errors: Array<{
41
+ userStoryId: string;
42
+ error: string;
43
+ }>;
44
+ }
45
+ /**
46
+ * Push sync user stories to GitHub issues.
47
+ * For each US: search by [US-XXX] prefix, create if new, update if existing.
48
+ */
49
+ export declare function pushSyncUserStories(userStories: UserStoryForSync[], options: PushSyncOptions): Promise<PushSyncResult>;
50
+ //# sourceMappingURL=github-push-sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-push-sync.d.ts","sourceRoot":"","sources":["../../../../plugins/specweave-github/lib/github-push-sync.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACnF,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,KAAK,CAAC;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpG,OAAO,EAAE,KAAK,CAAC;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/E,MAAM,EAAE,KAAK,CAAC;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACvD;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,gBAAgB,EAAE,EAC/B,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,cAAc,CAAC,CAoDzB"}
@@ -0,0 +1,114 @@
1
+ /**
2
+ * GitHub Push Sync — User Stories → GitHub Issues
3
+ *
4
+ * Creates or updates GitHub issues from SpecWeave user stories.
5
+ * Uses `gh` CLI for all operations (no direct HTTP).
6
+ *
7
+ * @module github-push-sync
8
+ */
9
+ import { execFileNoThrow } from '../../../src/utils/execFileNoThrow.js';
10
+ import { generateIssueBody } from './github-issue-body-generator.js';
11
+ /**
12
+ * Push sync user stories to GitHub issues.
13
+ * For each US: search by [US-XXX] prefix, create if new, update if existing.
14
+ */
15
+ export async function pushSyncUserStories(userStories, options) {
16
+ const result = { created: [], updated: [], errors: [] };
17
+ if (options.dryRun) {
18
+ return result;
19
+ }
20
+ const env = getEnv(options.token);
21
+ const repoSlug = `${options.owner}/${options.repo}`;
22
+ for (const us of userStories) {
23
+ try {
24
+ const existing = await searchIssueByPrefix(us.id, repoSlug, env);
25
+ const body = generateIssueBody({
26
+ id: us.id,
27
+ title: us.title,
28
+ description: us.description,
29
+ priority: us.priority,
30
+ acceptanceCriteria: us.acceptanceCriteria,
31
+ specId: us.specId,
32
+ });
33
+ const title = `[${us.id}] ${us.title}`;
34
+ if (existing) {
35
+ // Update existing issue
36
+ const updated = await updateIssue(existing.number, title, body, repoSlug, env);
37
+ result.updated.push({
38
+ userStoryId: us.id,
39
+ issueNumber: updated.number,
40
+ issueUrl: updated.url,
41
+ });
42
+ }
43
+ else {
44
+ // Create new issue
45
+ const created = await createIssue(title, body, us, repoSlug, env);
46
+ result.created.push({
47
+ userStoryId: us.id,
48
+ issueNumber: created.number,
49
+ issueUrl: created.url,
50
+ issueNodeId: created.node_id,
51
+ });
52
+ }
53
+ }
54
+ catch (err) {
55
+ result.errors.push({
56
+ userStoryId: us.id,
57
+ error: err instanceof Error ? err.message : String(err),
58
+ });
59
+ }
60
+ }
61
+ return result;
62
+ }
63
+ async function searchIssueByPrefix(usId, repoSlug, env) {
64
+ const res = await execFileNoThrow('gh', [
65
+ 'issue', 'list',
66
+ '--repo', repoSlug,
67
+ '--search', `[${usId}] in:title`,
68
+ '--json', 'number,title,node_id',
69
+ '--limit', '1',
70
+ ], { env });
71
+ if (!res.success) {
72
+ throw new Error(`Search failed: ${res.stderr}`);
73
+ }
74
+ const issues = JSON.parse(res.stdout);
75
+ return issues.length > 0 ? issues[0] : null;
76
+ }
77
+ async function createIssue(title, body, us, repoSlug, env) {
78
+ const args = [
79
+ 'issue', 'create',
80
+ '--repo', repoSlug,
81
+ '--title', title,
82
+ '--body', body,
83
+ '--label', 'user-story',
84
+ '--label', `spec:${us.specId || 'unknown'}`,
85
+ '--label', `priority:${us.priority}`,
86
+ '--json', 'number,url,node_id',
87
+ ];
88
+ const res = await execFileNoThrow('gh', args, { env });
89
+ if (!res.success) {
90
+ throw new Error(`Create failed: ${res.stderr}`);
91
+ }
92
+ return JSON.parse(res.stdout);
93
+ }
94
+ async function updateIssue(issueNumber, title, body, repoSlug, env) {
95
+ const args = [
96
+ 'issue', 'edit', String(issueNumber),
97
+ '--repo', repoSlug,
98
+ '--title', title,
99
+ '--body', body,
100
+ '--json', 'number,url',
101
+ ];
102
+ const res = await execFileNoThrow('gh', args, { env });
103
+ if (!res.success) {
104
+ throw new Error(`Update failed: ${res.stderr}`);
105
+ }
106
+ return JSON.parse(res.stdout);
107
+ }
108
+ function getEnv(token) {
109
+ if (token) {
110
+ return { ...process.env, GH_TOKEN: token };
111
+ }
112
+ return process.env;
113
+ }
114
+ //# sourceMappingURL=github-push-sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-push-sync.js","sourceRoot":"","sources":["../../../../plugins/specweave-github/lib/github-push-sync.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * GitHub Rate Limiter
3
+ *
4
+ * Shared token-bucket rate limiter for multi-repo GitHub sync.
5
+ * Queries `gh api rate_limit`, tracks cumulative usage, and gates
6
+ * sync operations when approaching API limits.
7
+ *
8
+ * @module github-rate-limiter
9
+ */
10
+ export interface RateLimitStatus {
11
+ /** Remaining requests in current window */
12
+ remaining: number;
13
+ /** Total limit per window */
14
+ limit: number;
15
+ /** When the rate limit resets */
16
+ resetAt: Date;
17
+ /** Percentage of limit used (0-100) */
18
+ percentUsed: number;
19
+ }
20
+ interface CanProceedResult {
21
+ allowed: boolean;
22
+ waitMs?: number;
23
+ reason?: string;
24
+ }
25
+ export declare class GitHubRateLimiter {
26
+ private token?;
27
+ private totalUsed;
28
+ private knownLimit;
29
+ constructor(token?: string);
30
+ /**
31
+ * Query current GitHub API rate limit via `gh api rate_limit`.
32
+ */
33
+ checkRateLimit(): Promise<RateLimitStatus>;
34
+ /**
35
+ * Estimate how many API calls a sync operation will require.
36
+ */
37
+ estimateApiCalls(specCount: number, userStoryCount: number): number;
38
+ /**
39
+ * Check whether a sync operation can proceed given the current rate limit.
40
+ */
41
+ canProceed(estimatedCalls: number): Promise<CanProceedResult>;
42
+ /**
43
+ * Record API calls made during a sync operation.
44
+ */
45
+ recordUsage(calls: number): void;
46
+ /**
47
+ * Get the percentage of the known limit used by this limiter instance.
48
+ */
49
+ getUsagePercent(): number;
50
+ private getEnv;
51
+ }
52
+ export {};
53
+ //# sourceMappingURL=github-rate-limiter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-rate-limiter.d.ts","sourceRoot":"","sources":["../../../../plugins/specweave-github/lib/github-rate-limiter.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,MAAM,WAAW,eAAe;IAC9B,2CAA2C;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,6BAA6B;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,iCAAiC;IACjC,OAAO,EAAE,IAAI,CAAC;IACd,uCAAuC;IACvC,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,gBAAgB;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAOD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,KAAK,CAAC,CAAS;IACvB,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,UAAU,CAAK;gBAEX,KAAK,CAAC,EAAE,MAAM;IAI1B;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,eAAe,CAAC;IAkChD;;OAEG;IACH,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM;IAOnE;;OAEG;IACG,UAAU,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAwBnE;;OAEG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAOhC;;OAEG;IACH,eAAe,IAAI,MAAM;IAMzB,OAAO,CAAC,MAAM;CAMf"}