codebakers 1.0.45 → 2.0.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 (81) hide show
  1. package/README.md +275 -60
  2. package/dist/index.d.ts +1 -0
  3. package/dist/index.js +3999 -0
  4. package/install.bat +9 -0
  5. package/package.json +71 -115
  6. package/src/channels/discord.ts +5 -0
  7. package/src/channels/slack.ts +5 -0
  8. package/src/channels/sms.ts +4 -0
  9. package/src/channels/telegram.ts +5 -0
  10. package/src/channels/whatsapp.ts +7 -0
  11. package/src/commands/check.ts +365 -0
  12. package/src/commands/code.ts +684 -0
  13. package/src/commands/connect.ts +12 -0
  14. package/src/commands/deploy.ts +414 -0
  15. package/src/commands/fix.ts +20 -0
  16. package/src/commands/gateway.ts +604 -0
  17. package/src/commands/generate.ts +178 -0
  18. package/src/commands/init.ts +574 -0
  19. package/src/commands/learn.ts +36 -0
  20. package/src/commands/security.ts +102 -0
  21. package/src/commands/setup.ts +448 -0
  22. package/src/commands/status.ts +56 -0
  23. package/src/index.ts +268 -0
  24. package/src/patterns/loader.ts +337 -0
  25. package/src/services/github.ts +61 -0
  26. package/src/services/supabase.ts +147 -0
  27. package/src/services/vercel.ts +61 -0
  28. package/src/utils/claude-md.ts +287 -0
  29. package/src/utils/config.ts +282 -0
  30. package/src/utils/updates.ts +27 -0
  31. package/tsconfig.json +17 -10
  32. package/.vscodeignore +0 -18
  33. package/LICENSE +0 -21
  34. package/codebakers-1.0.0.vsix +0 -0
  35. package/codebakers-1.0.10.vsix +0 -0
  36. package/codebakers-1.0.11.vsix +0 -0
  37. package/codebakers-1.0.12.vsix +0 -0
  38. package/codebakers-1.0.13.vsix +0 -0
  39. package/codebakers-1.0.14.vsix +0 -0
  40. package/codebakers-1.0.15.vsix +0 -0
  41. package/codebakers-1.0.16.vsix +0 -0
  42. package/codebakers-1.0.17.vsix +0 -0
  43. package/codebakers-1.0.18.vsix +0 -0
  44. package/codebakers-1.0.19.vsix +0 -0
  45. package/codebakers-1.0.20.vsix +0 -0
  46. package/codebakers-1.0.21.vsix +0 -0
  47. package/codebakers-1.0.22.vsix +0 -0
  48. package/codebakers-1.0.23.vsix +0 -0
  49. package/codebakers-1.0.24.vsix +0 -0
  50. package/codebakers-1.0.25.vsix +0 -0
  51. package/codebakers-1.0.26.vsix +0 -0
  52. package/codebakers-1.0.27.vsix +0 -0
  53. package/codebakers-1.0.28.vsix +0 -0
  54. package/codebakers-1.0.29.vsix +0 -0
  55. package/codebakers-1.0.30.vsix +0 -0
  56. package/codebakers-1.0.31.vsix +0 -0
  57. package/codebakers-1.0.32.vsix +0 -0
  58. package/codebakers-1.0.35.vsix +0 -0
  59. package/codebakers-1.0.36.vsix +0 -0
  60. package/codebakers-1.0.37.vsix +0 -0
  61. package/codebakers-1.0.38.vsix +0 -0
  62. package/codebakers-1.0.39.vsix +0 -0
  63. package/codebakers-1.0.40.vsix +0 -0
  64. package/codebakers-1.0.41.vsix +0 -0
  65. package/codebakers-1.0.42.vsix +0 -0
  66. package/codebakers-1.0.43.vsix +0 -0
  67. package/codebakers-1.0.44.vsix +0 -0
  68. package/codebakers-1.0.45.vsix +0 -0
  69. package/dist/extension.js +0 -1394
  70. package/esbuild.js +0 -63
  71. package/media/icon.png +0 -0
  72. package/media/icon.svg +0 -7
  73. package/nul +0 -1
  74. package/preview.html +0 -547
  75. package/src/ChatPanelProvider.ts +0 -1815
  76. package/src/ChatViewProvider.ts +0 -749
  77. package/src/CodeBakersClient.ts +0 -1146
  78. package/src/CodeValidator.ts +0 -645
  79. package/src/FileOperations.ts +0 -410
  80. package/src/ProjectContext.ts +0 -526
  81. package/src/extension.ts +0 -332
