specweave 0.32.10 → 0.33.3
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 +162 -1
- package/dist/plugins/specweave-ado/lib/per-us-sync.d.ts +120 -0
- package/dist/plugins/specweave-ado/lib/per-us-sync.d.ts.map +1 -0
- package/dist/plugins/specweave-ado/lib/per-us-sync.js +276 -0
- package/dist/plugins/specweave-ado/lib/per-us-sync.js.map +1 -0
- package/dist/plugins/specweave-github/lib/github-client-v2.d.ts +4 -1
- package/dist/plugins/specweave-github/lib/github-client-v2.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/github-client-v2.js +13 -3
- package/dist/plugins/specweave-github/lib/github-client-v2.js.map +1 -1
- package/dist/plugins/specweave-github/lib/per-us-sync.d.ts +97 -0
- package/dist/plugins/specweave-github/lib/per-us-sync.d.ts.map +1 -0
- package/dist/plugins/specweave-github/lib/per-us-sync.js +274 -0
- package/dist/plugins/specweave-github/lib/per-us-sync.js.map +1 -0
- package/dist/plugins/specweave-jira/lib/per-us-sync.d.ts +113 -0
- package/dist/plugins/specweave-jira/lib/per-us-sync.d.ts.map +1 -0
- package/dist/plugins/specweave-jira/lib/per-us-sync.js +254 -0
- package/dist/plugins/specweave-jira/lib/per-us-sync.js.map +1 -0
- package/dist/src/cli/add-child-pid.d.ts +11 -0
- package/dist/src/cli/add-child-pid.d.ts.map +1 -0
- package/dist/src/cli/add-child-pid.js +42 -0
- package/dist/src/cli/add-child-pid.js.map +1 -0
- package/dist/src/cli/add-child-process.d.ts +15 -0
- package/dist/src/cli/add-child-process.d.ts.map +1 -0
- package/dist/src/cli/add-child-process.js +40 -0
- package/dist/src/cli/add-child-process.js.map +1 -0
- package/dist/src/cli/check-watchdog.d.ts +15 -0
- package/dist/src/cli/check-watchdog.d.ts.map +1 -0
- package/dist/src/cli/check-watchdog.js +47 -0
- package/dist/src/cli/check-watchdog.js.map +1 -0
- package/dist/src/cli/cleanup-zombies.d.ts +14 -0
- package/dist/src/cli/cleanup-zombies.d.ts.map +1 -0
- package/dist/src/cli/cleanup-zombies.js +268 -0
- package/dist/src/cli/cleanup-zombies.js.map +1 -0
- package/dist/src/cli/find-session-by-pid.d.ts +14 -0
- package/dist/src/cli/find-session-by-pid.d.ts.map +1 -0
- package/dist/src/cli/find-session-by-pid.js +45 -0
- package/dist/src/cli/find-session-by-pid.js.map +1 -0
- package/dist/src/cli/get-stale-sessions.d.ts +17 -0
- package/dist/src/cli/get-stale-sessions.d.ts.map +1 -0
- package/dist/src/cli/get-stale-sessions.js +36 -0
- package/dist/src/cli/get-stale-sessions.js.map +1 -0
- package/dist/src/cli/register-session.d.ts +16 -0
- package/dist/src/cli/register-session.d.ts.map +1 -0
- package/dist/src/cli/register-session.js +48 -0
- package/dist/src/cli/register-session.js.map +1 -0
- package/dist/src/cli/remove-session.d.ts +11 -0
- package/dist/src/cli/remove-session.d.ts.map +1 -0
- package/dist/src/cli/remove-session.js +36 -0
- package/dist/src/cli/remove-session.js.map +1 -0
- package/dist/src/cli/update-heartbeat.d.ts +11 -0
- package/dist/src/cli/update-heartbeat.d.ts.map +1 -0
- package/dist/src/cli/update-heartbeat.js +36 -0
- package/dist/src/cli/update-heartbeat.js.map +1 -0
- package/dist/src/config/types.d.ts +1208 -203
- package/dist/src/config/types.d.ts.map +1 -1
- package/dist/src/core/background/job-manager.d.ts +16 -0
- package/dist/src/core/background/job-manager.d.ts.map +1 -1
- package/dist/src/core/background/job-manager.js +110 -15
- package/dist/src/core/background/job-manager.js.map +1 -1
- package/dist/src/core/config/config-manager.d.ts.map +1 -1
- package/dist/src/core/config/config-manager.js +58 -0
- package/dist/src/core/config/config-manager.js.map +1 -1
- package/dist/src/core/config/types.d.ts +80 -0
- package/dist/src/core/config/types.d.ts.map +1 -1
- package/dist/src/core/config/types.js.map +1 -1
- package/dist/src/core/increment/increment-utils.d.ts +26 -1
- package/dist/src/core/increment/increment-utils.d.ts.map +1 -1
- package/dist/src/core/increment/increment-utils.js +66 -4
- package/dist/src/core/increment/increment-utils.js.map +1 -1
- package/dist/src/core/increment/status-change-sync-trigger.d.ts +3 -1
- package/dist/src/core/increment/status-change-sync-trigger.d.ts.map +1 -1
- package/dist/src/core/increment/status-change-sync-trigger.js +5 -2
- package/dist/src/core/increment/status-change-sync-trigger.js.map +1 -1
- package/dist/src/core/living-docs/cross-project-sync.d.ts +87 -15
- package/dist/src/core/living-docs/cross-project-sync.d.ts.map +1 -1
- package/dist/src/core/living-docs/cross-project-sync.js +147 -28
- package/dist/src/core/living-docs/cross-project-sync.js.map +1 -1
- package/dist/src/core/living-docs/intelligent-analyzer/architecture-generator.d.ts.map +1 -1
- package/dist/src/core/living-docs/intelligent-analyzer/architecture-generator.js +48 -12
- package/dist/src/core/living-docs/intelligent-analyzer/architecture-generator.js.map +1 -1
- package/dist/src/core/living-docs/intelligent-analyzer/cache-manager.d.ts +70 -0
- package/dist/src/core/living-docs/intelligent-analyzer/cache-manager.d.ts.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/cache-manager.js +188 -0
- package/dist/src/core/living-docs/intelligent-analyzer/cache-manager.js.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/dashboard-generator.d.ts +33 -0
- package/dist/src/core/living-docs/intelligent-analyzer/dashboard-generator.d.ts.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/dashboard-generator.js +290 -0
- package/dist/src/core/living-docs/intelligent-analyzer/dashboard-generator.js.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/deep-repo-analyzer.d.ts.map +1 -1
- package/dist/src/core/living-docs/intelligent-analyzer/deep-repo-analyzer.js +114 -11
- package/dist/src/core/living-docs/intelligent-analyzer/deep-repo-analyzer.js.map +1 -1
- package/dist/src/core/living-docs/intelligent-analyzer/graph-visualizer.d.ts +23 -0
- package/dist/src/core/living-docs/intelligent-analyzer/graph-visualizer.d.ts.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/graph-visualizer.js +283 -0
- package/dist/src/core/living-docs/intelligent-analyzer/graph-visualizer.js.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/mermaid-generator.d.ts +44 -0
- package/dist/src/core/living-docs/intelligent-analyzer/mermaid-generator.d.ts.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/mermaid-generator.js +61 -0
- package/dist/src/core/living-docs/intelligent-analyzer/mermaid-generator.js.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/orchestrator.d.ts +126 -0
- package/dist/src/core/living-docs/intelligent-analyzer/orchestrator.d.ts.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/orchestrator.js +378 -0
- package/dist/src/core/living-docs/intelligent-analyzer/orchestrator.js.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.d.ts.map +1 -1
- package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.js +57 -0
- package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.js.map +1 -1
- package/dist/src/core/living-docs/intelligent-analyzer/pattern-analyzer.d.ts +82 -0
- package/dist/src/core/living-docs/intelligent-analyzer/pattern-analyzer.d.ts.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/pattern-analyzer.js +430 -0
- package/dist/src/core/living-docs/intelligent-analyzer/pattern-analyzer.js.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/repo-scanner.d.ts +84 -0
- package/dist/src/core/living-docs/intelligent-analyzer/repo-scanner.d.ts.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/repo-scanner.js +387 -0
- package/dist/src/core/living-docs/intelligent-analyzer/repo-scanner.js.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/report-writer.d.ts +61 -0
- package/dist/src/core/living-docs/intelligent-analyzer/report-writer.d.ts.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/report-writer.js +174 -0
- package/dist/src/core/living-docs/intelligent-analyzer/report-writer.js.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/types.d.ts +1 -1
- package/dist/src/core/living-docs/intelligent-analyzer/types.d.ts.map +1 -1
- package/dist/src/core/living-docs/living-docs-sync.d.ts.map +1 -1
- package/dist/src/core/living-docs/living-docs-sync.js +26 -22
- package/dist/src/core/living-docs/living-docs-sync.js.map +1 -1
- package/dist/src/core/living-docs/module-analyzer.d.ts +3 -0
- package/dist/src/core/living-docs/module-analyzer.d.ts.map +1 -1
- package/dist/src/core/living-docs/module-analyzer.js +40 -1
- package/dist/src/core/living-docs/module-analyzer.js.map +1 -1
- package/dist/src/core/living-docs/types.d.ts +24 -3
- package/dist/src/core/living-docs/types.d.ts.map +1 -1
- package/dist/src/core/qa/qa-runner.js +1 -1
- package/dist/src/core/qa/qa-runner.js.map +1 -1
- package/dist/src/core/scheduler/session-sync-executor.js +1 -1
- package/dist/src/core/scheduler/session-sync-executor.js.map +1 -1
- package/dist/src/core/status-line/status-line-updater.d.ts +1 -1
- package/dist/src/core/status-line/status-line-updater.d.ts.map +1 -1
- package/dist/src/core/status-line/status-line-updater.js +4 -3
- package/dist/src/core/status-line/status-line-updater.js.map +1 -1
- package/dist/src/core/types/config.d.ts +79 -0
- package/dist/src/core/types/config.d.ts.map +1 -1
- package/dist/src/core/types/config.js.map +1 -1
- package/dist/src/importers/jira-importer.d.ts.map +1 -1
- package/dist/src/importers/jira-importer.js +18 -9
- package/dist/src/importers/jira-importer.js.map +1 -1
- package/dist/src/init/architecture/types.d.ts +140 -33
- package/dist/src/init/architecture/types.d.ts.map +1 -1
- package/dist/src/init/compliance/types.d.ts +27 -30
- package/dist/src/init/compliance/types.d.ts.map +1 -1
- package/dist/src/init/repo/types.d.ts +34 -11
- package/dist/src/init/repo/types.d.ts.map +1 -1
- package/dist/src/init/research/src/config/types.d.ts +82 -15
- package/dist/src/init/research/src/config/types.d.ts.map +1 -1
- package/dist/src/init/research/types.d.ts +93 -38
- package/dist/src/init/research/types.d.ts.map +1 -1
- package/dist/src/init/team/types.d.ts +42 -4
- package/dist/src/init/team/types.d.ts.map +1 -1
- package/dist/src/sync/ado-reconciler.js +1 -1
- package/dist/src/sync/ado-reconciler.js.map +1 -1
- package/dist/src/sync/github-reconciler.js +1 -1
- package/dist/src/sync/github-reconciler.js.map +1 -1
- package/dist/src/sync/jira-reconciler.js +1 -1
- package/dist/src/sync/jira-reconciler.js.map +1 -1
- package/dist/src/sync/sync-coordinator.d.ts +20 -0
- package/dist/src/sync/sync-coordinator.d.ts.map +1 -1
- package/dist/src/sync/sync-coordinator.js +258 -33
- package/dist/src/sync/sync-coordinator.js.map +1 -1
- package/dist/src/types/session.d.ts +65 -0
- package/dist/src/types/session.d.ts.map +1 -0
- package/dist/src/types/session.js +8 -0
- package/dist/src/types/session.js.map +1 -0
- package/dist/src/utils/lock-manager.d.ts +48 -0
- package/dist/src/utils/lock-manager.d.ts.map +1 -0
- package/dist/src/utils/lock-manager.js +195 -0
- package/dist/src/utils/lock-manager.js.map +1 -0
- package/dist/src/utils/notification-manager.d.ts +45 -0
- package/dist/src/utils/notification-manager.d.ts.map +1 -0
- package/dist/src/utils/notification-manager.js +130 -0
- package/dist/src/utils/notification-manager.js.map +1 -0
- package/dist/src/utils/platform-utils.d.ts +136 -0
- package/dist/src/utils/platform-utils.d.ts.map +1 -0
- package/dist/src/utils/platform-utils.js +366 -0
- package/dist/src/utils/platform-utils.js.map +1 -0
- package/dist/src/utils/project-resolver.d.ts +156 -0
- package/dist/src/utils/project-resolver.d.ts.map +1 -0
- package/dist/src/utils/project-resolver.js +587 -0
- package/dist/src/utils/project-resolver.js.map +1 -0
- package/dist/src/utils/session-registry.d.ts +142 -0
- package/dist/src/utils/session-registry.d.ts.map +1 -0
- package/dist/src/utils/session-registry.js +480 -0
- package/dist/src/utils/session-registry.js.map +1 -0
- package/package.json +5 -2
- package/plugins/specweave/commands/specweave-living-docs.md +42 -0
- package/plugins/specweave/hooks/hooks.json +20 -0
- package/plugins/specweave/hooks/lib/update-active-increment.sh +2 -2
- package/plugins/specweave/hooks/lib/update-status-line.sh +1 -1
- package/plugins/specweave/hooks/post-increment-status-change.sh +3 -3
- package/plugins/specweave/hooks/post-metadata-change.sh +1 -1
- package/plugins/specweave/hooks/universal/hook-wrapper.cmd +26 -26
- package/plugins/specweave/hooks/universal/session-start.cmd +16 -16
- package/plugins/specweave/hooks/universal/session-start.ps1 +16 -16
- package/plugins/specweave/hooks/user-prompt-submit.sh +107 -5
- package/plugins/specweave/hooks/v2/guards/increment-root-guard.sh +61 -0
- package/plugins/specweave/hooks/v2/guards/per-us-project-validator.sh +281 -0
- package/plugins/specweave/hooks/v2/handlers/living-specs-handler.sh +29 -0
- package/plugins/specweave/hooks/v2/session-end.sh +69 -0
- package/plugins/specweave/hooks/v2/session-start.sh +81 -0
- package/plugins/specweave/lib/vendor/sync/github-reconciler.js +1 -1
- package/plugins/specweave/lib/vendor/sync/github-reconciler.js.map +1 -1
- package/plugins/specweave/scripts/heartbeat.sh +110 -0
- package/plugins/specweave/scripts/progress.js +34 -4
- package/plugins/specweave/scripts/read-jobs.sh +1 -1
- package/plugins/specweave/scripts/read-progress.sh +50 -5
- package/plugins/specweave/scripts/read-workflow.sh +1 -1
- package/plugins/specweave/scripts/session-watchdog.sh +65 -0
- package/plugins/specweave/scripts/status.js +28 -11
- package/plugins/specweave-ado/lib/per-us-sync.js +247 -0
- package/plugins/specweave-ado/lib/per-us-sync.ts +410 -0
- package/plugins/specweave-github/hooks/.specweave/logs/hooks-debug.log +738 -0
- package/plugins/specweave-github/lib/github-client-v2.js +10 -3
- package/plugins/specweave-github/lib/github-client-v2.ts +15 -3
- package/plugins/specweave-github/lib/per-us-sync.js +241 -0
- package/plugins/specweave-github/lib/per-us-sync.ts +375 -0
- package/plugins/specweave-jira/lib/per-us-sync.js +224 -0
- package/plugins/specweave-jira/lib/per-us-sync.ts +366 -0
- package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +1107 -0
package/CLAUDE.md
CHANGED
|
@@ -114,6 +114,62 @@ const config = detectStructureLevel(projectRoot);
|
|
|
114
114
|
|
|
115
115
|
**Pre-tool-use hook `spec-project-validator.sh` BLOCKS spec.md without required fields (2-level).**
|
|
116
116
|
|
|
117
|
+
### 2c-bis. Each User Story MUST Have **Project**: (and **Board**: for 2-level) (v0.34.0+)
|
|
118
|
+
|
|
119
|
+
**CRITICAL 1:1 MAPPING RULE: Each User Story maps to EXACTLY ONE project and ONE board!**
|
|
120
|
+
|
|
121
|
+
```markdown
|
|
122
|
+
### US-001: Login Form UI
|
|
123
|
+
**Project**: frontend-app ← MANDATORY (exactly ONE project)
|
|
124
|
+
**Board**: ui-team ← MANDATORY for 2-level (exactly ONE board)
|
|
125
|
+
**As a** user, I want a login form...
|
|
126
|
+
|
|
127
|
+
### US-002: Auth API Endpoints
|
|
128
|
+
**Project**: backend-api ← DIFFERENT project = OK
|
|
129
|
+
**Board**: api-team ← DIFFERENT board = OK
|
|
130
|
+
**As a** developer, I want JWT auth API...
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**1:1 MAPPING ENFORCEMENT:**
|
|
134
|
+
```
|
|
135
|
+
❌ FORBIDDEN: **Project**: frontend-app, backend-api (MULTIPLE projects)
|
|
136
|
+
❌ FORBIDDEN: **Board**: ui-team, api-team (MULTIPLE boards)
|
|
137
|
+
❌ FORBIDDEN: User Story without **Project**: field
|
|
138
|
+
|
|
139
|
+
✅ REQUIRED: Each US has exactly ONE **Project**: value
|
|
140
|
+
✅ REQUIRED: Each US has exactly ONE **Board**: value (2-level)
|
|
141
|
+
✅ CROSS-PROJECT: Split into separate USs per project
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
**Cross-project features → Create SEPARATE User Stories:**
|
|
145
|
+
```markdown
|
|
146
|
+
## OAuth Feature (Cross-Project)
|
|
147
|
+
|
|
148
|
+
### US-001: OAuth Login Form
|
|
149
|
+
**Project**: frontend-app ← One project per US
|
|
150
|
+
...
|
|
151
|
+
|
|
152
|
+
### US-002: OAuth API Endpoints
|
|
153
|
+
**Project**: backend-api ← Different project = separate US
|
|
154
|
+
...
|
|
155
|
+
|
|
156
|
+
### US-003: OAuth Mobile Screen
|
|
157
|
+
**Project**: mobile-app ← Different project = separate US
|
|
158
|
+
...
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
**Pre-tool-use hook `per-us-project-validator.sh` BLOCKS spec.md with:**
|
|
162
|
+
- Missing `**Project**:` field per US
|
|
163
|
+
- Missing `**Board**:` field per US (2-level)
|
|
164
|
+
- Multiple comma-separated projects
|
|
165
|
+
- Multiple comma-separated boards
|
|
166
|
+
|
|
167
|
+
**Bypass (EMERGENCY ONLY):**
|
|
168
|
+
```bash
|
|
169
|
+
SPECWEAVE_FORCE_PROJECT=1 # Skip all validation
|
|
170
|
+
SPECWEAVE_LEGACY_SPEC=1 # Allow legacy specs without per-US fields
|
|
171
|
+
```
|
|
172
|
+
|
|
117
173
|
### 2d. NEVER Create Files in _features/ Folder (OBSOLETE v5.0.0+)
|
|
118
174
|
|
|
119
175
|
**The `_features/` folder is OBSOLETE!** Features MUST live in project folders:
|
|
@@ -132,7 +188,36 @@ const config = detectStructureLevel(projectRoot);
|
|
|
132
188
|
|
|
133
189
|
**Pre-tool-use hook `features-folder-guard.sh` BLOCKS writes to `_features/` (v0.33.0+).**
|
|
134
190
|
|
|
135
|
-
### 2e. NEVER Create
|
|
191
|
+
### 2e. NEVER Create Files at Increment Root (FOLDER STRUCTURE v0.33.0+)
|
|
192
|
+
|
|
193
|
+
**Files at increment root MUST be limited to required files!**
|
|
194
|
+
|
|
195
|
+
```
|
|
196
|
+
❌ FORBIDDEN (Bug pattern from 2025-12-09):
|
|
197
|
+
.specweave/increments/0134-feature/COMPLETION_REPORT.md
|
|
198
|
+
.specweave/increments/0135-feature/COMPLETION_SUMMARY.md
|
|
199
|
+
|
|
200
|
+
✅ CORRECT - Use reports/ subfolder:
|
|
201
|
+
.specweave/increments/0134-feature/reports/COMPLETION_REPORT.md
|
|
202
|
+
.specweave/increments/0135-feature/reports/COMPLETION_SUMMARY.md
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
**ONLY ALLOWED at increment root:**
|
|
206
|
+
- `metadata.json`
|
|
207
|
+
- `spec.md`
|
|
208
|
+
- `plan.md`
|
|
209
|
+
- `tasks.md`
|
|
210
|
+
|
|
211
|
+
**Everything else → subfolders:**
|
|
212
|
+
- `reports/` - completion reports, validation reports, analysis docs
|
|
213
|
+
- `scripts/` - helper scripts, automation
|
|
214
|
+
- `logs/` - execution logs, debug output
|
|
215
|
+
- `backups/` - backup files
|
|
216
|
+
- `docs/` - additional documentation
|
|
217
|
+
|
|
218
|
+
**Pre-tool-use hook `increment-root-guard.sh` BLOCKS non-standard files at root (v0.33.0+).**
|
|
219
|
+
|
|
220
|
+
### 2f. NEVER Create Duplicate Increment IDs (v0.33.0+)
|
|
136
221
|
|
|
137
222
|
**Increment numbers MUST be unique across ALL directories!**
|
|
138
223
|
|
|
@@ -171,6 +256,44 @@ IncrementNumberManager.findDuplicates('0121');
|
|
|
171
256
|
|
|
172
257
|
**Pre-tool-use hook `increment-duplicate-guard.sh` BLOCKS duplicate increment creation (v0.33.0+).**
|
|
173
258
|
|
|
259
|
+
### 2f. Gap-Filling Increment IDs (v0.33.1+)
|
|
260
|
+
|
|
261
|
+
**Increment IDs now FILL GAPS instead of always using highest + 1!**
|
|
262
|
+
|
|
263
|
+
```
|
|
264
|
+
OLD BEHAVIOR (v0.33.0 and earlier):
|
|
265
|
+
0128 (exists) → next is 0136 (highest + 1, even if gaps exist)
|
|
266
|
+
|
|
267
|
+
NEW BEHAVIOR (v0.33.1+):
|
|
268
|
+
0106, 0108, 0128, 0131 (exists) → next is 0107 (fills first gap!)
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
**Gap-filling algorithm:**
|
|
272
|
+
1. Scans ALL directories (main, _archive, _paused, _abandoned)
|
|
273
|
+
2. Finds first available number starting from 0001
|
|
274
|
+
3. Returns gap number if found, otherwise returns highest + 1
|
|
275
|
+
|
|
276
|
+
**Examples:**
|
|
277
|
+
```typescript
|
|
278
|
+
// Existing: [0001, 0002, 0004, 0005]
|
|
279
|
+
IncrementNumberManager.getNextIncrementNumber(); // "0003" ← Fills gap!
|
|
280
|
+
|
|
281
|
+
// Existing: [0001, 0002, 0003, 0004]
|
|
282
|
+
IncrementNumberManager.getNextIncrementNumber(); // "0005" ← Sequential (no gaps)
|
|
283
|
+
|
|
284
|
+
// Existing: [0050, 0051]
|
|
285
|
+
IncrementNumberManager.getNextIncrementNumber(); // "0001" ← Starts from beginning!
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
**Benefits:**
|
|
289
|
+
- ✅ No wasted ID space (4-digit limit = max 9999 increments)
|
|
290
|
+
- ✅ Clear sequence without confusing gaps
|
|
291
|
+
- ✅ Total increment count = highest number (no need to scan all)
|
|
292
|
+
|
|
293
|
+
**Migration:** Automatic, no action required. Next increment fills first gap!
|
|
294
|
+
|
|
295
|
+
**Details:** See ADR-0142 (`.specweave/docs/internal/architecture/adr/0142-gap-filling-increment-ids.md`)
|
|
296
|
+
|
|
174
297
|
### 3. Protected Directories
|
|
175
298
|
|
|
176
299
|
**NEVER delete**: `.specweave/docs/`, `.specweave/increments/`
|
|
@@ -555,6 +678,44 @@ bash plugins/specweave/scripts/cleanup-state.sh
|
|
|
555
678
|
- Update Claude Code VS Code extension regularly
|
|
556
679
|
- Use terminal mode for long-running sessions
|
|
557
680
|
|
|
681
|
+
### Zombie Processes (v0.33.0+ AUTO-CLEANUP)
|
|
682
|
+
|
|
683
|
+
**Status**: ✅ AUTOMATED - No manual intervention needed!
|
|
684
|
+
|
|
685
|
+
**How it works:**
|
|
686
|
+
- SessionStart hook registers all Claude Code sessions
|
|
687
|
+
- Heartbeat process monitors parent health every 5s
|
|
688
|
+
- Session watchdog cleans up zombies every 60s
|
|
689
|
+
- Automatic cleanup within 60s of session termination
|
|
690
|
+
|
|
691
|
+
**Session Registry**: `.specweave/state/.session-registry.json`
|
|
692
|
+
|
|
693
|
+
**Logs**:
|
|
694
|
+
```bash
|
|
695
|
+
# Session tracking logs
|
|
696
|
+
cat .specweave/logs/sessions/session-*.log
|
|
697
|
+
|
|
698
|
+
# Cleanup logs
|
|
699
|
+
cat .specweave/logs/cleanup.log
|
|
700
|
+
|
|
701
|
+
# Heartbeat logs
|
|
702
|
+
cat .specweave/logs/heartbeat-*.log
|
|
703
|
+
```
|
|
704
|
+
|
|
705
|
+
**Manual Cleanup (if needed)**:
|
|
706
|
+
```bash
|
|
707
|
+
# Kill all zombie processes
|
|
708
|
+
node dist/src/cli/cleanup-zombies.js 60
|
|
709
|
+
|
|
710
|
+
# Or use watchdog
|
|
711
|
+
bash plugins/specweave/scripts/session-watchdog.sh
|
|
712
|
+
```
|
|
713
|
+
|
|
714
|
+
**Troubleshooting**:
|
|
715
|
+
- If zombies persist >5 minutes: Check `.specweave/state/.session-registry.json`
|
|
716
|
+
- If cleanup fails: Run `bash plugins/specweave/scripts/cleanup-state.sh`
|
|
717
|
+
- For details: See `.specweave/docs/internal/troubleshooting/zombie-processes.md`
|
|
718
|
+
|
|
558
719
|
### Crash loop / prompt duplication
|
|
559
720
|
|
|
560
721
|
**Disable hooks FIRST:**
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-US Azure DevOps Sync (v0.34.0+)
|
|
3
|
+
*
|
|
4
|
+
* Syncs each User Story to its explicitly declared project's ADO project/area.
|
|
5
|
+
* Uses the **Project**: and **Board**: fields in spec.md (NOT keyword-based classification).
|
|
6
|
+
*
|
|
7
|
+
* Key difference from multi-project-sync:
|
|
8
|
+
* - Multi-project sync uses keyword/heuristic classification
|
|
9
|
+
* - Per-US sync uses EXPLICIT **Project**: and **Board**: fields from spec.md
|
|
10
|
+
*
|
|
11
|
+
* @module per-us-sync
|
|
12
|
+
* @since v0.34.0
|
|
13
|
+
*/
|
|
14
|
+
import type { UserStoryData } from '../../../src/core/living-docs/types.js';
|
|
15
|
+
import type { ProjectMappings } from '../../../src/core/types/config.js';
|
|
16
|
+
import type { USExternalRefsMap } from '../../../src/core/types/increment-metadata.js';
|
|
17
|
+
import { Logger } from '../../../src/utils/logger.js';
|
|
18
|
+
/**
|
|
19
|
+
* Result of syncing a single US to ADO
|
|
20
|
+
*/
|
|
21
|
+
export interface USSyncResult {
|
|
22
|
+
usId: string;
|
|
23
|
+
projectId: string;
|
|
24
|
+
adoProject: string;
|
|
25
|
+
areaPath: string;
|
|
26
|
+
workItemId: number;
|
|
27
|
+
url: string;
|
|
28
|
+
action: 'created' | 'updated' | 'skipped';
|
|
29
|
+
error?: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Result of syncing all USs in an increment
|
|
33
|
+
*/
|
|
34
|
+
export interface PerUSSyncResult {
|
|
35
|
+
success: boolean;
|
|
36
|
+
synced: USSyncResult[];
|
|
37
|
+
failed: USSyncResult[];
|
|
38
|
+
externalRefs: USExternalRefsMap;
|
|
39
|
+
summary: {
|
|
40
|
+
total: number;
|
|
41
|
+
created: number;
|
|
42
|
+
updated: number;
|
|
43
|
+
skipped: number;
|
|
44
|
+
failed: number;
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Options for per-US sync
|
|
49
|
+
*/
|
|
50
|
+
export interface PerUSSyncOptions {
|
|
51
|
+
dryRun?: boolean;
|
|
52
|
+
force?: boolean;
|
|
53
|
+
defaultProject?: string;
|
|
54
|
+
defaultBoard?: string;
|
|
55
|
+
logger?: Logger;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* ADO client interface (to be injected)
|
|
59
|
+
*/
|
|
60
|
+
export interface AdoClient {
|
|
61
|
+
createWorkItem(project: string, workItemType: string, title: string, description: string, areaPath?: string): Promise<{
|
|
62
|
+
id: number;
|
|
63
|
+
url: string;
|
|
64
|
+
}>;
|
|
65
|
+
updateWorkItem(project: string, workItemId: number, title: string, description: string, areaPath?: string): Promise<void>;
|
|
66
|
+
searchWorkItems(project: string, query: string): Promise<Array<{
|
|
67
|
+
id: number;
|
|
68
|
+
fields: {
|
|
69
|
+
'System.Title': string;
|
|
70
|
+
};
|
|
71
|
+
}>>;
|
|
72
|
+
getWorkItemUrl(project: string, workItemId: number): string;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Per-US ADO Sync
|
|
76
|
+
*
|
|
77
|
+
* Syncs each US to its declared project's ADO project/area path.
|
|
78
|
+
* For 2-level structures, uses **Board**: to determine area path.
|
|
79
|
+
*/
|
|
80
|
+
export declare class PerUSAdoSync {
|
|
81
|
+
private projectMappings;
|
|
82
|
+
private adoClient;
|
|
83
|
+
private logger;
|
|
84
|
+
constructor(adoClient: AdoClient, projectMappings: ProjectMappings, options?: {
|
|
85
|
+
logger?: Logger;
|
|
86
|
+
});
|
|
87
|
+
/**
|
|
88
|
+
* Sync all user stories to their respective ADO projects
|
|
89
|
+
*
|
|
90
|
+
* @param userStories - User stories with explicit project/board fields
|
|
91
|
+
* @param featureId - Feature ID (e.g., "FS-137")
|
|
92
|
+
* @param options - Sync options
|
|
93
|
+
*/
|
|
94
|
+
syncUserStories(userStories: UserStoryData[], featureId: string, options?: PerUSSyncOptions): Promise<PerUSSyncResult>;
|
|
95
|
+
/**
|
|
96
|
+
* Sync a single user story to ADO
|
|
97
|
+
*
|
|
98
|
+
* For 2-level structures:
|
|
99
|
+
* - **Project**: maps to ADO project
|
|
100
|
+
* - **Board**: maps to area path under the project
|
|
101
|
+
*/
|
|
102
|
+
private syncUserStory;
|
|
103
|
+
/**
|
|
104
|
+
* Find existing work item by US ID in title
|
|
105
|
+
*/
|
|
106
|
+
private findExistingWorkItem;
|
|
107
|
+
/**
|
|
108
|
+
* Build work item description from user story
|
|
109
|
+
*/
|
|
110
|
+
private buildWorkItemDescription;
|
|
111
|
+
/**
|
|
112
|
+
* Group user stories by their explicit project field
|
|
113
|
+
*/
|
|
114
|
+
private groupByProject;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Format per-US sync results for display
|
|
118
|
+
*/
|
|
119
|
+
export declare function formatPerUSSyncResults(result: PerUSSyncResult): string;
|
|
120
|
+
//# sourceMappingURL=per-us-sync.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"per-us-sync.d.ts","sourceRoot":"","sources":["../../../../plugins/specweave-ado/lib/per-us-sync.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-US Azure DevOps Sync (v0.34.0+)
|
|
3
|
+
*
|
|
4
|
+
* Syncs each User Story to its explicitly declared project's ADO project/area.
|
|
5
|
+
* Uses the **Project**: and **Board**: fields in spec.md (NOT keyword-based classification).
|
|
6
|
+
*
|
|
7
|
+
* Key difference from multi-project-sync:
|
|
8
|
+
* - Multi-project sync uses keyword/heuristic classification
|
|
9
|
+
* - Per-US sync uses EXPLICIT **Project**: and **Board**: fields from spec.md
|
|
10
|
+
*
|
|
11
|
+
* @module per-us-sync
|
|
12
|
+
* @since v0.34.0
|
|
13
|
+
*/
|
|
14
|
+
import { consoleLogger } from '../../../src/utils/logger.js';
|
|
15
|
+
/**
|
|
16
|
+
* Per-US ADO Sync
|
|
17
|
+
*
|
|
18
|
+
* Syncs each US to its declared project's ADO project/area path.
|
|
19
|
+
* For 2-level structures, uses **Board**: to determine area path.
|
|
20
|
+
*/
|
|
21
|
+
export class PerUSAdoSync {
|
|
22
|
+
constructor(adoClient, projectMappings, options = {}) {
|
|
23
|
+
this.adoClient = adoClient;
|
|
24
|
+
this.projectMappings = projectMappings;
|
|
25
|
+
this.logger = options.logger ?? consoleLogger;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Sync all user stories to their respective ADO projects
|
|
29
|
+
*
|
|
30
|
+
* @param userStories - User stories with explicit project/board fields
|
|
31
|
+
* @param featureId - Feature ID (e.g., "FS-137")
|
|
32
|
+
* @param options - Sync options
|
|
33
|
+
*/
|
|
34
|
+
async syncUserStories(userStories, featureId, options = {}) {
|
|
35
|
+
const synced = [];
|
|
36
|
+
const failed = [];
|
|
37
|
+
const externalRefs = {};
|
|
38
|
+
// Group USs by their declared project
|
|
39
|
+
const groups = this.groupByProject(userStories, options.defaultProject);
|
|
40
|
+
this.logger.log(`📡 Per-US ADO Sync: ${userStories.length} USs across ${groups.size} projects`);
|
|
41
|
+
for (const [projectId, stories] of groups) {
|
|
42
|
+
// Get ADO mapping for this project
|
|
43
|
+
const mapping = this.projectMappings[projectId]?.ado;
|
|
44
|
+
if (!mapping) {
|
|
45
|
+
// No ADO mapping for this project
|
|
46
|
+
this.logger.warn(` ⚠️ No ADO mapping for project "${projectId}" - skipping ${stories.length} USs`);
|
|
47
|
+
for (const story of stories) {
|
|
48
|
+
failed.push({
|
|
49
|
+
usId: story.id,
|
|
50
|
+
projectId,
|
|
51
|
+
adoProject: 'N/A',
|
|
52
|
+
areaPath: '',
|
|
53
|
+
workItemId: 0,
|
|
54
|
+
url: '',
|
|
55
|
+
action: 'skipped',
|
|
56
|
+
error: `No ADO mapping for project "${projectId}"`
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
// Sync each US to this project's ADO project
|
|
62
|
+
for (const story of stories) {
|
|
63
|
+
try {
|
|
64
|
+
const result = await this.syncUserStory(story, mapping, featureId, options);
|
|
65
|
+
synced.push({
|
|
66
|
+
...result,
|
|
67
|
+
projectId
|
|
68
|
+
});
|
|
69
|
+
// Build external ref
|
|
70
|
+
if (!options.dryRun && result.action !== 'skipped') {
|
|
71
|
+
externalRefs[story.id] = {
|
|
72
|
+
ado: {
|
|
73
|
+
provider: 'ado',
|
|
74
|
+
issueNumber: result.workItemId,
|
|
75
|
+
url: result.url,
|
|
76
|
+
targetProject: projectId,
|
|
77
|
+
lastSynced: new Date().toISOString()
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
failed.push({
|
|
84
|
+
usId: story.id,
|
|
85
|
+
projectId,
|
|
86
|
+
adoProject: mapping.project,
|
|
87
|
+
areaPath: mapping.areaPath || '',
|
|
88
|
+
workItemId: 0,
|
|
89
|
+
url: '',
|
|
90
|
+
action: 'skipped',
|
|
91
|
+
error: error instanceof Error ? error.message : String(error)
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// Calculate summary
|
|
97
|
+
const created = synced.filter(r => r.action === 'created').length;
|
|
98
|
+
const updated = synced.filter(r => r.action === 'updated').length;
|
|
99
|
+
const skipped = synced.filter(r => r.action === 'skipped').length;
|
|
100
|
+
return {
|
|
101
|
+
success: failed.length === 0,
|
|
102
|
+
synced,
|
|
103
|
+
failed,
|
|
104
|
+
externalRefs,
|
|
105
|
+
summary: {
|
|
106
|
+
total: userStories.length,
|
|
107
|
+
created,
|
|
108
|
+
updated,
|
|
109
|
+
skipped,
|
|
110
|
+
failed: failed.length
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Sync a single user story to ADO
|
|
116
|
+
*
|
|
117
|
+
* For 2-level structures:
|
|
118
|
+
* - **Project**: maps to ADO project
|
|
119
|
+
* - **Board**: maps to area path under the project
|
|
120
|
+
*/
|
|
121
|
+
async syncUserStory(story, mapping, featureId, options) {
|
|
122
|
+
const title = `[${featureId}][${story.id}] ${story.title}`;
|
|
123
|
+
const description = this.buildWorkItemDescription(story, featureId);
|
|
124
|
+
// Determine area path:
|
|
125
|
+
// - Use story.board if available (2-level structure)
|
|
126
|
+
// - Fall back to mapping.areaPath
|
|
127
|
+
// - Fall back to project root
|
|
128
|
+
let areaPath = mapping.areaPath || mapping.project;
|
|
129
|
+
if (story.board) {
|
|
130
|
+
// 2-level structure: append board as area path segment
|
|
131
|
+
areaPath = `${mapping.project}\\${story.board}`;
|
|
132
|
+
}
|
|
133
|
+
if (options.dryRun) {
|
|
134
|
+
this.logger.log(` 🔍 [DRY-RUN] Would sync ${story.id} to ${mapping.project} (area: ${areaPath})`);
|
|
135
|
+
return {
|
|
136
|
+
usId: story.id,
|
|
137
|
+
projectId: story.project || 'unknown',
|
|
138
|
+
adoProject: mapping.project,
|
|
139
|
+
areaPath,
|
|
140
|
+
workItemId: 0,
|
|
141
|
+
url: '',
|
|
142
|
+
action: 'skipped'
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
// Check for existing work item
|
|
146
|
+
const existingItem = await this.findExistingWorkItem(mapping.project, story.id);
|
|
147
|
+
if (existingItem) {
|
|
148
|
+
// Update existing work item
|
|
149
|
+
await this.adoClient.updateWorkItem(mapping.project, existingItem.id, title, description, areaPath);
|
|
150
|
+
this.logger.log(` 🔄 Updated ${story.id} → ${mapping.project}/${existingItem.id}`);
|
|
151
|
+
return {
|
|
152
|
+
usId: story.id,
|
|
153
|
+
projectId: story.project || 'unknown',
|
|
154
|
+
adoProject: mapping.project,
|
|
155
|
+
areaPath,
|
|
156
|
+
workItemId: existingItem.id,
|
|
157
|
+
url: this.adoClient.getWorkItemUrl(mapping.project, existingItem.id),
|
|
158
|
+
action: 'updated'
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
// Create new work item
|
|
163
|
+
const newItem = await this.adoClient.createWorkItem(mapping.project, 'User Story', title, description, areaPath);
|
|
164
|
+
this.logger.log(` ✅ Created ${story.id} → ${mapping.project}/${newItem.id}`);
|
|
165
|
+
return {
|
|
166
|
+
usId: story.id,
|
|
167
|
+
projectId: story.project || 'unknown',
|
|
168
|
+
adoProject: mapping.project,
|
|
169
|
+
areaPath,
|
|
170
|
+
workItemId: newItem.id,
|
|
171
|
+
url: newItem.url,
|
|
172
|
+
action: 'created'
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Find existing work item by US ID in title
|
|
178
|
+
*/
|
|
179
|
+
async findExistingWorkItem(project, usId) {
|
|
180
|
+
try {
|
|
181
|
+
const query = `[System.Title] Contains '[${usId}]'`;
|
|
182
|
+
const results = await this.adoClient.searchWorkItems(project, query);
|
|
183
|
+
return results.length > 0 ? { id: results[0].id } : null;
|
|
184
|
+
}
|
|
185
|
+
catch {
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Build work item description from user story
|
|
191
|
+
*/
|
|
192
|
+
buildWorkItemDescription(story, featureId) {
|
|
193
|
+
const lines = [];
|
|
194
|
+
lines.push(`<h1>${story.title}</h1>`);
|
|
195
|
+
lines.push('');
|
|
196
|
+
if (story.description) {
|
|
197
|
+
lines.push(`<p>${story.description}</p>`);
|
|
198
|
+
lines.push('');
|
|
199
|
+
}
|
|
200
|
+
if (story.acceptanceCriteria && story.acceptanceCriteria.length > 0) {
|
|
201
|
+
lines.push('<h2>Acceptance Criteria</h2>');
|
|
202
|
+
lines.push('<ul>');
|
|
203
|
+
for (const ac of story.acceptanceCriteria) {
|
|
204
|
+
lines.push(` <li>${ac}</li>`);
|
|
205
|
+
}
|
|
206
|
+
lines.push('</ul>');
|
|
207
|
+
lines.push('');
|
|
208
|
+
}
|
|
209
|
+
lines.push('<hr/>');
|
|
210
|
+
lines.push('');
|
|
211
|
+
lines.push(`<p><strong>Feature</strong>: ${featureId}</p>`);
|
|
212
|
+
lines.push(`<p><strong>User Story</strong>: ${story.id}</p>`);
|
|
213
|
+
if (story.project) {
|
|
214
|
+
lines.push(`<p><strong>Project</strong>: ${story.project}</p>`);
|
|
215
|
+
}
|
|
216
|
+
if (story.board) {
|
|
217
|
+
lines.push(`<p><strong>Board</strong>: ${story.board}</p>`);
|
|
218
|
+
}
|
|
219
|
+
lines.push('');
|
|
220
|
+
lines.push('<p><em>Auto-generated by SpecWeave</em></p>');
|
|
221
|
+
return lines.join('\n');
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Group user stories by their explicit project field
|
|
225
|
+
*/
|
|
226
|
+
groupByProject(userStories, defaultProject) {
|
|
227
|
+
const groups = new Map();
|
|
228
|
+
for (const story of userStories) {
|
|
229
|
+
const project = story.project || defaultProject || 'default';
|
|
230
|
+
if (!groups.has(project)) {
|
|
231
|
+
groups.set(project, []);
|
|
232
|
+
}
|
|
233
|
+
groups.get(project).push(story);
|
|
234
|
+
}
|
|
235
|
+
return groups;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Format per-US sync results for display
|
|
240
|
+
*/
|
|
241
|
+
export function formatPerUSSyncResults(result) {
|
|
242
|
+
const lines = [];
|
|
243
|
+
lines.push('');
|
|
244
|
+
lines.push('📊 Per-US ADO Sync Results');
|
|
245
|
+
lines.push('');
|
|
246
|
+
// Group by project
|
|
247
|
+
const byProject = new Map();
|
|
248
|
+
for (const r of [...result.synced, ...result.failed]) {
|
|
249
|
+
const existing = byProject.get(r.projectId) || [];
|
|
250
|
+
existing.push(r);
|
|
251
|
+
byProject.set(r.projectId, existing);
|
|
252
|
+
}
|
|
253
|
+
for (const [projectId, results] of byProject) {
|
|
254
|
+
const adoProject = results[0]?.adoProject || 'N/A';
|
|
255
|
+
const areaPath = results[0]?.areaPath || '';
|
|
256
|
+
lines.push(`**${projectId}** (→ ${adoProject}${areaPath ? ` [${areaPath}]` : ''}):`);
|
|
257
|
+
for (const r of results) {
|
|
258
|
+
const icon = r.action === 'created' ? '✅' :
|
|
259
|
+
r.action === 'updated' ? '🔄' :
|
|
260
|
+
r.error ? '❌' : '⏭️';
|
|
261
|
+
if (r.workItemId > 0) {
|
|
262
|
+
lines.push(` ${icon} ${r.usId} → ${r.adoProject}/${r.workItemId}`);
|
|
263
|
+
}
|
|
264
|
+
else if (r.error) {
|
|
265
|
+
lines.push(` ${icon} ${r.usId}: ${r.error}`);
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
lines.push(` ${icon} ${r.usId} (${r.action})`);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
lines.push('');
|
|
272
|
+
}
|
|
273
|
+
lines.push(`📈 Summary: ${result.summary.created} created, ${result.summary.updated} updated, ${result.summary.failed} failed`);
|
|
274
|
+
return lines.join('\n');
|
|
275
|
+
}
|
|
276
|
+
//# sourceMappingURL=per-us-sync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"per-us-sync.js","sourceRoot":"","sources":["../../../../plugins/specweave-ado/lib/per-us-sync.ts"],"names":[],"mappings":"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"}
|
|
@@ -101,8 +101,11 @@ export declare class GitHubClientV2 {
|
|
|
101
101
|
* Search for issue by exact title match
|
|
102
102
|
*
|
|
103
103
|
* IDEMPOTENCY: Use this before creating issues to prevent duplicates
|
|
104
|
+
*
|
|
105
|
+
* @param title - Title pattern to search for (e.g., "[FS-136][US-001]")
|
|
106
|
+
* @param includeClosedIssues - If true, searches all issues (open+closed). Default: false (open only)
|
|
104
107
|
*/
|
|
105
|
-
searchIssueByTitle(title: string): Promise<GitHubIssue | null>;
|
|
108
|
+
searchIssueByTitle(title: string, includeClosedIssues?: boolean): Promise<GitHubIssue | null>;
|
|
106
109
|
/**
|
|
107
110
|
* Update issue body
|
|
108
111
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"github-client-v2.d.ts","sourceRoot":"","sources":["../../../../plugins/specweave-github/lib/github-client-v2.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,WAAW,EAAgB,eAAe,EAAE,MAAM,sCAAsC,CAAC;AAElG,qBAAa,cAAc;IACzB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,QAAQ,CAAS;IAEzB;;OAEG;gBACS,OAAO,EAAE,WAAW;IAWhC;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,cAAc;IAU5D;;OAEG;IACH,QAAQ,IAAI,MAAM;IAIlB;;OAEG;IACH,OAAO,IAAI,MAAM;IAQjB;;OAEG;WACU,QAAQ,IAAI,OAAO,CAAC;QAC/B,SAAS,EAAE,OAAO,CAAC;QACnB,aAAa,EAAE,OAAO,CAAC;QACvB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IAwBF;;OAEG;WACU,UAAU,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAC,GAAG,IAAI,CAAC;IA4BpF;;OAEG;IACG,oBAAoB,CACxB,KAAK,EAAE,MAAM,EACb,WAAW,CAAC,EAAE,MAAM,EACpB,WAAW,GAAE,MAAU,GACtB,OAAO,CAAC,eAAe,CAAC;IAqC3B;;OAEG;YACW,mBAAmB;IAqBjC;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,kBAAkB;IAqC1B;;;;;;;;;;OAUG;IACG,oBAAoB,CAAC,MAAM,EAAE;QACjC,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAC3B,GAAG,OAAO,CAAC,WAAW,CAAC;IAgBxB;;OAEG;IACG,eAAe,CACnB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,EAC3B,MAAM,GAAE,MAAM,EAAO,GACpB,OAAO,CAAC,WAAW,CAAC;IA4DvB;;OAEG;IACG,eAAe,CACnB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,EAC3B,MAAM,GAAE,MAAM,EAAO,GACpB,OAAO,CAAC,WAAW,CAAC;IAOvB;;OAEG;IACG,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAyBzD
|
|
1
|
+
{"version":3,"file":"github-client-v2.d.ts","sourceRoot":"","sources":["../../../../plugins/specweave-github/lib/github-client-v2.ts"],"names":[],"mappings":"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"}
|
|
@@ -299,11 +299,14 @@ export class GitHubClientV2 {
|
|
|
299
299
|
* Search for issue by exact title match
|
|
300
300
|
*
|
|
301
301
|
* IDEMPOTENCY: Use this before creating issues to prevent duplicates
|
|
302
|
+
*
|
|
303
|
+
* @param title - Title pattern to search for (e.g., "[FS-136][US-001]")
|
|
304
|
+
* @param includeClosedIssues - If true, searches all issues (open+closed). Default: false (open only)
|
|
302
305
|
*/
|
|
303
|
-
async searchIssueByTitle(title) {
|
|
306
|
+
async searchIssueByTitle(title, includeClosedIssues = false) {
|
|
304
307
|
// Escape double quotes in title for gh search
|
|
305
308
|
const escapedTitle = title.replace(/"/g, '\\"');
|
|
306
|
-
const
|
|
309
|
+
const args = [
|
|
307
310
|
'issue',
|
|
308
311
|
'list',
|
|
309
312
|
'--repo',
|
|
@@ -314,7 +317,14 @@ export class GitHubClientV2 {
|
|
|
314
317
|
'number,title,state,url,labels',
|
|
315
318
|
'--limit',
|
|
316
319
|
'50', // ✅ FIX: Increased from 1 to 50 to catch duplicates (Issue #0047)
|
|
317
|
-
]
|
|
320
|
+
];
|
|
321
|
+
// v0.34.0: Add --state all to search closed issues too (for closure flow)
|
|
322
|
+
// Without this, closeGitHubIssuesForUserStories() can't find already-closed issues
|
|
323
|
+
// and reports "No GitHub issue found" instead of "already closed"
|
|
324
|
+
if (includeClosedIssues) {
|
|
325
|
+
args.push('--state', 'all');
|
|
326
|
+
}
|
|
327
|
+
const result = await execFileNoThrow('gh', args);
|
|
318
328
|
if (result.exitCode !== 0) {
|
|
319
329
|
// Search failed, return null (treat as not found)
|
|
320
330
|
return null;
|