@paths.design/caws-cli 2.0.0 → 3.0.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 (50) hide show
  1. package/dist/index.d.ts.map +1 -1
  2. package/dist/index.js +101 -96
  3. package/package.json +3 -3
  4. package/templates/agents.md +820 -0
  5. package/templates/apps/tools/caws/COMPLETION_REPORT.md +331 -0
  6. package/templates/apps/tools/caws/MIGRATION_SUMMARY.md +360 -0
  7. package/templates/apps/tools/caws/README.md +463 -0
  8. package/templates/apps/tools/caws/TEST_STATUS.md +365 -0
  9. package/templates/apps/tools/caws/attest.js +357 -0
  10. package/templates/apps/tools/caws/ci-optimizer.js +642 -0
  11. package/templates/apps/tools/caws/config.ts +245 -0
  12. package/templates/apps/tools/caws/cross-functional.js +876 -0
  13. package/templates/apps/tools/caws/dashboard.js +1112 -0
  14. package/templates/apps/tools/caws/flake-detector.ts +362 -0
  15. package/templates/apps/tools/caws/gates.js +198 -0
  16. package/templates/apps/tools/caws/gates.ts +237 -0
  17. package/templates/apps/tools/caws/language-adapters.ts +381 -0
  18. package/templates/apps/tools/caws/language-support.d.ts +367 -0
  19. package/templates/apps/tools/caws/language-support.d.ts.map +1 -0
  20. package/templates/apps/tools/caws/language-support.js +585 -0
  21. package/templates/apps/tools/caws/legacy-assessment.ts +408 -0
  22. package/templates/apps/tools/caws/legacy-assessor.js +764 -0
  23. package/templates/apps/tools/caws/mutant-analyzer.js +734 -0
  24. package/templates/apps/tools/caws/perf-budgets.ts +349 -0
  25. package/templates/apps/tools/caws/property-testing.js +707 -0
  26. package/templates/apps/tools/caws/provenance.d.ts +14 -0
  27. package/templates/apps/tools/caws/provenance.d.ts.map +1 -0
  28. package/templates/apps/tools/caws/provenance.js +132 -0
  29. package/templates/apps/tools/caws/provenance.ts +211 -0
  30. package/templates/apps/tools/caws/schemas/waivers.schema.json +30 -0
  31. package/templates/apps/tools/caws/schemas/working-spec.schema.json +115 -0
  32. package/templates/apps/tools/caws/scope-guard.js +208 -0
  33. package/templates/apps/tools/caws/security-provenance.ts +483 -0
  34. package/templates/apps/tools/caws/shared/base-tool.ts +281 -0
  35. package/templates/apps/tools/caws/shared/config-manager.ts +366 -0
  36. package/templates/apps/tools/caws/shared/gate-checker.ts +597 -0
  37. package/templates/apps/tools/caws/shared/types.ts +444 -0
  38. package/templates/apps/tools/caws/shared/validator.ts +305 -0
  39. package/templates/apps/tools/caws/shared/waivers-manager.ts +174 -0
  40. package/templates/apps/tools/caws/spec-test-mapper.ts +391 -0
  41. package/templates/apps/tools/caws/templates/working-spec.template.yml +60 -0
  42. package/templates/apps/tools/caws/test-quality.js +578 -0
  43. package/templates/apps/tools/caws/tools-allow.json +331 -0
  44. package/templates/apps/tools/caws/validate.js +76 -0
  45. package/templates/apps/tools/caws/validate.ts +228 -0
  46. package/templates/apps/tools/caws/waivers.js +344 -0
  47. package/templates/apps/tools/caws/waivers.yml +19 -0
  48. package/templates/codemod/README.md +1 -0
  49. package/templates/codemod/test.js +1 -0
  50. package/templates/docs/README.md +150 -0
