@paths.design/caws-cli 8.0.0 → 8.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 (149) hide show
  1. package/dist/budget-derivation.d.ts +74 -0
  2. package/dist/budget-derivation.d.ts.map +1 -0
  3. package/dist/cicd-optimizer.d.ts +142 -0
  4. package/dist/cicd-optimizer.d.ts.map +1 -0
  5. package/dist/commands/archive.d.ts +51 -0
  6. package/dist/commands/archive.d.ts.map +1 -0
  7. package/dist/commands/archive.js +114 -6
  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 +109 -10
  11. package/dist/commands/diagnose.d.ts +52 -0
  12. package/dist/commands/diagnose.d.ts.map +1 -0
  13. package/dist/commands/diagnose.js +1 -1
  14. package/dist/commands/evaluate.d.ts +8 -0
  15. package/dist/commands/evaluate.d.ts.map +1 -0
  16. package/dist/commands/init.d.ts +5 -0
  17. package/dist/commands/init.d.ts.map +1 -0
  18. package/dist/commands/iterate.d.ts +8 -0
  19. package/dist/commands/iterate.d.ts.map +1 -0
  20. package/dist/commands/mode.d.ts +24 -0
  21. package/dist/commands/mode.d.ts.map +1 -0
  22. package/dist/commands/mode.js +24 -14
  23. package/dist/commands/plan.d.ts +49 -0
  24. package/dist/commands/plan.d.ts.map +1 -0
  25. package/dist/commands/provenance.d.ts +32 -0
  26. package/dist/commands/provenance.d.ts.map +1 -0
  27. package/dist/commands/provenance.js +216 -93
  28. package/dist/commands/quality-gates.d.ts +6 -0
  29. package/dist/commands/quality-gates.d.ts.map +1 -0
  30. package/dist/commands/quality-gates.js +82 -3
  31. package/dist/commands/quality-monitor.d.ts +17 -0
  32. package/dist/commands/quality-monitor.d.ts.map +1 -0
  33. package/dist/commands/specs.d.ts +71 -0
  34. package/dist/commands/specs.d.ts.map +1 -0
  35. package/dist/commands/specs.js +184 -6
  36. package/dist/commands/status.d.ts +44 -0
  37. package/dist/commands/status.d.ts.map +1 -0
  38. package/dist/commands/status.js +134 -10
  39. package/dist/commands/templates.d.ts +74 -0
  40. package/dist/commands/templates.d.ts.map +1 -0
  41. package/dist/commands/templates.js +2 -2
  42. package/dist/commands/tool.d.ts +13 -0
  43. package/dist/commands/tool.d.ts.map +1 -0
  44. package/dist/commands/troubleshoot.d.ts +8 -0
  45. package/dist/commands/troubleshoot.d.ts.map +1 -0
  46. package/dist/commands/tutorial.d.ts +55 -0
  47. package/dist/commands/tutorial.d.ts.map +1 -0
  48. package/dist/commands/validate.d.ts +15 -0
  49. package/dist/commands/validate.d.ts.map +1 -0
  50. package/dist/commands/waivers.d.ts +8 -0
  51. package/dist/commands/waivers.d.ts.map +1 -0
  52. package/dist/commands/workflow.d.ts +85 -0
  53. package/dist/commands/workflow.d.ts.map +1 -0
  54. package/dist/config/index.d.ts +29 -0
  55. package/dist/config/index.d.ts.map +1 -0
  56. package/dist/config/modes.d.ts +225 -0
  57. package/dist/config/modes.d.ts.map +1 -0
  58. package/dist/constants/spec-types.d.ts +41 -0
  59. package/dist/constants/spec-types.d.ts.map +1 -0
  60. package/dist/error-handler.d.ts +164 -0
  61. package/dist/error-handler.d.ts.map +1 -0
  62. package/dist/error-handler.js +6 -98
  63. package/dist/generators/jest-config-generator.js +242 -0
  64. package/dist/generators/jest-config.d.ts +32 -0
  65. package/dist/generators/jest-config.d.ts.map +1 -0
  66. package/dist/generators/working-spec.d.ts +13 -0
  67. package/dist/generators/working-spec.d.ts.map +1 -0
  68. package/dist/index-new.d.ts +5 -0
  69. package/dist/index-new.d.ts.map +1 -0
  70. package/dist/index-new.js +317 -0
  71. package/dist/index.d.ts +5 -0
  72. package/dist/index.d.ts.map +1 -0
  73. package/dist/index.js +14 -7
  74. package/dist/index.js.backup +4711 -0
  75. package/dist/minimal-cli.d.ts +3 -0
  76. package/dist/minimal-cli.d.ts.map +1 -0
  77. package/dist/minimal-cli.js +3 -1
  78. package/dist/policy/PolicyManager.d.ts +104 -0
  79. package/dist/policy/PolicyManager.d.ts.map +1 -0
  80. package/dist/scaffold/claude-hooks.js +316 -0
  81. package/dist/scaffold/cursor-hooks.d.ts +7 -0
  82. package/dist/scaffold/cursor-hooks.d.ts.map +1 -0
  83. package/dist/scaffold/git-hooks.d.ts +38 -0
  84. package/dist/scaffold/git-hooks.d.ts.map +1 -0
  85. package/dist/scaffold/index.d.ts +15 -0
  86. package/dist/scaffold/index.d.ts.map +1 -0
  87. package/dist/scaffold/index.js +18 -0
  88. package/dist/spec/SpecFileManager.d.ts +146 -0
  89. package/dist/spec/SpecFileManager.d.ts.map +1 -0
  90. package/dist/templates/.claude/README.md +190 -0
  91. package/dist/templates/.claude/hooks/audit.sh +96 -0
  92. package/dist/templates/.claude/hooks/block-dangerous.sh +90 -0
  93. package/dist/templates/.claude/hooks/naming-check.sh +97 -0
  94. package/dist/templates/.claude/hooks/quality-check.sh +68 -0
  95. package/dist/templates/.claude/hooks/scan-secrets.sh +85 -0
  96. package/dist/templates/.claude/hooks/scope-guard.sh +105 -0
  97. package/dist/templates/.claude/hooks/validate-spec.sh +76 -0
  98. package/dist/templates/.claude/settings.json +95 -0
  99. package/dist/test-analysis.d.ts +182 -0
  100. package/dist/test-analysis.d.ts.map +1 -0
  101. package/dist/test-analysis.js +203 -10
  102. package/dist/tool-interface.d.ts +236 -0
  103. package/dist/tool-interface.d.ts.map +1 -0
  104. package/dist/tool-loader.d.ts +77 -0
  105. package/dist/tool-loader.d.ts.map +1 -0
  106. package/dist/tool-validator.d.ts +72 -0
  107. package/dist/tool-validator.d.ts.map +1 -0
  108. package/dist/utils/async-utils.d.ts +73 -0
  109. package/dist/utils/async-utils.d.ts.map +1 -0
  110. package/dist/utils/command-wrapper.d.ts +66 -0
  111. package/dist/utils/command-wrapper.d.ts.map +1 -0
  112. package/dist/utils/detection.d.ts +14 -0
  113. package/dist/utils/detection.d.ts.map +1 -0
  114. package/dist/utils/error-categories.js +210 -0
  115. package/dist/utils/finalization.d.ts +17 -0
  116. package/dist/utils/finalization.d.ts.map +1 -0
  117. package/dist/utils/git-lock.d.ts +13 -0
  118. package/dist/utils/git-lock.d.ts.map +1 -0
  119. package/dist/utils/gitignore-updater.d.ts +39 -0
  120. package/dist/utils/gitignore-updater.d.ts.map +1 -0
  121. package/dist/utils/project-analysis.d.ts +34 -0
  122. package/dist/utils/project-analysis.d.ts.map +1 -0
  123. package/dist/utils/promise-utils.d.ts +30 -0
  124. package/dist/utils/promise-utils.d.ts.map +1 -0
  125. package/dist/utils/quality-gates-utils.js +402 -0
  126. package/dist/utils/quality-gates.d.ts +49 -0
  127. package/dist/utils/quality-gates.d.ts.map +1 -0
  128. package/dist/utils/spec-resolver.d.ts +80 -0
  129. package/dist/utils/spec-resolver.d.ts.map +1 -0
  130. package/dist/utils/typescript-detector.d.ts +63 -0
  131. package/dist/utils/typescript-detector.d.ts.map +1 -0
  132. package/dist/utils/typescript-detector.js +36 -90
  133. package/dist/utils/yaml-validation.d.ts +32 -0
  134. package/dist/utils/yaml-validation.d.ts.map +1 -0
  135. package/dist/validation/spec-validation.d.ts +43 -0
  136. package/dist/validation/spec-validation.d.ts.map +1 -0
  137. package/dist/validation/spec-validation.js +59 -6
  138. package/dist/waivers-manager.d.ts +167 -0
  139. package/dist/waivers-manager.d.ts.map +1 -0
  140. package/package.json +5 -3
  141. package/templates/.claude/README.md +190 -0
  142. package/templates/.claude/hooks/audit.sh +96 -0
  143. package/templates/.claude/hooks/block-dangerous.sh +90 -0
  144. package/templates/.claude/hooks/naming-check.sh +97 -0
  145. package/templates/.claude/hooks/quality-check.sh +68 -0
  146. package/templates/.claude/hooks/scan-secrets.sh +85 -0
  147. package/templates/.claude/hooks/scope-guard.sh +105 -0
  148. package/templates/.claude/hooks/validate-spec.sh +76 -0
  149. package/templates/.claude/settings.json +95 -0
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=minimal-cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"minimal-cli.d.ts","sourceRoot":"","sources":["../src/minimal-cli.js"],"names":[],"mappings":""}
@@ -1,7 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  /**
4
- * @fileoverview Minimal CAWS CLI to test Chalk functionality
4
+ * @fileoverview Minimal CAWS CLI for testing and development
5
+ * Provides a lightweight CLI structure with version and help commands
6
+ * for quick verification of CLI functionality.
5
7
  * @author @darianrosebrook
6
8
  */
