codebakers 2.5.3 → 3.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 (60) hide show
  1. package/README.md +54 -255
  2. package/dist/chunk-HOWR3YTF.js +146 -0
  3. package/dist/index.d.ts +0 -3
  4. package/dist/index.js +10489 -7994
  5. package/dist/terminal-6ZQVP6R7.js +10 -0
  6. package/package.json +26 -41
  7. package/AUDIT_REPORT.md +0 -138
  8. package/dist/advisors-RWRTSJRR.js +0 -7
  9. package/dist/chunk-ASIJIQYC.js +0 -320
  10. package/dist/chunk-D44U3IEA.js +0 -565
  11. package/dist/chunk-LANM5XQW.js +0 -326
  12. package/dist/prd-RYITSL6Q.js +0 -7
  13. package/install.bat +0 -9
  14. package/installers/CodeBakers-Install.bat +0 -207
  15. package/installers/CodeBakers-Install.command +0 -232
  16. package/installers/README.md +0 -157
  17. package/installers/mac/assets/README.txt +0 -31
  18. package/installers/mac/build-mac-installer.sh +0 -240
  19. package/installers/windows/CodeBakers.iss +0 -256
  20. package/installers/windows/assets/README.txt +0 -16
  21. package/installers/windows/scripts/post-install.bat +0 -15
  22. package/src/channels/discord.ts +0 -5
  23. package/src/channels/slack.ts +0 -5
  24. package/src/channels/sms.ts +0 -4
  25. package/src/channels/telegram.ts +0 -5
  26. package/src/channels/whatsapp.ts +0 -7
  27. package/src/commands/advisors.ts +0 -699
  28. package/src/commands/build.ts +0 -1025
  29. package/src/commands/check.ts +0 -365
  30. package/src/commands/code.ts +0 -806
  31. package/src/commands/connect.ts +0 -12
  32. package/src/commands/deploy.ts +0 -448
  33. package/src/commands/design.ts +0 -298
  34. package/src/commands/fix.ts +0 -20
  35. package/src/commands/gateway.ts +0 -604
  36. package/src/commands/generate.ts +0 -178
  37. package/src/commands/init.ts +0 -634
  38. package/src/commands/integrate.ts +0 -884
  39. package/src/commands/learn.ts +0 -36
  40. package/src/commands/migrate.ts +0 -419
  41. package/src/commands/prd-maker.ts +0 -588
  42. package/src/commands/prd.ts +0 -419
  43. package/src/commands/security.ts +0 -102
  44. package/src/commands/setup.ts +0 -600
  45. package/src/commands/status.ts +0 -56
  46. package/src/commands/website.ts +0 -741
  47. package/src/index.ts +0 -627
  48. package/src/patterns/loader.ts +0 -337
  49. package/src/services/github.ts +0 -61
  50. package/src/services/supabase.ts +0 -147
  51. package/src/services/vercel.ts +0 -61
  52. package/src/utils/claude-md.ts +0 -287
  53. package/src/utils/config.ts +0 -375
  54. package/src/utils/display.ts +0 -338
  55. package/src/utils/files.ts +0 -418
  56. package/src/utils/nlp.ts +0 -312
  57. package/src/utils/ui.ts +0 -441
  58. package/src/utils/updates.ts +0 -8
  59. package/src/utils/voice.ts +0 -323
  60. package/tsconfig.json +0 -26
