@codebakers/cli 3.9.40 → 3.9.42
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/dist/commands/install-precommit.js +1106 -926
- package/dist/mcp/server.js +154 -0
- package/package.json +1 -1
- package/src/commands/install-precommit.ts +1205 -1024
- package/src/mcp/server.ts +170 -0
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,
|