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.
- package/README.md +54 -255
- package/dist/chunk-HOWR3YTF.js +146 -0
- package/dist/index.d.ts +0 -3
- package/dist/index.js +10489 -7994
- package/dist/terminal-6ZQVP6R7.js +10 -0
- package/package.json +26 -41
- package/AUDIT_REPORT.md +0 -138
- package/dist/advisors-RWRTSJRR.js +0 -7
- package/dist/chunk-ASIJIQYC.js +0 -320
- package/dist/chunk-D44U3IEA.js +0 -565
- package/dist/chunk-LANM5XQW.js +0 -326
- package/dist/prd-RYITSL6Q.js +0 -7
- package/install.bat +0 -9
- package/installers/CodeBakers-Install.bat +0 -207
- package/installers/CodeBakers-Install.command +0 -232
- package/installers/README.md +0 -157
- package/installers/mac/assets/README.txt +0 -31
- package/installers/mac/build-mac-installer.sh +0 -240
- package/installers/windows/CodeBakers.iss +0 -256
- package/installers/windows/assets/README.txt +0 -16
- package/installers/windows/scripts/post-install.bat +0 -15
- package/src/channels/discord.ts +0 -5
- package/src/channels/slack.ts +0 -5
- package/src/channels/sms.ts +0 -4
- package/src/channels/telegram.ts +0 -5
- package/src/channels/whatsapp.ts +0 -7
- package/src/commands/advisors.ts +0 -699
- package/src/commands/build.ts +0 -1025
- package/src/commands/check.ts +0 -365
- package/src/commands/code.ts +0 -806
- package/src/commands/connect.ts +0 -12
- package/src/commands/deploy.ts +0 -448
- package/src/commands/design.ts +0 -298
- package/src/commands/fix.ts +0 -20
- package/src/commands/gateway.ts +0 -604
- package/src/commands/generate.ts +0 -178
- package/src/commands/init.ts +0 -634
- package/src/commands/integrate.ts +0 -884
- package/src/commands/learn.ts +0 -36
- package/src/commands/migrate.ts +0 -419
- package/src/commands/prd-maker.ts +0 -588
- package/src/commands/prd.ts +0 -419
- package/src/commands/security.ts +0 -102
- package/src/commands/setup.ts +0 -600
- package/src/commands/status.ts +0 -56
- package/src/commands/website.ts +0 -741
- package/src/index.ts +0 -627
- package/src/patterns/loader.ts +0 -337
- package/src/services/github.ts +0 -61
- package/src/services/supabase.ts +0 -147
- package/src/services/vercel.ts +0 -61
- package/src/utils/claude-md.ts +0 -287
- package/src/utils/config.ts +0 -375
- package/src/utils/display.ts +0 -338
- package/src/utils/files.ts +0 -418
- package/src/utils/nlp.ts +0 -312
- package/src/utils/ui.ts +0 -441
- package/src/utils/updates.ts +0 -8
- package/src/utils/voice.ts +0 -323
- package/tsconfig.json +0 -26
package/src/utils/voice.ts
DELETED
|
@@ -1,323 +0,0 @@
|
|
|
1
|
-
import * as p from '@clack/prompts';
|
|
2
|
-
import chalk from 'chalk';
|
|
3
|
-
import fs from 'fs-extra';
|
|
4
|
-
import { execa } from 'execa';
|
|
5
|
-
|
|
6
|
-
let voiceAvailable: boolean | null = null;
|
|
7
|
-
|
|
8
|
-
export async function checkVoiceAvailability(): Promise<boolean> {
|
|
9
|
-
if (voiceAvailable !== null) return voiceAvailable;
|
|
10
|
-
|
|
11
|
-
try {
|
|
12
|
-
if (process.platform === 'win32') {
|
|
13
|
-
// Windows always has PowerShell speech
|
|
14
|
-
voiceAvailable = true;
|
|
15
|
-
} else if (process.platform === 'darwin') {
|
|
16
|
-
// macOS - check for sox
|
|
17
|
-
await execa('which', ['sox'], { reject: true });
|
|
18
|
-
voiceAvailable = true;
|
|
19
|
-
} else {
|
|
20
|
-
// Linux - check for sox or arecord
|
|
21
|
-
try {
|
|
22
|
-
await execa('which', ['sox'], { reject: true });
|
|
23
|
-
voiceAvailable = true;
|
|
24
|
-
} catch {
|
|
25
|
-
await execa('which', ['arecord'], { reject: true });
|
|
26
|
-
voiceAvailable = true;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
} catch {
|
|
30
|
-
voiceAvailable = false;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return voiceAvailable;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Enhanced text input that supports voice
|
|
38
|
-
* User can type "voice" or "v" to switch to voice input
|
|
39
|
-
*/
|
|
40
|
-
export async function textWithVoice(options: {
|
|
41
|
-
message: string;
|
|
42
|
-
placeholder?: string;
|
|
43
|
-
initialValue?: string;
|
|
44
|
-
validate?: (value: string) => string | undefined;
|
|
45
|
-
}): Promise<string | symbol> {
|
|
46
|
-
const hasVoice = await checkVoiceAvailability();
|
|
47
|
-
|
|
48
|
-
const hint = hasVoice ? chalk.dim(' (type "v" for voice)') : '';
|
|
49
|
-
|
|
50
|
-
const result = await p.text({
|
|
51
|
-
message: options.message + hint,
|
|
52
|
-
placeholder: options.placeholder,
|
|
53
|
-
initialValue: options.initialValue,
|
|
54
|
-
validate: (value) => {
|
|
55
|
-
// Don't validate if they're switching to voice
|
|
56
|
-
if (value.toLowerCase() === 'v' || value.toLowerCase() === 'voice') {
|
|
57
|
-
return undefined;
|
|
58
|
-
}
|
|
59
|
-
return options.validate?.(value);
|
|
60
|
-
},
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
if (p.isCancel(result)) return result;
|
|
64
|
-
|
|
65
|
-
// Check if user wants voice input
|
|
66
|
-
const val = (result as string).toLowerCase().trim();
|
|
67
|
-
if (val === 'v' || val === 'voice') {
|
|
68
|
-
if (!hasVoice) {
|
|
69
|
-
console.log(chalk.yellow('Voice input not available on this system.'));
|
|
70
|
-
return textWithVoice(options); // Try again with text
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const voiceResult = await getVoiceInput(options.message);
|
|
74
|
-
if (voiceResult === null) {
|
|
75
|
-
return textWithVoice(options); // Cancelled, try again
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// Validate voice result
|
|
79
|
-
if (options.validate) {
|
|
80
|
-
const error = options.validate(voiceResult);
|
|
81
|
-
if (error) {
|
|
82
|
-
console.log(chalk.red(error));
|
|
83
|
-
return textWithVoice(options);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
return voiceResult;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
return result;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Get voice input from microphone
|
|
95
|
-
*/
|
|
96
|
-
export async function getVoiceInput(prompt: string): Promise<string | null> {
|
|
97
|
-
console.log(chalk.cyan(`\n🎤 ${prompt}`));
|
|
98
|
-
console.log(chalk.dim(' Speak after the beep. Recording stops after silence.\n'));
|
|
99
|
-
|
|
100
|
-
const ready = await p.confirm({
|
|
101
|
-
message: 'Ready to record?',
|
|
102
|
-
initialValue: true,
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
if (!ready || p.isCancel(ready)) {
|
|
106
|
-
return null;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// Play a beep sound if possible
|
|
110
|
-
await playBeep();
|
|
111
|
-
|
|
112
|
-
const spinner = p.spinner();
|
|
113
|
-
spinner.start('🔴 Recording...');
|
|
114
|
-
|
|
115
|
-
try {
|
|
116
|
-
let transcription = '';
|
|
117
|
-
|
|
118
|
-
if (process.platform === 'win32') {
|
|
119
|
-
transcription = await recordWithWindowsSpeech();
|
|
120
|
-
} else if (process.platform === 'darwin') {
|
|
121
|
-
transcription = await recordWithMacOS();
|
|
122
|
-
} else {
|
|
123
|
-
transcription = await recordWithLinux();
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
spinner.stop('Recording complete');
|
|
127
|
-
|
|
128
|
-
if (transcription) {
|
|
129
|
-
console.log(chalk.green(`\n ✓ Heard: "${transcription}"\n`));
|
|
130
|
-
|
|
131
|
-
const confirm = await p.confirm({
|
|
132
|
-
message: 'Is this correct?',
|
|
133
|
-
initialValue: true,
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
if (confirm && !p.isCancel(confirm)) {
|
|
137
|
-
return transcription;
|
|
138
|
-
} else {
|
|
139
|
-
const action = await p.select({
|
|
140
|
-
message: 'What would you like to do?',
|
|
141
|
-
options: [
|
|
142
|
-
{ value: 'retry', label: '🎤 Try again' },
|
|
143
|
-
{ value: 'type', label: '⌨️ Type instead' },
|
|
144
|
-
{ value: 'cancel', label: '✗ Cancel' },
|
|
145
|
-
],
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
if (p.isCancel(action) || action === 'cancel') return null;
|
|
149
|
-
|
|
150
|
-
if (action === 'retry') {
|
|
151
|
-
return await getVoiceInput(prompt);
|
|
152
|
-
} else {
|
|
153
|
-
const text = await p.text({ message: 'Type your response:' });
|
|
154
|
-
return p.isCancel(text) ? null : text as string;
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
} else {
|
|
158
|
-
console.log(chalk.yellow('\n No speech detected. Try again or type your response.\n'));
|
|
159
|
-
|
|
160
|
-
const text = await p.text({ message: 'Type instead:' });
|
|
161
|
-
return p.isCancel(text) ? null : text as string;
|
|
162
|
-
}
|
|
163
|
-
} catch (error) {
|
|
164
|
-
spinner.stop('Recording failed');
|
|
165
|
-
console.log(chalk.yellow('Voice input failed. Please type instead.'));
|
|
166
|
-
|
|
167
|
-
const text = await p.text({ message: prompt });
|
|
168
|
-
return p.isCancel(text) ? null : text as string;
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
async function playBeep(): Promise<void> {
|
|
173
|
-
try {
|
|
174
|
-
if (process.platform === 'win32') {
|
|
175
|
-
await execa('powershell', ['-Command', '[console]::beep(800,200)'], { reject: false });
|
|
176
|
-
} else if (process.platform === 'darwin') {
|
|
177
|
-
await execa('afplay', ['/System/Library/Sounds/Tink.aiff'], { reject: false });
|
|
178
|
-
} else {
|
|
179
|
-
// Linux - try beep or paplay
|
|
180
|
-
try {
|
|
181
|
-
await execa('beep', ['-f', '800', '-l', '200'], { reject: false });
|
|
182
|
-
} catch {
|
|
183
|
-
await execa('paplay', ['/usr/share/sounds/freedesktop/stereo/message.oga'], { reject: false });
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
} catch {
|
|
187
|
-
// Silent fail - beep is optional
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
async function recordWithWindowsSpeech(): Promise<string> {
|
|
192
|
-
const psScript = `
|
|
193
|
-
Add-Type -AssemblyName System.Speech
|
|
194
|
-
$recognizer = New-Object System.Speech.Recognition.SpeechRecognitionEngine
|
|
195
|
-
$recognizer.SetInputToDefaultAudioDevice()
|
|
196
|
-
$grammar = New-Object System.Speech.Recognition.DictationGrammar
|
|
197
|
-
$recognizer.LoadGrammar($grammar)
|
|
198
|
-
try {
|
|
199
|
-
$result = $recognizer.Recognize([TimeSpan]::FromSeconds(10))
|
|
200
|
-
if ($result) {
|
|
201
|
-
Write-Output $result.Text
|
|
202
|
-
}
|
|
203
|
-
} finally {
|
|
204
|
-
$recognizer.Dispose()
|
|
205
|
-
}
|
|
206
|
-
`;
|
|
207
|
-
|
|
208
|
-
try {
|
|
209
|
-
const result = await execa('powershell', ['-Command', psScript], {
|
|
210
|
-
timeout: 15000,
|
|
211
|
-
});
|
|
212
|
-
return result.stdout.trim();
|
|
213
|
-
} catch {
|
|
214
|
-
return '';
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
async function recordWithMacOS(): Promise<string> {
|
|
219
|
-
const tempFile = `/tmp/codebakers-voice-${Date.now()}.wav`;
|
|
220
|
-
|
|
221
|
-
try {
|
|
222
|
-
// Record with sox - stops on silence
|
|
223
|
-
await execa('sox', [
|
|
224
|
-
'-d', // default input
|
|
225
|
-
'-r', '16000', // sample rate
|
|
226
|
-
'-c', '1', // mono
|
|
227
|
-
'-b', '16', // 16-bit
|
|
228
|
-
tempFile,
|
|
229
|
-
'silence', '1', '0.1', '3%', // start on sound
|
|
230
|
-
'1', '2.0', '3%', // stop after 2s silence
|
|
231
|
-
'trim', '0', '30', // max 30 seconds
|
|
232
|
-
], { timeout: 35000 });
|
|
233
|
-
|
|
234
|
-
// Try whisper for transcription
|
|
235
|
-
return await transcribeWithWhisper(tempFile);
|
|
236
|
-
} finally {
|
|
237
|
-
await fs.remove(tempFile).catch(() => {});
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
async function recordWithLinux(): Promise<string> {
|
|
242
|
-
const tempFile = `/tmp/codebakers-voice-${Date.now()}.wav`;
|
|
243
|
-
|
|
244
|
-
try {
|
|
245
|
-
// Try sox first
|
|
246
|
-
try {
|
|
247
|
-
await execa('sox', [
|
|
248
|
-
'-d', tempFile,
|
|
249
|
-
'rate', '16000',
|
|
250
|
-
'channels', '1',
|
|
251
|
-
'silence', '1', '0.1', '3%',
|
|
252
|
-
'1', '2.0', '3%',
|
|
253
|
-
'trim', '0', '30',
|
|
254
|
-
], { timeout: 35000 });
|
|
255
|
-
} catch {
|
|
256
|
-
// Fall back to arecord
|
|
257
|
-
await execa('arecord', [
|
|
258
|
-
'-f', 'S16_LE',
|
|
259
|
-
'-r', '16000',
|
|
260
|
-
'-c', '1',
|
|
261
|
-
'-d', '10',
|
|
262
|
-
tempFile,
|
|
263
|
-
], { timeout: 15000 });
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
return await transcribeWithWhisper(tempFile);
|
|
267
|
-
} finally {
|
|
268
|
-
await fs.remove(tempFile).catch(() => {});
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
async function transcribeWithWhisper(audioFile: string): Promise<string> {
|
|
273
|
-
try {
|
|
274
|
-
// Try local whisper first
|
|
275
|
-
const outputBase = audioFile.replace('.wav', '');
|
|
276
|
-
|
|
277
|
-
await execa('whisper', [
|
|
278
|
-
audioFile,
|
|
279
|
-
'--language', 'en',
|
|
280
|
-
'--output_format', 'txt',
|
|
281
|
-
'--output_dir', '/tmp',
|
|
282
|
-
], { timeout: 60000 });
|
|
283
|
-
|
|
284
|
-
const txtFile = outputBase + '.txt';
|
|
285
|
-
if (await fs.pathExists(txtFile)) {
|
|
286
|
-
const text = await fs.readFile(txtFile, 'utf-8');
|
|
287
|
-
await fs.remove(txtFile).catch(() => {});
|
|
288
|
-
return text.trim();
|
|
289
|
-
}
|
|
290
|
-
} catch {
|
|
291
|
-
// Whisper not available - try online API or return empty
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
return '';
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
/**
|
|
298
|
-
* Voice-enabled select (read options aloud, accept voice selection)
|
|
299
|
-
*/
|
|
300
|
-
export async function selectWithVoice<T extends string>(options: {
|
|
301
|
-
message: string;
|
|
302
|
-
options: Array<{ value: T; label: string; hint?: string }>;
|
|
303
|
-
}): Promise<T | symbol> {
|
|
304
|
-
// For now, just use regular select
|
|
305
|
-
// Voice selection is complex and error-prone
|
|
306
|
-
return p.select(options) as Promise<T | symbol>;
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
/**
|
|
310
|
-
* Voice-enabled confirm
|
|
311
|
-
*/
|
|
312
|
-
export async function confirmWithVoice(options: {
|
|
313
|
-
message: string;
|
|
314
|
-
initialValue?: boolean;
|
|
315
|
-
}): Promise<boolean | symbol> {
|
|
316
|
-
const hasVoice = await checkVoiceAvailability();
|
|
317
|
-
const hint = hasVoice ? chalk.dim(' (say "yes" or "no")') : '';
|
|
318
|
-
|
|
319
|
-
return p.confirm({
|
|
320
|
-
message: options.message + hint,
|
|
321
|
-
initialValue: options.initialValue,
|
|
322
|
-
});
|
|
323
|
-
}
|
package/tsconfig.json
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2022",
|
|
4
|
-
"module": "NodeNext",
|
|
5
|
-
"moduleResolution": "NodeNext",
|
|
6
|
-
"esModuleInterop": true,
|
|
7
|
-
"strict": true,
|
|
8
|
-
"skipLibCheck": true,
|
|
9
|
-
"outDir": "dist",
|
|
10
|
-
"rootDir": "src",
|
|
11
|
-
"declaration": true,
|
|
12
|
-
"declarationMap": true,
|
|
13
|
-
"sourceMap": true,
|
|
14
|
-
"resolveJsonModule": true,
|
|
15
|
-
"allowSyntheticDefaultImports": true,
|
|
16
|
-
"forceConsistentCasingInFileNames": true,
|
|
17
|
-
"noUncheckedIndexedAccess": true,
|
|
18
|
-
"noImplicitOverride": true,
|
|
19
|
-
"noPropertyAccessFromIndexSignature": false,
|
|
20
|
-
"paths": {
|
|
21
|
-
"@/*": ["./src/*"]
|
|
22
|
-
}
|
|
23
|
-
},
|
|
24
|
-
"include": ["src/**/*"],
|
|
25
|
-
"exclude": ["node_modules", "dist", "templates"]
|
|
26
|
-
}
|