@@ -1,418 +0,0 @@
1
- import * as p from '@clack/prompts';
2
- import chalk from 'chalk';
3
- import fs from 'fs-extra';
4
- import * as path from 'path';
5
- import { execa } from 'execa';
6
-
7
- /**
8
- * Read content from clipboard
9
- */
10
- export async function readClipboard(): Promise<string | null> {
11
- try {
12
- if (process.platform === 'win32') {
13
- // Windows: PowerShell Get-Clipboard
14
- const result = await execa('powershell', ['-Command', 'Get-Clipboard'], { timeout: 5000 });
15
- return result.stdout;
16
- } else if (process.platform === 'darwin') {
17
- // macOS: pbpaste
18
- const result = await execa('pbpaste', [], { timeout: 5000 });
19
- return result.stdout;
20
- } else {
21
- // Linux: xclip or xsel
22
- try {
23
- const result = await execa('xclip', ['-selection', 'clipboard', '-o'], { timeout: 5000 });
24
- return result.stdout;
25
- } catch {
26
- const result = await execa('xsel', ['--clipboard', '--output'], { timeout: 5000 });
27
- return result.stdout;
28
- }
29
- }
30
- } catch {
31
- return null;
32
- }
33
- }
34
-
35
- /**
36
- * Read a file from path (supports drag & drop paths)
37
- */
38
- export async function readFile(filePath: string): Promise<{ content: string; type: string; name: string } | null> {
39
- try {
40
- // Clean up the path (remove quotes, handle drag & drop formatting)
41
- let cleanPath = filePath.trim();
42
-
43
- // Remove surrounding quotes (common when drag & dropping)
44
- if ((cleanPath.startsWith('"') && cleanPath.endsWith('"')) ||
45
- (cleanPath.startsWith("'") && cleanPath.endsWith("'"))) {
46
- cleanPath = cleanPath.slice(1, -1);
47
- }
48
-
49
- // Handle Windows paths with spaces
50
- cleanPath = cleanPath.replace(/\\ /g, ' ');
51
-
52
- // Check if file exists
53
- if (!await fs.pathExists(cleanPath)) {
54
- return null;
55
- }
56
-
57
- const stats = await fs.stat(cleanPath);
58
-
59
- // Don't read files larger than 10MB
60
- if (stats.size > 10 * 1024 * 1024) {
61
- console.log(chalk.yellow('File too large (max 10MB)'));
62
- return null;
63
- }
64
-
65
- const ext = path.extname(cleanPath).toLowerCase();
66
- const name = path.basename(cleanPath);
67
-
68
- // Determine file type
69
- const textExtensions = [
70
- '.txt', '.md', '.json', '.js', '.ts', '.tsx', '.jsx',
71
- '.css', '.scss', '.html', '.xml', '.yaml', '.yml',
72
- '.py', '.rb', '.go', '.rs', '.java', '.c', '.cpp', '.h',
73
- '.sql', '.sh', '.bash', '.zsh', '.fish', '.ps1',
74
- '.env', '.gitignore', '.dockerfile', '.toml', '.ini', '.cfg',
75
- '.csv', '.log', '.mdx', '.astro', '.vue', '.svelte',
76
- ];
77
-
78
- const imageExtensions = ['.png', '.jpg', '.jpeg', '.gif', '.webp', '.svg', '.bmp'];
79
- const pdfExtensions = ['.pdf'];
80
-
81
- if (textExtensions.includes(ext) || ext === '') {
82
- // Read as text
83
- const content = await fs.readFile(cleanPath, 'utf-8');
84
- return { content, type: 'text', name };
85
- } else if (imageExtensions.includes(ext)) {
86
- // Read as base64 for images
87
- const buffer = await fs.readFile(cleanPath);
88
- const base64 = buffer.toString('base64');
89
- const mimeType = getMimeType(ext);
90
- return {
91
- content: `data:${mimeType};base64,${base64}`,
92
- type: 'image',
93
- name
94
- };
95
- } else if (pdfExtensions.includes(ext)) {
96
- // For PDFs, try to extract text
97
- const text = await extractPdfText(cleanPath);
98
- if (text) {
99
- return { content: text, type: 'pdf', name };
100
- }
101
- // Fall back to noting it's a PDF
102
- return {
103
- content: `[PDF file: ${name} - text extraction not available]`,
104
- type: 'pdf',
105
- name
106
- };
107
- } else {
108
- // Try to read as text anyway
109
- try {
110
- const content = await fs.readFile(cleanPath, 'utf-8');
111
- // Check if it's actually text (not binary)
112
- if (content.includes('\0')) {
113
- return {
114
- content: `[Binary file: ${name}]`,
115
- type: 'binary',
116
- name
117
- };
118
- }
119
- return { content, type: 'text', name };
120
- } catch {
121
- return {
122
- content: `[Unsupported file type: ${name}]`,
123
- type: 'unknown',
124
- name
125
- };
126
- }
127
- }
128
- } catch (error) {
129
- console.log(chalk.red(`Error reading file: ${error instanceof Error ? error.message : 'Unknown error'}`));
130
- return null;
131
- }
132
- }
133
-
134
- /**
135
- * Extract text from PDF using pdftotext or pdf-parse
136
- */
137
- async function extractPdfText(filePath: string): Promise<string | null> {
138
- try {
139
- // Try pdftotext (poppler-utils)
140
- const result = await execa('pdftotext', [filePath, '-'], { timeout: 30000 });
141
- return result.stdout;
142
- } catch {
143
- // pdftotext not available
144
- return null;
145
- }
146
- }
147
-
148
- function getMimeType(ext: string): string {
149
- const mimeTypes: Record<string, string> = {
150
- '.png': 'image/png',
151
- '.jpg': 'image/jpeg',
152
- '.jpeg': 'image/jpeg',
153
- '.gif': 'image/gif',
154
- '.webp': 'image/webp',
155
- '.svg': 'image/svg+xml',
156
- '.bmp': 'image/bmp',
157
- };
158
- return mimeTypes[ext] || 'application/octet-stream';
159
- }
160
-
161
- /**
162
- * Watch for file drops/pastes and integrate with text input
163
- * Returns enhanced input with file contents
164
- */
165
- export async function textWithFileSupport(options: {
166
- message: string;
167
- placeholder?: string;
168
- }): Promise<{ text: string; files: Array<{ name: string; content: string; type: string }> } | symbol> {
169
-
170
- const hint = chalk.dim(' (paste file path, or "clip" for clipboard)');
171
-
172
- const input = await p.text({
173
- message: options.message + hint,
174
- placeholder: options.placeholder,
175
- });
176
-
177
- if (p.isCancel(input)) return input;
178
-
179
- const text = (input as string).trim();
180
- const files: Array<{ name: string; content: string; type: string }> = [];
181
-
182
- // Check for clipboard command
183
- if (text.toLowerCase() === 'clip' || text.toLowerCase() === 'clipboard' || text.toLowerCase() === 'paste') {
184
- const clipContent = await readClipboard();
185
- if (clipContent) {
186
- console.log(chalk.green(`\nšŸ“‹ Read ${clipContent.length} characters from clipboard\n`));
187
-
188
- // Check if clipboard contains a file path
189
- if (await fs.pathExists(clipContent.trim())) {
190
- const file = await readFile(clipContent.trim());
191
- if (file) {
192
- files.push(file);
193
- return { text: `[File: ${file.name}]`, files };
194
- }
195
- }
196
-
197
- // Otherwise treat as text
198
- files.push({ name: 'clipboard', content: clipContent, type: 'text' });
199
-
200
- const preview = clipContent.length > 100
201
- ? clipContent.slice(0, 100) + '...'
202
- : clipContent;
203
- console.log(chalk.dim(`Preview: ${preview}\n`));
204
-
205
- // Ask what to do with clipboard content
206
- const action = await p.select({
207
- message: 'What would you like me to do with this?',
208
- options: [
209
- { value: 'analyze', label: 'šŸ” Analyze this code/text' },
210
- { value: 'fix', label: 'šŸ”§ Fix any issues' },
211
- { value: 'explain', label: 'šŸ“– Explain this' },
212
- { value: 'improve', label: '✨ Improve/refactor' },
213
- { value: 'convert', label: 'šŸ”„ Convert to different format' },
214
- { value: 'custom', label: 'āœļø Custom instruction' },
215
- ],
216
- });
217
-
218
- if (p.isCancel(action)) return action;
219
-
220
- if (action === 'custom') {
221
- const customPrompt = await p.text({
222
- message: 'What should I do with this?',
223
- placeholder: 'Add error handling to this function',
224
- });
225
- if (p.isCancel(customPrompt)) return customPrompt;
226
- return { text: customPrompt as string, files };
227
- }
228
-
229
- const actionText: Record<string, string> = {
230
- analyze: 'Analyze this code/text and explain what it does',
231
- fix: 'Fix any bugs, issues, or problems in this code',
232
- explain: 'Explain this code/text in detail',
233
- improve: 'Improve and refactor this code for better quality',
234
- convert: 'Convert this to a better format or structure',
235
- };
236
-
237
- return { text: actionText[action as string], files };
238
- } else {
239
- console.log(chalk.yellow('Clipboard is empty'));
240
- // Re-prompt
241
- return textWithFileSupport(options);
242
- }
243
- }
244
-
245
- // Check if input is a file path
246
- if (await fs.pathExists(text)) {
247
- const file = await readFile(text);
248
- if (file) {
249
- files.push(file);
250
- console.log(chalk.green(`\nšŸ“„ Read file: ${file.name} (${file.type})\n`));
251
-
252
- // Ask what to do
253
- const action = await p.select({
254
- message: `What should I do with ${file.name}?`,
255
- options: [
256
- { value: 'analyze', label: 'šŸ” Analyze this file' },
257
- { value: 'fix', label: 'šŸ”§ Fix any issues' },
258
- { value: 'explain', label: 'šŸ“– Explain this' },
259
- { value: 'improve', label: '✨ Improve/refactor' },
260
- { value: 'custom', label: 'āœļø Custom instruction' },
261
- ],
262
- });
263
-
264
- if (p.isCancel(action)) return action;
265
-
266
- if (action === 'custom') {
267
- const customPrompt = await p.text({
268
- message: 'What should I do with this file?',
269
- placeholder: 'Add TypeScript types to this file',
270
- });
271
- if (p.isCancel(customPrompt)) return customPrompt;
272
- return { text: customPrompt as string, files };
273
- }
274
-
275
- const actionText: Record<string, string> = {
276
- analyze: `Analyze this file (${file.name}) and explain what it does`,
277
- fix: `Fix any bugs or issues in this file (${file.name})`,
278
- explain: `Explain this file (${file.name}) in detail`,
279
- improve: `Improve and refactor this file (${file.name})`,
280
- };
281
-
282
- return { text: actionText[action as string], files };
283
- }
284
- }
285
-
286
- // Check if input contains multiple file paths (drag & drop multiple)
287
- const potentialPaths = text.split('\n').map(p => p.trim()).filter(Boolean);
288
- if (potentialPaths.length > 1) {
289
- for (const potentialPath of potentialPaths) {
290
- if (await fs.pathExists(potentialPath)) {
291
- const file = await readFile(potentialPath);
292
- if (file) {
293
- files.push(file);
294
- }
295
- }
296
- }
297
-
298
- if (files.length > 0) {
299
- console.log(chalk.green(`\nšŸ“ Read ${files.length} files: ${files.map(f => f.name).join(', ')}\n`));
300
-
301
- const instruction = await p.text({
302
- message: 'What should I do with these files?',
303
- placeholder: 'Combine these into a single component',
304
- });
305
-
306
- if (p.isCancel(instruction)) return instruction;
307
- return { text: instruction as string, files };
308
- }
309
- }
310
-
311
- // Regular text input
312
- return { text, files };
313
- }
314
-
315
- /**
316
- * Format files for Claude context
317
- */
318
- export function formatFilesForContext(files: Array<{ name: string; content: string; type: string }>): string {
319
- if (files.length === 0) return '';
320
-
321
- let context = '\n\n--- ATTACHED FILES ---\n\n';
322
-
323
- for (const file of files) {
324
- if (file.type === 'image') {
325
- context += `[Image: ${file.name}]\n`;
326
- context += `${file.content}\n\n`; // base64 data URL
327
- } else {
328
- context += `--- ${file.name} ---\n`;
329
- context += '```\n';
330
- context += file.content;
331
- context += '\n```\n\n';
332
- }
333
- }
334
-
335
- context += '--- END FILES ---\n\n';
336
-
337
- return context;
338
- }
339
-
340
- /**
341
- * Quick paste detection - check if text looks like it was pasted
342
- */
343
- export function looksLikePaste(text: string): boolean {
344
- // Multi-line content is likely pasted
345
- if (text.includes('\n') && text.split('\n').length > 3) return true;
346
-
347
- // Code-like content
348
- if (text.includes('function ') || text.includes('const ') ||
349
- text.includes('import ') || text.includes('export ') ||
350
- text.includes('class ') || text.includes('def ') ||
351
- text.includes('public ') || text.includes('private ')) return true;
352
-
353
- // JSON/object-like
354
- if ((text.startsWith('{') && text.endsWith('}')) ||
355
- (text.startsWith('[') && text.endsWith(']'))) return true;
356
-
357
- // Very long single line
358
- if (text.length > 200 && !text.includes('\n')) return true;
359
-
360
- return false;
361
- }
362
-
363
- /**
364
- * Handle pasted content intelligently
365
- */
366
- export async function handlePastedContent(text: string): Promise<{ prompt: string; context: string } | null> {
367
- if (!looksLikePaste(text)) {
368
- return null; // Not pasted content, handle normally
369
- }
370
-
371
- console.log(chalk.cyan('\nšŸ“‹ Detected pasted content!\n'));
372
-
373
- const preview = text.length > 200 ? text.slice(0, 200) + '...' : text;
374
- console.log(chalk.dim(preview));
375
- console.log('');
376
-
377
- const action = await p.select({
378
- message: 'What should I do with this?',
379
- options: [
380
- { value: 'analyze', label: 'šŸ” Analyze this code' },
381
- { value: 'fix', label: 'šŸ”§ Fix any issues' },
382
- { value: 'explain', label: 'šŸ“– Explain this' },
383
- { value: 'improve', label: '✨ Improve/refactor' },
384
- { value: 'custom', label: 'āœļø Add my own instruction' },
385
- { value: 'literal', label: 'šŸ“ Use as literal prompt (not code)' },
386
- ],
387
- });
388
-
389
- if (p.isCancel(action)) return null;
390
-
391
- if (action === 'literal') {
392
- return { prompt: text, context: '' };
393
- }
394
-
395
- if (action === 'custom') {
396
- const instruction = await p.text({
397
- message: 'What should I do?',
398
- placeholder: 'Add error handling and types',
399
- });
400
- if (p.isCancel(instruction)) return null;
401
- return {
402
- prompt: instruction as string,
403
- context: `\n\n--- PASTED CODE ---\n\`\`\`\n${text}\n\`\`\`\n--- END ---\n\n`
404
- };
405
- }
406
-
407
- const actionPrompts: Record<string, string> = {
408
- analyze: 'Analyze this code and explain what it does, any issues, and potential improvements',
409
- fix: 'Fix any bugs, issues, or problems in this code',
410
- explain: 'Explain this code in detail, step by step',
411
- improve: 'Improve and refactor this code for better quality, readability, and performance',
412
- };
413
-
414
- return {
415
- prompt: actionPrompts[action as string],
416
- context: `\n\n--- PASTED CODE ---\n\`\`\`\n${text}\n\`\`\`\n--- END ---\n\n`
417
- };
418
- }