@paths.design/caws-cli 3.5.0 โ†’ 4.1.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 (87) hide show
  1. package/dist/budget-derivation.d.ts +41 -2
  2. package/dist/budget-derivation.d.ts.map +1 -1
  3. package/dist/budget-derivation.js +417 -30
  4. package/dist/commands/archive.d.ts +50 -0
  5. package/dist/commands/archive.d.ts.map +1 -0
  6. package/dist/commands/archive.js +353 -0
  7. package/dist/commands/iterate.d.ts.map +1 -1
  8. package/dist/commands/iterate.js +12 -13
  9. package/dist/commands/mode.d.ts +24 -0
  10. package/dist/commands/mode.d.ts.map +1 -0
  11. package/dist/commands/mode.js +259 -0
  12. package/dist/commands/plan.d.ts +49 -0
  13. package/dist/commands/plan.d.ts.map +1 -0
  14. package/dist/commands/plan.js +448 -0
  15. package/dist/commands/quality-gates.d.ts +52 -0
  16. package/dist/commands/quality-gates.d.ts.map +1 -0
  17. package/dist/commands/quality-gates.js +490 -0
  18. package/dist/commands/specs.d.ts +71 -0
  19. package/dist/commands/specs.d.ts.map +1 -0
  20. package/dist/commands/specs.js +735 -0
  21. package/dist/commands/status.d.ts +4 -3
  22. package/dist/commands/status.d.ts.map +1 -1
  23. package/dist/commands/status.js +552 -22
  24. package/dist/commands/tutorial.d.ts +55 -0
  25. package/dist/commands/tutorial.d.ts.map +1 -0
  26. package/dist/commands/tutorial.js +481 -0
  27. package/dist/commands/validate.d.ts +10 -2
  28. package/dist/commands/validate.d.ts.map +1 -1
  29. package/dist/commands/validate.js +199 -39
  30. package/dist/config/modes.d.ts +225 -0
  31. package/dist/config/modes.d.ts.map +1 -0
  32. package/dist/config/modes.js +321 -0
  33. package/dist/constants/spec-types.d.ts +41 -0
  34. package/dist/constants/spec-types.d.ts.map +1 -0
  35. package/dist/constants/spec-types.js +42 -0
  36. package/dist/index-new.d.ts +5 -0
  37. package/dist/index-new.d.ts.map +1 -0
  38. package/dist/index-new.js +317 -0
  39. package/dist/index.js +227 -10
  40. package/dist/index.js.backup +4711 -0
  41. package/dist/policy/PolicyManager.d.ts +104 -0
  42. package/dist/policy/PolicyManager.d.ts.map +1 -0
  43. package/dist/policy/PolicyManager.js +399 -0
  44. package/dist/scaffold/cursor-hooks.d.ts.map +1 -1
  45. package/dist/scaffold/cursor-hooks.js +15 -0
  46. package/dist/scaffold/git-hooks.d.ts.map +1 -1
  47. package/dist/scaffold/git-hooks.js +32 -44
  48. package/dist/scaffold/index.d.ts.map +1 -1
  49. package/dist/scaffold/index.js +19 -0
  50. package/dist/spec/SpecFileManager.d.ts +146 -0
  51. package/dist/spec/SpecFileManager.d.ts.map +1 -0
  52. package/dist/spec/SpecFileManager.js +419 -0
  53. package/dist/utils/quality-gates-errors.js +520 -0
  54. package/dist/utils/quality-gates.d.ts +49 -0
  55. package/dist/utils/quality-gates.d.ts.map +1 -0
  56. package/dist/utils/quality-gates.js +361 -0
  57. package/dist/utils/spec-resolver.d.ts +88 -0
  58. package/dist/utils/spec-resolver.d.ts.map +1 -0
  59. package/dist/utils/spec-resolver.js +602 -0
  60. package/dist/validation/spec-validation.d.ts +14 -0
  61. package/dist/validation/spec-validation.d.ts.map +1 -1
  62. package/dist/validation/spec-validation.js +225 -13
  63. package/package.json +6 -5
  64. package/templates/.cursor/hooks/caws-scope-guard.sh +64 -8
  65. package/templates/.cursor/hooks/validate-spec.sh +22 -12
  66. package/templates/.cursor/rules/00-claims-verification.mdc +144 -0
  67. package/templates/.cursor/rules/01-working-style.mdc +50 -0
  68. package/templates/.cursor/rules/02-quality-gates.mdc +370 -0
  69. package/templates/.cursor/rules/03-naming-and-refactor.mdc +33 -0
  70. package/templates/.cursor/rules/04-logging-language-style.mdc +23 -0
  71. package/templates/.cursor/rules/05-safe-defaults-guards.mdc +23 -0
  72. package/templates/.cursor/rules/06-typescript-conventions.mdc +36 -0
  73. package/templates/.cursor/rules/07-process-ops.mdc +20 -0
  74. package/templates/.cursor/rules/08-solid-and-architecture.mdc +16 -0
  75. package/templates/.cursor/rules/09-docstrings.mdc +89 -0
  76. package/templates/.cursor/rules/10-authorship-and-attribution.mdc +15 -0
  77. package/templates/.cursor/rules/11-documentation-quality-standards.mdc +390 -0
  78. package/templates/.cursor/rules/12-scope-management-waivers.mdc +385 -0
  79. package/templates/.cursor/rules/13-implementation-completeness.mdc +516 -0
  80. package/templates/.cursor/rules/14-language-agnostic-standards.mdc +588 -0
  81. package/templates/.cursor/rules/15-sophisticated-todo-detection.mdc +425 -0
  82. package/templates/.cursor/rules/README.md +150 -0
  83. package/templates/apps/tools/caws/prompt-lint.js.backup +274 -0
  84. package/templates/apps/tools/caws/provenance.js.backup +73 -0
  85. package/templates/scripts/quality-gates/check-god-objects.js +146 -0
  86. package/templates/scripts/quality-gates/run-quality-gates.js +50 -0
  87. package/templates/scripts/v3/analysis/todo_analyzer.py +1950 -0
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Policy Manager - Handles policy loading with intelligent caching
3
+ *
4
+ * Features:
5
+ * - TTL-based caching for performance
6
+ * - Graceful fallback to defaults when policy.yaml missing
7
+ * - Cache inspection and management API
8
+ * - Waiver validation and delta application
9
+ */
10
+ export class PolicyManager {
11
+ constructor(options?: {});
12
+ enableCaching: any;
13
+ cacheTTL: any;
14
+ policyCache: Map<any, any>;
15
+ /**
16
+ * Load CAWS policy from policy.yaml with caching
17
+ *
18
+ * @param {string} projectRoot - Project root directory
19
+ * @param {Object} options - Loading options
20
+ * @param {boolean} options.useCache - Use cache if available (default: true)
21
+ * @param {number} options.cacheTTL - Cache TTL override in milliseconds
22
+ * @returns {Promise<Object>} Policy object
23
+ */
24
+ loadPolicy(projectRoot: string, options?: {
25
+ useCache: boolean;
26
+ cacheTTL: number;
27
+ }): Promise<any>;
28
+ /**
29
+ * Load a waiver document by ID
30
+ *
31
+ * @param {string} waiverId - Waiver ID (e.g., WV-0001)
32
+ * @param {string} projectRoot - Project root directory
33
+ * @returns {Promise<Object|null>} Waiver document or null if not found
34
+ */
35
+ loadWaiver(waiverId: string, projectRoot: string): Promise<any | null>;
36
+ /**
37
+ * Check if a waiver is currently valid
38
+ *
39
+ * @param {Object} waiver - Waiver document
40
+ * @returns {boolean} True if waiver is valid and active
41
+ */
42
+ isWaiverValid(waiver: any): boolean;
43
+ /**
44
+ * Apply waivers to baseline budget
45
+ *
46
+ * @param {Object} baseline - Baseline budget from policy
47
+ * @param {string[]} waiverIds - Array of waiver IDs to apply
48
+ * @param {string} projectRoot - Project root directory
49
+ * @returns {Promise<Object>} Effective budget with waivers applied
50
+ */
51
+ applyWaivers(baseline: any, waiverIds: string[], projectRoot: string): Promise<any>;
52
+ /**
53
+ * Validate policy structure
54
+ *
55
+ * @param {Object} policy - Policy to validate
56
+ * @throws {Error} If policy is invalid
57
+ */
58
+ validatePolicy(policy: any): void;
59
+ /**
60
+ * Get default CAWS policy
61
+ *
62
+ * Returns sensible defaults when policy.yaml doesn't exist.
63
+ *
64
+ * @returns {Object} Default policy configuration
65
+ */
66
+ getDefaultPolicy(): any;
67
+ /**
68
+ * Clear policy cache
69
+ *
70
+ * @param {string} [projectRoot] - Specific project to clear, or all if omitted
71
+ */
72
+ clearCache(projectRoot?: string): void;
73
+ /**
74
+ * Get cache status for a project
75
+ *
76
+ * @param {string} projectRoot - Project root directory
77
+ * @returns {Object} Cache status information
78
+ */
79
+ getCacheStatus(projectRoot: string): any;
80
+ /**
81
+ * Reload policy from disk (bypassing cache)
82
+ *
83
+ * @param {string} projectRoot - Project root directory
84
+ * @returns {Promise<Object>} Fresh policy
85
+ */
86
+ reloadPolicy(projectRoot: string): Promise<any>;
87
+ /**
88
+ * Get all cached projects
89
+ *
90
+ * @returns {string[]} Array of project roots with cached policies
91
+ */
92
+ getCachedProjects(): string[];
93
+ /**
94
+ * Get cache statistics
95
+ *
96
+ * @returns {Object} Cache statistics
97
+ */
98
+ getCacheStats(): any;
99
+ }
100
+ export const defaultPolicyManager: PolicyManager;
101
+ export declare function loadPolicy(projectRoot: any, options: any): Promise<any>;
102
+ export declare function clearCache(projectRoot: any): void;
103
+ export declare function getCacheStatus(projectRoot: any): any;
104
+ //# sourceMappingURL=PolicyManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PolicyManager.d.ts","sourceRoot":"","sources":["../../src/policy/PolicyManager.js"],"names":[],"mappings":"AAWA;;;;;;;;GAQG;AACH;IACE,0BAIC;IAHC,mBAAkD;IAClD,cAA0C;IAC1C,2BAA4B;IAG9B;;;;;;;;OAQG;IACH,wBANW,MAAM,YAEd;QAAyB,QAAQ,EAAzB,OAAO;QACS,QAAQ,EAAxB,MAAM;KACd,GAAU,OAAO,KAAQ,CAuE3B;IAED;;;;;;OAMG;IACH,qBAJW,MAAM,eACN,MAAM,GACJ,OAAO,CAAC,MAAO,IAAI,CAAC,CAchC;IAED;;;;;OAKG;IACH,4BAFa,OAAO,CA2BnB;IAED;;;;;;;OAOG;IACH,uCAJW,MAAM,EAAE,eACR,MAAM,GACJ,OAAO,KAAQ,CA2B3B;IAED;;;;;OAKG;IACH,kCA8BC;IAED;;;;;;OAMG;IACH,wBAoDC;IAED;;;;OAIG;IACH,yBAFW,MAAM,QAQhB;IAED;;;;;OAKG;IACH,4BAHW,MAAM,OAmBhB;IAED;;;;;OAKG;IACH,0BAHW,MAAM,GACJ,OAAO,KAAQ,CAK3B;IAED;;;;OAIG;IACH,qBAFa,MAAM,EAAE,CAIpB;IAED;;;;OAIG;IACH,qBA2BC;CACF;AAGD,iDAAiD;AAOnC,iFAA+E;AAC/E,2DAA6D;AACzD,8DAAiE"}
@@ -0,0 +1,399 @@
1
+ /**
2
+ * @fileoverview Policy Manager with Intelligent Caching
3
+ * Manages policy.yaml loading with caching, default fallback, and waiver validation.
4
+ * Ported from agent-agency v2 CAWS integration patterns.
5
+ * @author @darianrosebrook
6
+ */
7
+
8
+ const fs = require('fs-extra');
9
+ const path = require('path');
10
+ const yaml = require('js-yaml');
11
+
12
+ /**
13
+ * Policy Manager - Handles policy loading with intelligent caching
14
+ *
15
+ * Features:
16
+ * - TTL-based caching for performance
17
+ * - Graceful fallback to defaults when policy.yaml missing
18
+ * - Cache inspection and management API
19
+ * - Waiver validation and delta application
20
+ */
21
+ class PolicyManager {
22
+ constructor(options = {}) {
23
+ this.enableCaching = options.enableCaching ?? true;
24
+ this.cacheTTL = options.cacheTTL ?? 300000; // 5 minutes default
25
+ this.policyCache = new Map(); // projectRoot -> { policy, cachedAt, ttl }
26
+ }
27
+
28
+ /**
29
+ * Load CAWS policy from policy.yaml with caching
30
+ *
31
+ * @param {string} projectRoot - Project root directory
32
+ * @param {Object} options - Loading options
33
+ * @param {boolean} options.useCache - Use cache if available (default: true)
34
+ * @param {number} options.cacheTTL - Cache TTL override in milliseconds
35
+ * @returns {Promise<Object>} Policy object
36
+ */
37
+ async loadPolicy(projectRoot, options = {}) {
38
+ const useCache = options.useCache ?? this.enableCaching;
39
+ const cacheTTL = options.cacheTTL ?? this.cacheTTL;
40
+ const startTime = Date.now();
41
+
42
+ try {
43
+ // Check cache first
44
+ if (useCache && this.policyCache.has(projectRoot)) {
45
+ const cached = this.policyCache.get(projectRoot);
46
+ const cacheAge = Date.now() - cached.cachedAt;
47
+
48
+ if (cacheAge < cacheTTL) {
49
+ return {
50
+ ...cached.policy,
51
+ _cacheHit: true,
52
+ _loadDuration: Date.now() - startTime,
53
+ };
54
+ }
55
+ }
56
+
57
+ // Load from file
58
+ const policyPath = path.join(projectRoot, '.caws', 'policy.yaml');
59
+
60
+ try {
61
+ const content = await fs.readFile(policyPath, 'utf-8');
62
+ const policy = yaml.load(content);
63
+
64
+ // Validate policy structure
65
+ this.validatePolicy(policy);
66
+
67
+ // Update cache
68
+ if (this.enableCaching) {
69
+ this.policyCache.set(projectRoot, {
70
+ policy,
71
+ cachedAt: Date.now(),
72
+ ttl: cacheTTL,
73
+ });
74
+ }
75
+
76
+ return {
77
+ ...policy,
78
+ _cacheHit: false,
79
+ _loadDuration: Date.now() - startTime,
80
+ };
81
+ } catch (error) {
82
+ if (error.code === 'ENOENT') {
83
+ // Policy file doesn't exist - use default
84
+ const defaultPolicy = this.getDefaultPolicy();
85
+
86
+ if (this.enableCaching) {
87
+ this.policyCache.set(projectRoot, {
88
+ policy: defaultPolicy,
89
+ cachedAt: Date.now(),
90
+ ttl: cacheTTL,
91
+ });
92
+ }
93
+
94
+ return {
95
+ ...defaultPolicy,
96
+ _isDefault: true,
97
+ _cacheHit: false,
98
+ _loadDuration: Date.now() - startTime,
99
+ };
100
+ }
101
+ throw error;
102
+ }
103
+ } catch (error) {
104
+ throw new Error(`Policy load failed: ${error.message}`);
105
+ }
106
+ }
107
+
108
+ /**
109
+ * Load a waiver document by ID
110
+ *
111
+ * @param {string} waiverId - Waiver ID (e.g., WV-0001)
112
+ * @param {string} projectRoot - Project root directory
113
+ * @returns {Promise<Object|null>} Waiver document or null if not found
114
+ */
115
+ async loadWaiver(waiverId, projectRoot) {
116
+ try {
117
+ const waiverPath = path.join(projectRoot, '.caws', 'waivers', `${waiverId}.yaml`);
118
+
119
+ const content = await fs.readFile(waiverPath, 'utf-8');
120
+ return yaml.load(content);
121
+ } catch (error) {
122
+ if (error.code === 'ENOENT') {
123
+ return null;
124
+ }
125
+ throw new Error(`Failed to load waiver ${waiverId}: ${error.message}`);
126
+ }
127
+ }
128
+
129
+ /**
130
+ * Check if a waiver is currently valid
131
+ *
132
+ * @param {Object} waiver - Waiver document
133
+ * @returns {boolean} True if waiver is valid and active
134
+ */
135
+ isWaiverValid(waiver) {
136
+ if (!waiver) {
137
+ return false;
138
+ }
139
+
140
+ // Check status
141
+ if (waiver.status !== 'active') {
142
+ return false;
143
+ }
144
+
145
+ // Check expiry
146
+ if (waiver.expires_at) {
147
+ const expiryDate = new Date(waiver.expires_at);
148
+ const now = new Date();
149
+ if (now > expiryDate) {
150
+ return false;
151
+ }
152
+ }
153
+
154
+ // Check if it has required approvals
155
+ if (!waiver.approvers || waiver.approvers.length === 0) {
156
+ return false;
157
+ }
158
+
159
+ return true;
160
+ }
161
+
162
+ /**
163
+ * Apply waivers to baseline budget
164
+ *
165
+ * @param {Object} baseline - Baseline budget from policy
166
+ * @param {string[]} waiverIds - Array of waiver IDs to apply
167
+ * @param {string} projectRoot - Project root directory
168
+ * @returns {Promise<Object>} Effective budget with waivers applied
169
+ */
170
+ async applyWaivers(baseline, waiverIds, projectRoot) {
171
+ const effective = { ...baseline };
172
+ const applied = [];
173
+
174
+ for (const waiverId of waiverIds) {
175
+ const waiver = await this.loadWaiver(waiverId, projectRoot);
176
+
177
+ if (waiver && this.isWaiverValid(waiver)) {
178
+ // Apply additive delta
179
+ if (waiver.delta) {
180
+ if (waiver.delta.max_files) {
181
+ effective.max_files += waiver.delta.max_files;
182
+ }
183
+ if (waiver.delta.max_loc) {
184
+ effective.max_loc += waiver.delta.max_loc;
185
+ }
186
+ }
187
+ applied.push(waiverId);
188
+ }
189
+ }
190
+
191
+ return {
192
+ effective,
193
+ applied,
194
+ };
195
+ }
196
+
197
+ /**
198
+ * Validate policy structure
199
+ *
200
+ * @param {Object} policy - Policy to validate
201
+ * @throws {Error} If policy is invalid
202
+ */
203
+ validatePolicy(policy) {
204
+ if (!policy.version) {
205
+ throw new Error('Policy missing version field');
206
+ }
207
+
208
+ if (!policy.risk_tiers) {
209
+ throw new Error('Policy missing risk_tiers configuration');
210
+ }
211
+
212
+ // Validate all tiers have required fields
213
+ for (const tier of [1, 2, 3]) {
214
+ const budget = policy.risk_tiers[tier];
215
+ if (!budget) {
216
+ throw new Error(`Policy missing risk tier ${tier} configuration`);
217
+ }
218
+
219
+ if (typeof budget.max_files !== 'number' || typeof budget.max_loc !== 'number') {
220
+ throw new Error(`Risk tier ${tier} missing or invalid budget limits`);
221
+ }
222
+ }
223
+
224
+ // Validate edit rules if present
225
+ if (policy.edit_rules) {
226
+ if (typeof policy.edit_rules.policy_and_code_same_pr !== 'boolean') {
227
+ throw new Error('edit_rules.policy_and_code_same_pr must be boolean');
228
+ }
229
+ if (typeof policy.edit_rules.min_approvers_for_budget_raise !== 'number') {
230
+ throw new Error('edit_rules.min_approvers_for_budget_raise must be number');
231
+ }
232
+ }
233
+ }
234
+
235
+ /**
236
+ * Get default CAWS policy
237
+ *
238
+ * Returns sensible defaults when policy.yaml doesn't exist.
239
+ *
240
+ * @returns {Object} Default policy configuration
241
+ */
242
+ getDefaultPolicy() {
243
+ return {
244
+ version: 1,
245
+ risk_tiers: {
246
+ 1: {
247
+ max_files: 25,
248
+ max_loc: 1000,
249
+ description: 'Critical changes requiring manual review',
250
+ },
251
+ 2: {
252
+ max_files: 50,
253
+ max_loc: 2000,
254
+ description: 'Standard features with automated gates',
255
+ },
256
+ 3: {
257
+ max_files: 100,
258
+ max_loc: 5000,
259
+ description: 'Low-risk changes with minimal oversight',
260
+ },
261
+ },
262
+ edit_rules: {
263
+ policy_and_code_same_pr: false,
264
+ min_approvers_for_budget_raise: 2,
265
+ require_signed_commits: true,
266
+ },
267
+ gates: {
268
+ budget_limit: {
269
+ enabled: true,
270
+ description: 'Enforce change budget limits',
271
+ },
272
+ spec_completeness: {
273
+ enabled: true,
274
+ description: 'Require complete working specifications',
275
+ },
276
+ contract_compliance: {
277
+ enabled: true,
278
+ description: 'Validate API contracts',
279
+ },
280
+ coverage_threshold: {
281
+ enabled: true,
282
+ description: 'Maintain test coverage requirements',
283
+ },
284
+ mutation_threshold: {
285
+ enabled: true,
286
+ description: 'Require mutation testing for T1/T2 changes',
287
+ },
288
+ security_scan: {
289
+ enabled: true,
290
+ description: 'Run security vulnerability scans',
291
+ },
292
+ },
293
+ };
294
+ }
295
+
296
+ /**
297
+ * Clear policy cache
298
+ *
299
+ * @param {string} [projectRoot] - Specific project to clear, or all if omitted
300
+ */
301
+ clearCache(projectRoot) {
302
+ if (projectRoot) {
303
+ this.policyCache.delete(projectRoot);
304
+ } else {
305
+ this.policyCache.clear();
306
+ }
307
+ }
308
+
309
+ /**
310
+ * Get cache status for a project
311
+ *
312
+ * @param {string} projectRoot - Project root directory
313
+ * @returns {Object} Cache status information
314
+ */
315
+ getCacheStatus(projectRoot) {
316
+ const cached = this.policyCache.get(projectRoot);
317
+
318
+ if (!cached) {
319
+ return {
320
+ cached: false,
321
+ ttl: this.cacheTTL,
322
+ };
323
+ }
324
+
325
+ return {
326
+ cached: true,
327
+ age: Date.now() - cached.cachedAt,
328
+ ttl: cached.ttl,
329
+ remainingTTL: Math.max(0, cached.ttl - (Date.now() - cached.cachedAt)),
330
+ };
331
+ }
332
+
333
+ /**
334
+ * Reload policy from disk (bypassing cache)
335
+ *
336
+ * @param {string} projectRoot - Project root directory
337
+ * @returns {Promise<Object>} Fresh policy
338
+ */
339
+ async reloadPolicy(projectRoot) {
340
+ this.clearCache(projectRoot);
341
+ return this.loadPolicy(projectRoot, { useCache: false });
342
+ }
343
+
344
+ /**
345
+ * Get all cached projects
346
+ *
347
+ * @returns {string[]} Array of project roots with cached policies
348
+ */
349
+ getCachedProjects() {
350
+ return Array.from(this.policyCache.keys());
351
+ }
352
+
353
+ /**
354
+ * Get cache statistics
355
+ *
356
+ * @returns {Object} Cache statistics
357
+ */
358
+ getCacheStats() {
359
+ const projects = this.getCachedProjects();
360
+ const now = Date.now();
361
+
362
+ const stats = {
363
+ totalCached: projects.length,
364
+ validCaches: 0,
365
+ expiredCaches: 0,
366
+ totalAge: 0,
367
+ };
368
+
369
+ for (const project of projects) {
370
+ const cached = this.policyCache.get(project);
371
+ const age = now - cached.cachedAt;
372
+
373
+ stats.totalAge += age;
374
+
375
+ if (age < cached.ttl) {
376
+ stats.validCaches++;
377
+ } else {
378
+ stats.expiredCaches++;
379
+ }
380
+ }
381
+
382
+ stats.averageAge = projects.length > 0 ? stats.totalAge / projects.length : 0;
383
+
384
+ return stats;
385
+ }
386
+ }
387
+
388
+ // Export singleton instance with default configuration
389
+ const defaultPolicyManager = new PolicyManager();
390
+
391
+ module.exports = {
392
+ PolicyManager,
393
+ defaultPolicyManager,
394
+
395
+ // Convenience exports for backward compatibility
396
+ loadPolicy: (projectRoot, options) => defaultPolicyManager.loadPolicy(projectRoot, options),
397
+ clearCache: (projectRoot) => defaultPolicyManager.clearCache(projectRoot),
398
+ getCacheStatus: (projectRoot) => defaultPolicyManager.getCacheStatus(projectRoot),
399
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"cursor-hooks.d.ts","sourceRoot":"","sources":["../../src/scaffold/cursor-hooks.js"],"names":[],"mappings":"AAaA;;;;GAIG;AACH,gDAHW,MAAM,WACN,MAAM,EAAE,iBAsIlB"}
1
+ {"version":3,"file":"cursor-hooks.d.ts","sourceRoot":"","sources":["../../src/scaffold/cursor-hooks.js"],"names":[],"mappings":"AAaA;;;;GAIG;AACH,gDAHW,MAAM,WACN,MAAM,EAAE,iBAqJlB"}
@@ -138,6 +138,21 @@ async function scaffoldCursorHooks(projectDir, levels = ['safety', 'quality', 's
138
138
  await fs.copy(readmePath, path.join(cursorDir, 'README.md'));
139
139
  }
140
140
 
141
+ // Copy rules directory if it exists
142
+ const rulesTemplateDir = path.join(cursorTemplateDir, 'rules');
143
+ const rulesDestDir = path.join(cursorDir, 'rules');
144
+ if (fs.existsSync(rulesTemplateDir)) {
145
+ try {
146
+ await fs.ensureDir(rulesDestDir);
147
+ await fs.copy(rulesTemplateDir, rulesDestDir);
148
+ const ruleFiles = fs.readdirSync(rulesTemplateDir).filter((file) => file.endsWith('.mdc'));
149
+ console.log(chalk.green('โœ… Cursor rules configured'));
150
+ console.log(chalk.gray(` Rules: ${ruleFiles.length} rule files installed`));
151
+ } catch (error) {
152
+ console.warn(chalk.yellow('โš ๏ธ Failed to copy Cursor rules:'), error.message);
153
+ }
154
+ }
155
+
141
156
  console.log(chalk.green('โœ… Cursor hooks configured'));
142
157
  console.log(chalk.gray(` Enabled: ${levels.join(', ')}`));
143
158
  console.log(
@@ -1 +1 @@
1
- {"version":3,"file":"git-hooks.d.ts","sourceRoot":"","sources":["../../src/scaffold/git-hooks.js"],"names":[],"mappings":"AASA;;;;GAIG;AACH,6CAHW,MAAM;;;GAwGhB;AAoOD;;;GAGG;AACH,2CAFW,MAAM,iBAkChB;AAED;;;GAGG;AACH,gDAFW,MAAM,iBAgDhB"}
1
+ {"version":3,"file":"git-hooks.d.ts","sourceRoot":"","sources":["../../src/scaffold/git-hooks.js"],"names":[],"mappings":"AASA;;;;GAIG;AACH,6CAHW,MAAM;;;GAwGhB;AAwND;;;GAGG;AACH,2CAFW,MAAM,iBAkChB;AAED;;;GAGG;AACH,gDAFW,MAAM,iBAgDhB"}
@@ -116,10 +116,10 @@ async function scaffoldGitHooks(projectDir, options = {}) {
116
116
  }
117
117
 
118
118
  /**
119
- * Generate pre-commit hook content
119
+ * Generate pre-commit hook content with staged file quality gates
120
120
  */
121
121
  function generatePreCommitHook(options) {
122
- const { qualityGates = true } = options;
122
+ const { qualityGates = true, stagedOnly = true } = options;
123
123
 
124
124
  return `#!/bin/bash
125
125
  # CAWS Pre-commit Hook
@@ -127,8 +127,8 @@ function generatePreCommitHook(options) {
127
127
 
128
128
  set -e
129
129
 
130
- echo "๐Ÿ” CAWS Pre-commit Validation"
131
- echo "โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”"
130
+ echo "๐Ÿšฆ Running CAWS Quality Gates${qualityGates ? ' (Crisis Response Mode)' : ''}..."
131
+ echo "๐Ÿ“ Analyzing ${stagedOnly ? 'staged files only' : 'all files'}..."
132
132
 
133
133
  # Check if CAWS is initialized
134
134
  if [ ! -d ".caws" ]; then
@@ -136,55 +136,43 @@ if [ ! -d ".caws" ]; then
136
136
  exit 0
137
137
  fi
138
138
 
139
- # Run CAWS validation if available
140
- if command -v caws >/dev/null 2>&1; then
141
- echo "๐Ÿ“‹ Running CAWS validation..."
142
- if caws validate --quiet; then
143
- echo "โœ… CAWS validation passed"
139
+ # Run quality gates
140
+ if command -v node >/dev/null 2>&1; then
141
+ if node scripts/quality-gates/run-quality-gates.js; then
142
+ echo "โœ… Quality gates passed"
144
143
  else
145
- echo "โŒ CAWS validation failed"
146
- echo "๐Ÿ’ก Fix issues or skip with: git commit --no-verify (allowed)"
144
+ echo "โŒ Quality gates failed - commit blocked"
145
+ echo "๐Ÿ’ก Fix the violations above before committing"
146
+ echo "๐Ÿ“– See docs/refactoring.md for crisis response plan"
147
147
  exit 1
148
148
  fi
149
149
  else
150
- echo "โš ๏ธ CAWS CLI not found - install with: npm install -g @paths.design/caws-cli"
150
+ echo "โš ๏ธ Node.js not found - skipping quality gates"
151
+ echo "๐Ÿ’ก Install Node.js to enable automatic quality checking"
152
+ exit 0
151
153
  fi
152
154
 
153
- # Run quality gates if enabled
154
- ${
155
- qualityGates
156
- ? `
157
- echo "๐ŸŽฏ Running quality gates..."
158
- if [ -f "package.json" ]; then
159
- # Run linting if available
160
- if [ -f "node_modules/.bin/eslint" ] || command -v eslint >/dev/null 2>&1; then
161
- echo "๐Ÿ” Running ESLint..."
162
- if npx eslint . --quiet; then
163
- echo "โœ… ESLint passed"
164
- else
165
- echo "โŒ ESLint failed"
166
- echo "๐Ÿ’ก Fix issues or skip with: git commit --no-verify (allowed)"
167
- exit 1
168
- fi
169
- fi
170
-
171
- # Run tests if available
172
- if [ -f "package.json" ] && grep -q '"test"' package.json; then
173
- echo "๐Ÿงช Running tests..."
174
- if npm test; then
175
- echo "โœ… Tests passed"
176
- else
177
- echo "โŒ Tests failed"
178
- echo "๐Ÿ’ก Fix issues or skip with: git commit --no-verify (allowed)"
179
- exit 1
180
- fi
155
+ # Run hidden TODO analysis on staged files only
156
+ echo "๐Ÿ” Checking for hidden TODOs in staged files..."
157
+ if command -v python3 >/dev/null 2>&1; then
158
+ if python3 scripts/v3/analysis/todo_analyzer.py --staged-only --ci-mode --min-confidence 0.8 >/dev/null 2>&1; then
159
+ echo "โœ… No critical hidden TODOs found in staged files"
160
+ else
161
+ echo "โŒ Critical hidden TODOs detected in staged files - commit blocked"
162
+ echo "๐Ÿ’ก Fix stub implementations and placeholder code before committing"
163
+ echo "๐Ÿ“– See docs/PLACEHOLDER-DETECTION-GUIDE.md for classification"
164
+ echo ""
165
+ echo "๐Ÿ” Running detailed analysis on staged files..."
166
+ python3 scripts/v3/analysis/todo_analyzer.py --staged-only --min-confidence 0.8
167
+ exit 1
181
168
  fi
169
+ else
170
+ echo "โš ๏ธ Python3 not found - skipping hidden TODO analysis"
171
+ echo "๐Ÿ’ก Install Python3 to enable automatic TODO checking"
182
172
  fi
183
- `
184
- : ''
185
- }
186
173
 
187
- echo "๐ŸŽ‰ Pre-commit checks passed!"
174
+ echo "โœ… All quality checks passed - proceeding with commit"
175
+ exit 0
188
176
  `;
189
177
  }
190
178
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scaffold/index.js"],"names":[],"mappings":"AAkKA;;;GAGG;AACH,6DA0UC;AA7dD;;;;GAIG;AACH,mDAHW,MAAM;;;GA8HhB;AAMD;;;GAGG;AACH,yDAGC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scaffold/index.js"],"names":[],"mappings":"AAkKA;;;GAGG;AACH,6DA6VC;AAhfD;;;;GAIG;AACH,mDAHW,MAAM;;;GA8HhB;AAMD;;;GAGG;AACH,yDAGC"}
@@ -311,6 +311,25 @@ async function scaffoldProject(options) {
311
311
  },
312
312
  });
313
313
 
314
+ // Add quality gates scripts for staged file analysis
315
+ enhancements.push({
316
+ name: 'scripts/quality-gates/run-quality-gates.js',
317
+ description: 'Quality gates runner for staged files',
318
+ required: false,
319
+ });
320
+
321
+ enhancements.push({
322
+ name: 'scripts/quality-gates/check-god-objects.js',
323
+ description: 'God object detector for staged files',
324
+ required: false,
325
+ });
326
+
327
+ enhancements.push({
328
+ name: 'scripts/v3/analysis/todo_analyzer.py',
329
+ description: 'Advanced hidden TODO analyzer with dependency resolution',
330
+ required: false,
331
+ });
332
+
314
333
  // Add commit conventions for setups that don't have them
315
334
  if (!setup.hasTemplates || !fs.existsSync(path.join(currentDir, 'COMMIT_CONVENTIONS.md'))) {
316
335
  enhancements.push({