specweave 0.17.15 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. package/CLAUDE.md +405 -2495
  2. package/README.md +92 -2
  3. package/dist/plugins/specweave/lib/hooks/sync-living-docs.d.ts.map +1 -1
  4. package/dist/plugins/specweave/lib/hooks/sync-living-docs.js +188 -36
  5. package/dist/plugins/specweave/lib/hooks/sync-living-docs.js.map +1 -1
  6. package/dist/plugins/specweave-ado/lib/ado-status-sync.d.ts +54 -0
  7. package/dist/plugins/specweave-ado/lib/ado-status-sync.d.ts.map +1 -0
  8. package/dist/plugins/specweave-ado/lib/ado-status-sync.js +86 -0
  9. package/dist/plugins/specweave-ado/lib/ado-status-sync.js.map +1 -0
  10. package/dist/plugins/specweave-github/lib/duplicate-detector.d.ts +139 -0
  11. package/dist/plugins/specweave-github/lib/duplicate-detector.d.ts.map +1 -0
  12. package/dist/plugins/specweave-github/lib/duplicate-detector.js +389 -0
  13. package/dist/plugins/specweave-github/lib/duplicate-detector.js.map +1 -0
  14. package/dist/plugins/specweave-github/lib/enhanced-github-sync.d.ts +26 -0
  15. package/dist/plugins/specweave-github/lib/enhanced-github-sync.d.ts.map +1 -0
  16. package/dist/plugins/specweave-github/lib/enhanced-github-sync.js +249 -0
  17. package/dist/plugins/specweave-github/lib/enhanced-github-sync.js.map +1 -0
  18. package/dist/plugins/specweave-github/lib/github-client.d.ts +1 -1
  19. package/dist/plugins/specweave-github/lib/github-client.d.ts.map +1 -1
  20. package/dist/plugins/specweave-github/lib/github-client.js +25 -13
  21. package/dist/plugins/specweave-github/lib/github-client.js.map +1 -1
  22. package/dist/plugins/specweave-github/lib/github-epic-sync.d.ts +83 -0
  23. package/dist/plugins/specweave-github/lib/github-epic-sync.d.ts.map +1 -0
  24. package/dist/plugins/specweave-github/lib/github-epic-sync.js +451 -0
  25. package/dist/plugins/specweave-github/lib/github-epic-sync.js.map +1 -0
  26. package/dist/plugins/specweave-github/lib/github-status-sync.d.ts +43 -0
  27. package/dist/plugins/specweave-github/lib/github-status-sync.d.ts.map +1 -0
  28. package/dist/plugins/specweave-github/lib/github-status-sync.js +82 -0
  29. package/dist/plugins/specweave-github/lib/github-status-sync.js.map +1 -0
  30. package/dist/plugins/specweave-github/lib/task-sync.d.ts +5 -0
  31. package/dist/plugins/specweave-github/lib/task-sync.d.ts.map +1 -1
  32. package/dist/plugins/specweave-github/lib/task-sync.js +38 -2
  33. package/dist/plugins/specweave-github/lib/task-sync.js.map +1 -1
  34. package/dist/plugins/specweave-jira/lib/jira-epic-sync.d.ts +66 -0
  35. package/dist/plugins/specweave-jira/lib/jira-epic-sync.d.ts.map +1 -0
  36. package/dist/plugins/specweave-jira/lib/jira-epic-sync.js +274 -0
  37. package/dist/plugins/specweave-jira/lib/jira-epic-sync.js.map +1 -0
  38. package/dist/plugins/specweave-jira/lib/jira-status-sync.d.ts +56 -0
  39. package/dist/plugins/specweave-jira/lib/jira-status-sync.d.ts.map +1 -0
  40. package/dist/plugins/specweave-jira/lib/jira-status-sync.js +93 -0
  41. package/dist/plugins/specweave-jira/lib/jira-status-sync.js.map +1 -0
  42. package/dist/src/cli/helpers/issue-tracker/index.d.ts.map +1 -1
  43. package/dist/src/cli/helpers/issue-tracker/index.js +48 -3
  44. package/dist/src/cli/helpers/issue-tracker/index.js.map +1 -1
  45. package/dist/src/core/living-docs/hierarchy-mapper.d.ts +142 -0
  46. package/dist/src/core/living-docs/hierarchy-mapper.d.ts.map +1 -0
  47. package/dist/src/core/living-docs/hierarchy-mapper.js +453 -0
  48. package/dist/src/core/living-docs/hierarchy-mapper.js.map +1 -0
  49. package/dist/src/core/living-docs/index.d.ts +10 -84
  50. package/dist/src/core/living-docs/index.d.ts.map +1 -1
  51. package/dist/src/core/living-docs/index.js +10 -164
  52. package/dist/src/core/living-docs/index.js.map +1 -1
  53. package/dist/src/core/living-docs/spec-distributor.d.ts +106 -0
  54. package/dist/src/core/living-docs/spec-distributor.d.ts.map +1 -0
  55. package/dist/src/core/living-docs/spec-distributor.js +823 -0
  56. package/dist/src/core/living-docs/spec-distributor.js.map +1 -0
  57. package/dist/src/core/living-docs/types.d.ts +201 -0
  58. package/dist/src/core/living-docs/types.d.ts.map +1 -0
  59. package/dist/src/core/living-docs/types.js +15 -0
  60. package/dist/src/core/living-docs/types.js.map +1 -0
  61. package/dist/src/core/logging/prompt-logger.d.ts +70 -0
  62. package/dist/src/core/logging/prompt-logger.d.ts.map +1 -0
  63. package/dist/src/core/logging/prompt-logger.js +247 -0
  64. package/dist/src/core/logging/prompt-logger.js.map +1 -0
  65. package/dist/src/core/status-line/status-line-manager.d.ts +15 -24
  66. package/dist/src/core/status-line/status-line-manager.d.ts.map +1 -1
  67. package/dist/src/core/status-line/status-line-manager.js +33 -70
  68. package/dist/src/core/status-line/status-line-manager.js.map +1 -1
  69. package/dist/src/core/status-line/types.d.ts +19 -31
  70. package/dist/src/core/status-line/types.d.ts.map +1 -1
  71. package/dist/src/core/status-line/types.js +5 -9
  72. package/dist/src/core/status-line/types.js.map +1 -1
  73. package/dist/src/core/sync/conflict-resolver.d.ts +66 -0
  74. package/dist/src/core/sync/conflict-resolver.d.ts.map +1 -0
  75. package/dist/src/core/sync/conflict-resolver.js +108 -0
  76. package/dist/src/core/sync/conflict-resolver.js.map +1 -0
  77. package/dist/src/core/sync/enhanced-content-builder.d.ts +77 -0
  78. package/dist/src/core/sync/enhanced-content-builder.d.ts.map +1 -0
  79. package/dist/src/core/sync/enhanced-content-builder.js +199 -0
  80. package/dist/src/core/sync/enhanced-content-builder.js.map +1 -0
  81. package/dist/src/core/sync/label-detector.d.ts +66 -0
  82. package/dist/src/core/sync/label-detector.d.ts.map +1 -0
  83. package/dist/src/core/sync/label-detector.js +211 -0
  84. package/dist/src/core/sync/label-detector.js.map +1 -0
  85. package/dist/src/core/sync/retry-logic.d.ts +64 -0
  86. package/dist/src/core/sync/retry-logic.d.ts.map +1 -0
  87. package/dist/src/core/sync/retry-logic.js +165 -0
  88. package/dist/src/core/sync/retry-logic.js.map +1 -0
  89. package/dist/src/core/sync/spec-increment-mapper.d.ts +100 -0
  90. package/dist/src/core/sync/spec-increment-mapper.d.ts.map +1 -0
  91. package/dist/src/core/sync/spec-increment-mapper.js +424 -0
  92. package/dist/src/core/sync/spec-increment-mapper.js.map +1 -0
  93. package/dist/src/core/sync/status-cache.d.ts +91 -0
  94. package/dist/src/core/sync/status-cache.d.ts.map +1 -0
  95. package/dist/src/core/sync/status-cache.js +140 -0
  96. package/dist/src/core/sync/status-cache.js.map +1 -0
  97. package/dist/src/core/sync/status-mapper.d.ts +69 -0
  98. package/dist/src/core/sync/status-mapper.d.ts.map +1 -0
  99. package/dist/src/core/sync/status-mapper.js +90 -0
  100. package/dist/src/core/sync/status-mapper.js.map +1 -0
  101. package/dist/src/core/sync/status-sync-engine.d.ts +162 -0
  102. package/dist/src/core/sync/status-sync-engine.d.ts.map +1 -0
  103. package/dist/src/core/sync/status-sync-engine.js +347 -0
  104. package/dist/src/core/sync/status-sync-engine.js.map +1 -0
  105. package/dist/src/core/sync/sync-event-logger.d.ts +99 -0
  106. package/dist/src/core/sync/sync-event-logger.d.ts.map +1 -0
  107. package/dist/src/core/sync/sync-event-logger.js +103 -0
  108. package/dist/src/core/sync/sync-event-logger.js.map +1 -0
  109. package/dist/src/core/sync/workflow-detector.d.ts +95 -0
  110. package/dist/src/core/sync/workflow-detector.d.ts.map +1 -0
  111. package/dist/src/core/sync/workflow-detector.js +175 -0
  112. package/dist/src/core/sync/workflow-detector.js.map +1 -0
  113. package/dist/src/core/types/config.d.ts.map +1 -1
  114. package/dist/src/core/types/config.js +31 -0
  115. package/dist/src/core/types/config.js.map +1 -1
  116. package/dist/src/utils/github-url.d.ts +53 -0
  117. package/dist/src/utils/github-url.d.ts.map +1 -0
  118. package/dist/src/utils/github-url.js +90 -0
  119. package/dist/src/utils/github-url.js.map +1 -0
  120. package/dist/src/utils/plugin-validator.d.ts +9 -0
  121. package/dist/src/utils/plugin-validator.d.ts.map +1 -1
  122. package/dist/src/utils/plugin-validator.js +86 -19
  123. package/dist/src/utils/plugin-validator.js.map +1 -1
  124. package/dist/src/utils/spec-parser.d.ts +145 -0
  125. package/dist/src/utils/spec-parser.d.ts.map +1 -0
  126. package/dist/src/utils/spec-parser.js +640 -0
  127. package/dist/src/utils/spec-parser.js.map +1 -0
  128. package/package.json +1 -1
  129. package/plugins/specweave/agents/pm/AGENT.md +1 -1
  130. package/plugins/specweave/agents/pm/templates/increment-spec.md +158 -0
  131. package/plugins/specweave/agents/pm/templates/living-docs-spec.md +113 -0
  132. package/plugins/specweave/commands/specweave-done.md +163 -0
  133. package/plugins/specweave/hooks/lib/update-status-line.sh +79 -111
  134. package/plugins/specweave/hooks/post-increment-planning.sh +107 -35
  135. package/plugins/specweave/lib/hooks/sync-living-docs.js +139 -34
  136. package/plugins/specweave/lib/hooks/sync-living-docs.ts +234 -38
  137. package/plugins/specweave/skills/SKILLS-INDEX.md +4 -24
  138. package/plugins/specweave/skills/increment-planner/SKILL.md +94 -0
  139. package/plugins/specweave/skills/increment-work-router/SKILL.md +466 -0
  140. package/plugins/specweave/skills/plugin-validator/SKILL.md +16 -13
  141. package/plugins/specweave-ado/lib/ado-status-sync.js +80 -0
  142. package/plugins/specweave-ado/lib/ado-status-sync.ts +121 -0
  143. package/plugins/specweave-github/commands/specweave-github-cleanup-duplicates.md +205 -0
  144. package/plugins/specweave-github/commands/specweave-github-sync-epic.md +248 -0
  145. package/plugins/specweave-github/lib/duplicate-detector.js +370 -0
  146. package/plugins/specweave-github/lib/duplicate-detector.ts +525 -0
  147. package/plugins/specweave-github/lib/enhanced-github-sync.js +220 -0
  148. package/plugins/specweave-github/lib/enhanced-github-sync.ts +322 -0
  149. package/plugins/specweave-github/lib/github-client.js +21 -10
  150. package/plugins/specweave-github/lib/github-client.ts +27 -16
  151. package/plugins/specweave-github/lib/github-epic-sync.js +489 -0
  152. package/plugins/specweave-github/lib/github-epic-sync.ts +690 -0
  153. package/plugins/specweave-github/lib/github-status-sync.js +71 -0
  154. package/plugins/specweave-github/lib/github-status-sync.ts +107 -0
  155. package/plugins/specweave-github/lib/task-sync.js +33 -2
  156. package/plugins/specweave-github/lib/task-sync.ts +44 -2
  157. package/plugins/specweave-jira/commands/specweave-jira-sync-epic.md +267 -0
  158. package/plugins/specweave-jira/lib/enhanced-jira-sync.ts.disabled +222 -0
  159. package/plugins/specweave-jira/lib/jira-epic-sync.js +304 -0
  160. package/plugins/specweave-jira/lib/jira-epic-sync.ts +459 -0
  161. package/plugins/specweave-jira/lib/jira-status-sync.js +79 -0
  162. package/plugins/specweave-jira/lib/jira-status-sync.ts +139 -0
  163. package/src/templates/AGENTS.md.template +88 -1
  164. package/src/templates/CLAUDE.md.template +49 -0
  165. package/plugins/specweave/skills/increment-quality-judge/SKILL.md +0 -524
  166. package/plugins/specweave/skills/plugin-installer/SKILL.md +0 -353
