@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.
Files changed (44) hide show
  1. package/dist/commands/doctor.d.ts +8 -0
  2. package/dist/commands/doctor.js +218 -0
  3. package/dist/commands/init.d.ts +4 -0
  4. package/dist/commands/init.js +772 -0
  5. package/dist/commands/install-hook.d.ts +12 -0
  6. package/dist/commands/install-hook.js +193 -0
  7. package/dist/commands/install.d.ts +1 -0
  8. package/dist/commands/install.js +81 -0
  9. package/dist/commands/login.d.ts +1 -0
  10. package/dist/commands/login.js +54 -0
  11. package/dist/commands/mcp-config.d.ts +6 -0
  12. package/dist/commands/mcp-config.js +209 -0
  13. package/dist/commands/serve.d.ts +1 -0
  14. package/dist/commands/serve.js +26 -0
  15. package/dist/commands/setup.d.ts +1 -0
  16. package/dist/commands/setup.js +92 -0
  17. package/dist/commands/status.d.ts +1 -0
  18. package/dist/commands/status.js +49 -0
  19. package/dist/commands/uninstall.d.ts +1 -0
  20. package/dist/commands/uninstall.js +50 -0
  21. package/dist/config.d.ts +5 -0
  22. package/dist/config.js +33 -0
  23. package/dist/index.d.ts +1 -0
  24. package/dist/index.js +71 -1075
  25. package/dist/mcp/server.d.ts +2 -0
  26. package/dist/mcp/server.js +544 -0
  27. package/package.json +17 -38
  28. package/src/commands/doctor.ts +231 -0
  29. package/src/commands/init.ts +827 -0
  30. package/src/commands/install-hook.ts +207 -0
  31. package/src/commands/install.ts +94 -0
  32. package/src/commands/login.ts +56 -0
  33. package/src/commands/mcp-config.ts +235 -0
  34. package/src/commands/serve.ts +23 -0
  35. package/src/commands/setup.ts +104 -0
  36. package/src/commands/status.ts +48 -0
  37. package/src/commands/uninstall.ts +49 -0
  38. package/src/config.ts +34 -0
  39. package/src/index.ts +87 -0
  40. package/src/mcp/server.ts +617 -0
  41. package/tsconfig.json +16 -0
  42. package/README.md +0 -89
  43. package/dist/chunk-7CKLRE2H.js +0 -36
  44. 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,6 @@
1
+ export declare function mcpConfig(options: {
2
+ install?: boolean;
3
+ show?: boolean;
4
+ project?: boolean;
5
+ }): Promise<void>;
6
+ export declare function mcpUninstall(): Promise<void>;
@@ -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>;