@paths.design/caws-cli 3.0.0 → 3.1.1

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 (95) hide show
  1. package/README.md +295 -150
  2. package/dist/budget-derivation.d.ts +35 -0
  3. package/dist/budget-derivation.d.ts.map +1 -0
  4. package/dist/budget-derivation.js +204 -0
  5. package/dist/cicd-optimizer.d.ts +142 -0
  6. package/dist/cicd-optimizer.d.ts.map +1 -0
  7. package/dist/cicd-optimizer.js +504 -0
  8. package/dist/commands/burnup.d.ts +6 -0
  9. package/dist/commands/burnup.d.ts.map +1 -0
  10. package/dist/commands/burnup.js +90 -0
  11. package/dist/commands/init.d.ts +5 -0
  12. package/dist/commands/init.d.ts.map +1 -0
  13. package/dist/commands/init.js +514 -0
  14. package/dist/commands/provenance.d.ts +22 -0
  15. package/dist/commands/provenance.d.ts.map +1 -0
  16. package/dist/commands/provenance.js +594 -0
  17. package/dist/commands/tool.d.ts +13 -0
  18. package/dist/commands/tool.d.ts.map +1 -0
  19. package/dist/commands/tool.js +138 -0
  20. package/dist/commands/validate.d.ts +7 -0
  21. package/dist/commands/validate.d.ts.map +1 -0
  22. package/dist/commands/validate.js +80 -0
  23. package/dist/config/index.d.ts +29 -0
  24. package/dist/config/index.d.ts.map +1 -0
  25. package/dist/config/index.js +132 -0
  26. package/dist/error-handler.d.ts +50 -0
  27. package/dist/error-handler.d.ts.map +1 -0
  28. package/dist/error-handler.js +253 -0
  29. package/dist/generators/working-spec.d.ts +13 -0
  30. package/dist/generators/working-spec.d.ts.map +1 -0
  31. package/dist/generators/working-spec.js +204 -0
  32. package/dist/index-new.d.ts +5 -0
  33. package/dist/index-new.d.ts.map +1 -0
  34. package/dist/index-new.js +317 -0
  35. package/dist/index.d.ts +3 -12
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +100 -1659
  38. package/dist/index.js.backup +4711 -0
  39. package/dist/scaffold/cursor-hooks.d.ts +7 -0
  40. package/dist/scaffold/cursor-hooks.d.ts.map +1 -0
  41. package/dist/scaffold/cursor-hooks.js +152 -0
  42. package/dist/scaffold/index.d.ts +20 -0
  43. package/dist/scaffold/index.d.ts.map +1 -0
  44. package/dist/scaffold/index.js +486 -0
  45. package/dist/test-analysis.d.ts +182 -0
  46. package/dist/test-analysis.d.ts.map +1 -0
  47. package/dist/test-analysis.js +580 -0
  48. package/dist/tool-interface.d.ts +236 -0
  49. package/dist/tool-interface.d.ts.map +1 -0
  50. package/dist/tool-interface.js +314 -0
  51. package/dist/tool-loader.d.ts +77 -0
  52. package/dist/tool-loader.d.ts.map +1 -0
  53. package/dist/tool-loader.js +298 -0
  54. package/dist/tool-validator.d.ts +72 -0
  55. package/dist/tool-validator.d.ts.map +1 -0
  56. package/dist/tool-validator.js +387 -0
  57. package/dist/utils/detection.d.ts +7 -0
  58. package/dist/utils/detection.d.ts.map +1 -0
  59. package/dist/utils/detection.js +174 -0
  60. package/dist/utils/finalization.d.ts +17 -0
  61. package/dist/utils/finalization.d.ts.map +1 -0
  62. package/dist/utils/finalization.js +229 -0
  63. package/dist/utils/project-analysis.d.ts +14 -0
  64. package/dist/utils/project-analysis.d.ts.map +1 -0
  65. package/dist/utils/project-analysis.js +105 -0
  66. package/dist/validation/spec-validation.d.ts +29 -0
  67. package/dist/validation/spec-validation.d.ts.map +1 -0
  68. package/dist/validation/spec-validation.js +376 -0
  69. package/dist/waivers-manager.d.ts +167 -0
  70. package/dist/waivers-manager.d.ts.map +1 -0
  71. package/dist/waivers-manager.js +549 -0
  72. package/package.json +10 -12
  73. package/templates/.cursor/README.md +311 -0
  74. package/templates/.cursor/hooks/audit.sh +55 -0
  75. package/templates/.cursor/hooks/block-dangerous.sh +77 -0
  76. package/templates/.cursor/hooks/caws-quality-check.sh +52 -0
  77. package/templates/.cursor/hooks/caws-scope-guard.sh +74 -0
  78. package/templates/.cursor/hooks/caws-tool-validation.sh +121 -0
  79. package/templates/.cursor/hooks/format.sh +38 -0
  80. package/templates/.cursor/hooks/naming-check.sh +64 -0
  81. package/templates/.cursor/hooks/scan-secrets.sh +46 -0
  82. package/templates/.cursor/hooks/scope-guard.sh +52 -0
  83. package/templates/.cursor/hooks/validate-spec.sh +38 -0
  84. package/templates/.cursor/hooks.json +59 -0
  85. package/templates/.github/copilot/instructions.md +311 -0
  86. package/templates/.idea/runConfigurations/CAWS_Evaluate.xml +5 -0
  87. package/templates/.idea/runConfigurations/CAWS_Validate.xml +5 -0
  88. package/templates/.vscode/launch.json +56 -0
  89. package/templates/.vscode/settings.json +93 -0
  90. package/templates/.windsurf/workflows/caws-guided-development.md +92 -0
  91. package/templates/apps/tools/caws/README.md +1 -1
  92. package/templates/apps/tools/caws/prompt-lint.js.backup +274 -0
  93. package/templates/apps/tools/caws/provenance.js.backup +73 -0
  94. package/templates/apps/tools/caws/schemas/working-spec.schema.json +21 -3
  95. package/templates/codemod/test.js +93 -1