@@ -0,0 +1,139 @@
1
+ /**
2
+ * Global Duplicate Detection System for GitHub Issues
3
+ *
4
+ * CRITICAL ARCHITECTURE:
5
+ * ALL GitHub issue creation in SpecWeave MUST use this module.
6
+ * This is the SINGLE SOURCE OF TRUTH for duplicate prevention.
7
+ *
8
+ * THREE-PHASE PROTECTION:
9
+ * 1. Detection (Before Create): Search GitHub for existing issues
10
+ * 2. Verification (After Create): Count check to detect duplicates
11
+ * 3. Reflection (Auto-Correct): Close duplicate issues automatically
12
+ *
13
+ * USAGE:
14
+ * ```typescript
15
+ * // Simple: Create with full protection
16
+ * const result = await DuplicateDetector.createWithProtection({
17
+ * title: '[FS-031] Feature Title',
18
+ * body: 'Description...',
19
+ * titlePattern: '[FS-031]',
20
+ * labels: ['specweave', 'feature']
21
+ * });
22
+ *
23
+ * // Manual: Check before creating
24
+ * const existing = await DuplicateDetector.checkBeforeCreate('[FS-031]');
25
+ * if (!existing) {
26
+ * // Create issue...
27
+ * }
28
+ * ```
29
+ *
30
+ * @module duplicate-detector
31
+ */
32
+ export interface GitHubIssue {
33
+ number: number;
34
+ title: string;
35
+ url: string;
36
+ body?: string;
37
+ state?: 'open' | 'closed';
38
+ createdAt?: string;
39
+ }
40
+ export interface VerificationResult {
41
+ success: boolean;
42
+ expectedCount: number;
43
+ actualCount: number;
44
+ duplicates: GitHubIssue[];
45
+ message: string;
46
+ }
47
+ export interface CorrectionResult {
48
+ success: boolean;
49
+ duplicatesClosed: number;
50
+ keptIssue: number;
51
+ errors: string[];
52
+ }
53
+ export interface CreateOptions {
54
+ title: string;
55
+ body: string;
56
+ titlePattern: string;
57
+ incrementId?: string;
58
+ labels?: string[];
59
+ milestone?: string;
60
+ assignees?: string[];
61
+ repo?: string;
62
+ }
63
+ export interface CreateResult {
64
+ issue: GitHubIssue;
65
+ duplicatesFound: number;
66
+ duplicatesClosed: number;
67
+ wasReused: boolean;
68
+ }
69
+ export declare class DuplicateDetector {
70
+ /**
71
+ * PHASE 1: Detection (Before Creating Issue)
72
+ *
73
+ * Searches GitHub for existing issues matching the title pattern.
74
+ * This is the PRIMARY defense against duplicates.
75
+ *
76
+ * @param titlePattern - Pattern to search (e.g., "[FS-031]" or "[INC-0031]")
77
+ * @param incrementId - Optional increment ID for more precise matching
78
+ * @param repo - Optional repo (format: "owner/repo")
79
+ * @returns Existing issue if found, null otherwise
80
+ */
81
+ static checkBeforeCreate(titlePattern: string, incrementId?: string, repo?: string): Promise<GitHubIssue | null>;
82
+ /**
83
+ * PHASE 2: Verification (After Creating Issue)
84
+ *
85
+ * Counts issues matching the pattern and identifies duplicates.
86
+ * This is the SECONDARY defense - catches duplicates that slipped through.
87
+ *
88
+ * @param titlePattern - Pattern to search (e.g., "[FS-031]")
89
+ * @param expectedCount - Expected number of issues (usually 1)
90
+ * @param repo - Optional repo (format: "owner/repo")
91
+ * @returns Verification result with duplicate list
92
+ */
93
+ static verifyAfterCreate(titlePattern: string, expectedCount?: number, repo?: string): Promise<VerificationResult>;
94
+ /**
95
+ * PHASE 3: Reflection (Auto-Correct Duplicates)
96
+ *
97
+ * Automatically closes duplicate issues and keeps the oldest one.
98
+ * This is the CLEANUP phase - fixes problems that occurred.
99
+ *
100
+ * @param duplicates - List of duplicate issues to close
101
+ * @param keepIssueNumber - Issue number to keep (usually the oldest)
102
+ * @param repo - Optional repo (format: "owner/repo")
103
+ * @returns Correction result with count of closed issues
104
+ */
105
+ static correctDuplicates(duplicates: GitHubIssue[], keepIssueNumber: number, repo?: string): Promise<CorrectionResult>;
106
+ /**
107
+ * ALL-IN-ONE: Create Issue with Full Protection
108
+ *
109
+ * This is the RECOMMENDED way to create GitHub issues in SpecWeave.
110
+ * Combines all 3 phases: Detection → Creation → Verification → Reflection
111
+ *
112
+ * GUARANTEES:
113
+ * - No duplicates will be created
114
+ * - Existing duplicates will be detected and closed
115
+ * - Idempotent: can run multiple times safely
116
+ *
117
+ * @param options - Create options (title, body, labels, etc.)
118
+ * @returns Create result with issue details and duplicate stats
119
+ */
120
+ static createWithProtection(options: CreateOptions): Promise<CreateResult>;
121
+ /**
122
+ * Utility: Extract title pattern from full title
123
+ *
124
+ * Examples:
125
+ * - "[FS-031] Feature Title" → "[FS-031]"
126
+ * - "[INC-0031] Increment Title" → "[INC-0031]"
127
+ *
128
+ * @param title - Full issue title
129
+ * @returns Extracted pattern or null
130
+ */
131
+ static extractTitlePattern(title: string): string | null;
132
+ /**
133
+ * Utility: Check if GitHub CLI is available and authenticated
134
+ *
135
+ * @returns true if gh CLI is ready, false otherwise
136
+ */
137
+ static checkGitHubCLI(): boolean;
138
+ }
139
+ //# sourceMappingURL=duplicate-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"duplicate-detector.d.ts","sourceRoot":"","sources":["../../../../plugins/specweave-github/lib/duplicate-detector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAQH,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,WAAW,EAAE,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,WAAW,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;CACpB;AAMD,qBAAa,iBAAiB;IAC5B;;;;;;;;;;OAUG;WACU,iBAAiB,CAC5B,YAAY,EAAE,MAAM,EACpB,WAAW,CAAC,EAAE,MAAM,EACpB,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IA+D9B;;;;;;;;;;OAUG;WACU,iBAAiB,CAC5B,YAAY,EAAE,MAAM,EACpB,aAAa,GAAE,MAAU,EACzB,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,kBAAkB,CAAC;IAwF9B;;;;;;;;;;OAUG;WACU,iBAAiB,CAC5B,UAAU,EAAE,WAAW,EAAE,EACzB,eAAe,EAAE,MAAM,EACvB,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,gBAAgB,CAAC;IA0E5B;;;;;;;;;;;;;OAaG;WACU,oBAAoB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;IA+HhF;;;;;;;;;OASG;IACH,MAAM,CAAC,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAKxD;;;;OAIG;IACH,MAAM,CAAC,cAAc,IAAI,OAAO;CAQjC"}
@@ -0,0 +1,389 @@
1
+ /**
2
+ * Global Duplicate Detection System for GitHub Issues
3
+ *
4
+ * CRITICAL ARCHITECTURE:
5
+ * ALL GitHub issue creation in SpecWeave MUST use this module.
6
+ * This is the SINGLE SOURCE OF TRUTH for duplicate prevention.
7
+ *
8
+ * THREE-PHASE PROTECTION:
9
+ * 1. Detection (Before Create): Search GitHub for existing issues
10
+ * 2. Verification (After Create): Count check to detect duplicates
11
+ * 3. Reflection (Auto-Correct): Close duplicate issues automatically
12
+ *
13
+ * USAGE:
14
+ * ```typescript
15
+ * // Simple: Create with full protection
16
+ * const result = await DuplicateDetector.createWithProtection({
17
+ * title: '[FS-031] Feature Title',
18
+ * body: 'Description...',
19
+ * titlePattern: '[FS-031]',
20
+ * labels: ['specweave', 'feature']
21
+ * });
22
+ *
23
+ * // Manual: Check before creating
24
+ * const existing = await DuplicateDetector.checkBeforeCreate('[FS-031]');
25
+ * if (!existing) {
26
+ * // Create issue...
27
+ * }
28
+ * ```
29
+ *
30
+ * @module duplicate-detector
31
+ */
32
+ import { execFileSync } from 'child_process';
33
+ // ============================================================================
34
+ // MAIN CLASS
35
+ // ============================================================================
36
+ export class DuplicateDetector {
37
+ /**
38
+ * PHASE 1: Detection (Before Creating Issue)
39
+ *
40
+ * Searches GitHub for existing issues matching the title pattern.
41
+ * This is the PRIMARY defense against duplicates.
42
+ *
43
+ * @param titlePattern - Pattern to search (e.g., "[FS-031]" or "[INC-0031]")
44
+ * @param incrementId - Optional increment ID for more precise matching
45
+ * @param repo - Optional repo (format: "owner/repo")
46
+ * @returns Existing issue if found, null otherwise
47
+ */
48
+ static async checkBeforeCreate(titlePattern, incrementId, repo) {
49
+ console.log(`šŸ” DETECTION: Checking for existing issue with pattern: ${titlePattern}`);
50
+ try {
51
+ const args = [
52
+ 'issue',
53
+ 'list',
54
+ '--search', `"${titlePattern}" in:title`,
55
+ '--json', 'number,title,url,body,createdAt',
56
+ '--limit', '20',
57
+ '--state', 'all' // Check both open and closed
58
+ ];
59
+ if (repo) {
60
+ args.push('--repo', repo);
61
+ }
62
+ const output = execFileSync('gh', args, { encoding: 'utf-8' });
63
+ const issues = JSON.parse(output);
64
+ if (issues.length === 0) {
65
+ console.log(' āœ… No existing issues found (safe to create)');
66
+ return null;
67
+ }
68
+ console.log(` šŸ“‹ Found ${issues.length} issue(s) matching pattern`);
69
+ // Strategy 1: Exact title match
70
+ const exactMatch = issues.find(issue => issue.title.includes(titlePattern));
71
+ if (exactMatch) {
72
+ console.log(` āš ļø DUPLICATE DETECTED: Issue #${exactMatch.number}`);
73
+ console.log(` šŸ“Ž URL: ${exactMatch.url}`);
74
+ return exactMatch;
75
+ }
76
+ // Strategy 2: Body match (if incrementId provided)
77
+ if (incrementId) {
78
+ const bodyMatch = issues.find(issue => issue.body && (issue.body.includes(`**Increment**: ${incrementId}`) ||
79
+ issue.body.includes(incrementId)));
80
+ if (bodyMatch) {
81
+ console.log(` āš ļø DUPLICATE DETECTED (body match): Issue #${bodyMatch.number}`);
82
+ console.log(` šŸ“Ž URL: ${bodyMatch.url}`);
83
+ return bodyMatch;
84
+ }
85
+ }
86
+ console.log(' āœ… No exact match found (safe to create)');
87
+ return null;
88
+ }
89
+ catch (error) {
90
+ console.warn(` āš ļø Detection failed (continuing anyway): ${error.message}`);
91
+ return null; // Fail gracefully - allow creation to proceed
92
+ }
93
+ }
94
+ /**
95
+ * PHASE 2: Verification (After Creating Issue)
96
+ *
97
+ * Counts issues matching the pattern and identifies duplicates.
98
+ * This is the SECONDARY defense - catches duplicates that slipped through.
99
+ *
100
+ * @param titlePattern - Pattern to search (e.g., "[FS-031]")
101
+ * @param expectedCount - Expected number of issues (usually 1)
102
+ * @param repo - Optional repo (format: "owner/repo")
103
+ * @returns Verification result with duplicate list
104
+ */
105
+ static async verifyAfterCreate(titlePattern, expectedCount = 1, repo) {
106
+ console.log(`\nšŸ” VERIFICATION: Checking issue count for pattern: ${titlePattern}`);
107
+ try {
108
+ const args = [
109
+ 'issue',
110
+ 'list',
111
+ '--search', `"${titlePattern}" in:title`,
112
+ '--json', 'number,title,url,createdAt',
113
+ '--limit', '50',
114
+ '--state', 'all'
115
+ ];
116
+ if (repo) {
117
+ args.push('--repo', repo);
118
+ }
119
+ const output = execFileSync('gh', args, { encoding: 'utf-8' });
120
+ const issues = JSON.parse(output);
121
+ // Filter exact matches only
122
+ const exactMatches = issues.filter(issue => issue.title.includes(titlePattern));
123
+ const actualCount = exactMatches.length;
124
+ console.log(` Expected: ${expectedCount} issue(s)`);
125
+ console.log(` Actual: ${actualCount} issue(s)`);
126
+ if (actualCount === expectedCount) {
127
+ console.log(` āœ… VERIFICATION PASSED: Count matches!`);
128
+ return {
129
+ success: true,
130
+ expectedCount,
131
+ actualCount,
132
+ duplicates: [],
133
+ message: 'Verification passed'
134
+ };
135
+ }
136
+ else if (actualCount > expectedCount) {
137
+ // DUPLICATES DETECTED!
138
+ console.warn(` āš ļø VERIFICATION FAILED: ${actualCount - expectedCount} duplicate(s) detected!`);
139
+ // Sort by creation date (oldest first)
140
+ const sorted = exactMatches.sort((a, b) => {
141
+ const dateA = new Date(a.createdAt || 0).getTime();
142
+ const dateB = new Date(b.createdAt || 0).getTime();
143
+ return dateA - dateB;
144
+ });
145
+ // Keep first (oldest), mark rest as duplicates
146
+ const duplicates = sorted.slice(1);
147
+ console.warn(` šŸ“‹ Duplicate issues:`);
148
+ duplicates.forEach(dup => {
149
+ console.warn(` - #${dup.number}: ${dup.title}`);
150
+ });
151
+ return {
152
+ success: false,
153
+ expectedCount,
154
+ actualCount,
155
+ duplicates,
156
+ message: `${duplicates.length} duplicate(s) found`
157
+ };
158
+ }
159
+ else {
160
+ console.warn(` āš ļø VERIFICATION WARNING: Expected ${expectedCount} but found ${actualCount}`);
161
+ return {
162
+ success: false,
163
+ expectedCount,
164
+ actualCount,
165
+ duplicates: [],
166
+ message: 'Count mismatch (fewer than expected)'
167
+ };
168
+ }
169
+ }
170
+ catch (error) {
171
+ console.error(` āŒ Verification failed: ${error.message}`);
172
+ return {
173
+ success: false,
174
+ expectedCount,
175
+ actualCount: -1,
176
+ duplicates: [],
177
+ message: `Verification error: ${error.message}`
178
+ };
179
+ }
180
+ }
181
+ /**
182
+ * PHASE 3: Reflection (Auto-Correct Duplicates)
183
+ *
184
+ * Automatically closes duplicate issues and keeps the oldest one.
185
+ * This is the CLEANUP phase - fixes problems that occurred.
186
+ *
187
+ * @param duplicates - List of duplicate issues to close
188
+ * @param keepIssueNumber - Issue number to keep (usually the oldest)
189
+ * @param repo - Optional repo (format: "owner/repo")
190
+ * @returns Correction result with count of closed issues
191
+ */
192
+ static async correctDuplicates(duplicates, keepIssueNumber, repo) {
193
+ if (duplicates.length === 0) {
194
+ return {
195
+ success: true,
196
+ duplicatesClosed: 0,
197
+ keptIssue: keepIssueNumber,
198
+ errors: []
199
+ };
200
+ }
201
+ console.log(`\nšŸ”§ REFLECTION: Auto-correcting ${duplicates.length} duplicate(s)...`);
202
+ const errors = [];
203
+ let closed = 0;
204
+ for (const duplicate of duplicates) {
205
+ try {
206
+ console.log(` šŸ—‘ļø Closing duplicate #${duplicate.number}...`);
207
+ const comment = `Duplicate of #${keepIssueNumber}
208
+
209
+ This issue was automatically closed by SpecWeave's Global Duplicate Detection System.
210
+
211
+ The original issue (#${keepIssueNumber}) should be used for tracking instead.
212
+
213
+ šŸ¤– Auto-closed by SpecWeave`;
214
+ const commentArgs = [
215
+ 'issue',
216
+ 'comment',
217
+ duplicate.number.toString(),
218
+ '--body', comment
219
+ ];
220
+ if (repo) {
221
+ commentArgs.push('--repo', repo);
222
+ }
223
+ // Add comment explaining closure
224
+ execFileSync('gh', commentArgs, { encoding: 'utf-8' });
225
+ const closeArgs = [
226
+ 'issue',
227
+ 'close',
228
+ duplicate.number.toString()
229
+ ];
230
+ if (repo) {
231
+ closeArgs.push('--repo', repo);
232
+ }
233
+ // Close the issue
234
+ execFileSync('gh', closeArgs, { encoding: 'utf-8' });
235
+ console.log(` āœ… Closed #${duplicate.number}`);
236
+ closed++;
237
+ }
238
+ catch (error) {
239
+ const errorMsg = `Failed to close #${duplicate.number}: ${error.message}`;
240
+ console.error(` āŒ ${errorMsg}`);
241
+ errors.push(errorMsg);
242
+ }
243
+ }
244
+ console.log(`\n āœ… REFLECTION COMPLETE: Kept #${keepIssueNumber}, closed ${closed}/${duplicates.length} duplicate(s)`);
245
+ return {
246
+ success: errors.length === 0,
247
+ duplicatesClosed: closed,
248
+ keptIssue: keepIssueNumber,
249
+ errors
250
+ };
251
+ }
252
+ /**
253
+ * ALL-IN-ONE: Create Issue with Full Protection
254
+ *
255
+ * This is the RECOMMENDED way to create GitHub issues in SpecWeave.
256
+ * Combines all 3 phases: Detection → Creation → Verification → Reflection
257
+ *
258
+ * GUARANTEES:
259
+ * - No duplicates will be created
260
+ * - Existing duplicates will be detected and closed
261
+ * - Idempotent: can run multiple times safely
262
+ *
263
+ * @param options - Create options (title, body, labels, etc.)
264
+ * @returns Create result with issue details and duplicate stats
265
+ */
266
+ static async createWithProtection(options) {
267
+ const { title, body, titlePattern, incrementId, labels = ['specweave'], milestone, assignees = [], repo } = options;
268
+ console.log(`\nšŸ›”ļø Creating GitHub issue with FULL PROTECTION...`);
269
+ console.log(` Title: ${title}`);
270
+ console.log(` Pattern: ${titlePattern}`);
271
+ // PHASE 1: Detection (Check if issue already exists)
272
+ console.log(`\n━━━ PHASE 1: DETECTION ━━━`);
273
+ const existing = await this.checkBeforeCreate(titlePattern, incrementId, repo);
274
+ let issueNumber;
275
+ let issueUrl;
276
+ let wasReused = false;
277
+ if (existing) {
278
+ // Reuse existing issue instead of creating duplicate
279
+ console.log(`\nā™»ļø Using existing issue #${existing.number} (skipping creation)`);
280
+ issueNumber = existing.number;
281
+ issueUrl = existing.url;
282
+ wasReused = true;
283
+ }
284
+ else {
285
+ // PHASE 2: Creation (No duplicate found, safe to create)
286
+ console.log(`\n━━━ PHASE 2: CREATION ━━━`);
287
+ console.log(` Creating new GitHub issue...`);
288
+ try {
289
+ const args = [
290
+ 'issue',
291
+ 'create',
292
+ '--title', title,
293
+ '--body', body
294
+ ];
295
+ if (repo) {
296
+ args.push('--repo', repo);
297
+ }
298
+ // Add labels
299
+ labels.forEach(label => {
300
+ args.push('--label', label);
301
+ });
302
+ // Add milestone if provided
303
+ if (milestone) {
304
+ args.push('--milestone', milestone);
305
+ }
306
+ // Add assignees if provided
307
+ assignees.forEach(assignee => {
308
+ args.push('--assignee', assignee);
309
+ });
310
+ const output = execFileSync('gh', args, { encoding: 'utf-8' });
311
+ // Extract issue number from output (format: "https://github.com/owner/repo/issues/123")
312
+ const match = output.match(/\/issues\/(\d+)/);
313
+ if (!match) {
314
+ throw new Error('Could not extract issue number from gh CLI output');
315
+ }
316
+ issueNumber = parseInt(match[1], 10);
317
+ issueUrl = output.trim();
318
+ console.log(` āœ… Created issue #${issueNumber}`);
319
+ console.log(` šŸ“Ž ${issueUrl}`);
320
+ }
321
+ catch (error) {
322
+ throw new Error(`Failed to create GitHub issue: ${error.message}`);
323
+ }
324
+ }
325
+ // PHASE 3: Verification (Count check for duplicates)
326
+ console.log(`\n━━━ PHASE 3: VERIFICATION ━━━`);
327
+ const verification = await this.verifyAfterCreate(titlePattern, 1, repo);
328
+ let duplicatesClosed = 0;
329
+ if (!verification.success && verification.duplicates.length > 0) {
330
+ // PHASE 4: Reflection (Auto-correct duplicates)
331
+ console.log(`\n━━━ PHASE 4: REFLECTION ━━━`);
332
+ console.warn(` āš ļø ${verification.duplicates.length} duplicate(s) detected!`);
333
+ const correction = await this.correctDuplicates(verification.duplicates, issueNumber, repo);
334
+ duplicatesClosed = correction.duplicatesClosed;
335
+ if (correction.errors.length > 0) {
336
+ console.warn(` āš ļø Some duplicates could not be closed:`);
337
+ correction.errors.forEach(err => console.warn(` - ${err}`));
338
+ }
339
+ }
340
+ else if (verification.success) {
341
+ console.log(` āœ… No duplicates detected!`);
342
+ }
343
+ // Final Summary
344
+ console.log(`\nāœ… Issue creation complete!`);
345
+ console.log(` Issue: #${issueNumber}`);
346
+ console.log(` Duplicates found: ${verification.duplicates.length}`);
347
+ console.log(` Duplicates closed: ${duplicatesClosed}`);
348
+ console.log(` Reused existing: ${wasReused ? 'Yes' : 'No'}`);
349
+ return {
350
+ issue: {
351
+ number: issueNumber,
352
+ title,
353
+ url: issueUrl
354
+ },
355
+ duplicatesFound: verification.duplicates.length,
356
+ duplicatesClosed,
357
+ wasReused
358
+ };
359
+ }
360
+ /**
361
+ * Utility: Extract title pattern from full title
362
+ *
363
+ * Examples:
364
+ * - "[FS-031] Feature Title" → "[FS-031]"
365
+ * - "[INC-0031] Increment Title" → "[INC-0031]"
366
+ *
367
+ * @param title - Full issue title
368
+ * @returns Extracted pattern or null
369
+ */
370
+ static extractTitlePattern(title) {
371
+ const match = title.match(/^(\[[^\]]+\])/);
372
+ return match ? match[1] : null;
373
+ }
374
+ /**
375
+ * Utility: Check if GitHub CLI is available and authenticated
376
+ *
377
+ * @returns true if gh CLI is ready, false otherwise
378
+ */
379
+ static checkGitHubCLI() {
380
+ try {
381
+ execFileSync('gh', ['auth', 'status'], { encoding: 'utf-8' });
382
+ return true;
383
+ }
384
+ catch {
385
+ return false;
386
+ }
387
+ }
388
+ }
389
+ //# sourceMappingURL=duplicate-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"duplicate-detector.js","sourceRoot":"","sources":["../../../../plugins/specweave-github/lib/duplicate-detector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Enhanced GitHub Spec Content Sync
3
+ *
4
+ * Uses EnhancedContentBuilder and SpecIncrementMapper for rich external descriptions.
5
+ * NEW (v0.21.0): Supports task checkboxes and automatic labeling.
6
+ */
7
+ export interface EnhancedGitHubSyncOptions {
8
+ specPath: string;
9
+ owner?: string;
10
+ repo?: string;
11
+ dryRun?: boolean;
12
+ verbose?: boolean;
13
+ }
14
+ export interface EnhancedSyncResult {
15
+ success: boolean;
16
+ action: 'created' | 'updated' | 'no-change' | 'error';
17
+ issueNumber?: number;
18
+ issueUrl?: string;
19
+ error?: string;
20
+ tasksLinked?: number;
21
+ }
22
+ /**
23
+ * Enhanced sync with rich content including task mappings
24
+ */
25
+ export declare function syncSpecWithEnhancedContent(options: EnhancedGitHubSyncOptions): Promise<EnhancedSyncResult>;
26
+ //# sourceMappingURL=enhanced-github-sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enhanced-github-sync.d.ts","sourceRoot":"","sources":["../../../../plugins/specweave-github/lib/enhanced-github-sync.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,OAAO,CAAC;IACtD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,wBAAsB,2BAA2B,CAC/C,OAAO,EAAE,yBAAyB,GACjC,OAAO,CAAC,kBAAkB,CAAC,CAsL7B"}