@paths.design/caws-cli 3.2.4 ā 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/diagnose.d.ts +52 -0
- package/dist/commands/diagnose.d.ts.map +1 -0
- package/dist/commands/diagnose.js +472 -0
- package/dist/commands/status.d.ts +38 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +276 -0
- package/dist/commands/templates.d.ts +74 -0
- package/dist/commands/templates.d.ts.map +1 -0
- package/dist/commands/templates.js +235 -0
- package/dist/error-handler.d.ts +27 -2
- package/dist/error-handler.d.ts.map +1 -1
- package/dist/error-handler.js +187 -16
- package/dist/generators/jest-config.d.ts +32 -0
- package/dist/generators/jest-config.d.ts.map +1 -0
- package/dist/generators/jest-config.js +242 -0
- package/dist/index.js +174 -4
- package/dist/utils/typescript-detector.d.ts +32 -0
- package/dist/utils/typescript-detector.d.ts.map +1 -0
- package/dist/utils/typescript-detector.js +185 -0
- package/package.json +1 -1
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Diagnose command handler
|
|
3
|
+
* @param {Object} options - Command options
|
|
4
|
+
*/
|
|
5
|
+
export function diagnoseCommand(options?: any): Promise<void>;
|
|
6
|
+
/**
|
|
7
|
+
* Run all health checks
|
|
8
|
+
* @returns {Promise<Object>} Diagnosis results
|
|
9
|
+
*/
|
|
10
|
+
export function runDiagnosis(): Promise<any>;
|
|
11
|
+
/**
|
|
12
|
+
* Display diagnosis results
|
|
13
|
+
* @param {Object[]} results - Diagnosis results
|
|
14
|
+
*/
|
|
15
|
+
export function displayResults(results: any[]): void;
|
|
16
|
+
/**
|
|
17
|
+
* Apply automatic fixes
|
|
18
|
+
* @param {Object[]} results - Diagnosis results
|
|
19
|
+
* @returns {Promise<Object>} Fix results
|
|
20
|
+
*/
|
|
21
|
+
export function applyAutoFixes(results: any[]): Promise<any>;
|
|
22
|
+
/**
|
|
23
|
+
* Health check: Working spec validity
|
|
24
|
+
* @returns {Promise<Object>} Check result
|
|
25
|
+
*/
|
|
26
|
+
export function checkWorkingSpec(): Promise<any>;
|
|
27
|
+
/**
|
|
28
|
+
* Health check: Git repository
|
|
29
|
+
* @returns {Promise<Object>} Check result
|
|
30
|
+
*/
|
|
31
|
+
export function checkGitSetup(): Promise<any>;
|
|
32
|
+
/**
|
|
33
|
+
* Health check: Git hooks
|
|
34
|
+
* @returns {Promise<Object>} Check result
|
|
35
|
+
*/
|
|
36
|
+
export function checkGitHooks(): Promise<any>;
|
|
37
|
+
/**
|
|
38
|
+
* Health check: TypeScript configuration
|
|
39
|
+
* @returns {Promise<Object>} Check result
|
|
40
|
+
*/
|
|
41
|
+
export function checkTypeScriptConfig(): Promise<any>;
|
|
42
|
+
/**
|
|
43
|
+
* Health check: Test files exist
|
|
44
|
+
* @returns {Promise<Object>} Check result
|
|
45
|
+
*/
|
|
46
|
+
export function checkTestFiles(): Promise<any>;
|
|
47
|
+
/**
|
|
48
|
+
* Health check: CAWS tools directory
|
|
49
|
+
* @returns {Promise<Object>} Check result
|
|
50
|
+
*/
|
|
51
|
+
export function checkCAWSTools(): Promise<any>;
|
|
52
|
+
//# sourceMappingURL=diagnose.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnose.d.ts","sourceRoot":"","sources":["../../src/commands/diagnose.js"],"names":[],"mappings":"AAoZA;;;GAGG;AACH,8DAiDC;AApMD;;;GAGG;AACH,gCAFa,OAAO,KAAQ,CAkD3B;AAED;;;GAGG;AACH,wCAFW,KAAQ,QA4BlB;AAED;;;;GAIG;AACH,wCAHW,KAAQ,GACN,OAAO,KAAQ,CAoD3B;AAnYD;;;GAGG;AACH,oCAFa,OAAO,KAAQ,CA2C3B;AAED;;;GAGG;AACH,iCAFa,OAAO,KAAQ,CAiB3B;AAED;;;GAGG;AACH,iCAFa,OAAO,KAAQ,CA0C3B;AAED;;;GAGG;AACH,yCAFa,OAAO,KAAQ,CA6C3B;AAED;;;GAGG;AACH,kCAFa,OAAO,KAAQ,CAoC3B;AAED;;;GAGG;AACH,kCAFa,OAAO,KAAQ,CAuC3B"}
|
|
@@ -0,0 +1,472 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview CAWS Diagnose Command
|
|
3
|
+
* Run health checks and suggest fixes
|
|
4
|
+
* @author @darianrosebrook
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const fs = require('fs-extra');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
const yaml = require('js-yaml');
|
|
10
|
+
const chalk = require('chalk');
|
|
11
|
+
|
|
12
|
+
// Import utilities
|
|
13
|
+
const { checkTypeScriptTestConfig } = require('../utils/typescript-detector');
|
|
14
|
+
const { configureJestForTypeScript } = require('../generators/jest-config');
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Health check: Working spec validity
|
|
18
|
+
* @returns {Promise<Object>} Check result
|
|
19
|
+
*/
|
|
20
|
+
async function checkWorkingSpec() {
|
|
21
|
+
const specPath = '.caws/working-spec.yaml';
|
|
22
|
+
|
|
23
|
+
if (!(await fs.pathExists(specPath))) {
|
|
24
|
+
return {
|
|
25
|
+
passed: false,
|
|
26
|
+
severity: 'high',
|
|
27
|
+
message: 'Working spec not found',
|
|
28
|
+
fix: 'Initialize CAWS: caws init .',
|
|
29
|
+
autoFixable: false,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
try {
|
|
34
|
+
const content = await fs.readFile(specPath, 'utf8');
|
|
35
|
+
const spec = yaml.load(content);
|
|
36
|
+
|
|
37
|
+
// Basic validation
|
|
38
|
+
if (!spec.id || !spec.title || !spec.risk_tier) {
|
|
39
|
+
return {
|
|
40
|
+
passed: false,
|
|
41
|
+
severity: 'high',
|
|
42
|
+
message: 'Working spec missing required fields',
|
|
43
|
+
fix: 'Run: caws validate for details',
|
|
44
|
+
autoFixable: false,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
passed: true,
|
|
50
|
+
message: 'Working spec is valid',
|
|
51
|
+
};
|
|
52
|
+
} catch (error) {
|
|
53
|
+
return {
|
|
54
|
+
passed: false,
|
|
55
|
+
severity: 'high',
|
|
56
|
+
message: `Working spec has errors: ${error.message}`,
|
|
57
|
+
fix: 'Run: caws validate for details',
|
|
58
|
+
autoFixable: false,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Health check: Git repository
|
|
65
|
+
* @returns {Promise<Object>} Check result
|
|
66
|
+
*/
|
|
67
|
+
async function checkGitSetup() {
|
|
68
|
+
if (!(await fs.pathExists('.git'))) {
|
|
69
|
+
return {
|
|
70
|
+
passed: false,
|
|
71
|
+
severity: 'medium',
|
|
72
|
+
message: 'Not a git repository',
|
|
73
|
+
fix: 'Initialize git: git init',
|
|
74
|
+
autoFixable: false,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
passed: true,
|
|
80
|
+
message: 'Git repository initialized',
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Health check: Git hooks
|
|
86
|
+
* @returns {Promise<Object>} Check result
|
|
87
|
+
*/
|
|
88
|
+
async function checkGitHooks() {
|
|
89
|
+
const hooksDir = '.git/hooks';
|
|
90
|
+
|
|
91
|
+
if (!(await fs.pathExists(hooksDir))) {
|
|
92
|
+
return {
|
|
93
|
+
passed: false,
|
|
94
|
+
severity: 'medium',
|
|
95
|
+
message: 'Git hooks directory not found',
|
|
96
|
+
fix: 'Ensure .git directory exists',
|
|
97
|
+
autoFixable: false,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const cawsHooks = ['pre-commit', 'post-commit', 'pre-push'];
|
|
102
|
+
let installedCount = 0;
|
|
103
|
+
|
|
104
|
+
for (const hook of cawsHooks) {
|
|
105
|
+
const hookPath = path.join(hooksDir, hook);
|
|
106
|
+
if (await fs.pathExists(hookPath)) {
|
|
107
|
+
const content = await fs.readFile(hookPath, 'utf8');
|
|
108
|
+
if (content.includes('CAWS')) {
|
|
109
|
+
installedCount++;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (installedCount === 0) {
|
|
115
|
+
return {
|
|
116
|
+
passed: false,
|
|
117
|
+
severity: 'low',
|
|
118
|
+
message: 'No CAWS git hooks installed',
|
|
119
|
+
fix: 'Install hooks: caws hooks install',
|
|
120
|
+
autoFixable: false,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return {
|
|
125
|
+
passed: true,
|
|
126
|
+
message: `${installedCount}/${cawsHooks.length} CAWS hooks installed`,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Health check: TypeScript configuration
|
|
132
|
+
* @returns {Promise<Object>} Check result
|
|
133
|
+
*/
|
|
134
|
+
async function checkTypeScriptConfig() {
|
|
135
|
+
const tsConfig = checkTypeScriptTestConfig('.');
|
|
136
|
+
|
|
137
|
+
if (!tsConfig.isTypeScript) {
|
|
138
|
+
return {
|
|
139
|
+
passed: true,
|
|
140
|
+
message: 'Not a TypeScript project (check skipped)',
|
|
141
|
+
skipped: true,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (tsConfig.needsJestConfig) {
|
|
146
|
+
return {
|
|
147
|
+
passed: false,
|
|
148
|
+
severity: 'medium',
|
|
149
|
+
message: 'TypeScript project missing Jest configuration',
|
|
150
|
+
fix: 'Auto-configure Jest for TypeScript',
|
|
151
|
+
autoFixable: true,
|
|
152
|
+
autoFix: async () => {
|
|
153
|
+
const result = await configureJestForTypeScript('.', { quiet: false });
|
|
154
|
+
return {
|
|
155
|
+
success: result.configured,
|
|
156
|
+
message: 'Jest configuration created',
|
|
157
|
+
nextSteps: result.nextSteps,
|
|
158
|
+
};
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if (tsConfig.needsTsJest) {
|
|
164
|
+
return {
|
|
165
|
+
passed: false,
|
|
166
|
+
severity: 'high',
|
|
167
|
+
message: 'TypeScript + Jest detected but missing ts-jest',
|
|
168
|
+
fix: 'Install ts-jest: npm install --save-dev ts-jest',
|
|
169
|
+
autoFixable: false,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return {
|
|
174
|
+
passed: true,
|
|
175
|
+
message: 'TypeScript configuration is correct',
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Health check: Test files exist
|
|
181
|
+
* @returns {Promise<Object>} Check result
|
|
182
|
+
*/
|
|
183
|
+
async function checkTestFiles() {
|
|
184
|
+
const testsDirs = ['tests', 'test', '__tests__', 'spec'];
|
|
185
|
+
let testsDir = null;
|
|
186
|
+
|
|
187
|
+
for (const dir of testsDirs) {
|
|
188
|
+
if (await fs.pathExists(dir)) {
|
|
189
|
+
testsDir = dir;
|
|
190
|
+
break;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if (!testsDir) {
|
|
195
|
+
return {
|
|
196
|
+
passed: false,
|
|
197
|
+
severity: 'medium',
|
|
198
|
+
message: 'No tests directory found',
|
|
199
|
+
fix: 'Create tests directory: mkdir tests',
|
|
200
|
+
autoFixable: true,
|
|
201
|
+
autoFix: async () => {
|
|
202
|
+
await fs.ensureDir('tests');
|
|
203
|
+
await fs.ensureDir('tests/unit');
|
|
204
|
+
await fs.ensureDir('tests/integration');
|
|
205
|
+
return {
|
|
206
|
+
success: true,
|
|
207
|
+
message: 'Created tests/ directory structure',
|
|
208
|
+
};
|
|
209
|
+
},
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
return {
|
|
214
|
+
passed: true,
|
|
215
|
+
message: `Tests directory exists: ${testsDir}/`,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Health check: CAWS tools directory
|
|
221
|
+
* @returns {Promise<Object>} Check result
|
|
222
|
+
*/
|
|
223
|
+
async function checkCAWSTools() {
|
|
224
|
+
const toolsPath = 'apps/tools/caws';
|
|
225
|
+
|
|
226
|
+
if (!(await fs.pathExists(toolsPath))) {
|
|
227
|
+
return {
|
|
228
|
+
passed: false,
|
|
229
|
+
severity: 'low',
|
|
230
|
+
message: 'CAWS tools directory not found',
|
|
231
|
+
fix: 'Scaffold tools: caws scaffold',
|
|
232
|
+
autoFixable: false,
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Check for essential tools
|
|
237
|
+
const essentialTools = ['validate.js', 'gates.js', 'provenance.js'];
|
|
238
|
+
let missingTools = [];
|
|
239
|
+
|
|
240
|
+
for (const tool of essentialTools) {
|
|
241
|
+
if (!(await fs.pathExists(path.join(toolsPath, tool)))) {
|
|
242
|
+
missingTools.push(tool);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
if (missingTools.length > 0) {
|
|
247
|
+
return {
|
|
248
|
+
passed: false,
|
|
249
|
+
severity: 'medium',
|
|
250
|
+
message: `Missing ${missingTools.length} essential tools`,
|
|
251
|
+
fix: 'Re-scaffold tools: caws scaffold --force',
|
|
252
|
+
autoFixable: false,
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
return {
|
|
257
|
+
passed: true,
|
|
258
|
+
message: 'All essential CAWS tools present',
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Run all health checks
|
|
264
|
+
* @returns {Promise<Object>} Diagnosis results
|
|
265
|
+
*/
|
|
266
|
+
async function runDiagnosis() {
|
|
267
|
+
const checks = [
|
|
268
|
+
{ name: 'Working spec validity', fn: checkWorkingSpec },
|
|
269
|
+
{ name: 'Git repository', fn: checkGitSetup },
|
|
270
|
+
{ name: 'Git hooks', fn: checkGitHooks },
|
|
271
|
+
{ name: 'TypeScript configuration', fn: checkTypeScriptConfig },
|
|
272
|
+
{ name: 'Test files', fn: checkTestFiles },
|
|
273
|
+
{ name: 'CAWS tools', fn: checkCAWSTools },
|
|
274
|
+
];
|
|
275
|
+
|
|
276
|
+
console.log(chalk.cyan('\nš Diagnosing CAWS Project...\n'));
|
|
277
|
+
console.log(chalk.gray('Running checks:'));
|
|
278
|
+
|
|
279
|
+
const results = [];
|
|
280
|
+
|
|
281
|
+
for (const check of checks) {
|
|
282
|
+
process.stdout.write(chalk.gray(` ${check.name}... `));
|
|
283
|
+
|
|
284
|
+
try {
|
|
285
|
+
const result = await check.fn();
|
|
286
|
+
|
|
287
|
+
if (result.skipped) {
|
|
288
|
+
console.log(chalk.gray('skipped'));
|
|
289
|
+
} else if (result.passed) {
|
|
290
|
+
console.log(chalk.green('ā
'));
|
|
291
|
+
} else {
|
|
292
|
+
const icon = result.severity === 'high' ? chalk.red('ā') : chalk.yellow('ā ļø');
|
|
293
|
+
console.log(icon);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
results.push({
|
|
297
|
+
name: check.name,
|
|
298
|
+
...result,
|
|
299
|
+
});
|
|
300
|
+
} catch (error) {
|
|
301
|
+
console.log(chalk.red('ā'));
|
|
302
|
+
results.push({
|
|
303
|
+
name: check.name,
|
|
304
|
+
passed: false,
|
|
305
|
+
severity: 'high',
|
|
306
|
+
message: `Check failed: ${error.message}`,
|
|
307
|
+
fix: 'Review error and try again',
|
|
308
|
+
autoFixable: false,
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
return results;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Display diagnosis results
|
|
318
|
+
* @param {Object[]} results - Diagnosis results
|
|
319
|
+
*/
|
|
320
|
+
function displayResults(results) {
|
|
321
|
+
const issues = results.filter((r) => !r.passed && !r.skipped);
|
|
322
|
+
|
|
323
|
+
if (issues.length === 0) {
|
|
324
|
+
console.log(chalk.green('\nā
No issues found! Your CAWS project is healthy.\n'));
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
console.log(
|
|
329
|
+
chalk.bold.yellow(`\nā ļø Found ${issues.length} issue${issues.length > 1 ? 's' : ''}:\n`)
|
|
330
|
+
);
|
|
331
|
+
|
|
332
|
+
issues.forEach((issue, index) => {
|
|
333
|
+
const icon = issue.severity === 'high' ? chalk.red('ā') : chalk.yellow('ā ļø');
|
|
334
|
+
const severity = chalk.gray(`[${issue.severity.toUpperCase()}]`);
|
|
335
|
+
|
|
336
|
+
console.log(`${index + 1}. ${icon} ${issue.name} ${severity}`);
|
|
337
|
+
console.log(chalk.white(` Issue: ${issue.message}`));
|
|
338
|
+
console.log(chalk.cyan(` Fix: ${issue.fix}`));
|
|
339
|
+
|
|
340
|
+
if (issue.autoFixable) {
|
|
341
|
+
console.log(chalk.green(' ⨠Auto-fix available'));
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
console.log('');
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Apply automatic fixes
|
|
350
|
+
* @param {Object[]} results - Diagnosis results
|
|
351
|
+
* @returns {Promise<Object>} Fix results
|
|
352
|
+
*/
|
|
353
|
+
async function applyAutoFixes(results) {
|
|
354
|
+
const fixableIssues = results.filter((r) => !r.passed && r.autoFixable && r.autoFix);
|
|
355
|
+
|
|
356
|
+
if (fixableIssues.length === 0) {
|
|
357
|
+
console.log(chalk.yellow('\nā ļø No auto-fixable issues found\n'));
|
|
358
|
+
return {
|
|
359
|
+
applied: 0,
|
|
360
|
+
skipped: 0,
|
|
361
|
+
failed: 0,
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
console.log(chalk.cyan(`\nš§ Applying ${fixableIssues.length} automatic fixes...\n`));
|
|
366
|
+
|
|
367
|
+
let applied = 0;
|
|
368
|
+
let failed = 0;
|
|
369
|
+
|
|
370
|
+
for (const issue of fixableIssues) {
|
|
371
|
+
process.stdout.write(chalk.gray(` Fixing: ${issue.name}... `));
|
|
372
|
+
|
|
373
|
+
try {
|
|
374
|
+
const result = await issue.autoFix();
|
|
375
|
+
|
|
376
|
+
if (result.success) {
|
|
377
|
+
console.log(chalk.green('ā
'));
|
|
378
|
+
applied++;
|
|
379
|
+
|
|
380
|
+
if (result.nextSteps && result.nextSteps.length > 0) {
|
|
381
|
+
console.log(chalk.blue(' Next steps:'));
|
|
382
|
+
result.nextSteps.forEach((step) => {
|
|
383
|
+
console.log(chalk.blue(` ${step}`));
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
} else {
|
|
387
|
+
console.log(chalk.red('ā'));
|
|
388
|
+
failed++;
|
|
389
|
+
}
|
|
390
|
+
} catch (error) {
|
|
391
|
+
console.log(chalk.red(`ā ${error.message}`));
|
|
392
|
+
failed++;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
console.log(chalk.bold.green(`\nš Results: ${applied} fixed, ${failed} failed\n`));
|
|
397
|
+
|
|
398
|
+
return {
|
|
399
|
+
applied,
|
|
400
|
+
skipped: results.filter((r) => !r.passed && !r.autoFixable).length,
|
|
401
|
+
failed,
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* Diagnose command handler
|
|
407
|
+
* @param {Object} options - Command options
|
|
408
|
+
*/
|
|
409
|
+
async function diagnoseCommand(options = {}) {
|
|
410
|
+
try {
|
|
411
|
+
// Run all health checks
|
|
412
|
+
const results = await runDiagnosis();
|
|
413
|
+
|
|
414
|
+
// Display results
|
|
415
|
+
displayResults(results);
|
|
416
|
+
|
|
417
|
+
// Check if there are auto-fixable issues
|
|
418
|
+
const fixableCount = results.filter((r) => !r.passed && r.autoFixable).length;
|
|
419
|
+
|
|
420
|
+
if (fixableCount > 0 && !options.fix) {
|
|
421
|
+
console.log(
|
|
422
|
+
chalk.yellow(
|
|
423
|
+
`š” ${fixableCount} issue${fixableCount > 1 ? 's' : ''} can be fixed automatically`
|
|
424
|
+
)
|
|
425
|
+
);
|
|
426
|
+
console.log(chalk.yellow(' Run: caws diagnose --fix to apply fixes\n'));
|
|
427
|
+
} else if (options.fix) {
|
|
428
|
+
const fixResults = await applyAutoFixes(results);
|
|
429
|
+
|
|
430
|
+
if (fixResults.applied > 0) {
|
|
431
|
+
console.log(chalk.green('ā
Auto-fixes applied successfully'));
|
|
432
|
+
console.log(chalk.blue('š” Run: caws validate to verify fixes\n'));
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
if (fixResults.skipped > 0) {
|
|
436
|
+
console.log(
|
|
437
|
+
chalk.yellow(
|
|
438
|
+
`ā ļø ${fixResults.skipped} issue${fixResults.skipped > 1 ? 's' : ''} require manual intervention\n`
|
|
439
|
+
)
|
|
440
|
+
);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
// Provide next steps
|
|
445
|
+
const issueCount = results.filter((r) => !r.passed && !r.skipped).length;
|
|
446
|
+
|
|
447
|
+
if (issueCount === 0) {
|
|
448
|
+
console.log(chalk.blue('š Next steps:'));
|
|
449
|
+
console.log(chalk.blue(' ⢠Run: caws status to view project health'));
|
|
450
|
+
console.log(chalk.blue(' ⢠Run: caws validate to check working spec'));
|
|
451
|
+
console.log(chalk.blue(' ⢠Run: node apps/tools/caws/gates.js for quality gates'));
|
|
452
|
+
}
|
|
453
|
+
} catch (error) {
|
|
454
|
+
console.error(chalk.red('\nā Error running diagnosis:'), error.message);
|
|
455
|
+
console.error(chalk.yellow('\nš” Try: caws status for basic health check'));
|
|
456
|
+
process.exit(1);
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
module.exports = {
|
|
461
|
+
diagnoseCommand,
|
|
462
|
+
runDiagnosis,
|
|
463
|
+
displayResults,
|
|
464
|
+
applyAutoFixes,
|
|
465
|
+
// Export individual checks for testing
|
|
466
|
+
checkWorkingSpec,
|
|
467
|
+
checkGitSetup,
|
|
468
|
+
checkGitHooks,
|
|
469
|
+
checkTypeScriptConfig,
|
|
470
|
+
checkTestFiles,
|
|
471
|
+
checkCAWSTools,
|
|
472
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Status command handler
|
|
3
|
+
* @param {Object} options - Command options
|
|
4
|
+
*/
|
|
5
|
+
export function statusCommand(options?: any): Promise<void>;
|
|
6
|
+
/**
|
|
7
|
+
* Load working specification
|
|
8
|
+
* @param {string} specPath - Path to working spec
|
|
9
|
+
* @returns {Promise<Object|null>} Parsed spec or null
|
|
10
|
+
*/
|
|
11
|
+
export function loadWorkingSpec(specPath?: string): Promise<any | null>;
|
|
12
|
+
/**
|
|
13
|
+
* Check Git hooks status
|
|
14
|
+
* @returns {Promise<Object>} Hooks status
|
|
15
|
+
*/
|
|
16
|
+
export function checkGitHooks(): Promise<any>;
|
|
17
|
+
/**
|
|
18
|
+
* Load provenance chain
|
|
19
|
+
* @returns {Promise<Object>} Provenance status
|
|
20
|
+
*/
|
|
21
|
+
export function loadProvenanceChain(): Promise<any>;
|
|
22
|
+
/**
|
|
23
|
+
* Check quality gates status (simplified)
|
|
24
|
+
* @returns {Promise<Object>} Quality gates status
|
|
25
|
+
*/
|
|
26
|
+
export function checkQualityGates(): Promise<any>;
|
|
27
|
+
/**
|
|
28
|
+
* Display project status
|
|
29
|
+
* @param {Object} data - Status data
|
|
30
|
+
*/
|
|
31
|
+
export function displayStatus(data: any): void;
|
|
32
|
+
/**
|
|
33
|
+
* Generate actionable suggestions based on status
|
|
34
|
+
* @param {Object} data - Status data
|
|
35
|
+
* @returns {string[]} Array of suggestions
|
|
36
|
+
*/
|
|
37
|
+
export function generateSuggestions(data: any): string[];
|
|
38
|
+
//# sourceMappingURL=status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.js"],"names":[],"mappings":"AAiPA;;;GAGG;AACH,4DAoBC;AA9PD;;;;GAIG;AACH,2CAHW,MAAM,GACJ,OAAO,CAAC,MAAO,IAAI,CAAC,CAahC;AAED;;;GAGG;AACH,iCAFa,OAAO,KAAQ,CAgC3B;AAED;;;GAGG;AACH,uCAFa,OAAO,KAAQ,CA+B3B;AAED;;;GAGG;AACH,qCAFa,OAAO,KAAQ,CAS3B;AAwBD;;;GAGG;AACH,+CAyEC;AAED;;;;GAIG;AACH,gDAFa,MAAM,EAAE,CAsBpB"}
|