@@ -0,0 +1,237 @@
1
+ #!/usr/bin/env tsx
2
+
3
+ /**
4
+ * CAWS Gates Tool - Enhanced Implementation
5
+ * CLI wrapper for CawsGateChecker with tier policies
6
+ *
7
+ * @author @darianrosebrook
8
+ */
9
+
10
+ import { CawsGateChecker } from './shared/gate-checker.js';
11
+ import { CawsConfigManager } from './shared/config-manager.js';
12
+
13
+ // Tier policies for quality gates
14
+ const TIER_POLICIES = {
15
+ 1: {
16
+ branch_coverage: 0.9,
17
+ mutation_score: 0.7,
18
+ max_files: 40,
19
+ max_loc: 1500,
20
+ trust_score: 85,
21
+ },
22
+ 2: {
23
+ branch_coverage: 0.8,
24
+ mutation_score: 0.5,
25
+ max_files: 25,
26
+ max_loc: 1000,
27
+ trust_score: 82,
28
+ },
29
+ 3: {
30
+ branch_coverage: 0.7,
31
+ mutation_score: 0.3,
32
+ max_files: 15,
33
+ max_loc: 500,
34
+ trust_score: 75,
35
+ },
36
+ };
37
+
38
+ class GatesCLI {
39
+ private gateChecker: CawsGateChecker;
40
+ private configManager: CawsConfigManager;
41
+
42
+ constructor() {
43
+ this.gateChecker = new CawsGateChecker();
44
+ this.configManager = new CawsConfigManager();
45
+ }
46
+
47
+ /**
48
+ * Show tier policy
49
+ */
50
+ showTierPolicy(tier: number = 1): void {
51
+ const policy = TIER_POLICIES[tier as keyof typeof TIER_POLICIES];
52
+ if (!policy) {
53
+ console.error(`āŒ Unknown tier: ${tier}`);
54
+ process.exit(1);
55
+ }
56
+
57
+ console.log(`šŸ“‹ Tier ${tier} Policy:`);
58
+ console.log(`Branch Coverage: ≄${policy.branch_coverage * 100}%`);
59
+ console.log(`Mutation Score: ≄${policy.mutation_score * 100}%`);
60
+ console.log(`Max Files: ${policy.max_files}`);
61
+ console.log(`Max LOC: ${policy.max_loc}`);
62
+ console.log(`Trust Score: ≄${policy.trust_score}`);
63
+ console.log('Requires Contracts: true');
64
+ console.log('Manual Review: Required');
65
+ }
66
+
67
+ /**
68
+ * Enforce coverage gate using CawsGateChecker
69
+ */
70
+ async enforceCoverageGate(tier: number = 2): Promise<boolean> {
71
+ try {
72
+ const policy = TIER_POLICIES[tier as keyof typeof TIER_POLICIES];
73
+ const result = await this.gateChecker.checkCoverage({
74
+ tier,
75
+ workingDirectory: process.cwd(),
76
+ });
77
+
78
+ if (result.passed) {
79
+ console.log(
80
+ `āœ… Coverage gate passed: ${(result.score * 100).toFixed(1)}% ≄ ${policy.branch_coverage * 100}%`
81
+ );
82
+ return true;
83
+ } else {
84
+ console.log(
85
+ `āŒ Coverage gate failed: ${(result.score * 100).toFixed(1)}% < ${policy.branch_coverage * 100}%`
86
+ );
87
+ if (result.errors && result.errors.length > 0) {
88
+ result.errors.forEach((error) => console.error(` - ${error}`));
89
+ }
90
+ return false;
91
+ }
92
+ } catch (error) {
93
+ console.error(`āŒ Coverage gate check failed: ${error}`);
94
+ return false;
95
+ }
96
+ }
97
+
98
+ /**
99
+ * Enforce mutation gate using CawsGateChecker
100
+ */
101
+ async enforceMutationGate(tier: number = 2): Promise<boolean> {
102
+ try {
103
+ const policy = TIER_POLICIES[tier as keyof typeof TIER_POLICIES];
104
+ const result = await this.gateChecker.checkMutation({
105
+ tier,
106
+ workingDirectory: process.cwd(),
107
+ });
108
+
109
+ if (result.passed) {
110
+ console.log(
111
+ `āœ… Mutation gate passed: ${(result.score * 100).toFixed(1)}% ≄ ${policy.mutation_score * 100}%`
112
+ );
113
+ return true;
114
+ } else {
115
+ console.log(
116
+ `āŒ Mutation gate failed: ${(result.score * 100).toFixed(1)}% < ${policy.mutation_score * 100}%`
117
+ );
118
+ if (result.errors && result.errors.length > 0) {
119
+ result.errors.forEach((error) => console.error(` - ${error}`));
120
+ }
121
+ return false;
122
+ }
123
+ } catch (error) {
124
+ console.error(`āŒ Mutation gate check failed: ${error}`);
125
+ return false;
126
+ }
127
+ }
128
+
129
+ /**
130
+ * Enforce contract gate using CawsGateChecker
131
+ */
132
+ async enforceContractGate(tier: number = 2): Promise<boolean> {
133
+ try {
134
+ const result = await this.gateChecker.checkContracts({
135
+ tier,
136
+ workingDirectory: process.cwd(),
137
+ });
138
+
139
+ if (result.passed) {
140
+ console.log('āœ… Contract gate passed');
141
+ return true;
142
+ } else {
143
+ console.log('āŒ Contract gate failed');
144
+ if (result.errors && result.errors.length > 0) {
145
+ result.errors.forEach((error) => console.error(` - ${error}`));
146
+ }
147
+ return false;
148
+ }
149
+ } catch (error) {
150
+ console.error(`āŒ Contract gate check failed: ${error}`);
151
+ return false;
152
+ }
153
+ }
154
+
155
+ /**
156
+ * Run all gates for a tier
157
+ */
158
+ async runAllGates(tier: number = 2): Promise<boolean> {
159
+ console.log(`\n🚪 Running all gates for Tier ${tier}...\n`);
160
+
161
+ const results = await Promise.all([
162
+ this.enforceCoverageGate(tier),
163
+ this.enforceMutationGate(tier),
164
+ this.enforceContractGate(tier),
165
+ ]);
166
+
167
+ const allPassed = results.every((r) => r);
168
+
169
+ console.log(`\n${'='.repeat(50)}`);
170
+ if (allPassed) {
171
+ console.log('āœ… All gates passed!');
172
+ } else {
173
+ console.log('āŒ Some gates failed');
174
+ }
175
+ console.log('='.repeat(50));
176
+
177
+ return allPassed;
178
+ }
179
+ }
180
+
181
+ // Main CLI handler
182
+ if (import.meta.url === `file://${process.argv[1]}`) {
183
+ (async () => {
184
+ const command = process.argv[2];
185
+ const cli = new GatesCLI();
186
+
187
+ switch (command) {
188
+ case 'tier': {
189
+ const tier = parseInt(process.argv[3]) || 1;
190
+ cli.showTierPolicy(tier);
191
+ break;
192
+ }
193
+
194
+ case 'coverage': {
195
+ const tier = parseInt(process.argv[3]) || 2;
196
+ const passed = await cli.enforceCoverageGate(tier);
197
+ process.exit(passed ? 0 : 1);
198
+ }
199
+
200
+ case 'mutation': {
201
+ const tier = parseInt(process.argv[3]) || 2;
202
+ const passed = await cli.enforceMutationGate(tier);
203
+ process.exit(passed ? 0 : 1);
204
+ }
205
+
206
+ case 'contracts': {
207
+ const tier = parseInt(process.argv[3]) || 2;
208
+ const passed = await cli.enforceContractGate(tier);
209
+ process.exit(passed ? 0 : 1);
210
+ }
211
+
212
+ case 'all': {
213
+ const tier = parseInt(process.argv[3]) || 2;
214
+ const passed = await cli.runAllGates(tier);
215
+ process.exit(passed ? 0 : 1);
216
+ }
217
+
218
+ default:
219
+ console.log('CAWS Gates Tool - Quality Gate Enforcement');
220
+ console.log('');
221
+ console.log('Commands:');
222
+ console.log(' tier <tier> - Show tier policy');
223
+ console.log(' coverage <tier> - Enforce coverage gate');
224
+ console.log(' mutation <tier> - Enforce mutation gate');
225
+ console.log(' contracts <tier> - Enforce contract gate');
226
+ console.log(' all <tier> - Run all gates for tier');
227
+ console.log('');
228
+ console.log('Examples:');
229
+ console.log(' gates.ts tier 1');
230
+ console.log(' gates.ts coverage 2');
231
+ console.log(' gates.ts all 2');
232
+ process.exit(1);
233
+ }
234
+ })();
235
+ }
236
+
237
+ export { GatesCLI };
@@ -0,0 +1,381 @@
1
+ #!/usr/bin/env tsx
2
+
3
+ /**
4
+ * CAWS Language Adapter Manager
5
+ * Multi-language support for TypeScript, Python, Rust, Go, Java
6
+ *
7
+ * @author @darianrosebrook
8
+ */
9
+
10
+ import * as path from 'path';
11
+ import { CawsBaseTool } from './shared/base-tool.js';
12
+ import { TierPolicy, GateConfig } from './shared/types.js';
13
+
14
+ interface LanguageAdapter {
15
+ language: string;
16
+ fileExtensions: string[];
17
+ tools: {
18
+ unitTest: { command: string; args: string[] };
19
+ coverage: { command: string; args: string[] };
20
+ mutationTest?: { command: string; args: string[] };
21
+ contractTest?: { command: string; args: string[] };
22
+ lint: { command: string; args: string[] };
23
+ };
24
+ tierAdjustments?: {
25
+ [tier: number]: Partial<TierPolicy>;
26
+ };
27
+ fallbacks?: {
28
+ mutation?: string; // What to do if mutation testing unavailable
29
+ contracts?: string;
30
+ };
31
+ }
32
+
33
+ export class LanguageAdapterManager extends CawsBaseTool {
34
+ private adapters: Map<string, LanguageAdapter> = new Map();
35
+
36
+ constructor() {
37
+ super();
38
+ this.initializeAdapters();
39
+ }
40
+
41
+ private initializeAdapters(): void {
42
+ // TypeScript/JavaScript adapter
43
+ this.adapters.set('typescript', {
44
+ language: 'typescript',
45
+ fileExtensions: ['.ts', '.tsx', '.js', '.jsx'],
46
+ tools: {
47
+ unitTest: { command: 'vitest', args: ['run'] },
48
+ coverage: { command: 'vitest', args: ['run', '--coverage'] },
49
+ mutationTest: { command: 'stryker', args: ['run'] },
50
+ contractTest: { command: 'pact', args: ['verify'] },
51
+ lint: { command: 'eslint', args: ['.'] },
52
+ },
53
+ });
54
+
55
+ // Python adapter
56
+ this.adapters.set('python', {
57
+ language: 'python',
58
+ fileExtensions: ['.py'],
59
+ tools: {
60
+ unitTest: { command: 'pytest', args: [] },
61
+ coverage: { command: 'pytest', args: ['--cov'] },
62
+ mutationTest: { command: 'mutmut', args: ['run'] },
63
+ contractTest: { command: 'schemathesis', args: ['run'] },
64
+ lint: { command: 'ruff', args: ['check', '.'] },
65
+ },
66
+ tierAdjustments: {
67
+ 1: { min_mutation: 0.6 }, // Python mutation testing is less mature
68
+ 2: { min_mutation: 0.4 },
69
+ 3: { min_mutation: 0.25 },
70
+ },
71
+ fallbacks: {
72
+ mutation: 'If mutation testing unavailable, increase integration test coverage by 20%',
73
+ contracts: 'Use pytest with OpenAPI schema validation',
74
+ },
75
+ });
76
+
77
+ // Rust adapter
78
+ this.adapters.set('rust', {
79
+ language: 'rust',
80
+ fileExtensions: ['.rs'],
81
+ tools: {
82
+ unitTest: { command: 'cargo', args: ['test'] },
83
+ coverage: { command: 'cargo', args: ['tarpaulin', '--out', 'Json'] },
84
+ mutationTest: { command: 'cargo', args: ['mutants'] },
85
+ lint: { command: 'cargo', args: ['clippy', '--', '-D', 'warnings'] },
86
+ },
87
+ tierAdjustments: {
88
+ 1: { min_mutation: 0.65 },
89
+ 2: { min_mutation: 0.45 },
90
+ 3: { min_mutation: 0.3 },
91
+ },
92
+ });
93
+
94
+ // Go adapter
95
+ this.adapters.set('go', {
96
+ language: 'go',
97
+ fileExtensions: ['.go'],
98
+ tools: {
99
+ unitTest: { command: 'go', args: ['test', './...'] },
100
+ coverage: {
101
+ command: 'go',
102
+ args: ['test', '-coverprofile=coverage.out', './...'],
103
+ },
104
+ lint: { command: 'golangci-lint', args: ['run'] },
105
+ },
106
+ fallbacks: {
107
+ mutation: 'Go lacks mature mutation testing - require 90% branch coverage instead',
108
+ contracts: 'Use go-swagger for API contract validation',
109
+ },
110
+ });
111
+
112
+ // Java adapter
113
+ this.adapters.set('java', {
114
+ language: 'java',
115
+ fileExtensions: ['.java'],
116
+ tools: {
117
+ unitTest: { command: 'mvn', args: ['test'] },
118
+ coverage: { command: 'mvn', args: ['jacoco:report'] },
119
+ mutationTest: {
120
+ command: 'mvn',
121
+ args: ['org.pitest:pitest-maven:mutationCoverage'],
122
+ },
123
+ contractTest: { command: 'mvn', args: ['pact:verify'] },
124
+ lint: { command: 'mvn', args: ['checkstyle:check'] },
125
+ },
126
+ });
127
+ }
128
+
129
+ /**
130
+ * Detect project language based on files present
131
+ */
132
+ detectLanguage(projectDir: string): string | null {
133
+ const indicators = [
134
+ { file: 'package.json', language: 'typescript' },
135
+ { file: 'tsconfig.json', language: 'typescript' },
136
+ { file: 'requirements.txt', language: 'python' },
137
+ { file: 'pyproject.toml', language: 'python' },
138
+ { file: 'Pipfile', language: 'python' },
139
+ { file: 'Cargo.toml', language: 'rust' },
140
+ { file: 'go.mod', language: 'go' },
141
+ { file: 'pom.xml', language: 'java' },
142
+ { file: 'build.gradle', language: 'java' },
143
+ ];
144
+
145
+ for (const indicator of indicators) {
146
+ const filePath = path.join(projectDir, indicator.file);
147
+ if (this.pathExists(filePath)) {
148
+ return indicator.language;
149
+ }
150
+ }
151
+
152
+ return null;
153
+ }
154
+
155
+ /**
156
+ * Get adapter for a specific language
157
+ */
158
+ getAdapter(language: string): LanguageAdapter | null {
159
+ return this.adapters.get(language.toLowerCase()) || null;
160
+ }
161
+
162
+ /**
163
+ * Get adjusted tier policy for a language
164
+ */
165
+ getAdjustedTierPolicy(language: string, tier: number): TierPolicy | null {
166
+ const adapter = this.getAdapter(language);
167
+ if (!adapter) return null;
168
+
169
+ const basePolicies: Record<number, TierPolicy> = {
170
+ 1: {
171
+ min_branch: 0.9,
172
+ min_coverage: 0.9,
173
+ min_mutation: 0.7,
174
+ requires_contracts: true,
175
+ requires_manual_review: true,
176
+ },
177
+ 2: {
178
+ min_branch: 0.8,
179
+ min_coverage: 0.8,
180
+ min_mutation: 0.5,
181
+ requires_contracts: true,
182
+ },
183
+ 3: {
184
+ min_branch: 0.7,
185
+ min_coverage: 0.7,
186
+ min_mutation: 0.3,
187
+ requires_contracts: false,
188
+ },
189
+ };
190
+
191
+ const basePolicy = basePolicies[tier];
192
+ if (!basePolicy) return null;
193
+
194
+ // Apply language-specific adjustments
195
+ const adjustments = adapter.tierAdjustments?.[tier] || {};
196
+ return { ...basePolicy, ...adjustments };
197
+ }
198
+
199
+ /**
200
+ * Generate language-specific configuration
201
+ */
202
+ generateConfig(language: string): Record<string, any> | null {
203
+ const adapter = this.getAdapter(language);
204
+ if (!adapter) return null;
205
+
206
+ return {
207
+ language: adapter.language,
208
+ tools: adapter.tools,
209
+ gates: this.generateGateConfig(adapter),
210
+ tierAdjustments: adapter.tierAdjustments,
211
+ fallbacks: adapter.fallbacks,
212
+ };
213
+ }
214
+
215
+ private generateGateConfig(adapter: LanguageAdapter): Record<string, GateConfig> {
216
+ const gates: Record<string, GateConfig> = {
217
+ coverage: {
218
+ enabled: true,
219
+ threshold: 0.8,
220
+ },
221
+ mutation: {
222
+ enabled: !!adapter.tools.mutationTest,
223
+ threshold: 0.5,
224
+ },
225
+ contracts: {
226
+ enabled: !!adapter.tools.contractTest,
227
+ threshold: 1.0,
228
+ },
229
+ };
230
+
231
+ return gates;
232
+ }
233
+
234
+ /**
235
+ * List all available adapters
236
+ */
237
+ listAdapters(): Array<{
238
+ language: string;
239
+ hasMutation: boolean;
240
+ hasContracts: boolean;
241
+ }> {
242
+ return Array.from(this.adapters.values()).map((adapter) => ({
243
+ language: adapter.language,
244
+ hasMutation: !!adapter.tools.mutationTest,
245
+ hasContracts: !!adapter.tools.contractTest,
246
+ }));
247
+ }
248
+
249
+ /**
250
+ * Check if tools are available for a language
251
+ */
252
+ checkToolAvailability(language: string): {
253
+ language: string;
254
+ available: Record<string, boolean>;
255
+ missing: string[];
256
+ } {
257
+ const adapter = this.getAdapter(language);
258
+ if (!adapter) {
259
+ return { language, available: {}, missing: [] };
260
+ }
261
+
262
+ const available: Record<string, boolean> = {};
263
+ const missing: string[] = [];
264
+
265
+ const toolChecks = [
266
+ { name: 'unitTest', tool: adapter.tools.unitTest },
267
+ { name: 'coverage', tool: adapter.tools.coverage },
268
+ { name: 'mutationTest', tool: adapter.tools.mutationTest },
269
+ { name: 'contractTest', tool: adapter.tools.contractTest },
270
+ { name: 'lint', tool: adapter.tools.lint },
271
+ ];
272
+
273
+ for (const { name, tool } of toolChecks) {
274
+ if (tool) {
275
+ // Simple check - just verify command exists (would need proper implementation)
276
+ available[name] = true; // Placeholder
277
+ } else {
278
+ available[name] = false;
279
+ missing.push(name);
280
+ }
281
+ }
282
+
283
+ return { language, available, missing };
284
+ }
285
+ }
286
+
287
+ // CLI interface
288
+ if (import.meta.url === `file://${process.argv[1]}`) {
289
+ const command = process.argv[2];
290
+ const manager = new LanguageAdapterManager();
291
+
292
+ switch (command) {
293
+ case 'detect': {
294
+ const projectDir = process.argv[3] || process.cwd();
295
+ const language = manager.detectLanguage(projectDir);
296
+
297
+ if (language) {
298
+ console.log(`āœ… Detected language: ${language}`);
299
+ const adapter = manager.getAdapter(language);
300
+ if (adapter) {
301
+ console.log(`\nšŸ“¦ Available tools:`);
302
+ console.log(` Unit tests: ${adapter.tools.unitTest.command}`);
303
+ console.log(` Coverage: ${adapter.tools.coverage.command}`);
304
+ if (adapter.tools.mutationTest) {
305
+ console.log(` Mutation: ${adapter.tools.mutationTest.command}`);
306
+ }
307
+ if (adapter.tools.contractTest) {
308
+ console.log(` Contracts: ${adapter.tools.contractTest.command}`);
309
+ }
310
+ console.log(` Lint: ${adapter.tools.lint.command}`);
311
+ }
312
+ } else {
313
+ console.log('āŒ Could not detect language');
314
+ process.exit(1);
315
+ }
316
+ break;
317
+ }
318
+
319
+ case 'list': {
320
+ const adapters = manager.listAdapters();
321
+ console.log('Available Language Adapters:');
322
+ console.log('='.repeat(50));
323
+ adapters.forEach((adapter) => {
324
+ console.log(`\nšŸ“š ${adapter.language}`);
325
+ console.log(` Mutation testing: ${adapter.hasMutation ? 'āœ…' : 'āŒ'}`);
326
+ console.log(` Contract testing: ${adapter.hasContracts ? 'āœ…' : 'āŒ'}`);
327
+ });
328
+ break;
329
+ }
330
+
331
+ case 'config': {
332
+ const language = process.argv[3];
333
+ if (!language) {
334
+ console.error('Usage: language-adapters config <language>');
335
+ process.exit(1);
336
+ }
337
+
338
+ const config = manager.generateConfig(language);
339
+ if (config) {
340
+ console.log(JSON.stringify(config, null, 2));
341
+ } else {
342
+ console.error(`āŒ No adapter found for language: ${language}`);
343
+ process.exit(1);
344
+ }
345
+ break;
346
+ }
347
+
348
+ case 'tier': {
349
+ const language = process.argv[3];
350
+ const tier = parseInt(process.argv[4]);
351
+
352
+ if (!language || !tier) {
353
+ console.error('Usage: language-adapters tier <language> <tier>');
354
+ process.exit(1);
355
+ }
356
+
357
+ const policy = manager.getAdjustedTierPolicy(language, tier);
358
+ if (policy) {
359
+ console.log(`Tier ${tier} policy for ${language}:`);
360
+ console.log(JSON.stringify(policy, null, 2));
361
+ } else {
362
+ console.error(`āŒ Could not get policy for ${language} tier ${tier}`);
363
+ process.exit(1);
364
+ }
365
+ break;
366
+ }
367
+
368
+ default:
369
+ console.log('CAWS Language Adapter Manager');
370
+ console.log('');
371
+ console.log('Usage:');
372
+ console.log(' language-adapters detect [dir] - Detect project language');
373
+ console.log(' language-adapters list - List available adapters');
374
+ console.log(' language-adapters config <language> - Generate config for language');
375
+ console.log(' language-adapters tier <language> <tier> - Get tier policy for language');
376
+ console.log('');
377
+ console.log('Supported Languages:');
378
+ console.log(' typescript, python, rust, go, java');
379
+ break;
380
+ }
381
+ }