@codebakers/cli 3.9.39 → 3.9.41

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.
package/src/mcp/server.ts CHANGED
@@ -71,6 +71,31 @@ class CodeBakersServer {
71
71
  private updateCheckInterval = 60 * 60 * 1000; // Check every hour
72
72
  private currentSessionToken: string | null = null; // v6.19: Server-side enforcement session
73
73
 
74
+ // Check for pre-commit violations
75
+ private checkForViolations(): { hasViolations: boolean; violations: any[] | null; message: string | null } {
76
+ const cwd = process.cwd();
77
+ const violationsPath = path.join(cwd, '.codebakers', 'violations.json');
78
+
79
+ if (!fs.existsSync(violationsPath)) {
80
+ return { hasViolations: false, violations: null, message: null };
81
+ }
82
+
83
+ try {
84
+ const data = JSON.parse(fs.readFileSync(violationsPath, 'utf-8'));
85
+ if (data.violations && data.violations.length > 0) {
86
+ return {
87
+ hasViolations: true,
88
+ violations: data.violations,
89
+ message: `⚠️ ${data.count} pre-commit violation(s) found! Call heal_violations() to auto-fix.`
90
+ };
91
+ }
92
+ } catch {
93
+ // Ignore parse errors
94
+ }
95
+
96
+ return { hasViolations: false, violations: null, message: null };
97
+ }
98
+
74
99
  constructor() {
75
100
  this.apiKey = getApiKey();
76
101
  this.apiUrl = getApiUrl();
@@ -1643,6 +1668,21 @@ class CodeBakersServer {
1643
1668
  },
1644
1669
  },
1645
1670
  },
1671
+ // Pre-commit violation healing tool
1672
+ {
1673
+ name: 'heal_violations',
1674
+ description:
1675
+ 'Auto-fix pre-commit hook violations. Call this when you see a violation warning in tool responses. Reads .codebakers/violations.json and provides fixes using CodeBakers patterns. After fixing, clears the violations file.',
1676
+ inputSchema: {
1677
+ type: 'object' as const,
1678
+ properties: {
1679
+ autoFix: {
1680
+ type: 'boolean',
1681
+ description: 'Automatically apply fixes (default: true). Set to false to just see the issues.',
1682
+ },
1683
+ },
1684
+ },
1685
+ },
1646
1686
  // Engineering workflow tools
1647
1687
  ...ENGINEERING_TOOLS,
1648
1688
  ],