@@ -0,0 +1,414 @@
1
+ import * as p from '@clack/prompts';
2
+ import chalk from 'chalk';
3
+ import { execa } from 'execa';
4
+ import * as fs from 'fs-extra';
5
+ import * as path from 'path';
6
+ import Anthropic from '@anthropic-ai/sdk';
7
+ import { Config } from '../utils/config.js';
8
+ import { VercelService } from '../services/vercel.js';
9
+ import { runPatternCheck } from './check.js';
10
+
11
+ interface DeployOptions {
12
+ preview?: boolean;
13
+ check?: boolean;
14
+ }
15
+
16
+ export async function deployCommand(options: DeployOptions = {}): Promise<void> {
17
+ const config = new Config();
18
+
19
+ if (!config.isInProject()) {
20
+ p.log.error('Not in a CodeBakers project.');
21
+ return;
22
+ }
23
+
24
+ p.intro(chalk.bgCyan.black(' Deploy to Production '));
25
+
26
+ const spinner = p.spinner();
27
+
28
+ // Step 1: Run pattern check (unless skipped)
29
+ if (options.check !== false) {
30
+ spinner.start('Running CodeBakers check...');
31
+ const checkResult = await runPatternCheck(false);
32
+
33
+ if (!checkResult.passed) {
34
+ spinner.stop('');
35
+ const errors = checkResult.violations.filter(v => v.severity === 'error');
36
+
37
+ if (errors.length > 0) {
38
+ p.log.error(`${errors.length} pattern violations found. Fix before deploying.`);
39
+
40
+ const showViolations = await p.confirm({
41
+ message: 'Show violations?',
42
+ initialValue: true,
43
+ });
44
+
45
+ if (showViolations && !p.isCancel(showViolations)) {
46
+ for (const v of errors) {
47
+ console.log(chalk.red(` ✗ ${v.file}:${v.line} - ${v.message}`));
48
+ }
49
+ }
50
+
51
+ const autoFix = await p.confirm({
52
+ message: 'Attempt auto-fix with AI?',
53
+ initialValue: true,
54
+ });
55
+
56
+ if (!autoFix || p.isCancel(autoFix)) {
57
+ p.outro(chalk.red('Deploy cancelled.'));
58
+ return;
59
+ }
60
+
61
+ // Auto-fix with AI
62
+ spinner.start('Auto-fixing with AI...');
63
+ await autoFixWithAI(config, errors);
64
+ spinner.stop('Auto-fix complete');
65
+
66
+ // Re-run check
67
+ const recheck = await runPatternCheck(false);
68
+ if (!recheck.passed) {
69
+ p.log.error('Some violations remain. Manual fix required.');
70
+ p.outro(chalk.red('Deploy cancelled.'));
71
+ return;
72
+ }
73
+ }
74
+ }
75
+ spinner.stop('Pattern check passed');
76
+ }
77
+
78
+ // Step 2: Run TypeScript check
79
+ spinner.start('Running TypeScript check...');
80
+ try {
81
+ await execa('npx', ['tsc', '--noEmit'], { cwd: process.cwd() });
82
+ spinner.stop('TypeScript check passed');
83
+ } catch (error) {
84
+ spinner.stop('');
85
+ p.log.error('TypeScript errors found.');
86
+
87
+ const fix = await p.confirm({
88
+ message: 'Attempt to fix TypeScript errors?',
89
+ initialValue: true,
90
+ });
91
+
92
+ if (fix && !p.isCancel(fix)) {
93
+ spinner.start('Fixing TypeScript errors...');
94
+ const fixed = await fixTypeScriptErrors(config);
95
+ spinner.stop(fixed ? 'TypeScript errors fixed' : 'Could not auto-fix all errors');
96
+
97
+ if (!fixed) {
98
+ p.outro(chalk.red('Deploy cancelled.'));
99
+ return;
100
+ }
101
+ } else {
102
+ p.outro(chalk.red('Deploy cancelled.'));
103
+ return;
104
+ }
105
+ }
106
+
107
+ // Step 3: Run build
108
+ spinner.start('Building project...');
109
+ try {
110
+ await execa('pnpm', ['build'], { cwd: process.cwd() });
111
+ spinner.stop('Build successful');
112
+ } catch (error) {
113
+ spinner.stop('');
114
+ p.log.error('Build failed.');
115
+
116
+ const errorOutput = error instanceof Error ? error.message : 'Unknown error';
117
+ console.log(chalk.dim(errorOutput));
118
+
119
+ const fix = await p.confirm({
120
+ message: 'Attempt to fix build errors with AI?',
121
+ initialValue: true,
122
+ });
123
+
124
+ if (fix && !p.isCancel(fix)) {
125
+ spinner.start('Fixing build errors...');
126
+ const fixed = await fixBuildErrors(config, errorOutput);
127
+ spinner.stop(fixed ? 'Build errors fixed' : 'Could not auto-fix');
128
+
129
+ if (fixed) {
130
+ // Retry build
131
+ spinner.start('Retrying build...');
132
+ try {
133
+ await execa('pnpm', ['build'], { cwd: process.cwd() });
134
+ spinner.stop('Build successful');
135
+ } catch {
136
+ spinner.stop('Build still failing');
137
+ p.outro(chalk.red('Deploy cancelled.'));
138
+ return;
139
+ }
140
+ } else {
141
+ p.outro(chalk.red('Deploy cancelled.'));
142
+ return;
143
+ }
144
+ } else {
145
+ p.outro(chalk.red('Deploy cancelled.'));
146
+ return;
147
+ }
148
+ }
149
+
150
+ // Step 4: Git commit if there are changes
151
+ spinner.start('Checking for uncommitted changes...');
152
+ const { stdout: gitStatus } = await execa('git', ['status', '--porcelain'], { cwd: process.cwd() });
153
+
154
+ if (gitStatus.trim()) {
155
+ spinner.stop('');
156
+ const commit = await p.confirm({
157
+ message: 'You have uncommitted changes. Commit before deploying?',
158
+ initialValue: true,
159
+ });
160
+
161
+ if (commit && !p.isCancel(commit)) {
162
+ const message = await p.text({
163
+ message: 'Commit message:',
164
+ placeholder: 'Pre-deploy changes',
165
+ initialValue: 'Pre-deploy changes',
166
+ });
167
+
168
+ if (!p.isCancel(message)) {
169
+ await execa('git', ['add', '.'], { cwd: process.cwd() });
170
+ await execa('git', ['commit', '-m', message as string], { cwd: process.cwd() });
171
+
172
+ spinner.start('Pushing to GitHub...');
173
+ await execa('git', ['push'], { cwd: process.cwd() });
174
+ spinner.stop('Pushed to GitHub');
175
+ }
176
+ }
177
+ } else {
178
+ spinner.stop('No uncommitted changes');
179
+ }
180
+
181
+ // Step 5: Deploy to Vercel
182
+ const deployType = options.preview ? 'preview' : 'production';
183
+ spinner.start(`Deploying to ${deployType}...`);
184
+
185
+ try {
186
+ const vercel = new VercelService(config);
187
+ const deployment = await vercel.deploy(process.cwd(), !options.preview);
188
+
189
+ spinner.stop('Deployment complete!');
190
+
191
+ console.log(boxedOutput(`
192
+ ${chalk.green('✓')} Deployed successfully!
193
+
194
+ ${chalk.bold('URL:')} ${deployment.url}
195
+ ${chalk.bold('Type:')} ${deployType}
196
+ ${chalk.bold('Time:')} ${new Date().toLocaleTimeString()}
197
+
198
+ ${chalk.dim('View in Vercel Dashboard:')}
199
+ ${chalk.dim(deployment.dashboardUrl || 'https://vercel.com/dashboard')}
200
+ `));
201
+
202
+ } catch (error) {
203
+ spinner.stop('');
204
+ const errorMsg = error instanceof Error ? error.message : 'Unknown error';
205
+ p.log.error(`Deployment failed: ${errorMsg}`);
206
+
207
+ // Check if it's a build error from Vercel
208
+ if (errorMsg.includes('Build failed')) {
209
+ const retry = await p.confirm({
210
+ message: 'Attempt to fix and retry?',
211
+ initialValue: true,
212
+ });
213
+
214
+ if (retry && !p.isCancel(retry)) {
215
+ spinner.start('Analyzing Vercel build error...');
216
+ // Would fetch Vercel logs and auto-fix
217
+ spinner.stop('Fix attempted');
218
+ }
219
+ }
220
+
221
+ p.outro(chalk.red('Deploy failed.'));
222
+ }
223
+ }
224
+
225
+ async function autoFixWithAI(
226
+ config: Config,
227
+ violations: Array<{ file: string; line: number; rule: string; message: string }>
228
+ ): Promise<void> {
229
+ const anthropicCreds = config.getCredentials('anthropic');
230
+ if (!anthropicCreds?.apiKey) {
231
+ throw new Error('Anthropic API key not configured');
232
+ }
233
+
234
+ const anthropic = new Anthropic({
235
+ apiKey: anthropicCreds.apiKey,
236
+ });
237
+
238
+ // Group by file
239
+ const byFile = new Map<string, typeof violations>();
240
+ for (const v of violations) {
241
+ if (!byFile.has(v.file)) {
242
+ byFile.set(v.file, []);
243
+ }
244
+ byFile.get(v.file)!.push(v);
245
+ }
246
+
247
+ for (const [file, fileViolations] of byFile) {
248
+ const filePath = path.join(process.cwd(), file);
249
+ const content = await fs.readFile(filePath, 'utf-8');
250
+
251
+ const prompt = `Fix these CodeBakers pattern violations in this file:
252
+
253
+ Violations:
254
+ ${fileViolations.map(v => `- Line ${v.line}: ${v.rule} - ${v.message}`).join('\n')}
255
+
256
+ Current file content:
257
+ \`\`\`typescript
258
+ ${content}
259
+ \`\`\`
260
+
261
+ Output ONLY the corrected file content, no explanations. Keep all existing functionality.`;
262
+
263
+ const response = await anthropic.messages.create({
264
+ model: 'claude-sonnet-4-20250514',
265
+ max_tokens: 8192,
266
+ messages: [{ role: 'user', content: prompt }],
267
+ });
268
+
269
+ let fixed = response.content[0].type === 'text' ? response.content[0].text : '';
270
+
271
+ // Extract code from markdown if present
272
+ const codeMatch = fixed.match(/```(?:typescript|tsx?)?\n([\s\S]+?)\n```/);
273
+ if (codeMatch) {
274
+ fixed = codeMatch[1];
275
+ }
276
+
277
+ await fs.writeFile(filePath, fixed);
278
+ }
279
+ }
280
+
281
+ async function fixTypeScriptErrors(config: Config): Promise<boolean> {
282
+ try {
283
+ // Get TypeScript errors
284
+ const { stderr } = await execa('npx', ['tsc', '--noEmit'], {
285
+ cwd: process.cwd(),
286
+ reject: false,
287
+ });
288
+
289
+ if (!stderr) return true;
290
+
291
+ const anthropicCreds = config.getCredentials('anthropic');
292
+ if (!anthropicCreds?.apiKey) {
293
+ return false;
294
+ }
295
+
296
+ const anthropic = new Anthropic({
297
+ apiKey: anthropicCreds.apiKey,
298
+ });
299
+
300
+ // Parse error locations
301
+ const errorLines = stderr.split('\n').filter(line => line.includes('error TS'));
302
+
303
+ for (const errorLine of errorLines.slice(0, 10)) { // Limit to 10 errors
304
+ const match = errorLine.match(/^(.+?)\((\d+),(\d+)\): error (TS\d+): (.+)$/);
305
+ if (!match) continue;
306
+
307
+ const [, file, line, , , message] = match;
308
+ const filePath = path.join(process.cwd(), file);
309
+
310
+ if (!await fs.pathExists(filePath)) continue;
311
+
312
+ const content = await fs.readFile(filePath, 'utf-8');
313
+
314
+ const prompt = `Fix this TypeScript error:
315
+
316
+ File: ${file}
317
+ Line: ${line}
318
+ Error: ${message}
319
+
320
+ Current file content:
321
+ \`\`\`typescript
322
+ ${content}
323
+ \`\`\`
324
+
325
+ Output ONLY the corrected file content, no explanations.`;
326
+
327
+ const response = await anthropic.messages.create({
328
+ model: 'claude-sonnet-4-20250514',
329
+ max_tokens: 8192,
330
+ messages: [{ role: 'user', content: prompt }],
331
+ });
332
+
333
+ let fixed = response.content[0].type === 'text' ? response.content[0].text : '';
334
+
335
+ const codeMatch = fixed.match(/```(?:typescript|tsx?)?\n([\s\S]+?)\n```/);
336
+ if (codeMatch) {
337
+ fixed = codeMatch[1];
338
+ }
339
+
340
+ await fs.writeFile(filePath, fixed);
341
+ }
342
+
343
+ return true;
344
+ } catch {
345
+ return false;
346
+ }
347
+ }
348
+
349
+ async function fixBuildErrors(config: Config, errorOutput: string): Promise<boolean> {
350
+ const anthropicCreds = config.getCredentials('anthropic');
351
+ if (!anthropicCreds?.apiKey) {
352
+ return false;
353
+ }
354
+
355
+ const anthropic = new Anthropic({
356
+ apiKey: anthropicCreds.apiKey,
357
+ });
358
+
359
+ // Parse error to find file
360
+ const fileMatch = errorOutput.match(/(?:Error|error).*?(?:in|at)\s+(.+?\.tsx?)(?::|$)/);
361
+ if (!fileMatch) return false;
362
+
363
+ const file = fileMatch[1];
364
+ const filePath = path.join(process.cwd(), file);
365
+
366
+ if (!await fs.pathExists(filePath)) return false;
367
+
368
+ const content = await fs.readFile(filePath, 'utf-8');
369
+
370
+ const prompt = `Fix this build error:
371
+
372
+ Error output:
373
+ ${errorOutput}
374
+
375
+ File: ${file}
376
+
377
+ Current file content:
378
+ \`\`\`typescript
379
+ ${content}
380
+ \`\`\`
381
+
382
+ Output ONLY the corrected file content, no explanations.`;
383
+
384
+ try {
385
+ const response = await anthropic.messages.create({
386
+ model: 'claude-sonnet-4-20250514',
387
+ max_tokens: 8192,
388
+ messages: [{ role: 'user', content: prompt }],
389
+ });
390
+
391
+ let fixed = response.content[0].type === 'text' ? response.content[0].text : '';
392
+
393
+ const codeMatch = fixed.match(/```(?:typescript|tsx?)?\n([\s\S]+?)\n```/);
394
+ if (codeMatch) {
395
+ fixed = codeMatch[1];
396
+ }
397
+
398
+ await fs.writeFile(filePath, fixed);
399
+ return true;
400
+ } catch {
401
+ return false;
402
+ }
403
+ }
404
+
405
+ function boxedOutput(content: string): string {
406
+ const lines = content.split('\n');
407
+ const maxLength = Math.max(...lines.map(l => l.replace(/\x1b\[[0-9;]*m/g, '').length));
408
+ const border = '─'.repeat(maxLength + 2);
409
+
410
+ return `
411
+ ╭${border}╮
412
+ ${lines.map(l => `│ ${l.padEnd(maxLength)} │`).join('\n')}
413
+ ╰${border}╯`;
414
+ }
@@ -0,0 +1,20 @@
1
+ import * as p from '@clack/prompts';
2
+ import chalk from 'chalk';
3
+ import { runPatternCheck } from './check.js';
4
+
5
+ export async function fixCommand(): Promise<void> {
6
+ p.intro(chalk.bgCyan.black(' Auto-Fix '));
7
+
8
+ const spinner = p.spinner();
9
+ spinner.start('Analyzing code...');
10
+
11
+ const result = await runPatternCheck(true);
12
+
13
+ if (result.passed) {
14
+ spinner.stop('No issues found!');
15
+ } else {
16
+ spinner.stop(`Fixed ${result.violations.length} issues`);
17
+ }
18
+
19
+ p.outro(chalk.green('Done!'));
20
+ }