@paths.design/caws-cli 2.0.1 → 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 -2
  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
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.js"],"names":[],"mappings":";AAgbA;;;;GAIG;AACH,mDAFa,MAAM,CAqJlB;AAED;;;;GAIG;AACH,mDAHW,MAAM,uBA8BhB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.js"],"names":[],"mappings":";AAgYA;;;;GAIG;AACH,mDAFa,MAAM,CAqJlB;AAED;;;;GAIG;AACH,mDAHW,MAAM,uBA8BhB"}
package/dist/index.js CHANGED
@@ -124,6 +124,9 @@ function detectCAWSSetup(cwd = process.cwd()) {
124
124
  // Check for template directory - try multiple possible locations
125
125
  let templateDir = null;
126
126
  const possibleTemplatePaths = [
127
+ // FIRST: Try bundled templates (for npm-installed CLI)
128
+ path.resolve(__dirname, '../templates'),
129
+ path.resolve(__dirname, 'templates'),
127
130
  // Try relative to current working directory (for monorepo setups)
128
131
  path.resolve(cwd, '../caws-template'),
129
132
  path.resolve(cwd, '../../caws-template'),
@@ -183,6 +186,22 @@ let cawsSetup = null;
183
186
  // Initialize global setup detection
184
187
  try {
185
188
  cawsSetup = detectCAWSSetup();
189
+
190
+ // If no template dir found in current directory, check CLI installation location
191
+ if (!cawsSetup.hasTemplateDir) {
192
+ const cliTemplatePaths = [
193
+ path.resolve(__dirname, '../templates'),
194
+ path.resolve(__dirname, 'templates'),
195
+ ];
196
+
197
+ for (const testPath of cliTemplatePaths) {
198
+ if (fs.existsSync(testPath)) {
199
+ cawsSetup.templateDir = testPath;
200
+ cawsSetup.hasTemplateDir = true;
201
+ break;
202
+ }
203
+ }
204
+ }
186
205
  } catch (error) {
187
206
  console.warn('⚠️ Failed to detect CAWS setup globally:', error.message);
188
207
  cawsSetup = {
@@ -363,73 +382,6 @@ if (!process.argv.includes('--version') && !process.argv.includes('-V')) {
363
382
  console.log(chalk.green('✅ Schema validation initialized successfully'));
364
383
  }
365
384
 
366
- /**
367
- * Copy template files to destination
368
- * @param {string} templatePath - Source template path
369
- * @param {string} destPath - Destination path
370
- * @param {Object} replacements - Template variable replacements
371
- */
372
- async function copyTemplate(templatePath, destPath, replacements = {}) {
373
- try {
374
- // Ensure destination directory exists
375
- await fs.ensureDir(destPath);
376
-
377
- // Check if template directory exists
378
- if (!fs.existsSync(templatePath)) {
379
- console.error(chalk.red('❌ Template directory not found:'), templatePath);
380
- console.error(chalk.blue("💡 Make sure you're running the CLI from the correct directory"));
381
- throw new Error(`Template directory not found: ${templatePath}`);
382
- }
383
-
384
- // Copy all files and directories
385
- await fs.copy(templatePath, destPath);
386
-
387
- // Replace template variables in text files
388
- const files = await fs.readdir(destPath, { recursive: true });
389
-
390
- for (const file of files) {
391
- const filePath = path.join(destPath, file);
392
- const stat = await fs.stat(filePath);
393
-
394
- if (
395
- stat.isFile() &&
396
- (file.endsWith('.md') || file.endsWith('.yml') || file.endsWith('.yaml'))
397
- ) {
398
- try {
399
- let content = await fs.readFile(filePath, 'utf8');
400
- Object.entries(replacements).forEach(([key, value]) => {
401
- content = content.replace(new RegExp(`{{${key}}}`, 'g'), value);
402
- });
403
- await fs.writeFile(filePath, content);
404
- } catch (fileError) {
405
- console.warn(
406
- chalk.yellow(`⚠️ Warning: Could not process template file ${file}:`),
407
- fileError.message
408
- );
409
- }
410
- }
411
- }
412
-
413
- console.log(chalk.green('✅ Template files copied successfully'));
414
- } catch (error) {
415
- console.error(chalk.red('❌ Error copying template:'), error.message);
416
-
417
- if (error.code === 'EACCES') {
418
- console.error(
419
- chalk.blue('💡 This might be a permissions issue. Try running with elevated privileges.')
420
- );
421
- } else if (error.code === 'ENOENT') {
422
- console.error(
423
- chalk.blue('💡 Template directory not found. Make sure the caws-template directory exists.')
424
- );
425
- } else if (error.code === 'ENOSPC') {
426
- console.error(chalk.blue('💡 Not enough disk space to copy template files.'));
427
- }
428
-
429
- process.exit(1);
430
- }
431
- }
432
-
433
385
  /**
434
386
  * Generate working spec YAML with user input
435
387
  * @param {Object} answers - User responses
@@ -634,11 +586,14 @@ async function initProject(projectName, options) {
634
586
  process.exit(1);
635
587
  }
636
588
 
637
- // Sanitize project name
638
- const sanitizedName = projectName.replace(/[^a-zA-Z0-9-_]/g, '-').toLowerCase();
639
- if (sanitizedName !== projectName) {
640
- console.warn(chalk.yellow(`⚠️ Project name sanitized to: ${sanitizedName}`));
641
- projectName = sanitizedName;
589
+ // Special case: '.' means current directory, don't sanitize
590
+ if (projectName !== '.') {
591
+ // Sanitize project name
592
+ const sanitizedName = projectName.replace(/[^a-zA-Z0-9-_]/g, '-').toLowerCase();
593
+ if (sanitizedName !== projectName) {
594
+ console.warn(chalk.yellow(`⚠️ Project name sanitized to: ${sanitizedName}`));
595
+ projectName = sanitizedName;
596
+ }
642
597
  }
643
598
 
644
599
  // Validate project name length
@@ -663,42 +618,89 @@ async function initProject(projectName, options) {
663
618
  process.exit(1);
664
619
  }
665
620
 
666
- // Check if directory already exists
667
- if (fs.existsSync(projectName)) {
621
+ // Determine if initializing in current directory
622
+ const initInCurrentDir = projectName === '.';
623
+ const targetDir = initInCurrentDir ? process.cwd() : path.resolve(process.cwd(), projectName);
624
+
625
+ // Check if directory already exists (skip check for current directory)
626
+ if (!initInCurrentDir && fs.existsSync(projectName)) {
668
627
  console.error(chalk.red(`❌ Directory ${projectName} already exists`));
669
628
  console.error(chalk.blue('💡 Choose a different name or remove the existing directory'));
670
629
  process.exit(1);
671
630
  }
672
631
 
673
- // Create project directory
674
- await fs.ensureDir(projectName);
675
- process.chdir(projectName);
632
+ // Save the original template directory before changing directories
633
+ const originalTemplateDir = cawsSetup?.hasTemplateDir ? cawsSetup.templateDir : null;
634
+
635
+ // Check for existing agents.md/caws.md in target directory
636
+ const existingAgentsMd = fs.existsSync(path.join(targetDir, 'agents.md'));
637
+ const existingCawsMd = fs.existsSync(path.join(targetDir, 'caws.md'));
676
638
 
677
- console.log(chalk.green(`📁 Created project directory: ${projectName}`));
639
+ // Create project directory and change to it (unless already in current directory)
640
+ if (!initInCurrentDir) {
641
+ await fs.ensureDir(projectName);
642
+ process.chdir(projectName);
643
+ console.log(chalk.green(`📁 Created project directory: ${projectName}`));
644
+ } else {
645
+ console.log(chalk.green(`📁 Initializing in current directory`));
646
+ }
678
647
 
679
648
  // Detect and adapt to existing setup
680
649
  const currentSetup = detectCAWSSetup(process.cwd());
681
650
 
682
651
  if (currentSetup.type === 'new') {
683
- // Copy template files from generic template
684
- if (cawsSetup && cawsSetup.hasTemplateDir && cawsSetup.templateDir) {
652
+ // Create minimal CAWS structure
653
+ await fs.ensureDir('.caws');
654
+ await fs.ensureDir('.agent');
655
+ console.log(chalk.blue('ℹ️ Created basic CAWS structure'));
656
+
657
+ // Copy agents.md guide if templates are available
658
+ if (originalTemplateDir) {
685
659
  try {
686
- await copyTemplate(cawsSetup.templateDir, '.');
687
- console.log(chalk.green('✅ Created CAWS project with templates'));
660
+ const agentsMdSource = path.join(originalTemplateDir, 'agents.md');
661
+ let targetFile = 'agents.md';
662
+
663
+ if (fs.existsSync(agentsMdSource)) {
664
+ // Use the pre-checked values for conflicts
665
+ if (existingAgentsMd) {
666
+ // Conflict: user already has agents.md
667
+ if (options.interactive && !options.nonInteractive) {
668
+ // Interactive mode: ask user
669
+ const overwriteAnswer = await inquirer.prompt([
670
+ {
671
+ type: 'confirm',
672
+ name: 'overwrite',
673
+ message: '⚠️ agents.md already exists. Overwrite with CAWS guide?',
674
+ default: false,
675
+ },
676
+ ]);
677
+
678
+ if (overwriteAnswer.overwrite) {
679
+ targetFile = 'agents.md';
680
+ } else {
681
+ targetFile = 'caws.md';
682
+ }
683
+ } else {
684
+ // Non-interactive mode: use caws.md instead
685
+ targetFile = 'caws.md';
686
+ console.log(chalk.blue('ℹ️ agents.md exists, using caws.md for CAWS guide'));
687
+ }
688
+ }
689
+
690
+ // If caws.md also exists and that's our target, skip
691
+ if (targetFile === 'caws.md' && existingCawsMd) {
692
+ console.log(
693
+ chalk.yellow('⚠️ Both agents.md and caws.md exist, skipping guide copy')
694
+ );
695
+ } else {
696
+ const agentsMdDest = path.join(process.cwd(), targetFile);
697
+ await fs.copyFile(agentsMdSource, agentsMdDest);
698
+ console.log(chalk.green(`✅ Added ${targetFile} guide`));
699
+ }
700
+ }
688
701
  } catch (templateError) {
689
- console.warn(
690
- chalk.yellow('⚠️ Template directory not available, creating basic structure')
691
- );
692
- // Create minimal CAWS structure
693
- await fs.ensureDir('.caws');
694
- await fs.ensureDir('.agent');
695
- console.log(chalk.blue('ℹ️ Created basic CAWS structure'));
702
+ console.warn(chalk.yellow('⚠️ Could not copy agents guide:'), templateError.message);
696
703
  }
697
- } else {
698
- // Create minimal CAWS structure
699
- await fs.ensureDir('.caws');
700
- await fs.ensureDir('.agent');
701
- console.log(chalk.blue('ℹ️ Created basic CAWS structure'));
702
704
  }
703
705
  } else {
704
706
  // Already has CAWS setup
@@ -707,9 +709,12 @@ async function initProject(projectName, options) {
707
709
 
708
710
  // Set default answers for non-interactive mode
709
711
  if (!options.interactive || options.nonInteractive) {
712
+ // Use directory name for current directory init
713
+ const displayName = initInCurrentDir ? path.basename(process.cwd()) : projectName;
714
+
710
715
  answers = {
711
- projectId: projectName.toUpperCase().replace(/[^A-Z0-9]/g, '-') + '-001',
712
- projectTitle: projectName.charAt(0).toUpperCase() + projectName.slice(1).replace(/-/g, ' '),
716
+ projectId: displayName.toUpperCase().replace(/[^A-Z0-9]/g, '-') + '-001',
717
+ projectTitle: displayName.charAt(0).toUpperCase() + displayName.slice(1).replace(/-/g, ' '),
713
718
  riskTier: 2,
714
719
  projectMode: 'feature',
715
720
  maxFiles: 25,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@paths.design/caws-cli",
3
- "version": "2.0.1",
3
+ "version": "3.0.0",
4
4
  "description": "CAWS CLI - Coding Agent Workflow System command line tools",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -9,7 +9,8 @@
9
9
  "preferGlobal": true,
10
10
  "files": [
11
11
  "dist",
12
- "README.md"
12
+ "README.md",
13
+ "templates"
13
14
  ],
14
15
  "scripts": {
15
16
  "build": "mkdir -p dist && cp src/*.js dist/ && npm run typecheck",