@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,24 @@
1
+ /**
2
+ * Mode command handler
3
+ * @param {string} action - Action to perform (current, set, compare, recommend)
4
+ * @param {Object} options - Command options
5
+ */
6
+ export function modeCommand(action: string, options?: any): Promise<any>;
7
+ import { getCurrentMode } from "../config/modes";
8
+ import { setCurrentMode } from "../config/modes";
9
+ /**
10
+ * Display current mode status
11
+ */
12
+ export function displayCurrentMode(): void;
13
+ /**
14
+ * Display mode details
15
+ * @param {string} mode - Mode to display
16
+ */
17
+ export function displayModeDetails(mode: string): void;
18
+ /**
19
+ * Interactive mode selection
20
+ * @returns {Promise<string>} Selected mode
21
+ */
22
+ export function interactiveModeSelection(): Promise<string>;
23
+ export { getCurrentMode, setCurrentMode };
24
+ //# sourceMappingURL=mode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mode.d.ts","sourceRoot":"","sources":["../../src/commands/mode.js"],"names":[],"mappings":"AAuHA;;;;GAIG;AACH,oCAHW,MAAM,+BAgIhB;;;AAvOD;;GAEG;AACH,2CAOC;AAED;;;GAGG;AACH,yCAFW,MAAM,QA+ChB;AAED;;;GAGG;AACH,4CAFa,OAAO,CAAC,MAAM,CAAC,CAkC3B"}
@@ -18,13 +18,32 @@ const {
18
18
 
19
19
  /**
20
20
  * Display current mode status
21
+ * @param {string} currentMode - The current mode to display
21
22
  */
22
- function displayCurrentMode() {
23
+ function displayCurrentMode(currentMode) {
24
+ const tier = getTier(currentMode);
25
+
23
26
  console.log(chalk.bold.cyan('\n🔧 CAWS Current Mode'));
24
27
  console.log(chalk.cyan('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'));
25
28
 
26
- // This will be implemented when we load the current mode
27
- console.log(chalk.yellow('Mode display will be implemented...'));
29
+ console.log(chalk.bold(`Active Mode: ${tier.icon} ${tier.color(currentMode)}`));
30
+ console.log(chalk.gray(`Description: ${tier.description}`));
31
+ console.log('');
32
+
33
+ // Quality requirements
34
+ console.log(chalk.bold('Quality Requirements:'));
35
+ console.log(chalk.gray(` Test Coverage: ≥${tier.qualityRequirements.testCoverage}%`));
36
+ console.log(chalk.gray(` Mutation Score: ≥${tier.qualityRequirements.mutationScore}%`));
37
+ console.log(chalk.gray(` Contracts: ${tier.qualityRequirements.contracts}`));
38
+ console.log('');
39
+
40
+ // Risk tiers supported
41
+ console.log(chalk.bold('Supported Risk Tiers:'));
42
+ tier.riskTiers.forEach((riskTier) => {
43
+ const riskColor =
44
+ riskTier === 'T1' ? chalk.red : riskTier === 'T2' ? chalk.yellow : chalk.green;
45
+ console.log(chalk.gray(` ${riskColor(riskTier)}`));
46
+ });
28
47
  console.log('');
29
48
  }
30
49
 
@@ -128,21 +147,12 @@ async function modeCommand(action, options = {}) {
128
147
  switch (action) {
129
148
  case 'current': {
130
149
  const currentMode = await getCurrentMode();
131
- displayCurrentMode();
132
-
133
- const tier = getTier(currentMode);
134
- console.log(chalk.bold(`Current Mode: ${tier.icon} ${tier.color(currentMode)}`));
135
- console.log(chalk.gray(`Description: ${tier.description}`));
136
- console.log(
137
- chalk.gray(
138
- `Quality: ${tier.qualityRequirements.testCoverage}% coverage, ${tier.qualityRequirements.mutationScore}% mutation`
139
- )
140
- );
150
+ displayCurrentMode(currentMode);
141
151
 
142
152
  return outputResult({
143
153
  command: 'mode current',
144
154
  mode: currentMode,
145
- tier: tier,
155
+ tier: getTier(currentMode),
146
156
  });
147
157
  }
148
158
 
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Plan command handler
3
+ * @param {string} action - Action to perform (generate)
4
+ * @param {Object} options - Command options
5
+ */
6
+ export function planCommand(action: string, options?: any): Promise<any>;
7
+ /**
8
+ * Generate implementation plan from spec
9
+ * @param {Object} spec - Spec data
10
+ * @returns {Object} Generated plan
11
+ */
12
+ export function generateImplementationPlan(spec: any): any;
13
+ /**
14
+ * Write plan to file
15
+ * @param {Object} plan - Plan data
16
+ * @param {string} outputPath - Output file path
17
+ * @returns {Promise<void>}
18
+ */
19
+ export function writePlanToFile(plan: any, outputPath: string): Promise<void>;
20
+ /**
21
+ * Generate markdown content from plan
22
+ * @param {Object} plan - Plan data
23
+ * @returns {string} Markdown content
24
+ */
25
+ export function generatePlanMarkdown(plan: any): string;
26
+ /**
27
+ * Display generated plan
28
+ * @param {Object} plan - Plan data
29
+ */
30
+ export function displayGeneratedPlan(plan: any): void;
31
+ export namespace PLAN_TEMPLATES {
32
+ namespace feature {
33
+ let sections: string[];
34
+ let defaultTasks: string[];
35
+ }
36
+ namespace fix {
37
+ let sections_1: string[];
38
+ export { sections_1 as sections };
39
+ let defaultTasks_1: string[];
40
+ export { defaultTasks_1 as defaultTasks };
41
+ }
42
+ namespace refactor {
43
+ let sections_2: string[];
44
+ export { sections_2 as sections };
45
+ let defaultTasks_2: string[];
46
+ export { defaultTasks_2 as defaultTasks };
47
+ }
48
+ }
49
+ //# sourceMappingURL=plan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../src/commands/plan.js"],"names":[],"mappings":"AA6XA;;;;GAIG;AACH,oCAHW,MAAM,+BAuDhB;AA1OD;;;;GAIG;AACH,2DA8CC;AAED;;;;;GAKG;AACH,uDAHW,MAAM,GACJ,OAAO,CAAC,IAAI,CAAC,CAQzB;AAED;;;;GAIG;AACH,iDAFa,MAAM,CAiElB;AAED;;;GAGG;AACH,sDAkCC"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Provenance command handler
3
+ * @param {string} subcommand - The subcommand to execute
4
+ * @param {Object} options - Command options
5
+ */
6
+ export function provenanceCommand(subcommand: string, options: any): Promise<any>;
7
+ /**
8
+ * Update provenance with new commit information
9
+ * @param {Object} options - Command options
10
+ */
11
+ export function updateProvenance(options: any): Promise<void>;
12
+ /**
13
+ * Show current provenance information
14
+ * @param {Object} options - Command options
15
+ */
16
+ export function showProvenance(options: any): Promise<void>;
17
+ /**
18
+ * Verify provenance chain integrity
19
+ * @param {Object} options - Command options
20
+ */
21
+ export function verifyProvenance(options: any): Promise<void>;
22
+ /**
23
+ * Initialize provenance tracking for the project
24
+ * @param {Object} options - Command options
25
+ */
26
+ export function initProvenance(options: any): Promise<void>;
27
+ /**
28
+ * Install git hooks for automatic provenance updates
29
+ * @param {Object} options - Command options
30
+ */
31
+ export function installHooks(options: any): Promise<void>;
32
+ //# sourceMappingURL=provenance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provenance.d.ts","sourceRoot":"","sources":["../../src/commands/provenance.js"],"names":[],"mappings":"AAYA;;;;GAIG;AACH,8CAHW,MAAM,8BA+BhB;AAED;;;GAGG;AACH,8DA4EC;AAED;;;GAGG;AACH,4DAyEC;AAED;;;GAGG;AACH,8DA8CC;AA6iBD;;;GAGG;AACH,4DAmEC;AAzcD;;;GAGG;AACH,0DAwEC"}
@@ -4,12 +4,43 @@
4
4
  * @author @darianrosebrook
5
5
  */
6
6
 
7
+ /* global fetch */
8
+
7
9
  const fs = require('fs-extra');
8
10
  const path = require('path');
9
11
  const crypto = require('crypto');
10
12
  const yaml = require('js-yaml');
13
+ const { execSync } = require('child_process');
11
14
  const { commandWrapper } = require('../utils/command-wrapper');
12
15
 
16
+ /**
17
+ * Get quality gates status from saved report
18
+ * @returns {Object} Quality gates status
19
+ */
20
+ function getQualityGatesStatus() {
21
+ const reportPath = path.join(process.cwd(), '.caws', 'quality-gates-report.json');
22
+
23
+ if (fs.existsSync(reportPath)) {
24
+ try {
25
+ const report = JSON.parse(fs.readFileSync(reportPath, 'utf8'));
26
+ return {
27
+ status: report.passed ? 'passing' : 'failing',
28
+ last_validated: report.timestamp || new Date().toISOString(),
29
+ violations: report.violations || 0,
30
+ gates: report.gates || {}
31
+ };
32
+ } catch (error) {
33
+ // Fall through to default
34
+ }
35
+ }
36
+
37
+ return {
38
+ status: 'not_validated',
39
+ last_validated: null,
40
+ violations: null
41
+ };
42
+ }
43
+
13
44
  /**
14
45
  * Provenance command handler
15
46
  * @param {string} subcommand - The subcommand to execute
@@ -87,12 +118,7 @@ async function updateProvenance(options) {
87
118
  mode: spec.mode,
88
119
  waiver_ids: spec.waiver_ids || [],
89
120
  },
90
- quality_gates: {
91
- // This would be populated by recent validation results
92
- // For now, we'll mark as unknown
93
- status: 'unknown',
94
- last_validated: new Date().toISOString(),
95
- },
121
+ quality_gates: getQualityGatesStatus(),
96
122
  agent: {
97
123
  type: detectAgentType(),
98
124
  confidence_level: null, // Would be populated by agent actions
@@ -407,6 +433,67 @@ function analyzeQualityMetrics(aiEntries) {
407
433
  /**
408
434
  * Analyze checkpoint usage patterns
409
435
  */
436
+ /**
437
+ * Calculate actual revert rate from git history
438
+ * Analyzes commits for revert patterns and calculates the percentage
439
+ * @param {number} maxCommits - Maximum number of commits to analyze
440
+ * @returns {number} Revert rate as a decimal (0.0 - 1.0)
441
+ */
442
+ function calculateRevertRate(maxCommits = 500) {
443
+ try {
444
+ // Get total commit count (limited)
445
+ const logOutput = execSync(`git log --oneline -n ${maxCommits} 2>/dev/null`, {
446
+ encoding: 'utf8',
447
+ cwd: process.cwd(),
448
+ }).trim();
449
+
450
+ if (!logOutput) {
451
+ return 0;
452
+ }
453
+
454
+ const totalCommits = logOutput.split('\n').filter(Boolean).length;
455
+
456
+ // Count revert commits (commits with "revert" in the message)
457
+ const revertOutput = execSync(
458
+ `git log --oneline -n ${maxCommits} --grep="[Rr]evert" 2>/dev/null || true`,
459
+ {
460
+ encoding: 'utf8',
461
+ cwd: process.cwd(),
462
+ }
463
+ ).trim();
464
+
465
+ const revertCommits = revertOutput ? revertOutput.split('\n').filter(Boolean).length : 0;
466
+
467
+ // Also check for reset/force-push patterns in reflog if available
468
+ let additionalReverts = 0;
469
+ try {
470
+ const reflogOutput = execSync(`git reflog --oneline -n ${maxCommits} 2>/dev/null || true`, {
471
+ encoding: 'utf8',
472
+ cwd: process.cwd(),
473
+ }).trim();
474
+
475
+ if (reflogOutput) {
476
+ const reflogLines = reflogOutput.split('\n').filter(Boolean);
477
+ additionalReverts = reflogLines.filter(
478
+ (line) => line.includes('reset:') || line.includes('checkout:')
479
+ ).length;
480
+ // Weight reflog reverts less since they may not be actual code reverts
481
+ additionalReverts = Math.floor(additionalReverts * 0.1);
482
+ }
483
+ } catch {
484
+ // Reflog not available or failed
485
+ }
486
+
487
+ const totalReverts = revertCommits + additionalReverts;
488
+ const revertRate = totalCommits > 0 ? totalReverts / totalCommits : 0;
489
+
490
+ return Math.min(1.0, revertRate); // Cap at 100%
491
+ } catch {
492
+ // Git not available or not a repo
493
+ return 0;
494
+ }
495
+ }
496
+
410
497
  function analyzeCheckpointUsage(aiEntries) {
411
498
  const entriesWithCheckpoints = aiEntries.filter(
412
499
  (entry) => entry.checkpoints?.available && entry.checkpoints.checkpoints?.length > 0
@@ -416,8 +503,8 @@ function analyzeCheckpointUsage(aiEntries) {
416
503
  .filter((entry) => entry.checkpoints?.available)
417
504
  .reduce((sum, entry) => sum + (entry.checkpoints.checkpoints?.length || 0), 0);
418
505
 
419
- // Mock revert rate - in real implementation, this would track actual reverts
420
- const revertRate = 0.15; // 15% estimated revert rate
506
+ // Calculate actual revert rate from git history
507
+ const revertRate = calculateRevertRate();
421
508
 
422
509
  return {
423
510
  entriesWithCheckpoints,
@@ -753,57 +840,63 @@ function provideAIInsights(contributionPatterns, qualityMetrics, checkpointAnaly
753
840
 
754
841
  /**
755
842
  * Get Cursor AI code tracking data for a commit
843
+ * Uses Cursor's AI Code Tracking API (Enterprise feature)
844
+ * @see https://cursor.com/docs/account/teams/ai-code-tracking-api
756
845
  * @param {string} commitHash - Git commit hash to analyze
757
846
  * @returns {Promise<Object>} AI code tracking data
758
847
  */
759
848
  async function getCursorTrackingData(commitHash) {
849
+ const apiUrl = process.env.CURSOR_TRACKING_API;
850
+ const apiKey = process.env.CURSOR_API_KEY;
851
+
852
+ if (!apiUrl || !apiKey) {
853
+ return {
854
+ available: false,
855
+ reason: 'Cursor API not configured. Set CURSOR_TRACKING_API and CURSOR_API_KEY environment variables.',
856
+ documentation: 'https://cursor.com/docs/account/teams/ai-code-tracking-api'
857
+ };
858
+ }
859
+
760
860
  try {
761
- // Check if Cursor tracking API is available
762
- if (!process.env.CURSOR_TRACKING_API || !process.env.CURSOR_PROJECT_ID) {
763
- return { available: false, reason: 'Cursor tracking API not configured' };
861
+ // Basic auth: base64(apiKey:) - Cursor API uses API key with empty password
862
+ const auth = Buffer.from(`${apiKey}:`).toString('base64');
863
+
864
+ const response = await fetch(`${apiUrl}/analytics/ai-code/commits`, {
865
+ method: 'GET',
866
+ headers: {
867
+ 'Authorization': `Basic ${auth}`,
868
+ 'Content-Type': 'application/json',
869
+ }
870
+ });
871
+
872
+ if (!response.ok) {
873
+ return {
874
+ available: false,
875
+ reason: `Cursor API error: ${response.status} ${response.statusText}`
876
+ };
764
877
  }
765
878
 
766
- // In a real implementation, this would call the Cursor API
767
- // For now, we'll return a mock structure showing what data would be available
768
- const mockTrackingData = {
879
+ const data = await response.json();
880
+
881
+ // Find commit-specific data if available
882
+ const commitData = data.commits?.find(c => c.commit_hash === commitHash) || data;
883
+
884
+ // Transform API response to our internal format
885
+ return {
769
886
  available: true,
770
887
  commit_hash: commitHash,
771
- ai_code_breakdown: {
772
- tab_completions: {
773
- lines_added: 45,
774
- percentage: 35,
775
- files_affected: ['src/utils.js', 'tests/utils.test.js'],
776
- },
777
- composer_chat: {
778
- lines_added: 78,
779
- percentage: 60,
780
- files_affected: ['src/new-feature.js', 'src/api.js'],
781
- checkpoints_created: 3,
782
- },
783
- manual_human: {
784
- lines_added: 5,
785
- percentage: 5,
786
- files_affected: ['README.md'],
787
- },
888
+ ai_code_breakdown: commitData.ai_code_breakdown || {
889
+ tab_completions: { lines_added: 0, percentage: 0, files_affected: [] },
890
+ composer_chat: { lines_added: 0, percentage: 0, files_affected: [], checkpoints_created: 0 },
891
+ manual_human: { lines_added: 0, percentage: 0, files_affected: [] },
788
892
  },
789
- change_groups: [
790
- {
791
- change_id: 'cg_12345',
792
- type: 'composer_session',
793
- lines_ai_generated: 42,
794
- lines_human_edited: 8,
795
- confidence_score: 0.85,
796
- timestamp: new Date().toISOString(),
797
- },
798
- ],
799
- quality_metrics: {
800
- ai_code_quality_score: 0.78,
801
- human_override_rate: 0.12,
802
- acceptance_rate: 0.94,
893
+ change_groups: commitData.change_groups || [],
894
+ quality_metrics: commitData.quality_metrics || {
895
+ ai_code_quality_score: 0,
896
+ human_override_rate: 0,
897
+ acceptance_rate: 0,
803
898
  },
804
899
  };
805
-
806
- return mockTrackingData;
807
900
  } catch (error) {
808
901
  return {
809
902
  available: false,
@@ -888,62 +981,92 @@ async function initProvenance(options) {
888
981
 
889
982
  /**
890
983
  * Get Cursor Composer/Chat checkpoint data
891
- * @returns {Promise<Array>} Array of checkpoint data
984
+ * Reads from local .cursor/ directory since checkpoints are stored locally by Cursor Agent
985
+ * @returns {Promise<Object>} Checkpoint data
892
986
  */
893
987
  async function getCursorCheckpoints() {
988
+ const cursorDir = path.join(process.cwd(), '.cursor');
989
+
990
+ if (!fs.existsSync(cursorDir)) {
991
+ return {
992
+ available: false,
993
+ reason: 'No .cursor directory found. Checkpoints are only available when using Cursor IDE.'
994
+ };
995
+ }
996
+
894
997
  try {
895
- // Check if Cursor checkpoint API is available
896
- if (!process.env.CURSOR_CHECKPOINT_API) {
897
- return { available: false, reason: 'Cursor checkpoint API not configured' };
998
+ // Look for checkpoint metadata in .cursor directory
999
+ // Cursor stores checkpoints locally during Composer/Agent sessions
1000
+ const checkpointPatterns = [
1001
+ '.cursor/**/checkpoint*.json',
1002
+ '.cursor/**/checkpoints.json',
1003
+ '.cursor/composer/checkpoints/*.json',
1004
+ '.cursor/agent/checkpoints/*.json',
1005
+ ];
1006
+
1007
+ let checkpointFiles = [];
1008
+ for (const pattern of checkpointPatterns) {
1009
+ const glob = require('glob');
1010
+ const matches = glob.sync(pattern, { cwd: process.cwd(), absolute: true });
1011
+ checkpointFiles = checkpointFiles.concat(matches);
898
1012
  }
899
1013
 
900
- // In a real implementation, this would call the Cursor checkpoint API
901
- // For now, we'll return a mock structure
902
- const mockCheckpoints = [
903
- {
904
- id: 'cp_001',
905
- timestamp: new Date(Date.now() - 3600000).toISOString(), // 1 hour ago
906
- description: 'Initial AI-generated function structure',
907
- changes_summary: {
908
- lines_added: 25,
909
- lines_modified: 0,
910
- files_affected: ['src/new-feature.js'],
911
- },
912
- ai_confidence: 0.82,
913
- can_revert: true,
914
- },
915
- {
916
- id: 'cp_002',
917
- timestamp: new Date(Date.now() - 1800000).toISOString(), // 30 min ago
918
- description: 'Added error handling and validation',
919
- changes_summary: {
920
- lines_added: 15,
921
- lines_modified: 8,
922
- files_affected: ['src/new-feature.js', 'tests/new-feature.test.js'],
923
- },
924
- ai_confidence: 0.91,
925
- can_revert: true,
926
- },
927
- {
928
- id: 'cp_003',
929
- timestamp: new Date().toISOString(), // Current
930
- description: 'Final implementation with documentation',
931
- changes_summary: {
932
- lines_added: 12,
933
- lines_modified: 5,
934
- files_affected: ['src/new-feature.js', 'README.md'],
935
- },
936
- ai_confidence: 0.88,
937
- can_revert: false, // Latest checkpoint
938
- },
939
- ];
1014
+ // Remove duplicates
1015
+ checkpointFiles = [...new Set(checkpointFiles)];
1016
+
1017
+ if (checkpointFiles.length === 0) {
1018
+ return {
1019
+ available: false,
1020
+ reason: 'No checkpoints found in current session. Checkpoints are created during Cursor Composer/Agent sessions.'
1021
+ };
1022
+ }
1023
+
1024
+ // Parse checkpoint files and aggregate data
1025
+ const checkpoints = [];
1026
+ for (const file of checkpointFiles) {
1027
+ try {
1028
+ const content = await fs.readFile(file, 'utf8');
1029
+ const data = JSON.parse(content);
1030
+
1031
+ // Handle both single checkpoint and array of checkpoints
1032
+ if (Array.isArray(data)) {
1033
+ checkpoints.push(...data);
1034
+ } else if (data.checkpoints) {
1035
+ checkpoints.push(...data.checkpoints);
1036
+ } else if (data.id || data.timestamp) {
1037
+ checkpoints.push(data);
1038
+ }
1039
+ } catch (parseError) {
1040
+ // Skip invalid checkpoint files
1041
+ continue;
1042
+ }
1043
+ }
1044
+
1045
+ if (checkpoints.length === 0) {
1046
+ return {
1047
+ available: false,
1048
+ reason: 'No valid checkpoints found in checkpoint files.'
1049
+ };
1050
+ }
1051
+
1052
+ // Sort by timestamp (newest first)
1053
+ checkpoints.sort((a, b) => {
1054
+ const timeA = new Date(a.timestamp || 0).getTime();
1055
+ const timeB = new Date(b.timestamp || 0).getTime();
1056
+ return timeB - timeA;
1057
+ });
1058
+
1059
+ // Mark latest checkpoint as non-revertible
1060
+ if (checkpoints.length > 0) {
1061
+ checkpoints[0].can_revert = false;
1062
+ }
940
1063
 
941
- return { available: true, checkpoints: mockCheckpoints };
1064
+ return { available: true, checkpoints };
942
1065
  } catch (error) {
943
1066
  return {
944
1067
  available: false,
945
1068
  error: error.message,
946
- reason: 'Failed to retrieve Cursor checkpoint data',
1069
+ reason: 'Failed to read Cursor checkpoint data',
947
1070
  };
948
1071
  }
949
1072
  }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Run comprehensive quality gates on staged files
3
+ * @param {Object} options - Command options
4
+ */
5
+ export function qualityGatesCommand(options?: any): Promise<any>;
6
+ //# sourceMappingURL=quality-gates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quality-gates.d.ts","sourceRoot":"","sources":["../../src/commands/quality-gates.js"],"names":[],"mappings":"AAqBA;;;GAGG;AACH,iEA8ZC"}