specweave 0.22.2 → 0.22.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 -13
- package/dist/src/cli/commands/repair-status-desync.d.ts +69 -0
- package/dist/src/cli/commands/repair-status-desync.d.ts.map +1 -0
- package/dist/src/cli/commands/repair-status-desync.js +221 -0
- package/dist/src/cli/commands/repair-status-desync.js.map +1 -0
- package/dist/src/cli/commands/validate-status-sync.d.ts +52 -0
- package/dist/src/cli/commands/validate-status-sync.d.ts.map +1 -0
- package/dist/src/cli/commands/validate-status-sync.js +176 -0
- package/dist/src/cli/commands/validate-status-sync.js.map +1 -0
- package/dist/src/cli/update-status-line.d.ts +16 -0
- package/dist/src/cli/update-status-line.d.ts.map +1 -0
- package/dist/src/cli/update-status-line.js +44 -0
- package/dist/src/cli/update-status-line.js.map +1 -0
- package/dist/src/core/increment/completion-validator.d.ts +56 -0
- package/dist/src/core/increment/completion-validator.d.ts.map +1 -0
- package/dist/src/core/increment/completion-validator.js +102 -0
- package/dist/src/core/increment/completion-validator.js.map +1 -0
- package/dist/src/core/increment/metadata-manager.d.ts.map +1 -1
- package/dist/src/core/increment/metadata-manager.js +10 -0
- package/dist/src/core/increment/metadata-manager.js.map +1 -1
- package/dist/src/core/increment/spec-frontmatter-updater.d.ts +78 -0
- package/dist/src/core/increment/spec-frontmatter-updater.d.ts.map +1 -0
- package/dist/src/core/increment/spec-frontmatter-updater.js +152 -0
- package/dist/src/core/increment/spec-frontmatter-updater.js.map +1 -0
- package/dist/src/core/living-docs/living-docs-sync.d.ts.map +1 -1
- package/dist/src/core/living-docs/living-docs-sync.js +2 -1
- package/dist/src/core/living-docs/living-docs-sync.js.map +1 -1
- package/dist/src/core/status-line/status-line-manager.d.ts +3 -2
- package/dist/src/core/status-line/status-line-manager.d.ts.map +1 -1
- package/dist/src/core/status-line/status-line-manager.js +40 -17
- package/dist/src/core/status-line/status-line-manager.js.map +1 -1
- package/dist/src/core/status-line/status-line-updater.d.ts +67 -0
- package/dist/src/core/status-line/status-line-updater.d.ts.map +1 -0
- package/dist/src/core/status-line/status-line-updater.js +203 -0
- package/dist/src/core/status-line/status-line-updater.js.map +1 -0
- package/dist/src/core/status-line/types.d.ts +19 -5
- package/dist/src/core/status-line/types.d.ts.map +1 -1
- package/dist/src/core/status-line/types.js +3 -3
- package/dist/src/core/status-line/types.js.map +1 -1
- package/package.json +1 -1
- package/plugins/specweave/commands/specweave-done.md +60 -4
- package/plugins/specweave/commands/specweave-reopen.md +29 -2
- package/plugins/specweave/commands/specweave-sync-docs.md +71 -4
- package/plugins/specweave/commands/specweave-update-status.md +151 -0
- package/plugins/specweave/hooks/lib/update-status-line.sh +34 -6
- package/plugins/specweave/hooks/user-prompt-submit.sh +21 -0
- package/plugins/specweave/hooks/validate-increment-completion.sh +113 -0
- package/plugins/specweave-ado/lib/ado-multi-project-sync.js +0 -1
- package/plugins/specweave-github/commands/specweave-github-cleanup-duplicates.md +21 -0
- package/plugins/specweave-jira/lib/enhanced-jira-sync.js +3 -3
- package/plugins/specweave-ado/lib/enhanced-ado-sync.js +0 -170
- package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +0 -3222
package/CLAUDE.md
CHANGED
|
@@ -10,6 +10,66 @@ Users receive a different CLAUDE.md via the template system.
|
|
|
10
10
|
|
|
11
11
|
---
|
|
12
12
|
|
|
13
|
+
## 🔍 CRITICAL FINDING: Claude Code Marketplace Directory vs Symlink Issue
|
|
14
|
+
|
|
15
|
+
**⚠️ RECENTLY DISCOVERED (2025-11-18) - AFFECTS ALL SPECWEAVE CONTRIBUTORS ⚠️**
|
|
16
|
+
|
|
17
|
+
### The Issue
|
|
18
|
+
|
|
19
|
+
Claude Code's hook execution system expects plugins at `~/.claude/plugins/marketplaces/specweave/`, but this path can be **either a directory OR a symlink**. The difference is critical:
|
|
20
|
+
|
|
21
|
+
| Type | Symbol | Behavior | Development Impact |
|
|
22
|
+
|------|--------|----------|-------------------|
|
|
23
|
+
| **Directory** | `drwxr-xr-x` | Stale copy from marketplace update | ❌ Hooks fail with "No such file or directory" |
|
|
24
|
+
| **Symlink** | `lrwxr-xr-x` | Live reference to repository | ✅ Hooks work, changes immediately reflected |
|
|
25
|
+
|
|
26
|
+
### Why This Matters
|
|
27
|
+
|
|
28
|
+
**Hooks ONLY work reliably with a symlink setup.** If the marketplace path is a directory:
|
|
29
|
+
- ❌ Post-task-completion hooks fail randomly
|
|
30
|
+
- ❌ Status line doesn't update
|
|
31
|
+
- ❌ Living docs don't sync
|
|
32
|
+
- ❌ You waste hours debugging "No such file or directory" errors
|
|
33
|
+
- ❌ Changes to hooks in your repo are NOT reflected until marketplace update
|
|
34
|
+
|
|
35
|
+
### How the Problem Occurs
|
|
36
|
+
|
|
37
|
+
1. **Initial setup**: You create a symlink (correct)
|
|
38
|
+
2. **Marketplace update**: Running `claude plugin marketplace update specweave` MAY replace the symlink with a directory copy
|
|
39
|
+
3. **Silent failure**: Hooks start failing but no clear error message points to symlink issue
|
|
40
|
+
|
|
41
|
+
### The Fix
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# ALWAYS verify your setup is a symlink:
|
|
45
|
+
ls -ld ~/.claude/plugins/marketplaces/specweave
|
|
46
|
+
# Should show: lrwxr-xr-x ... -> /path/to/your/repo (SYMLINK)
|
|
47
|
+
# NOT: drwxr-xr-x ... (DIRECTORY)
|
|
48
|
+
|
|
49
|
+
# If it's a directory, fix it:
|
|
50
|
+
rm -rf ~/.claude/plugins/marketplaces/specweave
|
|
51
|
+
ln -s "$(pwd)" ~/.claude/plugins/marketplaces/specweave
|
|
52
|
+
|
|
53
|
+
# Verify the fix:
|
|
54
|
+
bash .specweave/increments/0043-spec-md-desync-fix/scripts/verify-dev-setup.sh
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Protection Measures
|
|
58
|
+
|
|
59
|
+
1. ✅ **Pre-commit hook** verifies symlink before each commit (warns if broken)
|
|
60
|
+
2. ✅ **Verification script** checks all aspects of setup (see "Local Development Setup" below)
|
|
61
|
+
3. ✅ **This warning** ensures new contributors know about this issue
|
|
62
|
+
|
|
63
|
+
### Deep Dive
|
|
64
|
+
|
|
65
|
+
For complete root cause analysis, investigation process, and prevention strategies:
|
|
66
|
+
- **Ultrathink Report**: `.specweave/increments/0043-spec-md-desync-fix/reports/ULTRATHINK-HOOK-EXECUTION-ERRORS-ROOT-CAUSE-ANALYSIS-2025-11-18.md`
|
|
67
|
+
- **Fixes Applied**: `.specweave/increments/0043-spec-md-desync-fix/reports/HOOK-EXECUTION-ERRORS-FIXES-APPLIED-2025-11-18.md`
|
|
68
|
+
|
|
69
|
+
**Golden Rule**: If hooks fail with "No such file or directory", check the symlink FIRST!
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
13
73
|
## 🚨 CRITICAL: NEVER POLLUTE PROJECT ROOT!
|
|
14
74
|
|
|
15
75
|
**⛔ THIS IS THE #1 RULE - VIOLATING THIS WILL GET YOUR PR REJECTED ⛔**
|
|
@@ -283,9 +343,51 @@ For adapter implementation details, see "Multi-Tool Support via Adapters" sectio
|
|
|
283
343
|
/specweave:increment "feature name" # Plan new work (increment-planner skill)
|
|
284
344
|
/specweave:do # Execute tasks
|
|
285
345
|
/specweave:progress # Check status
|
|
286
|
-
/specweave:done # Close increment
|
|
346
|
+
/specweave:done # Close increment (with validation)
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
**🔥 CRITICAL: Increment Completion Validation**
|
|
350
|
+
|
|
351
|
+
**NEVER** mark an increment as "completed" without ALL of the following:
|
|
352
|
+
1. ✅ All acceptance criteria checked (`- [x] **AC-...`)
|
|
353
|
+
2. ✅ All tasks completed (`**Status**: [x] completed`)
|
|
354
|
+
3. ✅ All tests passing (unit, integration, E2E)
|
|
355
|
+
4. ✅ Coverage target met (`npm run test:coverage`)
|
|
356
|
+
|
|
357
|
+
**Automated Protection**:
|
|
358
|
+
- `/specweave:done` runs `IncrementCompletionValidator` before PM validation
|
|
359
|
+
- Pre-commit hook blocks commits with invalid completion status
|
|
360
|
+
- CI/CD validates completion on pull requests
|
|
361
|
+
|
|
362
|
+
**Manual Protection** (if editing metadata.json directly):
|
|
363
|
+
```bash
|
|
364
|
+
# ❌ NEVER DO THIS - Manual metadata edit without validation
|
|
365
|
+
vim .specweave/increments/0043-spec-md-desync-fix/metadata.json
|
|
366
|
+
# Change "status": "active" → "completed"
|
|
367
|
+
git commit -m "Complete increment" # Will be BLOCKED by pre-commit hook
|
|
368
|
+
|
|
369
|
+
# ✅ ALWAYS USE THIS - Let /specweave:done validate
|
|
370
|
+
/specweave:done 0043 # Validates ACs, tasks, tests, docs before closing
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
**What Happens if Validation Fails**:
|
|
374
|
+
```bash
|
|
375
|
+
/specweave:done 0043
|
|
376
|
+
|
|
377
|
+
❌ CANNOT CLOSE INCREMENT - Automated validation failed
|
|
378
|
+
|
|
379
|
+
• 17 acceptance criteria still open
|
|
380
|
+
• 13 tasks still pending
|
|
381
|
+
|
|
382
|
+
Fix these issues before running /specweave:done again
|
|
287
383
|
```
|
|
288
384
|
|
|
385
|
+
**Why This Matters**:
|
|
386
|
+
- **False completion** → Status line shows wrong increment
|
|
387
|
+
- **GitHub sync broken** → Issues marked closed with open work
|
|
388
|
+
- **Data integrity violation** → Source of truth is inconsistent
|
|
389
|
+
- **Stakeholder confusion** → External tools show wrong status
|
|
390
|
+
|
|
289
391
|
**State Management**:
|
|
290
392
|
```bash
|
|
291
393
|
/specweave:pause 0002 --reason="..." # Pause increment
|
|
@@ -380,7 +482,51 @@ When developing SpecWeave itself, you MUST use a **symlink** from the marketplac
|
|
|
380
482
|
- ✅ No need to reinstall plugins after every change
|
|
381
483
|
- ✅ Real-time testing of hooks, skills, and commands
|
|
382
484
|
|
|
383
|
-
|
|
485
|
+
**⚡ QUICK SETUP (MANDATORY - Do this FIRST!):**
|
|
486
|
+
|
|
487
|
+
```bash
|
|
488
|
+
# 1. Clone and install dependencies
|
|
489
|
+
git clone https://github.com/YOUR_USERNAME/specweave.git
|
|
490
|
+
cd specweave
|
|
491
|
+
npm install
|
|
492
|
+
|
|
493
|
+
# 2. Create marketplace symlink (CRITICAL!)
|
|
494
|
+
# ⚠️ IMPORTANT: Use absolute path, NOT $PWD (see ultrathink report for details)
|
|
495
|
+
mkdir -p ~/.claude/plugins/marketplaces
|
|
496
|
+
rm -rf ~/.claude/plugins/marketplaces/specweave # Remove any existing directory/symlink
|
|
497
|
+
ln -s "$(pwd)" ~/.claude/plugins/marketplaces/specweave
|
|
498
|
+
|
|
499
|
+
# 3. Verify setup (MANDATORY!)
|
|
500
|
+
bash .specweave/increments/0043-spec-md-desync-fix/scripts/verify-dev-setup.sh
|
|
501
|
+
# Must show: ✅ ALL CHECKS PASSED!
|
|
502
|
+
# If verification fails, see ultrathink report:
|
|
503
|
+
# .specweave/increments/0043-spec-md-desync-fix/reports/ULTRATHINK-HOOK-EXECUTION-ERRORS-ROOT-CAUSE-ANALYSIS-2025-11-18.md
|
|
504
|
+
|
|
505
|
+
# 4. Install git hooks (for pre-commit verification)
|
|
506
|
+
bash scripts/install-git-hooks.sh
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
**Why Symlink is MANDATORY:**
|
|
510
|
+
|
|
511
|
+
Claude Code's hook execution system looks for hooks in `~/.claude/plugins/marketplaces/specweave/`, NOT in your local repo.
|
|
512
|
+
|
|
513
|
+
**⚠️ CRITICAL: Directory vs Symlink Issue**
|
|
514
|
+
|
|
515
|
+
The marketplace path MUST be a **symlink**, NOT a **directory**:
|
|
516
|
+
- ✅ **Symlink** (`lrwxr-xr-x`): All hook changes immediately reflected
|
|
517
|
+
- ❌ **Directory** (`drwxr-xr-x`): Stale copy, hooks fail with "No such file or directory"
|
|
518
|
+
|
|
519
|
+
**Without the symlink:**
|
|
520
|
+
- ❌ All post-task-completion hooks fail with "No such file or directory"
|
|
521
|
+
- ❌ Status line doesn't update automatically
|
|
522
|
+
- ❌ Living docs don't sync after task completion
|
|
523
|
+
- ❌ Increment metadata doesn't update
|
|
524
|
+
- ❌ You'll waste hours debugging hook errors
|
|
525
|
+
|
|
526
|
+
**Root Cause Analysis**: See comprehensive ultrathink report at:
|
|
527
|
+
`.specweave/increments/0043-spec-md-desync-fix/reports/ULTRATHINK-HOOK-EXECUTION-ERRORS-ROOT-CAUSE-ANALYSIS-2025-11-18.md`
|
|
528
|
+
|
|
529
|
+
**Detailed Setup (if Quick Setup fails):**
|
|
384
530
|
|
|
385
531
|
```bash
|
|
386
532
|
# 1. Remove any existing marketplace installation
|
|
@@ -392,20 +538,23 @@ ln -s /path/to/your/specweave/repo ~/.claude/plugins/marketplaces/specweave
|
|
|
392
538
|
# Example:
|
|
393
539
|
ln -s ~/Projects/github/specweave ~/.claude/plugins/marketplaces/specweave
|
|
394
540
|
|
|
395
|
-
# 3.
|
|
396
|
-
|
|
397
|
-
|
|
541
|
+
# 3. Verify symlink is correct
|
|
542
|
+
readlink ~/.claude/plugins/marketplaces/specweave
|
|
543
|
+
# Should output: /path/to/your/specweave/repo
|
|
544
|
+
|
|
545
|
+
# 4. Verify hooks are accessible
|
|
546
|
+
test -f ~/.claude/plugins/marketplaces/specweave/plugins/specweave/hooks/post-task-completion.sh && \
|
|
547
|
+
echo "✅ Hooks accessible" || echo "❌ Setup failed"
|
|
398
548
|
|
|
399
|
-
#
|
|
400
|
-
|
|
401
|
-
|
|
549
|
+
# 5. Run automated verification
|
|
550
|
+
bash .specweave/increments/0043-spec-md-desync-fix/scripts/verify-dev-setup.sh
|
|
551
|
+
```
|
|
402
552
|
|
|
403
|
-
|
|
404
|
-
claude plugin marketplace update specweave
|
|
553
|
+
**Verification Output:**
|
|
405
554
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
555
|
+
```
|
|
556
|
+
✅ ALL CHECKS PASSED! Local development setup is correct.
|
|
557
|
+
You can now use TodoWrite and other tools without hook errors.
|
|
409
558
|
```
|
|
410
559
|
|
|
411
560
|
**If you see "Plugin not found" errors:**
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { DesyncResult } from './validate-status-sync.js';
|
|
3
|
+
/**
|
|
4
|
+
* Repair options
|
|
5
|
+
*/
|
|
6
|
+
export interface RepairOptions {
|
|
7
|
+
dryRun?: boolean;
|
|
8
|
+
createBackup?: boolean;
|
|
9
|
+
all?: boolean;
|
|
10
|
+
incrementId?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Repair result for a single increment
|
|
14
|
+
*/
|
|
15
|
+
export interface RepairResult {
|
|
16
|
+
incrementId: string;
|
|
17
|
+
oldStatus: string;
|
|
18
|
+
newStatus: string;
|
|
19
|
+
success: boolean;
|
|
20
|
+
error?: string;
|
|
21
|
+
backupPath?: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Audit log entry
|
|
25
|
+
*/
|
|
26
|
+
export interface AuditEntry {
|
|
27
|
+
timestamp: string;
|
|
28
|
+
incrementId: string;
|
|
29
|
+
oldStatus: string;
|
|
30
|
+
newStatus: string;
|
|
31
|
+
success: boolean;
|
|
32
|
+
error?: string;
|
|
33
|
+
backupPath?: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Create backup of spec.md before repair
|
|
37
|
+
*/
|
|
38
|
+
export declare function createBackup(incrementId: string): Promise<string>;
|
|
39
|
+
/**
|
|
40
|
+
* Repair a single desync
|
|
41
|
+
*/
|
|
42
|
+
export declare function repairDesync(desync: DesyncResult, options?: RepairOptions): Promise<RepairResult>;
|
|
43
|
+
/**
|
|
44
|
+
* Repair all desyncs or a specific increment
|
|
45
|
+
*/
|
|
46
|
+
export declare function repairStatusDesync(options?: RepairOptions): Promise<{
|
|
47
|
+
total: number;
|
|
48
|
+
repaired: number;
|
|
49
|
+
failed: number;
|
|
50
|
+
results: RepairResult[];
|
|
51
|
+
}>;
|
|
52
|
+
/**
|
|
53
|
+
* Write audit log
|
|
54
|
+
*/
|
|
55
|
+
export declare function writeAuditLog(results: RepairResult[]): Promise<string>;
|
|
56
|
+
/**
|
|
57
|
+
* Format repair report
|
|
58
|
+
*/
|
|
59
|
+
export declare function formatRepairReport(result: {
|
|
60
|
+
total: number;
|
|
61
|
+
repaired: number;
|
|
62
|
+
failed: number;
|
|
63
|
+
results: RepairResult[];
|
|
64
|
+
}, dryRun?: boolean): string;
|
|
65
|
+
/**
|
|
66
|
+
* Main CLI entry point
|
|
67
|
+
*/
|
|
68
|
+
export declare function main(argv?: string[]): Promise<void>;
|
|
69
|
+
//# sourceMappingURL=repair-status-desync.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repair-status-desync.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/repair-status-desync.ts"],"names":[],"mappings":";AAEA,OAAO,EAAsB,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAM7E;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQvE;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,YAAY,EACpB,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,YAAY,CAAC,CAuCvB;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC;IAC7E,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,YAAY,EAAE,CAAC;CACzB,CAAC,CAsCD;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAoB5E;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,YAAY,EAAE,CAAC;CACzB,EAAE,MAAM,GAAE,OAAe,GAAG,MAAM,CAsElC;AAED;;GAEG;AACH,wBAAsB,IAAI,CAAC,IAAI,GAAE,MAAM,EAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CA0CvE"}
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { validateStatusSync } from './validate-status-sync.js';
|
|
3
|
+
import { SpecFrontmatterUpdater } from '../../core/increment/spec-frontmatter-updater.js';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import fs from 'fs-extra';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
/**
|
|
8
|
+
* Create backup of spec.md before repair
|
|
9
|
+
*/
|
|
10
|
+
export async function createBackup(incrementId) {
|
|
11
|
+
const specPath = path.join(process.cwd(), '.specweave', 'increments', incrementId, 'spec.md');
|
|
12
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
13
|
+
const backupPath = `${specPath}.backup-${timestamp}`;
|
|
14
|
+
await fs.copyFile(specPath, backupPath);
|
|
15
|
+
return backupPath;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Repair a single desync
|
|
19
|
+
*/
|
|
20
|
+
export async function repairDesync(desync, options = {}) {
|
|
21
|
+
const { dryRun = false, createBackup: shouldBackup = true } = options;
|
|
22
|
+
// Dry-run: preview only
|
|
23
|
+
if (dryRun) {
|
|
24
|
+
return {
|
|
25
|
+
incrementId: desync.incrementId,
|
|
26
|
+
oldStatus: desync.specStatus,
|
|
27
|
+
newStatus: desync.metadataStatus,
|
|
28
|
+
success: true,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
// Create backup if enabled
|
|
33
|
+
let backupPath;
|
|
34
|
+
if (shouldBackup) {
|
|
35
|
+
backupPath = await createBackup(desync.incrementId);
|
|
36
|
+
}
|
|
37
|
+
// Update spec.md to match metadata.json
|
|
38
|
+
await SpecFrontmatterUpdater.updateStatus(desync.incrementId, desync.metadataStatus);
|
|
39
|
+
return {
|
|
40
|
+
incrementId: desync.incrementId,
|
|
41
|
+
oldStatus: desync.specStatus,
|
|
42
|
+
newStatus: desync.metadataStatus,
|
|
43
|
+
success: true,
|
|
44
|
+
backupPath,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
return {
|
|
49
|
+
incrementId: desync.incrementId,
|
|
50
|
+
oldStatus: desync.specStatus,
|
|
51
|
+
newStatus: desync.metadataStatus,
|
|
52
|
+
success: false,
|
|
53
|
+
error: error instanceof Error ? error.message : String(error),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Repair all desyncs or a specific increment
|
|
59
|
+
*/
|
|
60
|
+
export async function repairStatusDesync(options = {}) {
|
|
61
|
+
const { all = false, incrementId, dryRun = false } = options;
|
|
62
|
+
// Get desyncs from validation
|
|
63
|
+
const validation = await validateStatusSync();
|
|
64
|
+
let desyncsToRepair = [];
|
|
65
|
+
if (incrementId) {
|
|
66
|
+
// Repair specific increment
|
|
67
|
+
const desync = validation.desyncs.find((d) => d.incrementId === incrementId);
|
|
68
|
+
if (!desync) {
|
|
69
|
+
throw new Error(`No desync found for increment ${incrementId}`);
|
|
70
|
+
}
|
|
71
|
+
desyncsToRepair = [desync];
|
|
72
|
+
}
|
|
73
|
+
else if (all) {
|
|
74
|
+
// Repair all desyncs
|
|
75
|
+
desyncsToRepair = validation.desyncs;
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
throw new Error('Must specify either --all or <incrementId>');
|
|
79
|
+
}
|
|
80
|
+
const results = [];
|
|
81
|
+
for (const desync of desyncsToRepair) {
|
|
82
|
+
const result = await repairDesync(desync, options);
|
|
83
|
+
results.push(result);
|
|
84
|
+
}
|
|
85
|
+
const repaired = results.filter((r) => r.success).length;
|
|
86
|
+
const failed = results.filter((r) => !r.success).length;
|
|
87
|
+
return {
|
|
88
|
+
total: results.length,
|
|
89
|
+
repaired,
|
|
90
|
+
failed,
|
|
91
|
+
results,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Write audit log
|
|
96
|
+
*/
|
|
97
|
+
export async function writeAuditLog(results) {
|
|
98
|
+
const logsDir = path.join(process.cwd(), '.specweave', 'logs');
|
|
99
|
+
await fs.ensureDir(logsDir);
|
|
100
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
101
|
+
const logPath = path.join(logsDir, `status-desync-repair-${timestamp}.json`);
|
|
102
|
+
const entries = results.map((result) => ({
|
|
103
|
+
timestamp: new Date().toISOString(),
|
|
104
|
+
incrementId: result.incrementId,
|
|
105
|
+
oldStatus: result.oldStatus,
|
|
106
|
+
newStatus: result.newStatus,
|
|
107
|
+
success: result.success,
|
|
108
|
+
error: result.error,
|
|
109
|
+
backupPath: result.backupPath,
|
|
110
|
+
}));
|
|
111
|
+
await fs.writeFile(logPath, JSON.stringify(entries, null, 2), 'utf-8');
|
|
112
|
+
return logPath;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Format repair report
|
|
116
|
+
*/
|
|
117
|
+
export function formatRepairReport(result, dryRun = false) {
|
|
118
|
+
const lines = [];
|
|
119
|
+
lines.push('');
|
|
120
|
+
lines.push('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
121
|
+
if (dryRun) {
|
|
122
|
+
lines.push(chalk.cyan('DRY RUN: Status Desync Repair Preview'));
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
lines.push('Status Desync Repair Report');
|
|
126
|
+
}
|
|
127
|
+
lines.push('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
128
|
+
lines.push('');
|
|
129
|
+
lines.push(`Total desyncs: ${result.total}`);
|
|
130
|
+
if (dryRun) {
|
|
131
|
+
lines.push(chalk.cyan(`Would repair: ${result.repaired}`));
|
|
132
|
+
if (result.failed > 0) {
|
|
133
|
+
lines.push(chalk.yellow(`Would fail: ${result.failed}`));
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
lines.push(chalk.green(`Repaired: ${result.repaired}`));
|
|
138
|
+
if (result.failed > 0) {
|
|
139
|
+
lines.push(chalk.red(`Failed: ${result.failed}`));
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
lines.push('');
|
|
143
|
+
for (const repair of result.results) {
|
|
144
|
+
if (dryRun) {
|
|
145
|
+
lines.push(chalk.cyan(`DRY RUN: Would update ${chalk.bold(repair.incrementId)} from "${repair.oldStatus}" to "${repair.newStatus}"`));
|
|
146
|
+
}
|
|
147
|
+
else if (repair.success) {
|
|
148
|
+
lines.push(chalk.green(`✅ Repaired ${chalk.bold(repair.incrementId)}: "${repair.oldStatus}" → "${repair.newStatus}"`));
|
|
149
|
+
if (repair.backupPath) {
|
|
150
|
+
lines.push(` Backup: ${repair.backupPath}`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
lines.push(chalk.red(`❌ Failed ${chalk.bold(repair.incrementId)}: "${repair.oldStatus}" → "${repair.newStatus}"`));
|
|
155
|
+
if (repair.error) {
|
|
156
|
+
lines.push(` Error: ${repair.error}`);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
lines.push('');
|
|
161
|
+
if (!dryRun && result.repaired > 0) {
|
|
162
|
+
lines.push(chalk.green(`✅ ${result.repaired} desync(s) repaired successfully!`));
|
|
163
|
+
lines.push('');
|
|
164
|
+
lines.push('To verify:');
|
|
165
|
+
lines.push(chalk.cyan(' npx specweave validate-status-sync'));
|
|
166
|
+
}
|
|
167
|
+
else if (dryRun) {
|
|
168
|
+
lines.push(chalk.cyan('To apply these changes:'));
|
|
169
|
+
lines.push(chalk.cyan(' npx specweave repair-status-desync --all'));
|
|
170
|
+
}
|
|
171
|
+
lines.push('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
172
|
+
lines.push('');
|
|
173
|
+
return lines.join('\n');
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Main CLI entry point
|
|
177
|
+
*/
|
|
178
|
+
export async function main(argv = process.argv) {
|
|
179
|
+
try {
|
|
180
|
+
// Parse CLI arguments
|
|
181
|
+
const args = argv.slice(2);
|
|
182
|
+
const options = {
|
|
183
|
+
all: args.includes('--all'),
|
|
184
|
+
dryRun: args.includes('--dry-run'),
|
|
185
|
+
createBackup: !args.includes('--no-backup'),
|
|
186
|
+
};
|
|
187
|
+
// Check for increment ID (non-flag argument)
|
|
188
|
+
const incrementIdArg = args.find((arg) => !arg.startsWith('--'));
|
|
189
|
+
if (incrementIdArg) {
|
|
190
|
+
options.incrementId = incrementIdArg;
|
|
191
|
+
}
|
|
192
|
+
if (options.dryRun) {
|
|
193
|
+
console.log(chalk.cyan('🔍 DRY RUN MODE: No files will be modified\n'));
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
console.log('🔧 Repairing status desyncs...\n');
|
|
197
|
+
}
|
|
198
|
+
const result = await repairStatusDesync(options);
|
|
199
|
+
const report = formatRepairReport(result, options.dryRun);
|
|
200
|
+
console.log(report);
|
|
201
|
+
// Write audit log (skip in dry-run mode)
|
|
202
|
+
if (!options.dryRun && result.total > 0) {
|
|
203
|
+
const logPath = await writeAuditLog(result.results);
|
|
204
|
+
console.log(chalk.gray(`Audit log: ${logPath}\n`));
|
|
205
|
+
}
|
|
206
|
+
// Exit with error code if any repairs failed
|
|
207
|
+
if (result.failed > 0 && !options.dryRun) {
|
|
208
|
+
process.exit(1);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
catch (error) {
|
|
212
|
+
console.error(chalk.red('Error during repair:'));
|
|
213
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
214
|
+
process.exit(1);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
// Run if called directly
|
|
218
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
219
|
+
main();
|
|
220
|
+
}
|
|
221
|
+
//# sourceMappingURL=repair-status-desync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repair-status-desync.js","sourceRoot":"","sources":["../../../../src/cli/commands/repair-status-desync.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { IncrementStatus } from '../../core/types/increment-metadata.js';
|
|
3
|
+
/**
|
|
4
|
+
* Severity levels for status desyncs
|
|
5
|
+
*/
|
|
6
|
+
export declare enum DesyncSeverity {
|
|
7
|
+
CRITICAL = "CRITICAL",
|
|
8
|
+
HIGH = "HIGH",
|
|
9
|
+
MEDIUM = "MEDIUM",
|
|
10
|
+
LOW = "LOW"
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Desync detection result
|
|
14
|
+
*/
|
|
15
|
+
export interface DesyncResult {
|
|
16
|
+
incrementId: string;
|
|
17
|
+
metadataStatus: IncrementStatus;
|
|
18
|
+
specStatus: IncrementStatus;
|
|
19
|
+
severity: DesyncSeverity;
|
|
20
|
+
impact: string;
|
|
21
|
+
fix: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Calculate severity of a status desync
|
|
25
|
+
*/
|
|
26
|
+
export declare function calculateSeverity(metadataStatus: IncrementStatus, specStatus: IncrementStatus): {
|
|
27
|
+
severity: DesyncSeverity;
|
|
28
|
+
impact: string;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Validate status sync across all increments
|
|
32
|
+
*/
|
|
33
|
+
export declare function validateStatusSync(): Promise<{
|
|
34
|
+
total: number;
|
|
35
|
+
synced: number;
|
|
36
|
+
desynced: number;
|
|
37
|
+
desyncs: DesyncResult[];
|
|
38
|
+
}>;
|
|
39
|
+
/**
|
|
40
|
+
* Format and print validation report
|
|
41
|
+
*/
|
|
42
|
+
export declare function formatReport(result: {
|
|
43
|
+
total: number;
|
|
44
|
+
synced: number;
|
|
45
|
+
desynced: number;
|
|
46
|
+
desyncs: DesyncResult[];
|
|
47
|
+
}): string;
|
|
48
|
+
/**
|
|
49
|
+
* Main CLI entry point
|
|
50
|
+
*/
|
|
51
|
+
export declare function main(): Promise<void>;
|
|
52
|
+
//# sourceMappingURL=validate-status-sync.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-status-sync.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/validate-status-sync.ts"],"names":[],"mappings":";AAIA,OAAO,EAAE,eAAe,EAAE,MAAM,wCAAwC,CAAC;AAGzE;;GAEG;AACH,oBAAY,cAAc;IACxB,QAAQ,aAAa;IACrB,IAAI,SAAS;IACb,MAAM,WAAW;IACjB,GAAG,QAAQ;CACZ;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,eAAe,CAAC;IAChC,UAAU,EAAE,eAAe,CAAC;IAC5B,QAAQ,EAAE,cAAc,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,cAAc,EAAE,eAAe,EAC/B,UAAU,EAAE,eAAe,GAC1B;IAAE,QAAQ,EAAE,cAAc,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CA6C9C;AAED;;GAEG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,YAAY,EAAE,CAAC;CACzB,CAAC,CAqDD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,YAAY,EAAE,CAAC;CACzB,GAAG,MAAM,CAiDT;AAED;;GAEG;AACH,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAkB1C"}
|