@paths.design/caws-cli 3.3.1 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/commands/diagnose.d.ts.map +1 -1
  2. package/dist/commands/diagnose.js +39 -4
  3. package/dist/commands/evaluate.d.ts +8 -0
  4. package/dist/commands/evaluate.d.ts.map +1 -0
  5. package/dist/commands/evaluate.js +288 -0
  6. package/dist/commands/iterate.d.ts +8 -0
  7. package/dist/commands/iterate.d.ts.map +1 -0
  8. package/dist/commands/iterate.js +341 -0
  9. package/dist/commands/quality-monitor.d.ts +17 -0
  10. package/dist/commands/quality-monitor.d.ts.map +1 -0
  11. package/dist/commands/quality-monitor.js +265 -0
  12. package/dist/commands/status.d.ts +6 -1
  13. package/dist/commands/status.d.ts.map +1 -1
  14. package/dist/commands/status.js +120 -20
  15. package/dist/commands/troubleshoot.d.ts +8 -0
  16. package/dist/commands/troubleshoot.d.ts.map +1 -0
  17. package/dist/commands/troubleshoot.js +104 -0
  18. package/dist/commands/waivers.d.ts +8 -0
  19. package/dist/commands/waivers.d.ts.map +1 -0
  20. package/dist/commands/waivers.js +293 -0
  21. package/dist/commands/workflow.d.ts +85 -0
  22. package/dist/commands/workflow.d.ts.map +1 -0
  23. package/dist/commands/workflow.js +243 -0
  24. package/dist/error-handler.d.ts +91 -2
  25. package/dist/error-handler.d.ts.map +1 -1
  26. package/dist/error-handler.js +362 -16
  27. package/dist/index.js +95 -0
  28. package/dist/utils/typescript-detector.d.ts +31 -0
  29. package/dist/utils/typescript-detector.d.ts.map +1 -1
  30. package/dist/utils/typescript-detector.js +245 -7
  31. package/package.json +2 -1
  32. package/templates/apps/tools/caws/gates.ts +34 -0
  33. package/templates/apps/tools/caws/shared/gate-checker.ts +265 -13
  34. package/templates/apps/tools/caws/templates/working-spec.template.yml +14 -0
  35. package/dist/index-new.d.ts +0 -5
  36. package/dist/index-new.d.ts.map +0 -1
  37. package/dist/index-new.js +0 -317
  38. package/dist/index.js.backup +0 -4711
  39. package/templates/apps/tools/caws/prompt-lint.js.backup +0 -274
  40. package/templates/apps/tools/caws/provenance.js.backup +0 -73
@@ -8,6 +8,7 @@ const fs = require('fs-extra');
8
8
  const path = require('path');
9
9
  const yaml = require('js-yaml');
10
10
  const chalk = require('chalk');
11
+ const { safeAsync, outputResult } = require('../error-handler');
11
12
 
