@paths.design/caws-cli 8.1.0 → 8.2.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 (79) hide show
  1. package/README.md +5 -6
  2. package/dist/commands/archive.d.ts +1 -1
  3. package/dist/commands/archive.d.ts.map +1 -1
  4. package/dist/commands/init.d.ts.map +1 -1
  5. package/dist/commands/init.js +185 -39
  6. package/dist/commands/mode.d.ts +2 -1
  7. package/dist/commands/mode.d.ts.map +1 -1
  8. package/dist/commands/provenance.d.ts.map +1 -1
  9. package/dist/commands/quality-gates.js +1 -1
  10. package/dist/commands/specs.d.ts.map +1 -1
  11. package/dist/commands/worktree.d.ts +7 -0
  12. package/dist/commands/worktree.d.ts.map +1 -0
  13. package/dist/commands/worktree.js +136 -0
  14. package/dist/config/lite-scope.d.ts +33 -0
  15. package/dist/config/lite-scope.d.ts.map +1 -0
  16. package/dist/config/lite-scope.js +158 -0
  17. package/dist/config/modes.d.ts +90 -51
  18. package/dist/config/modes.d.ts.map +1 -1
  19. package/dist/config/modes.js +26 -0
  20. package/dist/error-handler.d.ts +3 -16
  21. package/dist/error-handler.d.ts.map +1 -1
  22. package/dist/generators/jest-config-generator.d.ts +32 -0
  23. package/dist/generators/jest-config-generator.d.ts.map +1 -0
  24. package/dist/index.js +36 -0
  25. package/dist/scaffold/claude-hooks.d.ts +28 -0
  26. package/dist/scaffold/claude-hooks.d.ts.map +1 -0
  27. package/dist/scaffold/claude-hooks.js +28 -0
  28. package/dist/scaffold/index.d.ts +2 -0
  29. package/dist/scaffold/index.d.ts.map +1 -1
  30. package/dist/scaffold/index.js +90 -88
  31. package/dist/templates/.caws/schemas/scope.schema.json +52 -0
  32. package/dist/templates/.caws/schemas/working-spec.schema.json +1 -1
  33. package/dist/templates/.caws/schemas/worktrees.schema.json +36 -0
  34. package/dist/templates/.claude/hooks/block-dangerous.sh +33 -0
  35. package/dist/templates/.claude/hooks/lite-sprawl-check.sh +117 -0
  36. package/dist/templates/.claude/hooks/scope-guard.sh +93 -6
  37. package/dist/templates/.claude/hooks/simplification-guard.sh +92 -0
  38. package/dist/templates/.cursor/README.md +0 -3
  39. package/dist/templates/.github/copilot-instructions.md +82 -0
  40. package/dist/templates/.junie/guidelines.md +73 -0
  41. package/dist/templates/.vscode/launch.json +0 -27
  42. package/dist/templates/.windsurf/rules/caws-quality-standards.md +54 -0
  43. package/dist/templates/CLAUDE.md +101 -0
  44. package/dist/templates/agents.md +73 -1016
  45. package/dist/templates/docs/README.md +5 -5
  46. package/dist/test-analysis.d.ts +50 -1
  47. package/dist/test-analysis.d.ts.map +1 -1
  48. package/dist/utils/error-categories.d.ts +52 -0
  49. package/dist/utils/error-categories.d.ts.map +1 -0
  50. package/dist/utils/gitignore-updater.d.ts +1 -1
  51. package/dist/utils/gitignore-updater.d.ts.map +1 -1
  52. package/dist/utils/gitignore-updater.js +4 -0
  53. package/dist/utils/ide-detection.js +133 -0
  54. package/dist/utils/quality-gates-utils.d.ts +49 -0
  55. package/dist/utils/quality-gates-utils.d.ts.map +1 -0
  56. package/dist/utils/typescript-detector.d.ts +8 -5
  57. package/dist/utils/typescript-detector.d.ts.map +1 -1
  58. package/dist/validation/spec-validation.d.ts.map +1 -1
  59. package/dist/worktree/worktree-manager.d.ts +54 -0
  60. package/dist/worktree/worktree-manager.d.ts.map +1 -0
  61. package/dist/worktree/worktree-manager.js +378 -0
  62. package/package.json +5 -1
  63. package/templates/.caws/schemas/scope.schema.json +52 -0
  64. package/templates/.caws/schemas/working-spec.schema.json +1 -1
  65. package/templates/.caws/schemas/worktrees.schema.json +36 -0
  66. package/templates/.claude/hooks/block-dangerous.sh +33 -0
  67. package/templates/.claude/hooks/lite-sprawl-check.sh +117 -0
  68. package/templates/.claude/hooks/scope-guard.sh +93 -6
  69. package/templates/.claude/hooks/simplification-guard.sh +92 -0
  70. package/templates/.cursor/README.md +0 -3
  71. package/templates/.github/copilot-instructions.md +82 -0
  72. package/templates/.junie/guidelines.md +73 -0
  73. package/templates/.vscode/launch.json +0 -27
  74. package/templates/.windsurf/rules/caws-quality-standards.md +54 -0
  75. package/templates/AGENTS.md +104 -0
  76. package/templates/CLAUDE.md +101 -0
  77. package/templates/docs/README.md +5 -5
  78. package/templates/.github/copilot/instructions.md +0 -311
  79. package/templates/agents.md +0 -1047