7
9
 
@@ -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,CAuG3B;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,316 @@
1
+ /**
2
+ * @fileoverview Claude Code Hooks Scaffolding
3
+ * Functions for setting up Claude Code hooks for CAWS projects
4
+ * @author @darianrosebrook
5
+ */
6
+
7
+ const fs = require('fs-extra');
8
+ const path = require('path');
9
+ const chalk = require('chalk');
10
+
11
+ // Import detection utilities
12
+ const { detectCAWSSetup, findPackageRoot } = require('../utils/detection');
13
+
14
+ /**
15
+ * Scaffold Claude Code hooks for a CAWS project
16
+ * Creates .claude/settings.json with hooks and .claude/hooks/ directory with scripts
17
+ *
18
+ * @param {string} projectDir - Project directory path
19
+ * @param {string[]} levels - Hook levels to enable: 'safety', 'quality', 'scope', 'audit'
20
+ */
21
+ async function scaffoldClaudeHooks(projectDir, levels = ['safety', 'quality', 'scope', 'audit']) {
22
+ try {
23
+ const claudeDir = path.join(projectDir, '.claude');
24
+ const claudeHooksDir = path.join(claudeDir, 'hooks');
25
+
26
+ // Create .claude directory structure
27
+ await fs.ensureDir(claudeDir);
28
+ await fs.ensureDir(claudeHooksDir);
29
+
30
+ // Determine template directory - prefer bundled templates
31
+ const setup = detectCAWSSetup(projectDir);
32
+
33
+ // Find package root using shared utility
34
+ const packageRoot = findPackageRoot(__dirname);
35
+
36
+ // Try templates relative to package root first (works in both dev and global install)
37
+ const bundledTemplateDir = path.join(packageRoot, 'templates');
38
+ const fallbackTemplateDir = path.join(__dirname, '../../templates');
39
+ const templateDir = fs.existsSync(bundledTemplateDir)
40
+ ? bundledTemplateDir
41
+ : fs.existsSync(fallbackTemplateDir)
42
+ ? fallbackTemplateDir
43
+ : setup.templateDir || path.resolve(__dirname, '../templates');
44
+
45
+ const claudeTemplateDir = path.join(templateDir, '.claude');
46
+ const claudeHooksTemplateDir = path.join(claudeTemplateDir, 'hooks');
47
+
48
+ if (!fs.existsSync(claudeTemplateDir)) {
49
+ console.warn(chalk.yellow('⚠️ Claude Code hooks templates not found'));
50
+ console.warn(chalk.blue('💡 Skipping Claude Code hooks setup'));
51
+ return;
52
+ }
53
+
54
+ // Map levels to hook scripts
55
+ const hookMapping = {
56
+ safety: ['block-dangerous.sh', 'scan-secrets.sh'],
57
+ quality: ['quality-check.sh', 'validate-spec.sh'],
58
+ scope: ['scope-guard.sh', 'naming-check.sh'],
59
+ audit: ['audit.sh'],
60
+ };
61
+
62
+ // Determine which hooks to enable
63
+ const enabledHooks = new Set();
64
+ levels.forEach((level) => {
65
+ const hooks = hookMapping[level] || [];
66
+ hooks.forEach((hook) => enabledHooks.add(hook));
67
+ });
68
+
69
+ // Always enable audit.sh if any hooks are enabled
70
+ if (enabledHooks.size > 0) {
71
+ enabledHooks.add('audit.sh');
72
+ }
73
+
74
+ // Copy enabled hook scripts
75
+ const allHookScripts = [
76
+ 'audit.sh',
77
+ 'validate-spec.sh',
78
+ 'quality-check.sh',
79
+ 'scan-secrets.sh',
80
+ 'block-dangerous.sh',
81
+ 'scope-guard.sh',
82
+ 'naming-check.sh',
83
+ ];
84
+
85
+ for (const script of allHookScripts) {
86
+ if (enabledHooks.has(script)) {
87
+ const sourcePath = path.join(claudeHooksTemplateDir, script);
88
+ const destPath = path.join(claudeHooksDir, script);
89
+
90
+ if (fs.existsSync(sourcePath)) {
91
+ await fs.copy(sourcePath, destPath);
92
+ // Make executable
93
+ await fs.chmod(destPath, 0o755);
94
+ }
95
+ }
96
+ }
97
+
98
+ // Generate settings.json with hooks configuration
99
+ const settings = generateClaudeSettings(levels, enabledHooks);
100
+
101
+ // Check for existing settings and merge
102
+ const settingsPath = path.join(claudeDir, 'settings.json');
103
+ if (fs.existsSync(settingsPath)) {
104
+ try {
105
+ const existingSettings = await fs.readJSON(settingsPath);
106
+ // Merge hooks, preserving existing non-hook settings
107
+ settings.hooks = {
108
+ ...existingSettings.hooks,
109
+ ...settings.hooks,
110
+ };
111
+ // Preserve other settings
112
+ Object.keys(existingSettings).forEach((key) => {
113
+ if (key !== 'hooks' && !(key in settings)) {
114
+ settings[key] = existingSettings[key];
115
+ }
116
+ });
117
+ } catch (error) {
118
+ console.warn(chalk.yellow('⚠️ Could not merge existing settings:'), error.message);
119
+ }
120
+ }
121
+
122
+ // Write settings.json
123
+ await fs.writeFile(settingsPath, JSON.stringify(settings, null, 2));
124
+
125
+ // Copy README if it exists
126
+ const readmePath = path.join(claudeTemplateDir, 'README.md');
127
+ if (fs.existsSync(readmePath)) {
128
+ await fs.copy(readmePath, path.join(claudeDir, 'README.md'));
129
+ }
130
+
131
+ console.log(chalk.green('✅ Claude Code hooks configured'));
132
+ console.log(chalk.gray(` Enabled: ${levels.join(', ')}`));
133
+ console.log(
134
+ chalk.gray(` Scripts: ${Array.from(enabledHooks).length} hook scripts installed`)
135
+ );
136
+ console.log(chalk.blue('💡 Hooks will activate on next Claude Code session'));
137
+ } catch (error) {
138
+ console.error(chalk.yellow('⚠️ Failed to setup Claude Code hooks:'), error.message);
139
+ console.log(chalk.blue('💡 You can manually copy .claude/ directory later'));
140
+ }
141
+ }
142
+
143
+ /**
144
+ * Generate Claude Code settings with hooks configuration
145
+ * @param {string[]} levels - Enabled hook levels
146
+ * @param {Set<string>} enabledHooks - Set of enabled hook script names
147
+ * @returns {Object} Settings object for settings.json
148
+ */
149
+ function generateClaudeSettings(levels, _enabledHooks) {
150
+ const settings = {
151
+ hooks: {},
152
+ };
153
+
154
+ // Build hooks configuration based on enabled levels
155
+ // Claude Code uses different event names and matcher patterns
156
+
157
+ if (levels.includes('safety')) {
158
+ // Block dangerous bash commands
159
+ settings.hooks.PreToolUse = settings.hooks.PreToolUse || [];
160
+ settings.hooks.PreToolUse.push({
161
+ matcher: 'Bash',
162
+ hooks: [
163
+ {
164
+ type: 'command',
165
+ command: '"$CLAUDE_PROJECT_DIR"/.claude/hooks/block-dangerous.sh',
166
+ timeout: 10,
167
+ },
168
+ ],
169
+ });
170
+
171
+ // Scan for secrets on file read
172
+ settings.hooks.PreToolUse.push({
173
+ matcher: 'Read',
174
+ hooks: [
175
+ {
176
+ type: 'command',
177
+ command: '"$CLAUDE_PROJECT_DIR"/.claude/hooks/scan-secrets.sh',
178
+ timeout: 10,
179
+ },
180
+ ],
181
+ });
182
+ }
183
+
184
+ if (levels.includes('quality')) {
185
+ // Run quality checks after file edits
186
+ settings.hooks.PostToolUse = settings.hooks.PostToolUse || [];
187
+ settings.hooks.PostToolUse.push({
188
+ matcher: 'Write|Edit',
189
+ hooks: [
190
+ {
191
+ type: 'command',
192
+ command: '"$CLAUDE_PROJECT_DIR"/.claude/hooks/quality-check.sh',
193
+ timeout: 30,
194
+ },
195
+ {
196
+ type: 'command',
197
+ command: '"$CLAUDE_PROJECT_DIR"/.claude/hooks/validate-spec.sh',
198
+ timeout: 15,
199
+ },
200
+ ],
201
+ });
202
+ }
203
+
204
+ if (levels.includes('scope')) {
205
+ // Scope guard before file writes
206
+ settings.hooks.PreToolUse = settings.hooks.PreToolUse || [];
207
+ settings.hooks.PreToolUse.push({
208
+ matcher: 'Write|Edit',
209
+ hooks: [
210
+ {
211
+ type: 'command',
212
+ command: '"$CLAUDE_PROJECT_DIR"/.claude/hooks/scope-guard.sh',
213
+ timeout: 10,
214
+ },
215
+ ],
216
+ });
217
+
218
+ // Naming check after edits
219
+ settings.hooks.PostToolUse = settings.hooks.PostToolUse || [];
220
+ settings.hooks.PostToolUse.push({
221
+ matcher: 'Write|Edit',
222
+ hooks: [
223
+ {
224
+ type: 'command',
225
+ command: '"$CLAUDE_PROJECT_DIR"/.claude/hooks/naming-check.sh',
226
+ timeout: 10,
227
+ },
228
+ ],
229
+ });
230
+ }
231
+
232
+ if (levels.includes('audit')) {
233
+ // Session audit logging
234
+ settings.hooks.SessionStart = settings.hooks.SessionStart || [];
235
+ settings.hooks.SessionStart.push({
236
+ hooks: [
237
+ {
238
+ type: 'command',
239
+ command: '"$CLAUDE_PROJECT_DIR"/.claude/hooks/audit.sh session-start',
240
+ timeout: 5,
241
+ },
242
+ ],
243
+ });
244
+
245
+ settings.hooks.Stop = settings.hooks.Stop || [];
246
+ settings.hooks.Stop.push({
247
+ hooks: [
248
+ {
249
+ type: 'command',
250
+ command: '"$CLAUDE_PROJECT_DIR"/.claude/hooks/audit.sh stop',
251
+ timeout: 5,
252
+ },
253
+ ],
254
+ });
255
+
256
+ // Audit tool usage
257
+ settings.hooks.PostToolUse = settings.hooks.PostToolUse || [];
258
+ settings.hooks.PostToolUse.push({
259
+ matcher: 'Write|Edit|Bash',
260
+ hooks: [
261
+ {
262
+ type: 'command',
263
+ command: '"$CLAUDE_PROJECT_DIR"/.claude/hooks/audit.sh tool-use',
264
+ timeout: 5,
265
+ },
266
+ ],
267
+ });
268
+ }
269
+
270
+ return settings;
271
+ }
272
+
273
+ /**
274
+ * Check if Claude Code hooks are already configured
275
+ * @param {string} projectDir - Project directory
276
+ * @returns {boolean} True if hooks are configured
277
+ */
278
+ function hasClaudeHooks(projectDir) {
279
+ const settingsPath = path.join(projectDir, '.claude', 'settings.json');
280
+ if (!fs.existsSync(settingsPath)) {
281
+ return false;
282
+ }
283
+
284
+ try {
285
+ const settings = fs.readJSONSync(settingsPath);
286
+ return settings.hooks && Object.keys(settings.hooks).length > 0;
287
+ } catch {
288
+ return false;
289
+ }
290
+ }
291
+
292
+ /**
293
+ * List configured Claude Code hooks
294
+ * @param {string} projectDir - Project directory
295
+ * @returns {Object} Hook configuration or null
296
+ */
297
+ function getClaudeHooksConfig(projectDir) {
298
+ const settingsPath = path.join(projectDir, '.claude', 'settings.json');
299
+ if (!fs.existsSync(settingsPath)) {
300
+ return null;
301
+ }
302
+
303
+ try {
304
+ const settings = fs.readJSONSync(settingsPath);
305
+ return settings.hooks || null;
306
+ } catch {
307
+ return null;
308
+ }
309
+ }
310
+
311
+ module.exports = {
312
+ scaffoldClaudeHooks,
313
+ generateClaudeSettings,
314
+ hasClaudeHooks,
315
+ getClaudeHooksConfig,
316
+ };
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Scaffold Cursor hooks for a CAWS project
3
+ * @param {string} projectDir - Project directory path
4
+ * @param {string[]} levels - Hook levels to enable
5
+ */
6
+ export function scaffoldCursorHooks(projectDir: string, levels?: string[]): Promise<void>;
7
+ //# sourceMappingURL=cursor-hooks.d.ts.map
@@ -0,0 +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,iBA6JlB"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Scaffold git hooks for CAWS provenance tracking
3
+ * @param {string} projectDir - Project directory path
4
+ * @param {Object} options - Hook options
5
+ */
6
+ export function scaffoldGitHooks(projectDir: string, options?: any): Promise<{
7
+ added: number;
8
+ skipped: number;
9
+ }>;
10
+ /**
11
+ * Remove CAWS git hooks
12
+ * @param {string} projectDir - Project directory path
13
+ */
14
+ export function removeGitHooks(projectDir: string): Promise<void>;
15
+ /**
16
+ * Check git hooks status
17
+ * @param {string} projectDir - Project directory path
18
+ */
19
+ export function checkGitHooksStatus(projectDir: string): Promise<void>;
20
+ /**
21
+ * Generate pre-push hook content
22
+ * Blocks --no-verify to enforce quality gates before pushing
23
+ */
24
+ export function generatePrePushHook(): string;
25
+ /**
26
+ * Generate pre-commit hook content with staged file quality gates
27
+ * Implements fallback chain: Node script → CLI → Python scripts → Skip gracefully
28
+ */
29
+ export function generatePreCommitHook(options: any): string;
30
+ /**
31
+ * Generate post-commit hook content
32
+ */
33
+ export function generatePostCommitHook(): string;
34
+ /**
35
+ * Generate commit-msg hook content
36
+ */
37
+ export function generateCommitMsgHook(): string;
38
+ //# sourceMappingURL=git-hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-hooks.d.ts","sourceRoot":"","sources":["../../src/scaffold/git-hooks.js"],"names":[],"mappings":"AAUA;;;;GAIG;AACH,6CAHW,MAAM;;;GAwGhB;AA4kBD;;;GAGG;AACH,2CAFW,MAAM,iBAkChB;AAED;;;GAGG;AACH,gDAFW,MAAM,iBAgDhB;AA9VD;;;GAGG;AACH,8CAqNC;AA7hBD;;;GAGG;AACH,4DAsRC;AAED;;GAEG;AACH,iDAmCC;AA6ND;;GAEG;AACH,gDAsCC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Scaffold existing project with CAWS components
3
+ * @param {Object} options - Scaffold options
4
+ */
5
+ export function scaffoldProject(options: any): Promise<void>;
6
+ export function scaffoldIDEIntegrations(targetDir: any, options: any): Promise<{
7
+ added: number;
8
+ skipped: number;
9
+ }>;
10
+ /**
11
+ * Set dependencies for scaffold module
12
+ * @param {Object} deps - Dependencies object
13
+ */
14
+ export function setScaffoldDependencies(deps: any): void;
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scaffold/index.js"],"names":[],"mappings":"AA6LA;;;GAGG;AACH,6DA6jBC;AA3sBD;;;GA2HC;AAMD;;;GAGG;AACH,yDAGC"}
@@ -16,6 +16,9 @@ const { detectsPublishing } = require('../utils/project-analysis');
16
16
  const { scaffoldGitHooks } = require('./git-hooks');