12
13
  /**
13
14
  * Load working specification
@@ -98,6 +99,68 @@ async function loadProvenanceChain() {
98
99
  }
99
100
  }
100
101
 
102
+ /**
103
+ * Load waiver status
104
+ * @returns {Promise<Object>} Waiver status
105
+ */
106
+ async function loadWaiverStatus() {
107
+ const waiversDir = '.caws/waivers';
108
+
109
+ if (!(await fs.pathExists(waiversDir))) {
110
+ return {
111
+ exists: false,
112
+ active: 0,
113
+ expired: 0,
114
+ revoked: 0,
115
+ total: 0,
116
+ };
117
+ }
118
+
119
+ try {
120
+ const waiverFiles = await fs.readdir(waiversDir);
121
+ const yamlFiles = waiverFiles.filter((f) => f.endsWith('.yaml'));
122
+
123
+ let active = 0;
124
+ let expired = 0;
125
+ let revoked = 0;
126
+
127
+ for (const file of yamlFiles) {
128
+ const waiverPath = path.join(waiversDir, file);
129
+ const content = await fs.readFile(waiverPath, 'utf8');
130
+ const waiver = yaml.load(content);
131
+
132
+ if (waiver.status === 'revoked') {
133
+ revoked++;
134
+ } else if (waiver.status === 'active') {
135
+ const now = new Date();
136
+ const expiresAt = new Date(waiver.expires_at);
137
+ if (now > expiresAt) {
138
+ expired++;
139
+ } else {
140
+ active++;
141
+ }
142
+ }
143
+ }
144
+
145
+ return {
146
+ exists: true,
147
+ active,
148
+ expired,
149
+ revoked,
150
+ total: active + expired + revoked,
151
+ };
152
+ } catch (error) {
153
+ return {
154
+ exists: false,
155
+ active: 0,
156
+ expired: 0,
157
+ revoked: 0,
158
+ total: 0,
159
+ error: error.message,
160
+ };
161
+ }
162
+ }
163
+
101
164
  /**
102
165
  * Check quality gates status (simplified)
103
166
  * @returns {Promise<Object>} Quality gates status
@@ -138,7 +201,7 @@ function getTimeSince(timestamp) {
138
201
  * @param {Object} data - Status data
139
202
  */
