specweave 0.22.2 → 0.22.4
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 +300 -920
- 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/sync-specs.d.ts +4 -1
- package/dist/src/cli/commands/sync-specs.d.ts.map +1 -1
- package/dist/src/cli/commands/sync-specs.js +99 -49
- package/dist/src/cli/commands/sync-specs.js.map +1 -1
- 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/cicd/workflow-monitor.d.ts +4 -0
- package/dist/src/core/cicd/workflow-monitor.d.ts.map +1 -1
- package/dist/src/core/cicd/workflow-monitor.js +6 -2
- package/dist/src/core/cicd/workflow-monitor.js.map +1 -1
- 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/increment-archiver.d.ts +4 -1
- package/dist/src/core/increment/increment-archiver.d.ts.map +1 -1
- package/dist/src/core/increment/increment-archiver.js +21 -9
- package/dist/src/core/increment/increment-archiver.js.map +1 -1
- package/dist/src/core/increment/metadata-manager.d.ts +22 -0
- package/dist/src/core/increment/metadata-manager.d.ts.map +1 -1
- package/dist/src/core/increment/metadata-manager.js +62 -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/increment/spec-sync-manager.d.ts +5 -1
- package/dist/src/core/increment/spec-sync-manager.d.ts.map +1 -1
- package/dist/src/core/increment/spec-sync-manager.js +4 -2
- package/dist/src/core/increment/spec-sync-manager.js.map +1 -1
- package/dist/src/core/increment-utils.d.ts.map +1 -1
- package/dist/src/core/increment-utils.js +18 -1
- package/dist/src/core/increment-utils.js.map +1 -1
- package/dist/src/core/living-docs/living-docs-sync.d.ts +5 -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 +36 -33
- package/dist/src/core/living-docs/living-docs-sync.js.map +1 -1
- package/dist/src/core/living-docs/task-project-specific-generator.d.ts.map +1 -1
- package/dist/src/core/living-docs/task-project-specific-generator.js +13 -8
- package/dist/src/core/living-docs/task-project-specific-generator.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 +42 -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/dist/src/integrations/jira/jira-incremental-mapper.d.ts.map +1 -1
- package/dist/src/integrations/jira/jira-incremental-mapper.js +4 -0
- package/dist/src/integrations/jira/jira-incremental-mapper.js.map +1 -1
- package/dist/src/integrations/jira/jira-mapper.d.ts.map +1 -1
- package/dist/src/integrations/jira/jira-mapper.js +4 -0
- package/dist/src/integrations/jira/jira-mapper.js.map +1 -1
- package/dist/src/utils/logger.d.ts +48 -0
- package/dist/src/utils/logger.d.ts.map +1 -0
- package/dist/src/utils/logger.js +53 -0
- package/dist/src/utils/logger.js.map +1 -0
- package/package.json +3 -2
- package/plugins/specweave/agents/code-standards-detective/AGENT.md +828 -0
- package/plugins/specweave/agents/test-aware-planner/templates/task-non-testable.md.template +12 -0
- package/plugins/specweave/agents/test-aware-planner/templates/task-testable.md.template +12 -0
- package/plugins/specweave/commands/specweave-analyze-standards.sh +315 -0
- package/plugins/specweave/commands/specweave-done.md +91 -4
- package/plugins/specweave/commands/specweave-reopen.md +29 -2
- package/plugins/specweave/commands/specweave-sync-docs.md +137 -22
- package/plugins/specweave/commands/specweave-update-status.md +151 -0
- package/plugins/specweave/hooks/lib/update-status-line.sh +39 -8
- package/plugins/specweave/hooks/user-prompt-submit.sh +21 -0
- package/plugins/specweave/hooks/validate-increment-completion.sh +113 -0
- package/plugins/specweave/skills/brownfield-analyzer/SKILL.md +40 -3
- package/plugins/specweave/skills/code-standards-analyzer/SKILL.md +455 -0
- package/plugins/specweave/templates/coding-standards.md.template +447 -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
|
@@ -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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"}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Syncs increment specifications to living docs structure
|
|
5
5
|
*/
|
|
6
|
+
import { Logger } from '../../utils/logger.js';
|
|
6
7
|
export interface SyncSpecsArgs {
|
|
7
8
|
incrementId?: string;
|
|
8
9
|
all?: boolean;
|
|
@@ -12,5 +13,7 @@ export interface SyncSpecsArgs {
|
|
|
12
13
|
/**
|
|
13
14
|
* Sync specs command entry point
|
|
14
15
|
*/
|
|
15
|
-
export declare function syncSpecs(args: string[]
|
|
16
|
+
export declare function syncSpecs(args: string[], options?: {
|
|
17
|
+
logger?: Logger;
|
|
18
|
+
}): Promise<void>;
|
|
16
19
|
//# sourceMappingURL=sync-specs.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-specs.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/sync-specs.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"sync-specs.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/sync-specs.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAE,MAAM,EAAiB,MAAM,uBAAuB,CAAC;AAE9D,MAAM,WAAW,aAAa;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAuFhG"}
|
|
@@ -6,65 +6,89 @@
|
|
|
6
6
|
import fs from 'fs-extra';
|
|
7
7
|
import path from 'path';
|
|
8
8
|
import { LivingDocsSync } from '../../core/living-docs/living-docs-sync.js';
|
|
9
|
+
import { consoleLogger } from '../../utils/logger.js';
|
|
9
10
|
/**
|
|
10
11
|
* Sync specs command entry point
|
|
11
12
|
*/
|
|
12
|
-
export async function syncSpecs(args) {
|
|
13
|
+
export async function syncSpecs(args, options = {}) {
|
|
14
|
+
const logger = options.logger ?? consoleLogger;
|
|
13
15
|
const parsedArgs = parseArgs(args);
|
|
14
16
|
const projectRoot = process.cwd();
|
|
15
|
-
const sync = new LivingDocsSync(projectRoot);
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
17
|
+
const sync = new LivingDocsSync(projectRoot, { logger });
|
|
18
|
+
// Default to --all if no increment ID provided
|
|
19
|
+
const shouldSyncAll = parsedArgs.all || !parsedArgs.incrementId;
|
|
20
|
+
if (shouldSyncAll) {
|
|
21
|
+
// Sync all increments (not just completed)
|
|
22
|
+
logger.log('🔄 Syncing all increments...\n');
|
|
23
|
+
let increments;
|
|
24
|
+
try {
|
|
25
|
+
increments = await findAllSyncableIncrements(projectRoot, logger);
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
logger.error('❌ Failed to find increments:', error);
|
|
29
|
+
process.exit(1);
|
|
30
|
+
return; // For type safety (unreachable)
|
|
31
|
+
}
|
|
32
|
+
let successCount = 0;
|
|
33
|
+
let failCount = 0;
|
|
34
|
+
for (const incrementId of increments) {
|
|
35
|
+
try {
|
|
36
|
+
const result = await sync.syncIncrement(incrementId, {
|
|
37
|
+
dryRun: parsedArgs.dryRun,
|
|
38
|
+
force: parsedArgs.force
|
|
39
|
+
});
|
|
40
|
+
if (result.success) {
|
|
41
|
+
successCount++;
|
|
36
42
|
}
|
|
37
|
-
|
|
43
|
+
else {
|
|
38
44
|
failCount++;
|
|
39
|
-
|
|
45
|
+
logger.error(` ❌ Failed: ${result.errors.join(', ')}`);
|
|
40
46
|
}
|
|
41
47
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
// Sync single increment
|
|
46
|
-
const incrementId = parsedArgs.incrementId || await findLatestCompletedIncrement(projectRoot);
|
|
47
|
-
if (!incrementId) {
|
|
48
|
-
console.error('❌ No increment specified and no completed increments found');
|
|
49
|
-
process.exit(1);
|
|
48
|
+
catch (error) {
|
|
49
|
+
failCount++;
|
|
50
|
+
logger.error(` ❌ Failed to sync ${incrementId}:`, error);
|
|
50
51
|
}
|
|
51
|
-
|
|
52
|
+
}
|
|
53
|
+
logger.log(`\n✅ Sync complete: ${successCount} succeeded, ${failCount} failed`);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
// Sync single increment
|
|
57
|
+
let incrementId;
|
|
58
|
+
try {
|
|
59
|
+
incrementId = parsedArgs.incrementId || await findLatestCompletedIncrement(projectRoot, logger);
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
logger.error('❌ Failed to find latest increment:', error);
|
|
63
|
+
process.exit(1);
|
|
64
|
+
return; // For type safety (unreachable)
|
|
65
|
+
}
|
|
66
|
+
if (!incrementId) {
|
|
67
|
+
logger.error('❌ No increment specified and no completed increments found');
|
|
68
|
+
process.exit(1);
|
|
69
|
+
return; // For type safety (unreachable)
|
|
70
|
+
}
|
|
71
|
+
let result;
|
|
72
|
+
try {
|
|
73
|
+
result = await sync.syncIncrement(incrementId, {
|
|
52
74
|
dryRun: parsedArgs.dryRun,
|
|
53
75
|
force: parsedArgs.force
|
|
54
76
|
});
|
|
55
|
-
if (!result.success) {
|
|
56
|
-
console.error('❌ Sync failed:', result.errors.join(', '));
|
|
57
|
-
process.exit(1);
|
|
58
|
-
}
|
|
59
|
-
console.log('\n✅ Sync complete!');
|
|
60
|
-
if (parsedArgs.dryRun) {
|
|
61
|
-
console.log(' (Dry run - no files were actually created)');
|
|
62
|
-
}
|
|
63
77
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
78
|
+
catch (error) {
|
|
79
|
+
logger.error('❌ Sync failed with unexpected error:', error);
|
|
80
|
+
process.exit(1);
|
|
81
|
+
return; // For type safety (unreachable)
|
|
82
|
+
}
|
|
83
|
+
if (!result.success) {
|
|
84
|
+
logger.error('❌ Sync failed:', result.errors.join(', '));
|
|
85
|
+
process.exit(1);
|
|
86
|
+
return; // For type safety (unreachable)
|
|
87
|
+
}
|
|
88
|
+
logger.log('\n✅ Sync complete!');
|
|
89
|
+
if (parsedArgs.dryRun) {
|
|
90
|
+
logger.log(' (Dry run - no files were actually created)');
|
|
91
|
+
}
|
|
68
92
|
}
|
|
69
93
|
}
|
|
70
94
|
/**
|
|
@@ -90,10 +114,36 @@ function parseArgs(args) {
|
|
|
90
114
|
}
|
|
91
115
|
return parsed;
|
|
92
116
|
}
|
|
117
|
+
/**
|
|
118
|
+
* Find all syncable increments (with spec.md, regardless of status)
|
|
119
|
+
* Excludes non-increment directories like _archive, _backup, etc.
|
|
120
|
+
*/
|
|
121
|
+
async function findAllSyncableIncrements(projectRoot, logger) {
|
|
122
|
+
const incrementsDir = path.join(projectRoot, '.specweave/increments');
|
|
123
|
+
if (!await fs.pathExists(incrementsDir)) {
|
|
124
|
+
return [];
|
|
125
|
+
}
|
|
126
|
+
const entries = await fs.readdir(incrementsDir);
|
|
127
|
+
const syncable = [];
|
|
128
|
+
for (const entry of entries) {
|
|
129
|
+
// Skip non-increment directories (_archive, _backup, etc.)
|
|
130
|
+
if (!entry.match(/^\d{4}-/)) {
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
// Require spec.md to exist
|
|
134
|
+
const specPath = path.join(incrementsDir, entry, 'spec.md');
|
|
135
|
+
if (!await fs.pathExists(specPath)) {
|
|
136
|
+
logger.log(` ⚠️ Skipping ${entry} (no spec.md)`);
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
syncable.push(entry);
|
|
140
|
+
}
|
|
141
|
+
return syncable.sort();
|
|
142
|
+
}
|
|
93
143
|
/**
|
|
94
144
|
* Find all completed increments
|
|
95
145
|
*/
|
|
96
|
-
async function findCompletedIncrements(projectRoot) {
|
|
146
|
+
async function findCompletedIncrements(projectRoot, logger) {
|
|
97
147
|
const incrementsDir = path.join(projectRoot, '.specweave/increments');
|
|
98
148
|
if (!await fs.pathExists(incrementsDir)) {
|
|
99
149
|
return [];
|
|
@@ -107,7 +157,7 @@ async function findCompletedIncrements(projectRoot) {
|
|
|
107
157
|
const specPath = path.join(incrementsDir, entry, 'spec.md');
|
|
108
158
|
// Skip if no spec.md
|
|
109
159
|
if (!await fs.pathExists(specPath)) {
|
|
110
|
-
|
|
160
|
+
logger.log(` ⚠️ Skipping ${entry} (no spec.md)`);
|
|
111
161
|
continue;
|
|
112
162
|
}
|
|
113
163
|
// Check if completed
|
|
@@ -123,8 +173,8 @@ async function findCompletedIncrements(projectRoot) {
|
|
|
123
173
|
/**
|
|
124
174
|
* Find latest completed increment
|
|
125
175
|
*/
|
|
126
|
-
async function findLatestCompletedIncrement(projectRoot) {
|
|
127
|
-
const completed = await findCompletedIncrements(projectRoot);
|
|
176
|
+
async function findLatestCompletedIncrement(projectRoot, logger) {
|
|
177
|
+
const completed = await findCompletedIncrements(projectRoot, logger);
|
|
128
178
|
return completed.length > 0 ? completed[completed.length - 1] : null;
|
|
129
179
|
}
|
|
130
180
|
//# sourceMappingURL=sync-specs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-specs.js","sourceRoot":"","sources":["../../../../src/cli/commands/sync-specs.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,cAAc,EAAe,MAAM,4CAA4C,CAAC;
|
|
1
|
+
{"version":3,"file":"sync-specs.js","sourceRoot":"","sources":["../../../../src/cli/commands/sync-specs.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"}
|