17
17
  const { updateGitignore } = require('../utils/gitignore-updater');
18
18
 
19
+ // Import Claude Code hooks scaffolding
20
+ const { scaffoldClaudeHooks } = require('./claude-hooks');
21
+
19
22
  // CLI version from package.json
20
23
  const CLI_VERSION = require('../../package.json').version;
21
24
 
@@ -120,8 +123,22 @@ async function scaffoldIDEIntegrations(targetDir, options) {
120
123
  dest: '.cursor/README.md',
121
124
  desc: 'Cursor integration documentation',
122
125
  },
126
+
127
+ // Claude Code hooks
128
+ {
129
+ src: '.claude/README.md',
130
+ dest: '.claude/README.md',
131
+ desc: 'Claude Code integration documentation',
132
+ },
123
133
  ];
124
134
 
135
+ // Setup Claude Code hooks
136
+ try {
137
+ await scaffoldClaudeHooks(targetDir, ['safety', 'quality', 'scope', 'audit']);
138
+ } catch (error) {
139
+ console.log(chalk.yellow(`⚠️ Claude Code hooks setup failed: ${error.message}`));
140
+ }
141
+
125
142
  for (const template of ideTemplates) {
126
143
  const srcPath = path.join(templateDir, template.src);
127
144
  const destPath = path.join(targetDir, template.dest);
@@ -769,5 +786,6 @@ async function scaffoldProject(options) {
769
786
  module.exports = {
770
787
  scaffoldProject,
771
788
  scaffoldIDEIntegrations,
789
+ scaffoldClaudeHooks,
772
790
  setScaffoldDependencies,
773
791
  };