@@ -0,0 +1,204 @@
1
+ /**
2
+ * @fileoverview Budget Derivation Logic
3
+ * Derives budgets from policy.yaml and applies waivers
4
+ * @author @darianrosebrook
5
+ */
6
+
7
+ const fs = require('fs-extra');
8
+ const path = require('path');
9
+ const yaml = require('js-yaml');
10
+
11
+ /**
12
+ * Derive budget for a working spec based on policy and waivers
13
+ * @param {Object} spec - Working spec object
14
+ * @param {string} projectRoot - Project root directory
15
+ * @returns {Object} Derived budget with baseline and effective limits
16
+ */
17
+ function deriveBudget(spec, projectRoot = process.cwd()) {
18
+ try {
19
+ // Load policy.yaml
20
+ const policyPath = path.join(projectRoot, '.caws', 'policy.yaml');
21
+ if (!fs.existsSync(policyPath)) {
22
+ throw new Error('Policy file not found: .caws/policy.yaml');
23
+ }
24
+
25
+ const policy = yaml.load(fs.readFileSync(policyPath, 'utf8'));
26
+
27
+ // Validate policy structure
28
+ if (!policy.risk_tiers || !policy.risk_tiers[spec.risk_tier]) {
29
+ throw new Error(`Risk tier ${spec.risk_tier} not defined in policy.yaml`);
30
+ }
31
+
32
+ const tierBudget = policy.risk_tiers[spec.risk_tier];
33
+ const baseline = {
34
+ max_files: tierBudget.max_files,
35
+ max_loc: tierBudget.max_loc
36
+ };
37
+
38
+ // Start with baseline budget
39
+ let effectiveBudget = { ...baseline };
40
+
41
+ // Apply waivers if any
42
+ if (spec.waiver_ids && Array.isArray(spec.waiver_ids)) {
43
+ for (const waiverId of spec.waiver_ids) {
44
+ const waiver = loadWaiver(waiverId, projectRoot);
45
+ if (waiver && waiver.status === 'active' && isWaiverValid(waiver)) {
46
+ // Apply additive deltas
47
+ if (waiver.delta) {
48
+ if (waiver.delta.max_files) {
49
+ effectiveBudget.max_files += waiver.delta.max_files;
50
+ }
51
+ if (waiver.delta.max_loc) {
52
+ effectiveBudget.max_loc += waiver.delta.max_loc;
53
+ }
54
+ }
55
+ }
56
+ }
57
+ }
58
+
59
+ return {
60
+ baseline,
61
+ effective: effectiveBudget,
62
+ waivers_applied: spec.waiver_ids || [],
63
+ derived_at: new Date().toISOString()
64
+ };
65
+
66
+ } catch (error) {
67
+ throw new Error(`Budget derivation failed: ${error.message}`);
68
+ }
69
+ }
70
+
71
+ /**
72
+ * Load a waiver by ID
73
+ * @param {string} waiverId - Waiver ID (e.g., WV-0001)
74
+ * @param {string} projectRoot - Project root directory
75
+ * @returns {Object|null} Waiver object or null if not found
76
+ */
77
+ function loadWaiver(waiverId, projectRoot) {
78
+ try {
79
+ const waiverPath = path.join(projectRoot, '.caws', 'waivers', `${waiverId}.yaml`);
80
+ if (!fs.existsSync(waiverPath)) {
81
+ console.warn(`Waiver file not found: ${waiverPath}`);
82
+ return null;
83
+ }
84
+
85
+ const waiver = yaml.load(fs.readFileSync(waiverPath, 'utf8'));
86
+ return waiver;
87
+ } catch (error) {
88
+ console.warn(`Failed to load waiver ${waiverId}: ${error.message}`);
89
+ return null;
90
+ }
91
+ }
92
+
93
+ /**
94
+ * Check if a waiver is currently valid
95
+ * @param {Object} waiver - Waiver object
96
+ * @returns {boolean} Whether waiver is valid and active
97
+ */
98
+ function isWaiverValid(waiver) {
99
+ try {
100
+ // Check if expired
101
+ if (waiver.expires_at) {
102
+ const expiryDate = new Date(waiver.expires_at);
103
+ const now = new Date();
104
+ if (now > expiryDate) {
105
+ return false;
106
+ }
107
+ }
108
+
109
+ // Check status
110
+ if (waiver.status !== 'active') {
111
+ return false;
112
+ }
113
+
114
+ // Check if it has required approvals (simplified check)
115
+ if (!waiver.approvers || waiver.approvers.length === 0) {
116
+ return false;
117
+ }
118
+
119
+ return true;
120
+ } catch (error) {
121
+ console.warn(`Waiver validation error: ${error.message}`);
122
+ return false;
123
+ }
124
+ }
125
+
126
+ /**
127
+ * Check if current changes exceed derived budget
128
+ * @param {Object} derivedBudget - Budget from deriveBudget()
129
+ * @param {Object} currentStats - Current change statistics
130
+ * @returns {Object} Budget check result
131
+ */
132
+ function checkBudgetCompliance(derivedBudget, currentStats) {
133
+ const violations = [];
134
+
135
+ if (currentStats.files_changed > derivedBudget.effective.max_files) {
136
+ violations.push({
137
+ gate: 'budget_limit',
138
+ type: 'max_files',
139
+ current: currentStats.files_changed,
140
+ limit: derivedBudget.effective.max_files,
141
+ baseline: derivedBudget.baseline.max_files,
142
+ message: `File count (${currentStats.files_changed}) exceeds budget (${derivedBudget.effective.max_files})`
143
+ });
144
+ }
145
+
146
+ if (currentStats.lines_changed > derivedBudget.effective.max_loc) {
147
+ violations.push({
148
+ gate: 'budget_limit',
149
+ type: 'max_loc',
150
+ current: currentStats.lines_changed,
151
+ limit: derivedBudget.effective.max_loc,
152
+ baseline: derivedBudget.baseline.max_loc,
153
+ message: `Lines of code (${currentStats.lines_changed}) exceed budget (${derivedBudget.effective.max_loc})`
154
+ });
155
+ }
156
+
157
+ return {
158
+ compliant: violations.length === 0,
159
+ violations,
160
+ budget: derivedBudget
161
+ };
162
+ }
163
+
164
+ /**
165
+ * Generate burn-up report for scope visibility
166
+ * @param {Object} derivedBudget - Budget from deriveBudget()
167
+ * @param {Object} currentStats - Current change statistics
168
+ * @returns {string} Human-readable burn-up report
169
+ */
170
+ function generateBurnupReport(derivedBudget, currentStats) {
171
+ const report = [
172
+ '📊 CAWS Budget Burn-up Report',
173
+ '===============================',
174
+ '',
175
+ `Risk Tier: ${currentStats.risk_tier}`,
176
+ `Baseline: ${derivedBudget.baseline.max_files} files, ${derivedBudget.baseline.max_loc} LOC`,
177
+ `Current: ${currentStats.files_changed} files, ${currentStats.lines_changed} LOC`,
178
+ ];
179
+
180
+ if (derivedBudget.waivers_applied.length > 0) {
181
+ report.push(`Waivers Applied: ${derivedBudget.waivers_applied.join(', ')}`);
182
+ report.push(`Effective Budget: ${derivedBudget.effective.max_files} files, ${derivedBudget.effective.max_loc} LOC`);
183
+ }
184
+
185
+ const filePercent = Math.round((currentStats.files_changed / derivedBudget.effective.max_files) * 100);
186
+ const locPercent = Math.round((currentStats.lines_changed / derivedBudget.effective.max_loc) * 100);
187
+
188
+ report.push(`File Usage: ${filePercent}% (${currentStats.files_changed}/${derivedBudget.effective.max_files})`);
189
+ report.push(`LOC Usage: ${locPercent}% (${currentStats.lines_changed}/${derivedBudget.effective.max_loc})`);
190
+
191
+ if (filePercent > 90 || locPercent > 90) {
192
+ report.push('', '⚠️ WARNING: Approaching budget limits');
193
+ }
194
+
195
+ return report.join('\n');
196
+ }
197
+
198
+ module.exports = {
199
+ deriveBudget,
200
+ loadWaiver,
201
+ isWaiverValid,
202
+ checkBudgetCompliance,
203
+ generateBurnupReport
204
+ };
@@ -0,0 +1,142 @@
1
+ export = CICDOptimizer;
2
+ declare class CICDOptimizer {
3
+ constructor(options?: {});
4
+ projectRoot: any;
5
+ cacheDir: string;
6
+ optimizationConfig: string;
7
+ /**
8
+ * Analyze project and generate CI/CD optimization recommendations
9
+ */
10
+ analyzeProject(specPath?: string): Promise<{
11
+ project_tier: string;
12
+ recommended_optimizations: any[];
13
+ cache_strategy: {};
14
+ parallel_groups: any[];
15
+ conditional_execution: {};
16
+ estimated_savings: {};
17
+ }>;
18
+ /**
19
+ * Generate tier-based conditional execution rules
20
+ */
21
+ generateConditionalExecutionRules(tier: any): {
22
+ coverage_required: boolean;
23
+ mutation_required: boolean;
24
+ contract_testing: boolean;
25
+ accessibility_check: boolean;
26
+ performance_budget: boolean;
27
+ security_scan: boolean;
28
+ lint_strict: boolean;
29
+ };
30
+ /**
31
+ * Analyze what optimizations are beneficial for this tier
32
+ */
33
+ analyzeOptimizationOpportunities(tier: any): Promise<{
34
+ type: string;
35
+ description: string;
36
+ impact: string;
37
+ effort: string;
38
+ }[]>;
39
+ /**
40
+ * Generate intelligent caching strategy
41
+ */
42
+ generateCacheStrategy(): Promise<{
43
+ node_modules: {
44
+ key: string;
45
+ paths: string[];
46
+ restore_keys: string[];
47
+ };
48
+ build_artifacts: {
49
+ key: string;
50
+ paths: string[];
51
+ restore_keys: any[];
52
+ };
53
+ test_cache: {
54
+ key: string;
55
+ paths: string[];
56
+ restore_keys: string[];
57
+ };
58
+ }>;
59
+ /**
60
+ * Create parallel execution groups for quality gates
61
+ */
62
+ createParallelGroups(): Promise<{
63
+ name: string;
64
+ description: string;
65
+ jobs: string[];
66
+ max_parallel: number;
67
+ timeout: number;
68
+ }[]>;
69
+ /**
70
+ * Analyze changed files to determine what tests to run
71
+ */
72
+ analyzeChangedFiles(changedFiles?: any[]): Promise<{
73
+ unit: any[];
74
+ integration: any[];
75
+ contract: any[];
76
+ e2e: any[];
77
+ }>;
78
+ /**
79
+ * Estimate time savings from optimizations
80
+ */
81
+ estimateTimeSavings(analysis: any): {
82
+ original_minutes: any;
83
+ optimized_minutes: number;
84
+ savings_percent: number;
85
+ monthly_savings_hours: number;
86
+ };
87
+ /**
88
+ * Generate optimized CI/CD configuration
89
+ */
90
+ generateOptimizedConfig(platform?: string): Promise<string | {
91
+ name: string;
92
+ on: {
93
+ push: {
94
+ branches: string[];
95
+ };
96
+ pull_request: {
97
+ branches: string[];
98
+ };
99
+ };
100
+ jobs: {};
101
+ } | {
102
+ stages: string[];
103
+ cache: {
104
+ key: string;
105
+ paths: string[];
106
+ };
107
+ }>;
108
+ /**
109
+ * Generate optimized GitHub Actions workflow
110
+ */
111
+ generateGitHubActionsConfig(analysis: any): {
112
+ name: string;
113
+ on: {
114
+ push: {
115
+ branches: string[];
116
+ };
117
+ pull_request: {
118
+ branches: string[];
119
+ };
120
+ };
121
+ jobs: {};
122
+ };
123
+ /**
124
+ * Generate GitLab CI configuration
125
+ */
126
+ generateGitLabCIConfig(analysis: any): {
127
+ stages: string[];
128
+ cache: {
129
+ key: string;
130
+ paths: string[];
131
+ };
132
+ };
133
+ /**
134
+ * Generate Jenkins pipeline configuration
135
+ */
136
+ generateJenkinsConfig(analysis: any): string;
137
+ /**
138
+ * Create hash for cache invalidation
139
+ */
140
+ createCacheHash(files: any): string;
141
+ }
142
+ //# sourceMappingURL=cicd-optimizer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cicd-optimizer.d.ts","sourceRoot":"","sources":["../src/cicd-optimizer.js"],"names":[],"mappings":";AAaA;IACE,0BASC;IARC,iBAAuD;IACvD,iBAA6D;IAC7D,2BAAkF;IAQpF;;OAEG;IACH;;;;;;;OAyCC;IAED;;OAEG;IACH;;;;;;;;MAyBC;IAED;;OAEG;IACH;;;;;SA6CC;IAED;;OAEG;IACH;;;;;;;;;;;;;;;;OA8CC;IAED;;OAEG;IACH;;;;;;SA0BC;IAED;;OAEG;IACH;;;;;OA2BC;IAED;;OAEG;IACH;;;;;MA+BC;IAED;;OAEG;IACH;;;;;;;;;;;;;;;;;OAYC;IAED;;OAEG;IACH;;;;;;;;;;;MA4EC;IAED;;OAEG;IACH;;;;;;MAiCC;IAED;;OAEG;IACH,6CA+CC;IAED;;OAEG;IACH,oCAQC;CACF"}