140
203
  function displayStatus(data) {
141
- const { spec, hooks, provenance, gates } = data;
204
+ const { spec, hooks, provenance, waivers, gates } = data;
142
205
 
143
206
  console.log(chalk.bold.cyan('\n📊 CAWS Project Status'));
144
207
  console.log(chalk.cyan('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'));
@@ -183,6 +246,26 @@ function displayStatus(data) {
183
246
 
184
247
  console.log('');
185
248
 
249
+ // Waivers Status
250
+ if (waivers.exists && waivers.total > 0) {
251
+ console.log(chalk.green('✅ Quality Gate Waivers'));
252
+ console.log(
253
+ chalk.gray(
254
+ ` ${waivers.active} active, ${waivers.expired} expired, ${waivers.revoked} revoked`
255
+ )
256
+ );
257
+ console.log(chalk.gray(` Total: ${waivers.total} waiver${waivers.total > 1 ? 's' : ''}`));
258
+ } else if (waivers.exists) {
259
+ console.log(chalk.blue('ℹ️ Quality Gate Waivers'));
260
+ console.log(chalk.gray(' No waivers configured'));
261
+ } else {
262
+ console.log(chalk.yellow('⚠️ Quality Gate Waivers'));
263
+ console.log(chalk.gray(' Waiver system not initialized'));
264
+ console.log(chalk.yellow(' 💡 Run: caws waivers create (when needed)'));
265
+ }
266
+
267
+ console.log('');
268
+
186
269
  // Quality Gates Status
187
270
  console.log(chalk.blue('ℹ️ Quality Gates'));
188
271
  console.log(chalk.gray(` ${gates.message}`));
@@ -207,6 +290,9 @@ function displayStatus(data) {
207
290
  if (provenance.exists) {
208
291
  console.log(chalk.blue(' View provenance: caws provenance show --format=dashboard'));
209
292
  }
293
+ if (waivers.exists && waivers.total > 0) {
294
+ console.log(chalk.blue(' View waivers: caws waivers list'));
295
+ }
210
296
  console.log(chalk.blue(' Full documentation: docs/agents/full-guide.md'));
211
297
 
212
298
  console.log('');
@@ -244,25 +330,38 @@ function generateSuggestions(data) {
244
330
  * @param {Object} options - Command options
245
331
  */
246
332
  async function statusCommand(options = {}) {
247
- try {
248
- // Load all status data
249
- const spec = await loadWorkingSpec(options.spec || '.caws/working-spec.yaml');
250
- const hooks = await checkGitHooks();
251
- const provenance = await loadProvenanceChain();
252
- const gates = await checkQualityGates();
253
-
254
- // Display status
255
- displayStatus({
256
- spec,
257
- hooks,
258
- provenance,
259
- gates,
260
- });
261
- } catch (error) {
262
- console.error(chalk.red('❌ Error checking project status:'), error.message);
263
- console.error(chalk.yellow('\n💡 Try: caws validate to check your setup'));
264
- process.exit(1);
265
- }
333
+ return safeAsync(
334
+ async () => {
335
+ // Load all status data
336
+ const spec = await loadWorkingSpec(options.spec || '.caws/working-spec.yaml');
337
+ const hooks = await checkGitHooks();
338
+ const provenance = await loadProvenanceChain();
339
+ const waivers = await loadWaiverStatus();
340
+ const gates = await checkQualityGates();
341
+
342
+ // Display status
343
+ displayStatus({
344
+ spec,
345
+ hooks,
346
+ provenance,
347
+ waivers,
348
+ gates,
349
+ });
350
+
351
+ const result = outputResult({
352
+ command: 'status',
353
+ spec: spec ? 'loaded' : 'not found',
354
+ hooks: hooks.installed,
355
+ provenance: provenance.entries?.length || 0,
356
+ waivers: waivers.active?.length || 0,
357
+ gates: gates.passed ? 'passed' : 'failed',
358
+ });
359
+
360
+ return result;
361
+ },
362
+ 'status check',
363
+ true
364
+ );
266
365
  }
267
366
 
268
367
  module.exports = {
@@ -270,6 +369,7 @@ module.exports = {
270
369
  loadWorkingSpec,
271
370
  checkGitHooks,
272
371
  loadProvenanceChain,
372
+ loadWaiverStatus,
273
373
  checkQualityGates,
274
374
  displayStatus,
275
375
  generateSuggestions,
@@ -0,0 +1,8 @@
1
+ export = troubleshootCommand;
2
+ /**
3
+ * Troubleshoot command handler
4
+ * @param {string} guide - Guide key argument
5
+ * @param {Object} options - Command options
6
+ */
7
+ declare function troubleshootCommand(guide: string, options: any): void;
8
+ //# sourceMappingURL=troubleshoot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"troubleshoot.d.ts","sourceRoot":"","sources":["../../src/commands/troubleshoot.js"],"names":[],"mappings":";AAqFA;;;;GAIG;AACH,4CAHW,MAAM,sBAchB"}
@@ -0,0 +1,104 @@
1
+ /**
2
+ * @fileoverview CAWS CLI Troubleshoot Command
3
+ * Provides detailed troubleshooting guides for common CAWS issues
4
+ * @author @darianrosebrook
5
+ */
6
+
7
+ const chalk = require('chalk');
8
+ const { getTroubleshootingGuide, getAllTroubleshootingGuides } = require('../error-handler');
9
+
10
+ /**
11
+ * Display a specific troubleshooting guide
12
+ * @param {string} guideKey - Key for the troubleshooting guide
13
+ */
14
+ function displayGuide(guideKey) {
15
+ const guide = getTroubleshootingGuide(guideKey);
16
+
17
+ if (!guide) {
18
+ console.error(chalk.red(`❌ Troubleshooting guide '${guideKey}' not found.`));
19
+ console.log(chalk.yellow('\nAvailable guides:'));
20
+ const allGuides = getAllTroubleshootingGuides();
21
+ Object.keys(allGuides).forEach((key) => {
22
+ console.log(chalk.yellow(` ${key}: ${allGuides[key].title}`));
23
+ });
24
+ console.log(chalk.yellow('\nTry: caws troubleshoot --list for all available guides'));
25
+ return;
26
+ }
27
+
28
+ console.log(chalk.bold.blue(`🔍 ${guide.title}`));
29
+ console.log(chalk.gray('═'.repeat(50)));
30
+
31
+ if (guide.symptoms && guide.symptoms.length > 0) {
32
+ console.log(chalk.yellow('\n📋 Symptoms:'));
33
+ guide.symptoms.forEach((symptom) => {
34
+ console.log(chalk.gray(` • ${symptom}`));
35
+ });
36
+ }
37
+
38
+ if (guide.rootCauses && guide.rootCauses.length > 0) {
39
+ console.log(chalk.red('\n🔍 Possible Root Causes:'));
40
+ guide.rootCauses.forEach((cause) => {
41
+ console.log(chalk.gray(` • ${cause}`));
42
+ });
43
+ }
44
+
45
+ if (guide.solutions && guide.solutions.length > 0) {
46
+ console.log(chalk.green('\n✅ Solutions:'));
47
+ guide.solutions.forEach((solution, index) => {
48
+ console.log(chalk.gray(` ${index + 1}. ${solution}`));
49
+ });
50
+ }
51
+
52
+ if (guide.commands && guide.commands.length > 0) {
53
+ console.log(chalk.cyan('\n💻 Try These Commands:'));
54
+ guide.commands.forEach((command) => {
55
+ console.log(chalk.gray(` $ ${command}`));
56
+ });
57
+ }
58
+
59
+ console.log(chalk.gray('\n═'.repeat(50)));
60
+ console.log(chalk.blue('📚 For more help: caws --help or visit the documentation'));
61
+ }
62
+
63
+ /**
64
+ * List all available troubleshooting guides
65
+ */
66
+ function listGuides() {
67
+ console.log(chalk.bold.blue('🔧 Available Troubleshooting Guides'));
68
+ console.log(chalk.gray('═'.repeat(50)));
69
+
70
+ const allGuides = getAllTroubleshootingGuides();
71
+ Object.entries(allGuides).forEach(([key, guide]) => {
72
+ console.log(chalk.cyan(`${key}:`));
73
+ console.log(chalk.gray(` ${guide.title}`));
74
+ if (guide.symptoms && guide.symptoms.length > 0) {
75
+ console.log(
76
+ chalk.gray(` Symptoms: ${guide.symptoms[0]}${guide.symptoms.length > 1 ? '...' : ''}`)
77
+ );
78
+ }
79
+ console.log('');
80
+ });
81
+
82
+ console.log(chalk.yellow('Usage: caws troubleshoot <guide-key>'));
83
+ console.log(chalk.yellow('Example: caws troubleshoot coverage-report-not-found'));
84
+ }
85
+
86
+ /**
87
+ * Troubleshoot command handler
88
+ * @param {string} guide - Guide key argument
89
+ * @param {Object} options - Command options
90
+ */
91
+ function troubleshootCommand(guide, options) {
92
+ try {
93
+ if (options.list || !guide) {
94
+ listGuides();
95
+ } else {
96
+ displayGuide(guide);
97
+ }
98
+ } catch (error) {
99
+ console.error(chalk.red(`❌ Error: ${error.message}`));
100
+ process.exit(1);
101
+ }
102
+ }
103
+
104
+ module.exports = troubleshootCommand;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Waivers command handler
3
+ *
4
+ * @param {string} subcommand - create, list, show, revoke
5
+ * @param {object} options - Command options
6
+ */
7
+ export function waiversCommand(subcommand?: string, options?: object): Promise<void>;
8
+ //# sourceMappingURL=waivers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"waivers.d.ts","sourceRoot":"","sources":["../../src/commands/waivers.js"],"names":[],"mappings":"AAkBA;;;;;GAKG;AACH,4CAHW,MAAM,YACN,MAAM,iBA2ChB"}
@@ -0,0 +1,293 @@
1
+ /**
2
+ * CAWS Waivers Command
3
+ *
4
+ * Manage quality gate waivers for exceptional circumstances.
5
+ * Waivers allow temporary exceptions to quality requirements
6
+ * with proper documentation and approval.
7
+ *
8
+ * @author @darianrosebrook
9
+ */
10
+
11
+ const fs = require('fs');
12
+ const path = require('path');
13
+ const yaml = require('js-yaml');
14
+ const chalk = require('chalk');
15
+ const { initializeGlobalSetup } = require('../config');
16
+
17
+ const WAIVER_DIR = '.caws/waivers';
18
+
19
+ /**
20
+ * Waivers command handler
21
+ *
22
+ * @param {string} subcommand - create, list, show, revoke
23
+ * @param {object} options - Command options
24
+ */
25
+ async function waiversCommand(subcommand = 'list', options = {}) {
26
+ try {
27
+ console.log('🔍 Detecting CAWS setup...');
28
+ const setup = initializeGlobalSetup();
29
+
30
+ if (setup.hasWorkingSpec) {
31
+ console.log(`✅ Detected ${setup.setupType} CAWS setup`);
32
+ console.log(` Capabilities: ${setup.capabilities.join(', ')}`);
33
+ }
34
+
35
+ // Ensure waivers directory exists
36
+ const waiversDir = path.join(process.cwd(), WAIVER_DIR);
37
+ if (!fs.existsSync(waiversDir)) {
38
+ fs.mkdirSync(waiversDir, { recursive: true });
39
+ }
40
+
41
+ switch (subcommand) {
42
+ case 'create':
43
+ await createWaiver(options);
44
+ break;
45
+ case 'list':
46
+ await listWaivers(options);
47
+ break;
48
+ case 'show':
49
+ await showWaiver(options.id, options);
50
+ break;
51
+ case 'revoke':
52
+ await revokeWaiver(options.id, options);
53
+ break;
54
+ default:
55
+ console.error(chalk.red(`\n❌ Unknown waiver subcommand: ${subcommand}`));
56
+ console.log(chalk.yellow('\n💡 Available subcommands: create, list, show, revoke'));
57
+ process.exit(1);
58
+ }
59
+ } catch (error) {
60
+ console.error(chalk.red(`\n❌ Waiver command failed: ${error.message}`));
61
+ if (options.verbose) {
62
+ console.error(error.stack);
63
+ }
64
+ process.exit(1);
65
+ }
66
+ }
67
+
68
+ /**
69
+ * Create a new waiver
70
+ */
71
+ async function createWaiver(options) {
72
+ // Validate required fields
73
+ const required = ['title', 'reason', 'description', 'gates', 'expiresAt', 'approvedBy', 'impactLevel', 'mitigationPlan'];
74
+ const missing = required.filter(field => !options[field]);
75
+
76
+ if (missing.length > 0) {
77
+ console.error(chalk.red(`\n❌ Missing required fields: ${missing.join(', ')}`));
78
+ console.log(chalk.yellow('\n💡 Example:'));
79
+ console.log(' caws waivers create \\');
80
+ console.log(' --title="Emergency hotfix waiver" \\');
81
+ console.log(' --reason=emergency_hotfix \\');
82
+ console.log(' --description="Critical production bug requires immediate fix" \\');
83
+ console.log(' --gates=coverage,mutation \\');
84
+ console.log(' --expires-at=2025-12-31T23:59:59Z \\');
85
+ console.log(' --approved-by="@manager" \\');
86
+ console.log(' --impact-level=high \\');
87
+ console.log(' --mitigation-plan="Will add tests in follow-up PR within 48h"');
88
+ process.exit(1);
89
+ }
90
+
91
+ // Generate waiver ID
92
+ const waiverId = `WV-${Date.now().toString().slice(-4)}`;
93
+ const timestamp = new Date().toISOString();
94
+
95
+ // Parse gates
96
+ const gates = typeof options.gates === 'string'
97
+ ? options.gates.split(',').map(g => g.trim())
98
+ : options.gates;
99
+
100
+ // Create waiver object
101
+ const waiver = {
102
+ id: waiverId,
103
+ title: options.title,
104
+ reason: options.reason,
105
+ description: options.description,
106
+ gates: gates,
107
+ created_at: timestamp,
108
+ expires_at: options.expiresAt,
109
+ approved_by: options.approvedBy,
110
+ impact_level: options.impactLevel,
111
+ mitigation_plan: options.mitigationPlan,
112
+ status: 'active',
113
+ };
114
+
115
+ // Save waiver
116
+ const waiverPath = path.join(process.cwd(), WAIVER_DIR, `${waiverId}.yaml`);
117
+ fs.writeFileSync(waiverPath, yaml.dump(waiver, { lineWidth: -1 }));
118
+
119
+ console.log(chalk.green(`\n✅ Waiver created: ${waiverId}`));
120
+ console.log(` Title: ${waiver.title}`);
121
+ console.log(` Reason: ${waiver.reason}`);
122
+ console.log(` Gates: ${waiver.gates.join(', ')}`);
123
+ console.log(` Expires: ${waiver.expires_at}`);
124
+ console.log(` Approved by: ${waiver.approved_by}`);
125
+ console.log(` Impact: ${waiver.impact_level}`);
126
+ console.log(chalk.yellow(`\n⚠️ Remember: This waiver expires on ${waiver.expires_at}`));
127
+ console.log(chalk.yellow(`⚠️ Mitigation plan: ${waiver.mitigation_plan}\n`));
128
+ }
129
+
130
+ /**
131
+ * List all waivers
132
+ */
133
+ async function listWaivers(_options) {
134
+ const waiversDir = path.join(process.cwd(), WAIVER_DIR);
135
+
136
+ if (!fs.existsSync(waiversDir)) {
137
+ console.log(chalk.yellow('\nℹ️ No waivers found\n'));
138
+ return;
139
+ }
140
+
141
+ const waiverFiles = fs.readdirSync(waiversDir).filter(f => f.endsWith('.yaml'));
142
+
143
+ if (waiverFiles.length === 0) {
144
+ console.log(chalk.yellow('\nℹ️ No waivers found\n'));
145
+ return;
146
+ }
147
+
148
+ const waivers = waiverFiles.map(file => {
149
+ const content = fs.readFileSync(path.join(waiversDir, file), 'utf8');
150
+ return yaml.load(content);
151
+ });
152
+
153
+ // Filter by status
154
+ const activeWaivers = waivers.filter(w => w.status === 'active' && new Date(w.expires_at) > new Date());
155
+ const expiredWaivers = waivers.filter(w => w.status === 'active' && new Date(w.expires_at) <= new Date());
156
+ const revokedWaivers = waivers.filter(w => w.status === 'revoked');
157
+
158
+ console.log(chalk.blue('\n🔖 CAWS Quality Gate Waivers\n'));
159
+ console.log('─'.repeat(60));
160
+
161
+ if (activeWaivers.length > 0) {
162
+ console.log(chalk.green('\n✅ Active Waivers:\n'));
163
+ activeWaivers.forEach(waiver => {
164
+ const daysLeft = Math.ceil((new Date(waiver.expires_at) - new Date()) / (1000 * 60 * 60 * 24));
165
+ console.log(`🔖 ${chalk.bold(waiver.id)}: ${waiver.title}`);
166
+ console.log(` Reason: ${waiver.reason}`);
167
+ console.log(` Gates: ${waiver.gates.join(', ')}`);
168
+ console.log(` Expires: ${waiver.expires_at} (${daysLeft} days)`);
169
+ console.log(` Impact: ${waiver.impact_level}`);
170
+ console.log();
171
+ });
172
+ }
173
+
174
+ if (expiredWaivers.length > 0) {
175
+ console.log(chalk.yellow('\n⚠️ Expired Waivers:\n'));
176
+ expiredWaivers.forEach(waiver => {
177
+ console.log(`🔖 ${chalk.bold(waiver.id)}: ${waiver.title}`);
178
+ console.log(` Expired: ${waiver.expires_at}`);
179
+ console.log();
180
+ });
181
+ }
182
+
183
+ if (revokedWaivers.length > 0) {
184
+ console.log(chalk.red('\n❌ Revoked Waivers:\n'));
185
+ revokedWaivers.forEach(waiver => {
186
+ console.log(`🔖 ${chalk.bold(waiver.id)}: ${waiver.title}`);
187
+ console.log(` Revoked: ${waiver.revoked_at}`);
188
+ console.log();
189
+ });
190
+ }
191
+
192
+ console.log(chalk.blue('📊 Summary:\n'));
193
+ console.log(` Active: ${activeWaivers.length}`);
194
+ console.log(` Expired: ${expiredWaivers.length}`);
195
+ console.log(` Revoked: ${revokedWaivers.length}`);
196
+ console.log(` Total: ${waivers.length}\n`);
197
+ }
198
+
199
+ /**
200
+ * Show waiver details
201
+ */
202
+ async function showWaiver(waiverId, _options) {
203
+ if (!waiverId) {
204
+ console.error(chalk.red('\n❌ Waiver ID required'));
205
+ console.log(chalk.yellow('💡 Usage: caws waivers show WV-1234\n'));
206
+ process.exit(1);
207
+ }
208
+
209
+ const waiverPath = path.join(process.cwd(), WAIVER_DIR, `${waiverId}.yaml`);
210
+
211
+ if (!fs.existsSync(waiverPath)) {
212
+ console.error(chalk.red(`\n❌ Waiver not found: ${waiverId}\n`));
213
+ process.exit(1);
214
+ }
215
+
216
+ const content = fs.readFileSync(waiverPath, 'utf8');
217
+ const waiver = yaml.load(content);
218
+
219
+ const isExpired = new Date(waiver.expires_at) <= new Date();
220
+ const isActive = waiver.status === 'active' && !isExpired;
221
+ const statusIcon = isActive ? '✅' : isExpired ? '⚠️' : '❌';
222
+
223
+ console.log(chalk.blue('\n🔖 Waiver Details\n'));
224
+ console.log('─'.repeat(60));
225
+ console.log(`\n${statusIcon} Status: ${chalk.bold(isActive ? 'Active' : isExpired ? 'Expired' : waiver.status)}`);
226
+ console.log(`\n📋 ${chalk.bold(waiver.title)}`);
227
+ console.log(` ID: ${waiver.id}`);
228
+ console.log(` Reason: ${waiver.reason}`);
229
+ console.log(` Impact Level: ${waiver.impact_level}`);
230
+ console.log(`\n📝 Description:`);
231
+ console.log(` ${waiver.description}`);
232
+ console.log(`\n🔒 Waived Quality Gates:`);
233
+ waiver.gates.forEach(gate => {
234
+ console.log(` • ${gate}`);
235
+ });
236
+ console.log(`\n🛡️ Mitigation Plan:`);
237
+ console.log(` ${waiver.mitigation_plan}`);
238
+ console.log(`\n📅 Timeline:`);
239
+ console.log(` Created: ${waiver.created_at}`);
240
+ console.log(` Expires: ${waiver.expires_at}`);
241
+ if (waiver.revoked_at) {
242
+ console.log(` Revoked: ${waiver.revoked_at}`);
243
+ }
244
+ console.log(`\n✍️ Approved by: ${waiver.approved_by}\n`);
245
+
246
+ if (isExpired && waiver.status === 'active') {
247
+ console.log(chalk.yellow('⚠️ This waiver has expired. Consider revoking it.\n'));
248
+ }
249
+ }
250
+
251
+ /**
252
+ * Revoke a waiver
253
+ */
254
+ async function revokeWaiver(waiverId, options) {
255
+ if (!waiverId) {
256
+ console.error(chalk.red('\n❌ Waiver ID required'));
257
+ console.log(chalk.yellow('💡 Usage: caws waivers revoke WV-1234\n'));
258
+ process.exit(1);
259
+ }
260
+
261
+ const waiverPath = path.join(process.cwd(), WAIVER_DIR, `${waiverId}.yaml`);
262
+
263
+ if (!fs.existsSync(waiverPath)) {
264
+ console.error(chalk.red(`\n❌ Waiver not found: ${waiverId}\n`));
265
+ process.exit(1);
266
+ }
267
+
268
+ const content = fs.readFileSync(waiverPath, 'utf8');
269
+ const waiver = yaml.load(content);
270
+
271
+ if (waiver.status === 'revoked') {
272
+ console.log(chalk.yellow(`\nℹ️ Waiver ${waiverId} is already revoked\n`));
273
+ return;
274
+ }
275
+
276
+ // Update waiver status
277
+ waiver.status = 'revoked';
278
+ waiver.revoked_at = new Date().toISOString();
279
+ waiver.revoked_by = options.revokedBy || 'system';
280
+ waiver.revocation_reason = options.reason || 'Manual revocation';
281
+
282
+ // Save updated waiver
283
+ fs.writeFileSync(waiverPath, yaml.dump(waiver, { lineWidth: -1 }));
284
+
285
+ console.log(chalk.green(`\n✅ Waiver revoked: ${waiverId}`));
286
+ console.log(` Title: ${waiver.title}`);
287
+ console.log(` Revoked at: ${waiver.revoked_at}`);
288
+ console.log(` Revoked by: ${waiver.revoked_by}`);
289
+ console.log(` Reason: ${waiver.revocation_reason}\n`);
290
+ }
291
+
292
+ module.exports = { waiversCommand };
293
+
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Workflow command handler
3
+ *
4
+ * @param {string} workflowType - Type of workflow
5
+ * @param {object} options - Command options
6
+ */
7
+ export function workflowCommand(workflowType: string, options?: object): Promise<void>;
8
+ /**
9
+ * Generate workflow guidance
10
+ *
11
+ * @param {string} workflowType - Type of workflow (tdd, refactor, feature)
12
+ * @param {number} currentStep - Current step number (1-based)
13
+ * @param {object} context - Optional context information
14
+ * @returns {object} Workflow guidance
15
+ */
16
+ export function generateWorkflowGuidance(workflowType: string, currentStep: number, context?: object): object;
17
+ export namespace WORKFLOW_TEMPLATES {
18
+ namespace tdd {
19
+ let name: string;
20
+ let steps: string[];
21
+ let guidance: {
22
+ 1: string;
23
+ 2: string;
24
+ 3: string;
25
+ 4: string;
26
+ 5: string;
27
+ 6: string;
28
+ };
29
+ let recommendations: {
30
+ 1: string[];
31
+ 2: string[];
32
+ 3: string[];
33
+ 4: string[];
34
+ 5: string[];
35
+ 6: string[];
36
+ };
37
+ }
38
+ namespace refactor {
39
+ let name_1: string;
40
+ export { name_1 as name };
41
+ let steps_1: string[];
42
+ export { steps_1 as steps };
43
+ let guidance_1: {
44
+ 1: string;
45
+ 2: string;
46
+ 3: string;
47
+ 4: string;
48
+ 5: string;
49
+ };
50
+ export { guidance_1 as guidance };
51
+ let recommendations_1: {
52
+ 1: string[];
53
+ 2: string[];
54
+ 3: string[];
55
+ 4: string[];
56
+ 5: string[];
57
+ };
58
+ export { recommendations_1 as recommendations };
59
+ }
60
+ namespace feature {
61
+ let name_2: string;
62
+ export { name_2 as name };
63
+ let steps_2: string[];
64
+ export { steps_2 as steps };
65
+ let guidance_2: {
66
+ 1: string;
67
+ 2: string;
68
+ 3: string;
69
+ 4: string;
70
+ 5: string;
71
+ 6: string;
72
+ };
73
+ export { guidance_2 as guidance };
74
+ let recommendations_2: {
75
+ 1: string[];
76
+ 2: string[];
77
+ 3: string[];
78
+ 4: string[];
79
+ 5: string[];
80
+ 6: string[];
81
+ };
82
+ export { recommendations_2 as recommendations };
83
+ }
84
+ }
85
+ //# sourceMappingURL=workflow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow.d.ts","sourceRoot":"","sources":["../../src/commands/workflow.js"],"names":[],"mappings":"AA2IA;;;;;GAKG;AACH,8CAHW,MAAM,YACN,MAAM,iBA6FhB;AA7ID;;;;;;;GAOG;AACH,uDALW,MAAM,eACN,MAAM,YACN,MAAM,GACJ,MAAM,CAoClB"}