@@ -1900,6 +1940,9 @@ class CodeBakersServer {
1900
1940
  case 'setup_services':
1901
1941
  return this.handleSetupServices(args as { services?: string[]; checkOnly?: boolean });
1902
1942
 
1943
+ case 'heal_violations':
1944
+ return this.handleHealViolations(args as { autoFix?: boolean });
1945
+
1903
1946
  // Engineering workflow tools
1904
1947
  case 'engineering_start':
1905
1948
  case 'engineering_scope':
@@ -4394,6 +4437,115 @@ If you want AI features and prefer Claude over GPT (or want both as fallback).`,
4394
4437
  };
4395
4438
  }
4396
4439
 
4440
+ private handleHealViolations(args: { autoFix?: boolean }) {
4441
+ const { autoFix = true } = args;
4442
+ const cwd = process.cwd();
4443
+ const violationsPath = path.join(cwd, '.codebakers', 'violations.json');
4444
+
4445
+ // Check if violations file exists
4446
+ if (!fs.existsSync(violationsPath)) {
4447
+ return {
4448
+ content: [{
4449
+ type: 'text' as const,
4450
+ text: `✅ **No violations found!**\n\nThe \`.codebakers/violations.json\` file doesn't exist, which means:\n- No pre-commit violations have been detected\n- Or they were already fixed\n\nYou're good to commit!`,
4451
+ }],
4452
+ };
4453
+ }
4454
+
4455
+ // Read violations
4456
+ let data: { timestamp: string; count: number; violations: Array<{ file: string; check: string; category: string; message: string; line?: number; code?: string }> };
4457
+ try {
4458
+ data = JSON.parse(fs.readFileSync(violationsPath, 'utf-8'));
4459
+ } catch {
4460
+ return {
4461
+ content: [{
4462
+ type: 'text' as const,
4463
+ text: `⚠️ **Could not parse violations file**\n\nThe violations.json file exists but couldn't be read. Try running \`git commit\` again to regenerate it.`,
4464
+ }],
4465
+ };
4466
+ }
4467
+
4468
+ if (!data.violations || data.violations.length === 0) {
4469
+ // Clean up empty violations file
4470
+ fs.unlinkSync(violationsPath);
4471
+ return {
4472
+ content: [{
4473
+ type: 'text' as const,
4474
+ text: `✅ **No violations to fix!**\n\nThe violations file was empty. Cleaned it up for you.`,
4475
+ }],
4476
+ };
4477
+ }
4478
+
4479
+ // Group violations by file
4480
+ const byFile: Record<string, typeof data.violations> = {};
4481
+ for (const v of data.violations) {
4482
+ if (!byFile[v.file]) byFile[v.file] = [];
4483
+ byFile[v.file].push(v);
4484
+ }
4485
+
4486
+ // Build response with fix instructions
4487
+ let response = `# 🔧 Pre-Commit Violations Found\n\n`;
4488
+ response += `**${data.count} violation(s)** detected at ${data.timestamp}\n\n`;
4489
+
4490
+ // Category fixes mapping
4491
+ const categoryFixes: Record<string, string> = {
4492
+ security: 'Use parameterized queries, escape user input, avoid eval()',
4493
+ errors: 'Add try/catch blocks, handle Promise rejections, use Result types',
4494
+ validation: 'Add Zod schemas at API boundaries, validate inputs before use',
4495
+ quality: 'Remove console.log, add explicit types, avoid any',
4496
+ typescript: 'Add proper type annotations, avoid type assertions',
4497
+ react: 'Add key props, wrap handlers in useCallback, handle loading states',
4498
+ accessibility: 'Add alt text, aria-labels, ensure keyboard navigation',
4499
+ performance: 'Use proper React hooks dependencies, memoize expensive operations',
4500
+ api: 'Use NextResponse for API routes, add rate limiting',
4501
+ imports: 'Fix import order, remove unused imports',
4502
+ };
4503
+
4504
+ for (const [file, violations] of Object.entries(byFile)) {
4505
+ response += `## 📄 ${file}\n\n`;
4506
+
4507
+ for (const v of violations) {
4508
+ response += `### ❌ ${v.check}\n`;
4509
+ response += `- **Category:** ${v.category}\n`;
4510
+ response += `- **Issue:** ${v.message}\n`;
4511
+ if (v.line) response += `- **Line:** ${v.line}\n`;
4512
+ if (v.code) response += `- **Code:** \`${v.code.substring(0, 100)}${v.code.length > 100 ? '...' : ''}\`\n`;
4513
+
4514
+ // Add fix suggestion
4515
+ const fix = categoryFixes[v.category] || 'Review the code and apply best practices';
4516
+ response += `- **Fix:** ${fix}\n\n`;
4517
+ }
4518
+ }
4519
+
4520
+ if (autoFix) {
4521
+ response += `---\n\n`;
4522
+ response += `## 🛠️ Auto-Fix Instructions\n\n`;
4523
+ response += `I'll now fix these violations. For each file:\n\n`;
4524
+
4525
+ for (const [file, violations] of Object.entries(byFile)) {
4526
+ response += `**${file}:**\n`;
4527
+ for (const v of violations) {
4528
+ response += `- Fix: ${v.check} (${v.category})\n`;
4529
+ }
4530
+ response += `\n`;
4531
+ }
4532
+
4533
+ response += `After fixing, run \`git add .\` and \`git commit\` again.\n\n`;
4534
+ response += `---\n\n`;
4535
+ response += `**⚠️ IMPORTANT:** Read each file and apply the fixes according to CodeBakers patterns. Load the relevant pattern module for each category (e.g., \`00-core.md\` for types, \`02-auth.md\` for security, \`03-api.md\` for API routes).\n`;
4536
+ } else {
4537
+ response += `---\n\n`;
4538
+ response += `Run \`heal_violations({ autoFix: true })\` to get fix instructions, or fix manually and commit again.\n`;
4539
+ }
4540
+
4541
+ return {
4542
+ content: [{
4543
+ type: 'text' as const,
4544
+ text: response,
4545
+ }],
4546
+ };
4547
+ }
4548
+
4397
4549
  private handleRunTests(args: { filter?: string; watch?: boolean }) {
4398
4550
  const { filter, watch = false } = args;
4399
4551
  const cwd = process.cwd();
@@ -5080,6 +5232,15 @@ If you want AI features and prefer Claude over GPT (or want both as fallback).`,
5080
5232
  responseText += `**${result.nextSteps || 'Fix the issues above and try again.'}**\n`;
5081
5233
  }
5082
5234
 
5235
+ // Check for pre-commit violations
5236
+ const violations = this.checkForViolations();
5237
+ if (violations.hasViolations) {
5238
+ responseText += `\n---\n\n`;
5239
+ responseText += `## 🚨 PRE-COMMIT VIOLATIONS DETECTED\n\n`;
5240
+ responseText += violations.message + `\n\n`;
5241
+ responseText += `**IMPORTANT:** These violations will block your commit. Call \`heal_violations()\` to fix them.\n`;
5242
+ }
5243
+
5083
5244
  return {
5084
5245
  content: [{
5085
5246
  type: 'text' as const,
@@ -5417,6 +5578,15 @@ If you want AI features and prefer Claude over GPT (or want both as fallback).`,
5417
5578
  responseText += `5. Pre-commit hook blocks commits without passed validation\n\n`;
5418
5579
  responseText += `**Server is tracking this session. Compliance is enforced.**`;
5419
5580
 
5581
+ // Check for pre-commit violations
5582
+ const violations = this.checkForViolations();
5583
+ if (violations.hasViolations) {
5584
+ responseText += `\n\n---\n\n`;
5585
+ responseText += `## 🚨 PRE-COMMIT VIOLATIONS DETECTED\n\n`;
5586
+ responseText += violations.message + `\n\n`;
5587
+ responseText += `**Fix these violations BEFORE writing new code.** Call \`heal_violations()\` to see details and fixes.\n`;
5588
+ }
5589
+
5420
5590
  return {
5421
5591
  content: [{
5422
5592
  type: 'text' as const,