@codebakers/cli 1.1.5 → 1.1.7
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/doctor.d.ts +8 -0
- package/dist/commands/doctor.js +218 -0
- package/dist/commands/init.d.ts +4 -0
- package/dist/commands/init.js +772 -0
- package/dist/commands/install-hook.d.ts +12 -0
- package/dist/commands/install-hook.js +193 -0
- package/dist/commands/install.d.ts +1 -0
- package/dist/commands/install.js +81 -0
- package/dist/commands/login.d.ts +1 -0
- package/dist/commands/login.js +54 -0
- package/dist/commands/mcp-config.d.ts +6 -0
- package/dist/commands/mcp-config.js +209 -0
- package/dist/commands/serve.d.ts +1 -0
- package/dist/commands/serve.js +26 -0
- package/dist/commands/setup.d.ts +1 -0
- package/dist/commands/setup.js +92 -0
- package/dist/commands/status.d.ts +1 -0
- package/dist/commands/status.js +49 -0
- package/dist/commands/uninstall.d.ts +1 -0
- package/dist/commands/uninstall.js +50 -0
- package/dist/config.d.ts +5 -0
- package/dist/config.js +33 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +71 -1075
- package/dist/mcp/server.d.ts +2 -0
- package/dist/mcp/server.js +544 -0
- package/package.json +17 -38
- package/src/commands/doctor.ts +231 -0
- package/src/commands/init.ts +827 -0
- package/src/commands/install-hook.ts +207 -0
- package/src/commands/install.ts +94 -0
- package/src/commands/login.ts +56 -0
- package/src/commands/mcp-config.ts +235 -0
- package/src/commands/serve.ts +23 -0
- package/src/commands/setup.ts +104 -0
- package/src/commands/status.ts +48 -0
- package/src/commands/uninstall.ts +49 -0
- package/src/config.ts +34 -0
- package/src/index.ts +87 -0
- package/src/mcp/server.ts +617 -0
- package/tsconfig.json +16 -0
- package/README.md +0 -89
- package/dist/chunk-7CKLRE2H.js +0 -36
- package/dist/config-R2H6JKGW.js +0 -16
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Install the CodeBakers hook into ~/.claude/settings.json
|
|
3
|
+
*/
|
|
4
|
+
export declare function installHook(): Promise<void>;
|
|
5
|
+
/**
|
|
6
|
+
* Remove the CodeBakers hook from ~/.claude/settings.json
|
|
7
|
+
*/
|
|
8
|
+
export declare function uninstallHook(): Promise<void>;
|
|
9
|
+
/**
|
|
10
|
+
* Check if the CodeBakers hook is installed
|
|
11
|
+
*/
|
|
12
|
+
export declare function isHookInstalled(): boolean;
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.installHook = installHook;
|
|
7
|
+
exports.uninstallHook = uninstallHook;
|
|
8
|
+
exports.isHookInstalled = isHookInstalled;
|
|
9
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
10
|
+
const ora_1 = __importDefault(require("ora"));
|
|
11
|
+
const fs_1 = require("fs");
|
|
12
|
+
const path_1 = require("path");
|
|
13
|
+
const os_1 = require("os");
|
|
14
|
+
// Enhanced hook with pre-flight checks and self-review automation
|
|
15
|
+
const HOOK_TEMPLATE = {
|
|
16
|
+
hooks: {
|
|
17
|
+
UserPromptSubmit: [
|
|
18
|
+
{
|
|
19
|
+
type: "command",
|
|
20
|
+
command: `echo '════════════════════════════════════════════════════════════════
|
|
21
|
+
🚀 CODEBAKERS ZERO-FRICTION PROTOCOL
|
|
22
|
+
════════════════════════════════════════════════════════════════
|
|
23
|
+
|
|
24
|
+
AUTOMATIC WORKFLOW - Execute silently, output only the acknowledgment:
|
|
25
|
+
|
|
26
|
+
▸ PHASE 1: CONTEXT LOAD
|
|
27
|
+
Read these files (if they exist):
|
|
28
|
+
- CLAUDE.md → Router & module instructions
|
|
29
|
+
- PRD.md → What we are building (requirements!)
|
|
30
|
+
- PROJECT-CONTEXT.md → Codebase knowledge
|
|
31
|
+
- PROJECT-STATE.md → What is in progress
|
|
32
|
+
- DECISIONS.md → Past architectural choices
|
|
33
|
+
|
|
34
|
+
▸ PHASE 2: PRE-FLIGHT CHECK (before writing code)
|
|
35
|
+
□ What existing code does this touch?
|
|
36
|
+
□ Is similar code in the codebase? (copy that pattern!)
|
|
37
|
+
□ Whats the data model?
|
|
38
|
+
□ What are the error cases?
|
|
39
|
+
□ Is someone else working on this? (check In Progress)
|
|
40
|
+
|
|
41
|
+
If PROJECT-CONTEXT.md is empty/stale, SCAN PROJECT FIRST:
|
|
42
|
+
- Read package.json
|
|
43
|
+
- Check file structure
|
|
44
|
+
- Find existing patterns
|
|
45
|
+
- Update PROJECT-CONTEXT.md
|
|
46
|
+
|
|
47
|
+
▸ PHASE 3: ACKNOWLEDGE & EXECUTE
|
|
48
|
+
Output: 📋 CodeBakers | [Type] | Modules: [list]
|
|
49
|
+
Then: Follow patterns from .claude/ folder EXACTLY
|
|
50
|
+
|
|
51
|
+
▸ PHASE 4: SELF-REVIEW (before saying done)
|
|
52
|
+
□ TypeScript compiles? (npx tsc --noEmit)
|
|
53
|
+
□ Imports resolve?
|
|
54
|
+
□ Error handling exists?
|
|
55
|
+
□ Matches existing patterns?
|
|
56
|
+
□ Tests written?
|
|
57
|
+
|
|
58
|
+
If ANY fails → FIX before responding
|
|
59
|
+
|
|
60
|
+
▸ PHASE 5: UPDATE STATE
|
|
61
|
+
- Update PROJECT-STATE.md (move to Completed)
|
|
62
|
+
- Add to DECISIONS.md if architectural choice made
|
|
63
|
+
|
|
64
|
+
════════════════════════════════════════════════════════════════
|
|
65
|
+
🔄 MULTI-AGENT MODE
|
|
66
|
+
════════════════════════════════════════════════════════════════
|
|
67
|
+
- Check PROJECT-STATE.md "In Progress" - dont duplicate work
|
|
68
|
+
- Add YOUR task to In Progress when starting
|
|
69
|
+
- If conflict → STOP and ask user
|
|
70
|
+
|
|
71
|
+
════════════════════════════════════════════════════════════════
|
|
72
|
+
💡 REMEMBER: Check existing code FIRST. Copy patterns. Validate.
|
|
73
|
+
════════════════════════════════════════════════════════════════'`
|
|
74
|
+
}
|
|
75
|
+
]
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* Install the CodeBakers hook into ~/.claude/settings.json
|
|
80
|
+
*/
|
|
81
|
+
async function installHook() {
|
|
82
|
+
console.log(chalk_1.default.blue('\n CodeBakers Hook Install\n'));
|
|
83
|
+
const claudeDir = (0, path_1.join)((0, os_1.homedir)(), '.claude');
|
|
84
|
+
const settingsPath = (0, path_1.join)(claudeDir, 'settings.json');
|
|
85
|
+
const spinner = (0, ora_1.default)('Installing hook...').start();
|
|
86
|
+
try {
|
|
87
|
+
// Create ~/.claude if it doesn't exist
|
|
88
|
+
if (!(0, fs_1.existsSync)(claudeDir)) {
|
|
89
|
+
(0, fs_1.mkdirSync)(claudeDir, { recursive: true });
|
|
90
|
+
spinner.text = 'Created ~/.claude directory';
|
|
91
|
+
}
|
|
92
|
+
// Read existing settings or start fresh
|
|
93
|
+
let settings = {};
|
|
94
|
+
if ((0, fs_1.existsSync)(settingsPath)) {
|
|
95
|
+
try {
|
|
96
|
+
const existingContent = (0, fs_1.readFileSync)(settingsPath, 'utf-8');
|
|
97
|
+
settings = JSON.parse(existingContent);
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
// Backup the invalid file
|
|
101
|
+
const backupPath = settingsPath + '.backup';
|
|
102
|
+
(0, fs_1.copyFileSync)(settingsPath, backupPath);
|
|
103
|
+
spinner.text = `Backed up invalid settings to ${backupPath}`;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// Check if hook already exists
|
|
107
|
+
const existingHooks = settings.hooks;
|
|
108
|
+
if (existingHooks?.UserPromptSubmit) {
|
|
109
|
+
const existingCommand = existingHooks.UserPromptSubmit[0]?.command || '';
|
|
110
|
+
if (existingCommand.includes('CODEBAKERS')) {
|
|
111
|
+
spinner.info('CodeBakers hook is already installed');
|
|
112
|
+
console.log(chalk_1.default.yellow('\n Reinstalling with latest version...\n'));
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
// There's a different hook - warn user
|
|
116
|
+
spinner.warn('An existing UserPromptSubmit hook was found');
|
|
117
|
+
console.log(chalk_1.default.yellow(' It will be replaced with the CodeBakers hook.\n'));
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
// Merge hook into settings
|
|
121
|
+
settings.hooks = settings.hooks || {};
|
|
122
|
+
settings.hooks.UserPromptSubmit = HOOK_TEMPLATE.hooks.UserPromptSubmit;
|
|
123
|
+
// Write back
|
|
124
|
+
(0, fs_1.writeFileSync)(settingsPath, JSON.stringify(settings, null, 2));
|
|
125
|
+
spinner.succeed('Hook installed successfully!');
|
|
126
|
+
console.log(chalk_1.default.white('\n What happens automatically on EVERY message:\n'));
|
|
127
|
+
console.log(chalk_1.default.gray(' ✓ Loads project context (CLAUDE.md, PROJECT-CONTEXT.md)'));
|
|
128
|
+
console.log(chalk_1.default.gray(' ✓ Checks what\'s in progress (PROJECT-STATE.md)'));
|
|
129
|
+
console.log(chalk_1.default.gray(' ✓ Runs pre-flight checks before coding'));
|
|
130
|
+
console.log(chalk_1.default.gray(' ✓ Copies existing patterns from your codebase'));
|
|
131
|
+
console.log(chalk_1.default.gray(' ✓ Self-reviews code before outputting'));
|
|
132
|
+
console.log(chalk_1.default.gray(' ✓ Updates project state when done'));
|
|
133
|
+
console.log(chalk_1.default.gray(' ✓ Logs architectural decisions\n'));
|
|
134
|
+
console.log(chalk_1.default.yellow(' ⚠️ Restart Claude Code for changes to take effect.\n'));
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
spinner.fail('Hook installation failed');
|
|
138
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
139
|
+
console.log(chalk_1.default.red(`\n Error: ${message}\n`));
|
|
140
|
+
process.exit(1);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Remove the CodeBakers hook from ~/.claude/settings.json
|
|
145
|
+
*/
|
|
146
|
+
async function uninstallHook() {
|
|
147
|
+
console.log(chalk_1.default.blue('\n CodeBakers Hook Uninstall\n'));
|
|
148
|
+
const settingsPath = (0, path_1.join)((0, os_1.homedir)(), '.claude', 'settings.json');
|
|
149
|
+
const spinner = (0, ora_1.default)('Removing hook...').start();
|
|
150
|
+
try {
|
|
151
|
+
if (!(0, fs_1.existsSync)(settingsPath)) {
|
|
152
|
+
spinner.info('No settings.json found. Nothing to remove.');
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
const settings = JSON.parse((0, fs_1.readFileSync)(settingsPath, 'utf-8'));
|
|
156
|
+
if (!settings.hooks?.UserPromptSubmit) {
|
|
157
|
+
spinner.info('No UserPromptSubmit hook found. Nothing to remove.');
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
// Remove the hook
|
|
161
|
+
delete settings.hooks.UserPromptSubmit;
|
|
162
|
+
// Clean up empty hooks object
|
|
163
|
+
if (Object.keys(settings.hooks).length === 0) {
|
|
164
|
+
delete settings.hooks;
|
|
165
|
+
}
|
|
166
|
+
(0, fs_1.writeFileSync)(settingsPath, JSON.stringify(settings, null, 2));
|
|
167
|
+
spinner.succeed('Hook removed successfully!');
|
|
168
|
+
console.log(chalk_1.default.yellow('\n ⚠️ Restart Claude Code for changes to take effect.\n'));
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
spinner.fail('Hook removal failed');
|
|
172
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
173
|
+
console.log(chalk_1.default.red(`\n Error: ${message}\n`));
|
|
174
|
+
process.exit(1);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Check if the CodeBakers hook is installed
|
|
179
|
+
*/
|
|
180
|
+
function isHookInstalled() {
|
|
181
|
+
const settingsPath = (0, path_1.join)((0, os_1.homedir)(), '.claude', 'settings.json');
|
|
182
|
+
if (!(0, fs_1.existsSync)(settingsPath)) {
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
try {
|
|
186
|
+
const settings = JSON.parse((0, fs_1.readFileSync)(settingsPath, 'utf-8'));
|
|
187
|
+
const command = settings.hooks?.UserPromptSubmit?.[0]?.command || '';
|
|
188
|
+
return command.includes('CODEBAKERS');
|
|
189
|
+
}
|
|
190
|
+
catch {
|
|
191
|
+
return false;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function install(): Promise<void>;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.install = install;
|
|
7
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
const ora_1 = __importDefault(require("ora"));
|
|
9
|
+
const fs_1 = require("fs");
|
|
10
|
+
const path_1 = require("path");
|
|
11
|
+
const config_js_1 = require("../config.js");
|
|
12
|
+
async function install() {
|
|
13
|
+
console.log(chalk_1.default.blue('\n CodeBakers Install\n'));
|
|
14
|
+
const apiKey = (0, config_js_1.getApiKey)();
|
|
15
|
+
if (!apiKey) {
|
|
16
|
+
console.log(chalk_1.default.red(' Not logged in. Run `codebakers login` first.\n'));
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
const spinner = (0, ora_1.default)('Downloading patterns...').start();
|
|
20
|
+
try {
|
|
21
|
+
const apiUrl = (0, config_js_1.getApiUrl)();
|
|
22
|
+
const response = await fetch(`${apiUrl}/api/content`, {
|
|
23
|
+
method: 'GET',
|
|
24
|
+
headers: {
|
|
25
|
+
Authorization: `Bearer ${apiKey}`,
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
if (!response.ok) {
|
|
29
|
+
const error = await response.json().catch(() => ({}));
|
|
30
|
+
throw new Error(error.error || 'Failed to fetch content');
|
|
31
|
+
}
|
|
32
|
+
const content = await response.json();
|
|
33
|
+
spinner.text = 'Installing patterns...';
|
|
34
|
+
const cwd = process.cwd();
|
|
35
|
+
// Write router file
|
|
36
|
+
if (content.router) {
|
|
37
|
+
(0, fs_1.writeFileSync)((0, path_1.join)(cwd, '.cursorrules'), content.router);
|
|
38
|
+
}
|
|
39
|
+
// Create CLAUDE.md symlink/copy for Claude Code
|
|
40
|
+
if (content.router) {
|
|
41
|
+
(0, fs_1.writeFileSync)((0, path_1.join)(cwd, 'CLAUDE.md'), content.router);
|
|
42
|
+
}
|
|
43
|
+
// Write modules
|
|
44
|
+
if (content.modules && Object.keys(content.modules).length > 0) {
|
|
45
|
+
const modulesDir = (0, path_1.join)(cwd, '.claude');
|
|
46
|
+
if (!(0, fs_1.existsSync)(modulesDir)) {
|
|
47
|
+
(0, fs_1.mkdirSync)(modulesDir, { recursive: true });
|
|
48
|
+
}
|
|
49
|
+
for (const [name, data] of Object.entries(content.modules)) {
|
|
50
|
+
(0, fs_1.writeFileSync)((0, path_1.join)(modulesDir, name), data);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
// Add to .gitignore if not present
|
|
54
|
+
const gitignorePath = (0, path_1.join)(cwd, '.gitignore');
|
|
55
|
+
if ((0, fs_1.existsSync)(gitignorePath)) {
|
|
56
|
+
const { readFileSync } = await import('fs');
|
|
57
|
+
const gitignore = readFileSync(gitignorePath, 'utf-8');
|
|
58
|
+
if (!gitignore.includes('.cursorrules')) {
|
|
59
|
+
const additions = '\n# CodeBakers (encoded patterns)\n.cursorrules\n.claude/\n';
|
|
60
|
+
(0, fs_1.writeFileSync)(gitignorePath, gitignore + additions);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
const moduleCount = Object.keys(content.modules || {}).length;
|
|
64
|
+
spinner.succeed('Patterns installed successfully!');
|
|
65
|
+
console.log(chalk_1.default.green(`\n Version: ${content.version}`));
|
|
66
|
+
console.log(chalk_1.default.green(` Modules: ${moduleCount}`));
|
|
67
|
+
console.log(chalk_1.default.gray('\n Files created:'));
|
|
68
|
+
console.log(chalk_1.default.gray(' - .cursorrules (for Cursor IDE)'));
|
|
69
|
+
console.log(chalk_1.default.gray(' - CLAUDE.md (for Claude Code)'));
|
|
70
|
+
if (moduleCount > 0) {
|
|
71
|
+
console.log(chalk_1.default.gray(` - .claude/ (${moduleCount} pattern modules)`));
|
|
72
|
+
}
|
|
73
|
+
console.log(chalk_1.default.blue('\n Start building! Your AI now knows 114 production patterns.\n'));
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
spinner.fail('Installation failed');
|
|
77
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
78
|
+
console.log(chalk_1.default.red(`\n Error: ${message}\n`));
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function login(): Promise<void>;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.login = login;
|
|
7
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
const ora_1 = __importDefault(require("ora"));
|
|
9
|
+
const readline_1 = require("readline");
|
|
10
|
+
const config_js_1 = require("../config.js");
|
|
11
|
+
async function prompt(question) {
|
|
12
|
+
const rl = (0, readline_1.createInterface)({
|
|
13
|
+
input: process.stdin,
|
|
14
|
+
output: process.stdout,
|
|
15
|
+
});
|
|
16
|
+
return new Promise((resolve) => {
|
|
17
|
+
rl.question(question, (answer) => {
|
|
18
|
+
rl.close();
|
|
19
|
+
resolve(answer);
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
async function login() {
|
|
24
|
+
console.log(chalk_1.default.blue('\n CodeBakers Login\n'));
|
|
25
|
+
console.log(chalk_1.default.gray(' Get your API key at https://codebakers.ai/dashboard\n'));
|
|
26
|
+
const apiKey = await prompt(' Enter your API key: ');
|
|
27
|
+
if (!apiKey || !apiKey.startsWith('cb_')) {
|
|
28
|
+
console.log(chalk_1.default.red('\n Invalid API key format. Keys start with "cb_"\n'));
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
const spinner = (0, ora_1.default)('Validating API key...').start();
|
|
32
|
+
try {
|
|
33
|
+
const apiUrl = (0, config_js_1.getApiUrl)();
|
|
34
|
+
const response = await fetch(`${apiUrl}/api/content`, {
|
|
35
|
+
method: 'GET',
|
|
36
|
+
headers: {
|
|
37
|
+
Authorization: `Bearer ${apiKey}`,
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
if (!response.ok) {
|
|
41
|
+
const error = await response.json().catch(() => ({}));
|
|
42
|
+
throw new Error(error.error || 'Invalid API key');
|
|
43
|
+
}
|
|
44
|
+
(0, config_js_1.setApiKey)(apiKey);
|
|
45
|
+
spinner.succeed('Logged in successfully!');
|
|
46
|
+
console.log(chalk_1.default.green('\n You can now run `codebakers install` in your project.\n'));
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
spinner.fail('Login failed');
|
|
50
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
51
|
+
console.log(chalk_1.default.red(`\n Error: ${message}\n`));
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.mcpConfig = mcpConfig;
|
|
7
|
+
exports.mcpUninstall = mcpUninstall;
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
const os_1 = require("os");
|
|
10
|
+
const path_1 = require("path");
|
|
11
|
+
const fs_1 = require("fs");
|
|
12
|
+
const config_js_1 = require("../config.js");
|
|
13
|
+
// The MCP server config (shared)
|
|
14
|
+
const CODEBAKERS_MCP_CONFIG = {
|
|
15
|
+
command: 'npx',
|
|
16
|
+
args: ['-y', '@codebakers/cli', 'serve'],
|
|
17
|
+
};
|
|
18
|
+
async function mcpConfig(options) {
|
|
19
|
+
console.log(chalk_1.default.blue('\n CodeBakers MCP Configuration\n'));
|
|
20
|
+
const apiKey = (0, config_js_1.getApiKey)();
|
|
21
|
+
if (!apiKey) {
|
|
22
|
+
console.log(chalk_1.default.red(' Not logged in. Run `codebakers login` first.\n'));
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
// Project-level config: create .mcp.json in current directory
|
|
26
|
+
if (options.project) {
|
|
27
|
+
return createProjectConfig();
|
|
28
|
+
}
|
|
29
|
+
// Global install: write to Claude Code's config file
|
|
30
|
+
if (options.install) {
|
|
31
|
+
return installGlobalConfig();
|
|
32
|
+
}
|
|
33
|
+
// Default: show the easy setup instructions
|
|
34
|
+
showSetupInstructions();
|
|
35
|
+
}
|
|
36
|
+
function showSetupInstructions() {
|
|
37
|
+
console.log(chalk_1.default.white(' Quick Setup (recommended):\n'));
|
|
38
|
+
console.log(chalk_1.default.gray(' Run this command in Claude Code:\n'));
|
|
39
|
+
console.log(chalk_1.default.cyan(' /mcp add codebakers npx -y @codebakers/cli serve\n'));
|
|
40
|
+
console.log(chalk_1.default.gray(' That\'s it! No restart needed.\n'));
|
|
41
|
+
console.log(chalk_1.default.white(' ─────────────────────────────────────\n'));
|
|
42
|
+
console.log(chalk_1.default.white(' Alternative Options:\n'));
|
|
43
|
+
console.log(chalk_1.default.gray(' • Project-level config (for boilerplates):'));
|
|
44
|
+
console.log(chalk_1.default.cyan(' codebakers mcp-config --project\n'));
|
|
45
|
+
console.log(chalk_1.default.gray(' • Global install (writes to config file):'));
|
|
46
|
+
console.log(chalk_1.default.cyan(' codebakers mcp-config --install\n'));
|
|
47
|
+
}
|
|
48
|
+
function createProjectConfig() {
|
|
49
|
+
const projectConfigPath = (0, path_1.join)(process.cwd(), '.mcp.json');
|
|
50
|
+
const config = {
|
|
51
|
+
mcpServers: {
|
|
52
|
+
codebakers: CODEBAKERS_MCP_CONFIG,
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
try {
|
|
56
|
+
// Check if file already exists
|
|
57
|
+
if ((0, fs_1.existsSync)(projectConfigPath)) {
|
|
58
|
+
// Merge with existing config
|
|
59
|
+
const existing = JSON.parse((0, fs_1.readFileSync)(projectConfigPath, 'utf-8'));
|
|
60
|
+
if (!existing.mcpServers) {
|
|
61
|
+
existing.mcpServers = {};
|
|
62
|
+
}
|
|
63
|
+
existing.mcpServers.codebakers = CODEBAKERS_MCP_CONFIG;
|
|
64
|
+
(0, fs_1.writeFileSync)(projectConfigPath, JSON.stringify(existing, null, 2));
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
(0, fs_1.writeFileSync)(projectConfigPath, JSON.stringify(config, null, 2));
|
|
68
|
+
}
|
|
69
|
+
console.log(chalk_1.default.green(' Created .mcp.json in current directory!\n'));
|
|
70
|
+
console.log(chalk_1.default.gray(' File: .mcp.json'));
|
|
71
|
+
console.log(chalk_1.default.gray(' '));
|
|
72
|
+
console.log(chalk_1.default.gray(' {'));
|
|
73
|
+
console.log(chalk_1.default.gray(' "mcpServers": {'));
|
|
74
|
+
console.log(chalk_1.default.yellow(' "codebakers": {'));
|
|
75
|
+
console.log(chalk_1.default.yellow(` "command": "npx",`));
|
|
76
|
+
console.log(chalk_1.default.yellow(` "args": ["-y", "@codebakers/cli", "serve"]`));
|
|
77
|
+
console.log(chalk_1.default.yellow(' }'));
|
|
78
|
+
console.log(chalk_1.default.gray(' }'));
|
|
79
|
+
console.log(chalk_1.default.gray(' }\n'));
|
|
80
|
+
console.log(chalk_1.default.white(' How to use:\n'));
|
|
81
|
+
console.log(chalk_1.default.gray(' 1. Commit .mcp.json to your repo'));
|
|
82
|
+
console.log(chalk_1.default.gray(' 2. When someone opens the project in Claude Code,'));
|
|
83
|
+
console.log(chalk_1.default.gray(' the MCP server starts automatically'));
|
|
84
|
+
console.log(chalk_1.default.gray(' 3. Patterns are fetched on-demand (never stored locally)\n'));
|
|
85
|
+
console.log(chalk_1.default.white(' Requirements:\n'));
|
|
86
|
+
console.log(chalk_1.default.gray(' Users must have run `codebakers login` once on their machine.\n'));
|
|
87
|
+
// Also add to .gitignore if it's not a file we want tracked
|
|
88
|
+
// Actually, we DO want .mcp.json tracked so it works for all users
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
92
|
+
console.log(chalk_1.default.red(`\n Error: ${message}\n`));
|
|
93
|
+
process.exit(1);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function installGlobalConfig() {
|
|
97
|
+
const home = (0, os_1.homedir)();
|
|
98
|
+
let configPath;
|
|
99
|
+
if ((0, os_1.platform)() === 'win32') {
|
|
100
|
+
configPath = (0, path_1.join)(home, 'AppData', 'Roaming', 'Claude', 'claude_desktop_config.json');
|
|
101
|
+
}
|
|
102
|
+
else if ((0, os_1.platform)() === 'darwin') {
|
|
103
|
+
configPath = (0, path_1.join)(home, 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json');
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
configPath = (0, path_1.join)(home, '.config', 'claude', 'claude_desktop_config.json');
|
|
107
|
+
}
|
|
108
|
+
try {
|
|
109
|
+
// Ensure config directory exists
|
|
110
|
+
const configDir = (0, path_1.join)(configPath, '..');
|
|
111
|
+
if (!(0, fs_1.existsSync)(configDir)) {
|
|
112
|
+
(0, fs_1.mkdirSync)(configDir, { recursive: true });
|
|
113
|
+
}
|
|
114
|
+
// Read existing config or create new
|
|
115
|
+
let config = { mcpServers: {} };
|
|
116
|
+
if ((0, fs_1.existsSync)(configPath)) {
|
|
117
|
+
try {
|
|
118
|
+
const existing = (0, fs_1.readFileSync)(configPath, 'utf-8');
|
|
119
|
+
config = JSON.parse(existing);
|
|
120
|
+
if (!config.mcpServers) {
|
|
121
|
+
config.mcpServers = {};
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
console.log(chalk_1.default.yellow(' Existing config is invalid, creating new one.'));
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
// Add CodeBakers MCP server
|
|
129
|
+
config.mcpServers.codebakers = CODEBAKERS_MCP_CONFIG;
|
|
130
|
+
// Write config
|
|
131
|
+
(0, fs_1.writeFileSync)(configPath, JSON.stringify(config, null, 2));
|
|
132
|
+
console.log(chalk_1.default.green(' MCP configuration installed!\n'));
|
|
133
|
+
console.log(chalk_1.default.gray(' Config written to:'));
|
|
134
|
+
console.log(chalk_1.default.cyan(` ${configPath}\n`));
|
|
135
|
+
console.log(chalk_1.default.white(' Next step:\n'));
|
|
136
|
+
console.log(chalk_1.default.gray(' Restart Claude Code to activate the MCP server.\n'));
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
140
|
+
console.log(chalk_1.default.red(`\n Error: ${message}\n`));
|
|
141
|
+
console.log(chalk_1.default.gray(' Try the quick setup instead:\n'));
|
|
142
|
+
console.log(chalk_1.default.cyan(' /mcp add codebakers npx -y @codebakers/cli serve\n'));
|
|
143
|
+
process.exit(1);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
async function mcpUninstall() {
|
|
147
|
+
console.log(chalk_1.default.blue('\n Remove CodeBakers MCP Configuration\n'));
|
|
148
|
+
// Check for project-level config
|
|
149
|
+
const projectConfigPath = (0, path_1.join)(process.cwd(), '.mcp.json');
|
|
150
|
+
if ((0, fs_1.existsSync)(projectConfigPath)) {
|
|
151
|
+
try {
|
|
152
|
+
const existing = JSON.parse((0, fs_1.readFileSync)(projectConfigPath, 'utf-8'));
|
|
153
|
+
if (existing.mcpServers?.codebakers) {
|
|
154
|
+
delete existing.mcpServers.codebakers;
|
|
155
|
+
if (Object.keys(existing.mcpServers).length === 0) {
|
|
156
|
+
// Remove file if empty
|
|
157
|
+
const { unlinkSync } = await import('fs');
|
|
158
|
+
unlinkSync(projectConfigPath);
|
|
159
|
+
console.log(chalk_1.default.green(' Removed .mcp.json (was empty)\n'));
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
(0, fs_1.writeFileSync)(projectConfigPath, JSON.stringify(existing, null, 2));
|
|
163
|
+
console.log(chalk_1.default.green(' Removed codebakers from .mcp.json\n'));
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
catch {
|
|
168
|
+
// Ignore errors with project config
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
// Check for global config
|
|
172
|
+
const home = (0, os_1.homedir)();
|
|
173
|
+
let configPath;
|
|
174
|
+
if ((0, os_1.platform)() === 'win32') {
|
|
175
|
+
configPath = (0, path_1.join)(home, 'AppData', 'Roaming', 'Claude', 'claude_desktop_config.json');
|
|
176
|
+
}
|
|
177
|
+
else if ((0, os_1.platform)() === 'darwin') {
|
|
178
|
+
configPath = (0, path_1.join)(home, 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json');
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
configPath = (0, path_1.join)(home, '.config', 'claude', 'claude_desktop_config.json');
|
|
182
|
+
}
|
|
183
|
+
if (!(0, fs_1.existsSync)(configPath)) {
|
|
184
|
+
console.log(chalk_1.default.gray(' No global MCP configuration found.\n'));
|
|
185
|
+
console.log(chalk_1.default.gray(' To remove from Claude Code, run:\n'));
|
|
186
|
+
console.log(chalk_1.default.cyan(' /mcp remove codebakers\n'));
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
try {
|
|
190
|
+
const existing = (0, fs_1.readFileSync)(configPath, 'utf-8');
|
|
191
|
+
const config = JSON.parse(existing);
|
|
192
|
+
if (config.mcpServers && config.mcpServers.codebakers) {
|
|
193
|
+
delete config.mcpServers.codebakers;
|
|
194
|
+
(0, fs_1.writeFileSync)(configPath, JSON.stringify(config, null, 2));
|
|
195
|
+
console.log(chalk_1.default.green(' Removed from global config.\n'));
|
|
196
|
+
console.log(chalk_1.default.gray(' Restart Claude Code to apply changes.\n'));
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
console.log(chalk_1.default.gray(' CodeBakers not found in global config.\n'));
|
|
200
|
+
console.log(chalk_1.default.gray(' To remove from Claude Code, run:\n'));
|
|
201
|
+
console.log(chalk_1.default.cyan(' /mcp remove codebakers\n'));
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
catch (error) {
|
|
205
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
206
|
+
console.log(chalk_1.default.red(`\n Error: ${message}\n`));
|
|
207
|
+
process.exit(1);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function serve(): Promise<void>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.serve = serve;
|
|
7
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
const config_js_1 = require("../config.js");
|
|
9
|
+
async function serve() {
|
|
10
|
+
const apiKey = (0, config_js_1.getApiKey)();
|
|
11
|
+
if (!apiKey) {
|
|
12
|
+
console.error(chalk_1.default.red('\n Not logged in. Run `codebakers login` first.\n'));
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
// Log to stderr so it doesn't interfere with MCP stdio protocol
|
|
16
|
+
console.error(chalk_1.default.blue('\n CodeBakers MCP Server\n'));
|
|
17
|
+
console.error(chalk_1.default.green(' Starting MCP server on stdio...'));
|
|
18
|
+
console.error(chalk_1.default.gray(' This server provides pattern tools to Claude Code.\n'));
|
|
19
|
+
console.error(chalk_1.default.gray(' Available tools:'));
|
|
20
|
+
console.error(chalk_1.default.gray(' - get_pattern: Fetch a single pattern'));
|
|
21
|
+
console.error(chalk_1.default.gray(' - list_patterns: List all available patterns'));
|
|
22
|
+
console.error(chalk_1.default.gray(' - get_patterns: Fetch multiple patterns\n'));
|
|
23
|
+
// Dynamically import and run the MCP server
|
|
24
|
+
const { runServer } = await import('../mcp/server.js');
|
|
25
|
+
await runServer();
|
|
26
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function setup(): Promise<void>;
|