@@ -0,0 +1,158 @@
1
+ /**
2
+ * @fileoverview CAWS Lite-Mode Scope Configuration Loader
3
+ * Reads and validates .caws/scope.json for guardrails-only mode
4
+ * @author @darianrosebrook
5
+ */
6
+
7
+ const fs = require('fs-extra');
8
+ const path = require('path');
9
+ const micromatch = require('micromatch');
10
+
11
+ const SCOPE_FILE = '.caws/scope.json';
12
+
13
+ /**
14
+ * Default scope configuration for lite mode
15
+ * @returns {Object} Default scope.json contents
16
+ */
17
+ function getLiteScopeDefaults() {
18
+ return {
19
+ version: 1,
20
+ allowedDirectories: ['src/', 'tests/', 'docs/'],
21
+ bannedPatterns: {
22
+ files: ['*-enhanced.*', '*-final.*', '*-v2.*', '*-copy.*'],
23
+ directories: ['*venv*', '.venv', 'm-venv', 'env/'],
24
+ docs: ['*-summary.md', '*-recap.md', '*-plan.md', 'sprint-*'],
25
+ },
26
+ maxNewFilesPerCommit: 10,
27
+ designatedVenvPath: '.venv',
28
+ };
29
+ }
30
+
31
+ /**
32
+ * Load lite scope configuration from .caws/scope.json
33
+ * @param {string} [projectRoot] - Project root directory (defaults to cwd)
34
+ * @returns {Object} Scope configuration (defaults if file not found)
35
+ */
36
+ function loadLiteScope(projectRoot) {
37
+ const root = projectRoot || process.cwd();
38
+ const scopePath = path.join(root, SCOPE_FILE);
39
+
40
+ try {
41
+ if (!fs.existsSync(scopePath)) {
42
+ return getLiteScopeDefaults();
43
+ }
44
+
45
+ const raw = fs.readFileSync(scopePath, 'utf8');
46
+ const config = JSON.parse(raw);
47
+
48
+ // Merge with defaults for any missing fields
49
+ const defaults = getLiteScopeDefaults();
50
+ return {
51
+ version: config.version || defaults.version,
52
+ allowedDirectories: config.allowedDirectories || defaults.allowedDirectories,
53
+ bannedPatterns: {
54
+ files: config.bannedPatterns?.files || defaults.bannedPatterns.files,
55
+ directories: config.bannedPatterns?.directories || defaults.bannedPatterns.directories,
56
+ docs: config.bannedPatterns?.docs || defaults.bannedPatterns.docs,
57
+ },
58
+ maxNewFilesPerCommit: config.maxNewFilesPerCommit ?? defaults.maxNewFilesPerCommit,
59
+ designatedVenvPath: config.designatedVenvPath || defaults.designatedVenvPath,
60
+ };
61
+ } catch (error) {
62
+ // If file is malformed, return defaults
63
+ return getLiteScopeDefaults();
64
+ }
65
+ }
66
+
67
+ /**
68
+ * Check if a file path is allowed by the scope configuration
69
+ * @param {string} filePath - Relative file path to check
70
+ * @param {Object} [scope] - Scope configuration (loads from disk if not provided)
71
+ * @param {string} [projectRoot] - Project root directory
72
+ * @returns {boolean} Whether the path is allowed
73
+ */
74
+ function isPathAllowed(filePath, scope, projectRoot) {
75
+ const config = scope || loadLiteScope(projectRoot);
76
+ const dirs = config.allowedDirectories;
77
+
78
+ // If no allowed directories specified, everything is allowed
79
+ if (!dirs || dirs.length === 0) {
80
+ return true;
81
+ }
82
+
83
+ // Normalize the file path
84
+ const normalized = filePath.replace(/\\/g, '/');
85
+
86
+ // Check if file is within any allowed directory
87
+ for (const dir of dirs) {
88
+ const normalizedDir = dir.replace(/\\/g, '/').replace(/\/$/, '');
89
+ if (normalized.startsWith(normalizedDir + '/') || normalized === normalizedDir) {
90
+ return true;
91
+ }
92
+ }
93
+
94
+ // Also allow root-level config files (package.json, etc.)
95
+ if (!normalized.includes('/')) {
96
+ return true;
97
+ }
98
+
99
+ // Allow .caws/ directory itself
100
+ if (normalized.startsWith('.caws/')) {
101
+ return true;
102
+ }
103
+
104
+ return false;
105
+ }
106
+
107
+ /**
108
+ * Check if a filename or path matches any banned pattern
109
+ * @param {string} filePath - File path to check
110
+ * @param {Object} [scope] - Scope configuration (loads from disk if not provided)
111
+ * @param {string} [projectRoot] - Project root directory
112
+ * @returns {{ matched: boolean, pattern: string|null, category: string|null }} Match result
113
+ */
114
+ function matchesBannedPattern(filePath, scope, projectRoot) {
115
+ const config = scope || loadLiteScope(projectRoot);
116
+ const banned = config.bannedPatterns;
117
+ const basename = path.basename(filePath);
118
+ const normalized = filePath.replace(/\\/g, '/');
119
+
120
+ // Check file patterns
121
+ if (banned.files && banned.files.length > 0) {
122
+ if (micromatch.isMatch(basename, banned.files, { dot: true })) {
123
+ const matched = banned.files.find((p) => micromatch.isMatch(basename, p, { dot: true }));
124
+ return { matched: true, pattern: matched, category: 'files' };
125
+ }
126
+ }
127
+
128
+ // Check directory patterns
129
+ if (banned.directories && banned.directories.length > 0) {
130
+ const parts = normalized.split('/');
131
+ for (const part of parts) {
132
+ if (micromatch.isMatch(part, banned.directories, { dot: true })) {
133
+ const matched = banned.directories.find((p) =>
134
+ micromatch.isMatch(part, p, { dot: true })
135
+ );
136
+ return { matched: true, pattern: matched, category: 'directories' };
137
+ }
138
+ }
139
+ }
140
+
141
+ // Check doc patterns
142
+ if (banned.docs && banned.docs.length > 0) {
143
+ if (micromatch.isMatch(basename, banned.docs, { dot: true })) {
144
+ const matched = banned.docs.find((p) => micromatch.isMatch(basename, p, { dot: true }));
145
+ return { matched: true, pattern: matched, category: 'docs' };
146
+ }
147
+ }
148
+
149
+ return { matched: false, pattern: null, category: null };
150
+ }
151
+
152
+ module.exports = {
153
+ loadLiteScope,
154
+ isPathAllowed,
155
+ matchesBannedPattern,
156
+ getLiteScopeDefaults,
157
+ SCOPE_FILE,
158
+ };
@@ -1,18 +1,16 @@
1
1
  export namespace COMPLEXITY_TIERS {
2
- namespace simple {
2
+ namespace lite {
3
3
  let name: string;
4
4
  let description: string;
5
5
  let color: chalk.Chalk;
6
6
  let icon: string;
7
7
  namespace features {
8
8
  let workingSpec: boolean;
9
- let basicValidation: boolean;
10
- let statusDisplay: boolean;
11
- let noQualityGates: boolean;
12
- let noProvenance: boolean;
13
- let noWaivers: boolean;
14
- let noChangeBudgets: boolean;
15
- let noMultiSpec: boolean;
9
+ let destructiveCommandBlocking: boolean;
10
+ let fileSprawlDetection: boolean;
11
+ let scopeFence: boolean;
12
+ let simplificationGuard: boolean;
13
+ let worktreeIsolation: boolean;
16
14
  }
17
15
  namespace qualityRequirements {
18
16
  let testCoverage: number;
@@ -22,12 +20,11 @@ export namespace COMPLEXITY_TIERS {
22
20
  let riskTiers: string[];
23
21
  namespace commands {
24
22
  let init: boolean;
25
- let validate: boolean;
26
23
  let status: boolean;
27
- let specs: boolean;
24
+ let worktree: boolean;
28
25
  }
29
26
  }
30
- namespace standard {
27
+ namespace simple {
31
28
  let name_1: string;
32
29
  export { name_1 as name };
33
30
  let description_1: string;
@@ -39,15 +36,13 @@ export namespace COMPLEXITY_TIERS {
39
36
  export namespace features_1 {
40
37
  let workingSpec_1: boolean;
41
38
  export { workingSpec_1 as workingSpec };
42
- export let fullValidation: boolean;
43
- let statusDisplay_1: boolean;
44
- export { statusDisplay_1 as statusDisplay };
45
- export let qualityGates: boolean;
46
- export let provenance: boolean;
47
- export let waivers: boolean;
48
- export let changeBudgets: boolean;
49
- export let multiSpec: boolean;
50
- export let changeFolders: boolean;
39
+ export let basicValidation: boolean;
40
+ export let statusDisplay: boolean;
41
+ export let noQualityGates: boolean;
42
+ export let noProvenance: boolean;
43
+ export let noWaivers: boolean;
44
+ export let noChangeBudgets: boolean;
45
+ export let noMultiSpec: boolean;
51
46
  }
52
47
  export { features_1 as features };
53
48
  export namespace qualityRequirements_1 {
@@ -64,25 +59,14 @@ export namespace COMPLEXITY_TIERS {
64
59
  export namespace commands_1 {
65
60
  let init_1: boolean;
66
61
  export { init_1 as init };
67
- let validate_1: boolean;
68
- export { validate_1 as validate };
62
+ export let validate: boolean;
69
63
  let status_1: boolean;
70
64
  export { status_1 as status };
71
- let specs_1: boolean;
72
- export { specs_1 as specs };
73
- export let diagnose: boolean;
74
- export let evaluate: boolean;
75
- export let iterate: boolean;
76
- let provenance_1: boolean;
77
- export { provenance_1 as provenance };
78
- let waivers_1: boolean;
79
- export { waivers_1 as waivers };
80
- export let hooks: boolean;
81
- export let archive: boolean;
65
+ export let specs: boolean;
82
66
  }
83
67
  export { commands_1 as commands };
84
68
  }
85
- namespace enterprise {
69
+ namespace standard {
86
70
  let name_2: string;
87
71
  export { name_2 as name };
88
72
  let description_2: string;
@@ -94,6 +78,61 @@ export namespace COMPLEXITY_TIERS {
94
78
  export namespace features_2 {
95
79
  let workingSpec_2: boolean;
96
80
  export { workingSpec_2 as workingSpec };
81
+ export let fullValidation: boolean;
82
+ let statusDisplay_1: boolean;
83
+ export { statusDisplay_1 as statusDisplay };
84
+ export let qualityGates: boolean;
85
+ export let provenance: boolean;
86
+ export let waivers: boolean;
87
+ export let changeBudgets: boolean;
88
+ export let multiSpec: boolean;
89
+ export let changeFolders: boolean;
90
+ }
91
+ export { features_2 as features };
92
+ export namespace qualityRequirements_2 {
93
+ let testCoverage_2: number;
94
+ export { testCoverage_2 as testCoverage };
95
+ let mutationScore_2: number;
96
+ export { mutationScore_2 as mutationScore };
97
+ let contracts_2: string;
98
+ export { contracts_2 as contracts };
99
+ }
100
+ export { qualityRequirements_2 as qualityRequirements };
101
+ let riskTiers_2: string[];
102
+ export { riskTiers_2 as riskTiers };
103
+ export namespace commands_2 {
104
+ let init_2: boolean;
105
+ export { init_2 as init };
106
+ let validate_1: boolean;
107
+ export { validate_1 as validate };
108
+ let status_2: boolean;
109
+ export { status_2 as status };
110
+ let specs_1: boolean;
111
+ export { specs_1 as specs };
112
+ export let diagnose: boolean;
113
+ export let evaluate: boolean;
114
+ export let iterate: boolean;
115
+ let provenance_1: boolean;
116
+ export { provenance_1 as provenance };
117
+ let waivers_1: boolean;
118
+ export { waivers_1 as waivers };
119
+ export let hooks: boolean;
120
+ export let archive: boolean;
121
+ }
122
+ export { commands_2 as commands };
123
+ }
124
+ namespace enterprise {
125
+ let name_3: string;
126
+ export { name_3 as name };
127
+ let description_3: string;
128
+ export { description_3 as description };
129
+ let color_3: chalk.Chalk;
130
+ export { color_3 as color };
131
+ let icon_3: string;
132
+ export { icon_3 as icon };
133
+ export namespace features_3 {
134
+ let workingSpec_3: boolean;
135
+ export { workingSpec_3 as workingSpec };
97
136
  let fullValidation_1: boolean;
98
137
  export { fullValidation_1 as fullValidation };
99
138
  let statusDisplay_2: boolean;
@@ -114,25 +153,25 @@ export namespace COMPLEXITY_TIERS {
114
153
  export let compliance: boolean;
115
154
  export let advancedMonitoring: boolean;
116
155
  }
117
- export { features_2 as features };
118
- export namespace qualityRequirements_2 {
119
- let testCoverage_2: number;
120
- export { testCoverage_2 as testCoverage };
121
- let mutationScore_2: number;
122
- export { mutationScore_2 as mutationScore };
123
- let contracts_2: string;
124
- export { contracts_2 as contracts };
156
+ export { features_3 as features };
157
+ export namespace qualityRequirements_3 {
158
+ let testCoverage_3: number;
159
+ export { testCoverage_3 as testCoverage };
160
+ let mutationScore_3: number;
161
+ export { mutationScore_3 as mutationScore };
162
+ let contracts_3: string;
163
+ export { contracts_3 as contracts };
125
164
  }
126
- export { qualityRequirements_2 as qualityRequirements };
127
- let riskTiers_2: string[];
128
- export { riskTiers_2 as riskTiers };
129
- export namespace commands_2 {
130
- let init_2: boolean;
131
- export { init_2 as init };
165
+ export { qualityRequirements_3 as qualityRequirements };
166
+ let riskTiers_3: string[];
167
+ export { riskTiers_3 as riskTiers };
168
+ export namespace commands_3 {
169
+ let init_3: boolean;
170
+ export { init_3 as init };
132
171
  let validate_2: boolean;
133
172
  export { validate_2 as validate };
134
- let status_2: boolean;
135
- export { status_2 as status };
173
+ let status_3: boolean;
174
+ export { status_3 as status };
136
175
  let specs_2: boolean;
137
176
  export { specs_2 as specs };
138
177
  let diagnose_1: boolean;
@@ -153,7 +192,7 @@ export namespace COMPLEXITY_TIERS {
153
192
  export let testAnalysis: boolean;
154
193
  export let qualityMonitor: boolean;
155
194
  }
156
- export { commands_2 as commands };
195
+ export { commands_3 as commands };
157
196
  }
158
197
  }
159
198
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"modes.d.ts","sourceRoot":"","sources":["../../src/config/modes.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2HA;;;;GAIG;AACH,8BAHW,MAAM,OAKhB;AAED;;;GAGG;AACH,qCAFa,MAAM,EAAE,CAIpB;AA8FD;;;GAGG;AACH,kCAFa,OAAO,CAAC,MAAM,CAAC,CAgB3B;AAED;;;;GAIG;AACH,qCAHW,MAAM,GACJ,OAAO,CAAC,OAAO,CAAC,CAuB5B;AA1ID;;;;;GAKG;AACH,4CAJW,MAAM,SACN,MAAM,GACJ,OAAO,CAKnB;AAED;;;;;GAKG;AACH,0CAJW,MAAM,SACN,MAAM,GACJ,OAAO,CAKnB;AAED;;;;GAIG;AACH,8CAHW,MAAM,OAMhB;AAED;;;;GAIG;AACH,6CAHW,MAAM,GACJ,MAAM,EAAE,CAKpB;AAED;;;;;GAKG;AACH,8CAJW,MAAM,mBACN,MAAM,GACJ,OAAO,CAKnB;AAED;;GAEG;AACH,8CAkCC;AAkDD;;;;GAIG;AACH,0DAFa,MAAM,CAsBlB"}
1
+ {"version":3,"file":"modes.d.ts","sourceRoot":"","sources":["../../src/config/modes.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqJA;;;;GAIG;AACH,8BAHW,MAAM,OAKhB;AAED;;;GAGG;AACH,qCAFa,MAAM,EAAE,CAIpB;AA8FD;;;GAGG;AACH,kCAFa,OAAO,CAAC,MAAM,CAAC,CAgB3B;AAED;;;;GAIG;AACH,qCAHW,MAAM,GACJ,OAAO,CAAC,OAAO,CAAC,CAuB5B;AA1ID;;;;;GAKG;AACH,4CAJW,MAAM,SACN,MAAM,GACJ,OAAO,CAKnB;AAED;;;;;GAKG;AACH,0CAJW,MAAM,SACN,MAAM,GACJ,OAAO,CAKnB;AAED;;;;GAIG;AACH,8CAHW,MAAM,OAMhB;AAED;;;;GAIG;AACH,6CAHW,MAAM,GACJ,MAAM,EAAE,CAKpB;AAED;;;;;GAKG;AACH,8CAJW,MAAM,mBACN,MAAM,GACJ,OAAO,CAKnB;AAED;;GAEG;AACH,8CAkCC;AAkDD;;;;GAIG;AACH,0DAFa,MAAM,CAsBlB"}
@@ -10,6 +10,32 @@ const chalk = require('chalk');
10
10
  * CAWS Complexity Tiers
11
11
  */
12
12
  const COMPLEXITY_TIERS = {
13
+ lite: {
14
+ name: 'Lite',
15
+ description: 'Guardrails-only mode — no YAML specs required',
16
+ color: chalk.magenta,
17
+ icon: '🛡️',
18
+ features: {
19
+ workingSpec: false,
20
+ destructiveCommandBlocking: true,
21
+ fileSprawlDetection: true,
22
+ scopeFence: true,
23
+ simplificationGuard: true,
24
+ worktreeIsolation: true,
25
+ },
26
+ qualityRequirements: {
27
+ testCoverage: 0,
28
+ mutationScore: 0,
29
+ contracts: 'none',
30
+ },
31
+ riskTiers: ['T3'],
32
+ commands: {
33
+ init: true,
34
+ status: true,
35
+ worktree: true,
36
+ },
37
+ },
38
+
13
39
  simple: {
14
40
  name: 'Simple',
15
41
  description: 'Minimal CAWS for small projects and quick prototyping',
@@ -8,16 +8,7 @@ export class CAWSError extends Error {
8
8
  timestamp: Date;
9
9
  executionTime: any;
10
10
  }
11
- export namespace ERROR_CATEGORIES {
12
- let VALIDATION: string;
13
- let PERMISSION: string;
14
- let FILESYSTEM: string;
15
- let NETWORK: string;
16
- let CONFIGURATION: string;
17
- let USER_INPUT: string;
18
- let DEPENDENCY: string;
19
- let UNKNOWN: string;
20
- }
11
+ import { ERROR_CATEGORIES } from "./utils/error-categories";
21
12
  /**
22
13
  * Execution timing utilities
23
14
  */
@@ -29,12 +20,7 @@ export class ExecutionTimer {
29
20
  getDuration(): number;
30
21
  formatDuration(): string;
31
22
  }
32
- /**
33
- * Get error category from error object or message
34
- * @param {Error|string} error - Error object or message
35
- * @returns {string} Error category
36
- */
37
- export function getErrorCategory(error: Error | string): string;
23
+ import { getErrorCategory } from "./utils/error-categories";
38
24
  /**
39
25
  * Wrap async operations with consistent error handling and timing
40
26
  * @param {Function} operation - Async operation to wrap
@@ -161,4 +147,5 @@ export function getAllTroubleshootingGuides(): any;
161
147
  * @returns {string|null} Issue key if match found, null otherwise
162
148
  */
163
149
  export function suggestTroubleshootingGuide(errorMessage: string): string | null;
150
+ export { ERROR_CATEGORIES, getErrorCategory };
164
151
  //# sourceMappingURL=error-handler.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"error-handler.d.ts","sourceRoot":"","sources":["../src/error-handler.js"],"names":[],"mappings":"AA0GA;;GAEG;AACH;IACE,+DAOC;IAJC,cAAqD;IACrD,mBAA2F;IAC3F,gBAA2B;IAC3B,mBAAyB;CAE5B;;;;;;;;;;;AAED;;GAEG;AACH;IAEI,kBAAqB;IACrB,gBAAmB;IAGrB,cAEC;IAED,cAGC;IAED,sBAIC;IAED,yBAMC;CACF;AAjHD;;;;GAIG;AACH,wCAHW,KAAK,GAAC,MAAM,GACV,MAAM,CA+DlB;AAiDD;;;;;;GAMG;AACH,yDAJW,MAAM,kBACN,OAAO,GACL,OAAO,CAAC,GAAG,CAAC,CA8BxB;AAED;;;;;;GAMG;AACH,wDAJW,MAAM,kBACN,OAAO,GACL,GAAG,CA8Bf;AAgSD;;;;;GAKG;AACH,sCAJW,KAAK,wBAEL,OAAO,QAmDjB;AA0JD;;;GAGG;AACH,2CAqBC;AAnXD;;;;;;GAMG;AACH,8CALW,KAAK,YACL,MAAM,kBAEJ,MAAM,EAAE,CAwDpB;AAED;;;;;GAKG;AACH,+CAJW,MAAM,kBAEJ,MAAM,CA4BlB;AAxJD;;;;;GAKG;AACH,0CAJW,MAAM,iBACN,MAAM,EAAE,GACN,MAAM,GAAC,IAAI,CAiBvB;AAjHD;;GAEG;AACH;;;;;EAuFE;AA4JF;;;;GAIG;AACH,qDAFW,OAAO,UAIjB;AAED;;;GAGG;AACH,gCAFa,OAAO,CAQnB;AAED;;;;GAIG;AACH,kDAFW,OAAO,OAcjB;AA2DD;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0GE;AAEF;;;;GAIG;AACH,kDAHW,MAAM,GACJ,MAAO,IAAI,CAIvB;AAED;;;GAGG;AACH,mDAEC;AAED;;;;GAIG;AACH,0DAHW,MAAM,GACJ,MAAM,GAAC,IAAI,CAmBvB"}
1
+ {"version":3,"file":"error-handler.d.ts","sourceRoot":"","sources":["../src/error-handler.js"],"names":[],"mappings":"AAcA;;GAEG;AACH;IACE,+DAOC;IAJC,cAAqD;IACrD,mBAA2F;IAC3F,gBAA2B;IAC3B,mBAAyB;CAE5B;;AAED;;GAEG;AACH;IAEI,kBAAqB;IACrB,gBAAmB;IAGrB,cAEC;IAED,cAGC;IAED,sBAIC;IAED,yBAMC;CACF;;AAED;;;;;;GAMG;AACH,yDAJW,MAAM,kBACN,OAAO,GACL,OAAO,CAAC,GAAG,CAAC,CA8BxB;AAED;;;;;;GAMG;AACH,wDAJW,MAAM,kBACN,OAAO,GACL,GAAG,CA8Bf;AAgSD;;;;;GAKG;AACH,sCAJW,KAAK,wBAEL,OAAO,QAmDjB;AA0JD;;;GAGG;AACH,2CAqBC;AAnXD;;;;;;GAMG;AACH,8CALW,KAAK,YACL,MAAM,kBAEJ,MAAM,EAAE,CAwDpB;AAED;;;;;GAKG;AACH,+CAJW,MAAM,kBAEJ,MAAM,CA4BlB;AAxJD;;;;;GAKG;AACH,0CAJW,MAAM,iBACN,MAAM,EAAE,GACN,MAAM,GAAC,IAAI,CAiBvB;AAjHD;;GAEG;AACH;;;;;EAuFE;AA4JF;;;;GAIG;AACH,qDAFW,OAAO,UAIjB;AAED;;;GAGG;AACH,gCAFa,OAAO,CAQnB;AAED;;;;GAIG;AACH,kDAFW,OAAO,OAcjB;AA2DD;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0GE;AAEF;;;;GAIG;AACH,kDAHW,MAAM,GACJ,MAAO,IAAI,CAIvB;AAED;;;GAGG;AACH,mDAEC;AAED;;;;GAIG;AACH,0DAHW,MAAM,GACJ,MAAM,GAAC,IAAI,CAmBvB"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Configure Jest for TypeScript project
3
+ * @param {string} projectDir - Project directory path
4
+ * @param {Object} options - Configuration options
5
+ * @returns {Promise<Object>} Configuration result
6
+ */
7
+ export function configureJestForTypeScript(projectDir?: string, options?: any): Promise<any>;
8
+ /**
9
+ * Generate Jest configuration for TypeScript project
10
+ * @param {Object} options - Configuration options
11
+ * @returns {string} Jest configuration content
12
+ */
13
+ export function generateJestConfig(options?: any): string;
14
+ /**
15
+ * Generate test setup file for TypeScript
16
+ * @returns {string} Setup file content
17
+ */
18
+ export function generateTestSetup(): string;
19
+ /**
20
+ * Install Jest and TypeScript dependencies
21
+ * @param {string} projectDir - Project directory
22
+ * @param {Object} packageJson - Existing package.json
23
+ * @returns {Promise<Object>} Installation result
24
+ */
25
+ export function installJestDependencies(projectDir: string, packageJson: any): Promise<any>;
26
+ /**
27
+ * Get Jest configuration recommendations
28
+ * @param {string} projectDir - Project directory path
29
+ * @returns {Object} Recommendations
30
+ */
31
+ export function getJestRecommendations(projectDir?: string): any;
32
+ //# sourceMappingURL=jest-config-generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jest-config-generator.d.ts","sourceRoot":"","sources":["../../src/generators/jest-config-generator.js"],"names":[],"mappings":"AA+GA;;;;;GAKG;AACH,wDAJW,MAAM,kBAEJ,OAAO,KAAQ,CAgE3B;AAzKD;;;;GAIG;AACH,mDAFa,MAAM,CA0ClB;AAED;;;GAGG;AACH,qCAFa,MAAM,CAiBlB;AAED;;;;;GAKG;AACH,oDAJW,MAAM,qBAEJ,OAAO,KAAQ,CA2B3B;AAwED;;;;GAIG;AACH,oDAHW,MAAM,OAkDhB"}
package/dist/index.js CHANGED
@@ -49,6 +49,7 @@ const { specsCommand } = require('./commands/specs');
49
49
  const { modeCommand } = require('./commands/mode');
50
50
  const { tutorialCommand } = require('./commands/tutorial');
51
51
  const { planCommand } = require('./commands/plan');
52
+ const { worktreeCommand } = require('./commands/worktree');
52
53
 
53
54
  // Import scaffold functionality
54
55
  const { scaffoldProject, setScaffoldDependencies } = require('./scaffold');
@@ -105,6 +106,8 @@ program
105
106
  .option('-i, --interactive', 'Run interactive setup wizard', true)
106
107
  .option('--non-interactive', 'Skip interactive prompts (use defaults)', false)
107
108
  .option('--template <template>', 'Use specific project template')
109
+ .option('--mode <mode>', 'CAWS mode (lite, simple, standard, enterprise)')
110
+ .option('--ide <ides>', 'IDE integrations to install (comma-separated: cursor,claude,vscode,intellij,windsurf,copilot,all,none)')
108
111
  .action(initProject);
109
112
 
110
113
  // Scaffold command
@@ -116,6 +119,7 @@ program
116
119
  .option('--with-codemods', 'Include codemod scripts', false)
117
120
  .option('--with-oidc', 'Include OIDC trusted publisher setup', false)
118
121
  .option('--with-quality-gates', 'Install quality gates package and scripts', false)
122
+ .option('--ide <ides>', 'IDE integrations to install (comma-separated: cursor,claude,vscode,intellij,windsurf,copilot,all,none)')
119
123
  .action(scaffoldProject);
120
124
 
121
125
  // Validate command
@@ -343,6 +347,37 @@ program
343
347
  .option('--output <path>', 'Output file path for the plan')
344
348
  .action((action, options) => planCommand(action, options));
345
349
 
350
+ // Worktree command group
351
+ const worktreeCmd = program
352
+ .command('worktree')
353
+ .description('Manage git worktrees for agent scope isolation');
354
+
355
+ worktreeCmd
356
+ .command('create <name>')
357
+ .description('Create a new isolated worktree')
358
+ .option('--scope <patterns>', 'Sparse checkout patterns (comma-separated, e.g., "src/auth/**")')
359
+ .option('--base-branch <branch>', 'Base branch to create from')
360
+ .option('--spec-id <id>', 'Associated spec ID')
361
+ .action((name, options) => worktreeCommand('create', { name, ...options }));
362
+
363
+ worktreeCmd
364
+ .command('list')
365
+ .description('List all managed worktrees')
366
+ .action(() => worktreeCommand('list'));
367
+
368
+ worktreeCmd
369
+ .command('destroy <name>')
370
+ .description('Destroy a worktree')
371
+ .option('--delete-branch', 'Also delete the associated branch', false)
372
+ .option('--force', 'Force removal even if worktree is dirty', false)
373
+ .action((name, options) => worktreeCommand('destroy', { name, ...options }));
374
+
375
+ worktreeCmd
376
+ .command('prune')
377
+ .description('Clean up stale worktree entries')
378
+ .option('--max-age <days>', 'Remove entries older than N days', '30')
379
+ .action((options) => worktreeCommand('prune', options));
380
+
346
381
  // Templates command
347
382
  program
348
383
  .command('templates [subcommand]')
@@ -611,6 +646,7 @@ program.exitOverride((err) => {
611
646
  'hooks',
612
647
  'burnup',
613
648
  'tool',
649
+ 'worktree',
614
650
  ];
615
651
  const similar = findSimilarCommand(commandName, validCommands);
616
652
 
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Scaffold Claude Code hooks for a CAWS project
3
+ * Creates .claude/settings.json with hooks and .claude/hooks/ directory with scripts
4
+ *
5
+ * @param {string} projectDir - Project directory path
6
+ * @param {string[]} levels - Hook levels to enable: 'safety', 'quality', 'scope', 'audit'
7
+ */
8
+ export function scaffoldClaudeHooks(projectDir: string, levels?: string[]): Promise<void>;
9
+ /**
10
+ * Generate Claude Code settings with hooks configuration
11
+ * @param {string[]} levels - Enabled hook levels
12
+ * @param {Set<string>} enabledHooks - Set of enabled hook script names
13
+ * @returns {Object} Settings object for settings.json
14
+ */
15
+ export function generateClaudeSettings(levels: string[], _enabledHooks: any): any;
16
+ /**
17
+ * Check if Claude Code hooks are already configured
18
+ * @param {string} projectDir - Project directory
19
+ * @returns {boolean} True if hooks are configured
20
+ */
21
+ export function hasClaudeHooks(projectDir: string): boolean;
22
+ /**
23
+ * List configured Claude Code hooks
24
+ * @param {string} projectDir - Project directory
25
+ * @returns {Object} Hook configuration or null
26
+ */
27
+ export function getClaudeHooksConfig(projectDir: string): any;
28
+ //# sourceMappingURL=claude-hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-hooks.d.ts","sourceRoot":"","sources":["../../src/scaffold/claude-hooks.js"],"names":[],"mappings":"AAaA;;;;;;GAMG;AACH,gDAHW,MAAM,WACN,MAAM,EAAE,iBA6HlB;AAED;;;;;GAKG;AACH,+CAJW,MAAM,EAAE,2BAuJlB;AAED;;;;GAIG;AACH,2CAHW,MAAM,GACJ,OAAO,CAcnB;AAED;;;;GAIG;AACH,iDAHW,MAAM,OAehB"}
@@ -57,6 +57,7 @@ async function scaffoldClaudeHooks(projectDir, levels = ['safety', 'quality', 's
57
57
  quality: ['quality-check.sh', 'validate-spec.sh'],
58
58
  scope: ['scope-guard.sh', 'naming-check.sh'],
59
59
  audit: ['audit.sh'],
60
+ lite: ['block-dangerous.sh', 'scope-guard.sh', 'lite-sprawl-check.sh', 'simplification-guard.sh'],
60
61
  };
61
62
 
62
63
  // Determine which hooks to enable
@@ -80,6 +81,8 @@ async function scaffoldClaudeHooks(projectDir, levels = ['safety', 'quality', 's
80
81
  'block-dangerous.sh',
81
82
  'scope-guard.sh',
82
83
  'naming-check.sh',
84
+ 'lite-sprawl-check.sh',
85
+ 'simplification-guard.sh',
83
86
  ];
84
87
 
85
88
  for (const script of allHookScripts) {
@@ -229,6 +232,31 @@ function generateClaudeSettings(levels, _enabledHooks) {
229
232
  });
230
233
  }
231
234
 
235
+ if (levels.includes('lite')) {
236
+ // Lite mode: sprawl check on Write, simplification guard on Edit
237
+ settings.hooks.PreToolUse = settings.hooks.PreToolUse || [];
238
+ settings.hooks.PreToolUse.push({
239
+ matcher: 'Write',
240
+ hooks: [
241
+ {
242
+ type: 'command',
243
+ command: '"$CLAUDE_PROJECT_DIR"/.claude/hooks/lite-sprawl-check.sh',
244
+ timeout: 10,
245
+ },
246
+ ],
247
+ });
248
+ settings.hooks.PreToolUse.push({
249
+ matcher: 'Edit',
250
+ hooks: [
251
+ {
252
+ type: 'command',
253
+ command: '"$CLAUDE_PROJECT_DIR"/.claude/hooks/simplification-guard.sh',
254
+ timeout: 10,
255
+ },
256
+ ],
257
+ });
258
+ }
259
+
232
260
  if (levels.includes('audit')) {
233
261
  // Session audit logging
234
262
  settings.hooks.SessionStart = settings.hooks.SessionStart || [];
@@ -7,9 +7,11 @@ export function scaffoldIDEIntegrations(targetDir: any, options: any): Promise<{
7
7
  added: number;
8
8
  skipped: number;
9
9
  }>;
10
+ import { scaffoldClaudeHooks } from "./claude-hooks";
10
11
  /**
11
12
  * Set dependencies for scaffold module
12
13
  * @param {Object} deps - Dependencies object
13
14
  */
14
15
  export function setScaffoldDependencies(deps: any): void;
16
+ export { scaffoldClaudeHooks };
15
17
  //# sourceMappingURL=index.d.ts.map
@@ -1 +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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scaffold/index.js"],"names":[],"mappings":"AA8MA;;;GAGG;AACH,6DA6jBC;AAztBD;;;GAyIC;;AAMD;;;GAGG;AACH,yDAGC"}