autotunez 0.1.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.
Potentially problematic release.
This version of autotunez might be problematic. Click here for more details.
- package/dist/agent.d.ts +14 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +163 -0
- package/dist/agent.js.map +1 -0
- package/dist/api-client.d.ts +28 -0
- package/dist/api-client.d.ts.map +1 -0
- package/dist/api-client.js +69 -0
- package/dist/api-client.js.map +1 -0
- package/dist/config.d.ts +18 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +70 -0
- package/dist/config.js.map +1 -0
- package/dist/executor.d.ts +51 -0
- package/dist/executor.d.ts.map +1 -0
- package/dist/executor.js +181 -0
- package/dist/executor.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +399 -0
- package/dist/index.js.map +1 -0
- package/dist/output-parser.d.ts +16 -0
- package/dist/output-parser.d.ts.map +1 -0
- package/dist/output-parser.js +32 -0
- package/dist/output-parser.js.map +1 -0
- package/dist/prompts.d.ts +5 -0
- package/dist/prompts.d.ts.map +1 -0
- package/dist/prompts.js +91 -0
- package/dist/prompts.js.map +1 -0
- package/dist/setup.d.ts +18 -0
- package/dist/setup.d.ts.map +1 -0
- package/dist/setup.js +267 -0
- package/dist/setup.js.map +1 -0
- package/package.json +67 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import ora from 'ora';
|
|
5
|
+
import * as readline from 'readline';
|
|
6
|
+
import * as fs from 'fs';
|
|
7
|
+
import * as path from 'path';
|
|
8
|
+
import { getApiKey, setApiKey, clearApiKey, promptForApiKey, validateApiKey, getAuthToken, setAuthToken, clearAuthToken, getServerUrl, } from './config.js';
|
|
9
|
+
import { transformPrompt, chatStructured } from './agent.js';
|
|
10
|
+
import { executeWithClaudeCode, spawnInteractiveClaude, checkClaudeCodeInstalled, checkClaudeCodeAuth, runClaudeLogin, } from './executor.js';
|
|
11
|
+
import { needsSetup, getMissingFiles, runSetup } from './setup.js';
|
|
12
|
+
import { ApiClient } from './api-client.js';
|
|
13
|
+
const program = new Command();
|
|
14
|
+
program
|
|
15
|
+
.name('autotunez')
|
|
16
|
+
.description('CLI assistant for vibe coding with Claude')
|
|
17
|
+
.version('0.1.0');
|
|
18
|
+
program
|
|
19
|
+
.command('config')
|
|
20
|
+
.description('Configure API key')
|
|
21
|
+
.option('--set <key>', 'Set API key')
|
|
22
|
+
.option('--clear', 'Clear stored API key')
|
|
23
|
+
.option('--show', 'Show if API key is configured')
|
|
24
|
+
.action(async (options) => {
|
|
25
|
+
if (options.clear) {
|
|
26
|
+
clearApiKey();
|
|
27
|
+
console.log(chalk.green('✓ API key cleared'));
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (options.show) {
|
|
31
|
+
const key = getApiKey();
|
|
32
|
+
if (key) {
|
|
33
|
+
console.log(chalk.green('✓ API key is configured'));
|
|
34
|
+
console.log(chalk.gray(` Key: ${key.slice(0, 10)}...${key.slice(-4)}`));
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
console.log(chalk.yellow('✗ No API key configured'));
|
|
38
|
+
console.log(chalk.gray(' Run: autotunez config --set <your-key>'));
|
|
39
|
+
}
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
if (options.set) {
|
|
43
|
+
if (!validateApiKey(options.set)) {
|
|
44
|
+
console.log(chalk.red('✗ Invalid API key format. Should start with sk-ant-'));
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
setApiKey(options.set);
|
|
48
|
+
console.log(chalk.green('✓ API key saved'));
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
// Interactive mode
|
|
52
|
+
const key = await promptForApiKey();
|
|
53
|
+
if (!validateApiKey(key)) {
|
|
54
|
+
console.log(chalk.red('✗ Invalid API key format. Should start with sk-ant-'));
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
setApiKey(key);
|
|
58
|
+
console.log(chalk.green('✓ API key saved'));
|
|
59
|
+
});
|
|
60
|
+
// --- Auth commands ---
|
|
61
|
+
program
|
|
62
|
+
.command('register')
|
|
63
|
+
.description('Create a new autotunez account')
|
|
64
|
+
.action(async () => {
|
|
65
|
+
const rl = readline.createInterface({
|
|
66
|
+
input: process.stdin,
|
|
67
|
+
output: process.stdout,
|
|
68
|
+
});
|
|
69
|
+
const ask = (q) => new Promise((resolve) => rl.question(q, (a) => resolve(a.trim())));
|
|
70
|
+
try {
|
|
71
|
+
const email = await ask(chalk.blue('Email: '));
|
|
72
|
+
const password = await ask(chalk.blue('Password: '));
|
|
73
|
+
if (!email || !password) {
|
|
74
|
+
console.log(chalk.red('✗ Email and password are required'));
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
77
|
+
const spinner = ora('Creating account...').start();
|
|
78
|
+
const apiClient = new ApiClient({ serverUrl: getServerUrl() });
|
|
79
|
+
const result = await apiClient.register(email, password);
|
|
80
|
+
spinner.stop();
|
|
81
|
+
setAuthToken(result.token);
|
|
82
|
+
console.log(chalk.green('✓ Account created and logged in'));
|
|
83
|
+
console.log(chalk.gray(` Token expires: ${result.expiresAt}`));
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
if (error instanceof Error) {
|
|
87
|
+
console.log(chalk.red(`✗ Registration failed: ${error.message}`));
|
|
88
|
+
}
|
|
89
|
+
process.exit(1);
|
|
90
|
+
}
|
|
91
|
+
finally {
|
|
92
|
+
rl.close();
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
program
|
|
96
|
+
.command('login')
|
|
97
|
+
.description('Log in to autotunez')
|
|
98
|
+
.action(async () => {
|
|
99
|
+
const rl = readline.createInterface({
|
|
100
|
+
input: process.stdin,
|
|
101
|
+
output: process.stdout,
|
|
102
|
+
});
|
|
103
|
+
const ask = (q) => new Promise((resolve) => rl.question(q, (a) => resolve(a.trim())));
|
|
104
|
+
try {
|
|
105
|
+
const email = await ask(chalk.blue('Email: '));
|
|
106
|
+
const password = await ask(chalk.blue('Password: '));
|
|
107
|
+
if (!email || !password) {
|
|
108
|
+
console.log(chalk.red('✗ Email and password are required'));
|
|
109
|
+
process.exit(1);
|
|
110
|
+
}
|
|
111
|
+
const spinner = ora('Logging in...').start();
|
|
112
|
+
const apiClient = new ApiClient({ serverUrl: getServerUrl() });
|
|
113
|
+
const result = await apiClient.login(email, password);
|
|
114
|
+
spinner.stop();
|
|
115
|
+
setAuthToken(result.token);
|
|
116
|
+
console.log(chalk.green('✓ Logged in successfully'));
|
|
117
|
+
console.log(chalk.gray(` Token expires: ${result.expiresAt}`));
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
if (error instanceof Error) {
|
|
121
|
+
console.log(chalk.red(`✗ Login failed: ${error.message}`));
|
|
122
|
+
}
|
|
123
|
+
process.exit(1);
|
|
124
|
+
}
|
|
125
|
+
finally {
|
|
126
|
+
rl.close();
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
program
|
|
130
|
+
.command('logout')
|
|
131
|
+
.description('Log out of autotunez')
|
|
132
|
+
.action(() => {
|
|
133
|
+
clearAuthToken();
|
|
134
|
+
console.log(chalk.green('✓ Logged out'));
|
|
135
|
+
});
|
|
136
|
+
// --- Main session ---
|
|
137
|
+
program
|
|
138
|
+
.command('start', { isDefault: true })
|
|
139
|
+
.description('Start interactive autotunez session')
|
|
140
|
+
.option('-i, --interactive', 'Run in interactive pass-through mode (keeps Claude Code session alive)')
|
|
141
|
+
.action(async (options) => {
|
|
142
|
+
// --- Check Claude Code prerequisites ---
|
|
143
|
+
const installCheck = await checkClaudeCodeInstalled();
|
|
144
|
+
if (!installCheck.installed) {
|
|
145
|
+
console.log(chalk.red('✗ Claude Code CLI not found.'));
|
|
146
|
+
console.log(chalk.gray(' Install it with: npm install -g @anthropic-ai/claude-code'));
|
|
147
|
+
console.log(chalk.gray(' Or visit: https://claude.ai/claude-code\n'));
|
|
148
|
+
process.exit(1);
|
|
149
|
+
}
|
|
150
|
+
console.log(chalk.green(`✓ Claude Code ${installCheck.version || ''} detected`));
|
|
151
|
+
const authCheck = await checkClaudeCodeAuth();
|
|
152
|
+
if (!authCheck.authenticated) {
|
|
153
|
+
console.log(chalk.yellow('⚠ Claude Code is not authenticated.'));
|
|
154
|
+
console.log(chalk.gray(' Starting Claude Code login...\n'));
|
|
155
|
+
const loginResult = await runClaudeLogin();
|
|
156
|
+
if (!loginResult.success) {
|
|
157
|
+
console.log(chalk.red('✗ Claude Code login failed or was cancelled.'));
|
|
158
|
+
console.log(chalk.gray(' You can also run: claude (in terminal) to authenticate manually.\n'));
|
|
159
|
+
process.exit(1);
|
|
160
|
+
}
|
|
161
|
+
console.log(chalk.green('✓ Claude Code authenticated\n'));
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
console.log(chalk.green('✓ Claude Code authenticated\n'));
|
|
165
|
+
}
|
|
166
|
+
const authToken = getAuthToken();
|
|
167
|
+
let apiKey = getApiKey();
|
|
168
|
+
// Check for auth: prefer server token, fall back to API key
|
|
169
|
+
if (!authToken && !apiKey) {
|
|
170
|
+
console.log(chalk.yellow('No authentication configured.'));
|
|
171
|
+
console.log(chalk.gray(' Option 1: autotunez login (recommended)'));
|
|
172
|
+
console.log(chalk.gray(' Option 2: autotunez config --set <api-key> (legacy)\n'));
|
|
173
|
+
const key = await promptForApiKey();
|
|
174
|
+
if (!validateApiKey(key)) {
|
|
175
|
+
console.log(chalk.red('✗ Invalid API key format'));
|
|
176
|
+
process.exit(1);
|
|
177
|
+
}
|
|
178
|
+
setApiKey(key);
|
|
179
|
+
apiKey = key;
|
|
180
|
+
console.log(chalk.green('✓ API key saved\n'));
|
|
181
|
+
}
|
|
182
|
+
// Check if project setup is needed
|
|
183
|
+
const cwd = process.cwd();
|
|
184
|
+
if (needsSetup(cwd)) {
|
|
185
|
+
const missing = getMissingFiles(cwd);
|
|
186
|
+
console.log(chalk.yellow(`⚠ 프로젝트 셋업이 필요합니다. 누락된 파일: ${missing.join(', ')}`));
|
|
187
|
+
const setupRl = readline.createInterface({
|
|
188
|
+
input: process.stdin,
|
|
189
|
+
output: process.stdout,
|
|
190
|
+
});
|
|
191
|
+
const doSetup = await new Promise((resolve) => {
|
|
192
|
+
setupRl.question(chalk.yellow(' 초기 셋업을 진행할까요? (Y/n): '), (answer) => {
|
|
193
|
+
setupRl.close();
|
|
194
|
+
const trimmed = answer.trim().toLowerCase();
|
|
195
|
+
resolve(trimmed === '' || trimmed === 'y' || trimmed === 'yes');
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
if (doSetup) {
|
|
199
|
+
const success = await runSetup(apiKey || '', cwd);
|
|
200
|
+
if (!success) {
|
|
201
|
+
console.log(chalk.red('셋업이 완료되지 않았습니다. 다시 시도해주세요.'));
|
|
202
|
+
process.exit(1);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
console.log(chalk.gray('셋업을 건너뜁니다. CLAUDE.md 없이 계속합니다.\n'));
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
// Load project context
|
|
210
|
+
let projectContext;
|
|
211
|
+
const claudeMdPath = path.join(cwd, 'CLAUDE.md');
|
|
212
|
+
if (fs.existsSync(claudeMdPath)) {
|
|
213
|
+
projectContext = fs.readFileSync(claudeMdPath, 'utf-8');
|
|
214
|
+
console.log(chalk.green('✓ Found CLAUDE.md - using project context\n'));
|
|
215
|
+
}
|
|
216
|
+
// Interactive pass-through mode
|
|
217
|
+
if (options.interactive) {
|
|
218
|
+
console.log(chalk.bold('autotunez CLI (Interactive Mode)'));
|
|
219
|
+
console.log(chalk.gray('Your input will be refined and passed to Claude Code.'));
|
|
220
|
+
console.log(chalk.gray('Claude Code session stays alive. Press Ctrl+C to exit.\n'));
|
|
221
|
+
const child = spawnInteractiveClaude({ cwd });
|
|
222
|
+
// Handle Claude Code exit
|
|
223
|
+
child.on('close', (code) => {
|
|
224
|
+
console.log(chalk.gray(`\nClaude Code exited (code ${code})`));
|
|
225
|
+
process.exit(code ?? 0);
|
|
226
|
+
});
|
|
227
|
+
child.on('error', (err) => {
|
|
228
|
+
if (err.code === 'ENOENT') {
|
|
229
|
+
console.log(chalk.red("✗ Claude Code CLI not found. Install it with 'npm install -g @anthropic-ai/claude-code'"));
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
console.log(chalk.red(`✗ Failed to start Claude Code: ${err.message}`));
|
|
233
|
+
}
|
|
234
|
+
process.exit(1);
|
|
235
|
+
});
|
|
236
|
+
// Intercept stdin, refine, and forward to Claude
|
|
237
|
+
const rl = readline.createInterface({
|
|
238
|
+
input: process.stdin,
|
|
239
|
+
output: process.stdout,
|
|
240
|
+
prompt: '',
|
|
241
|
+
});
|
|
242
|
+
rl.on('line', async (input) => {
|
|
243
|
+
const trimmed = input.trim();
|
|
244
|
+
if (!trimmed) {
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
// Pass through slash commands and single-char confirmations directly
|
|
248
|
+
const isPassThrough = trimmed.startsWith('/') || trimmed.length === 1;
|
|
249
|
+
if (isPassThrough) {
|
|
250
|
+
child.stdin?.write(trimmed + '\n');
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
// Refine all other input
|
|
254
|
+
if (projectContext) {
|
|
255
|
+
const spinner = ora('Refining...').start();
|
|
256
|
+
try {
|
|
257
|
+
const result = await transformPrompt(apiKey, trimmed, projectContext);
|
|
258
|
+
spinner.stop();
|
|
259
|
+
if (result.type === 'prompt') {
|
|
260
|
+
console.log(chalk.gray(' [refined]'));
|
|
261
|
+
child.stdin?.write(result.content + '\n');
|
|
262
|
+
}
|
|
263
|
+
else {
|
|
264
|
+
// Clarification needed - show it and wait for more input
|
|
265
|
+
console.log(chalk.yellow('\nautotunez: ') + result.content + '\n');
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
catch {
|
|
269
|
+
spinner.stop();
|
|
270
|
+
// On error, just pass through the original input
|
|
271
|
+
child.stdin?.write(trimmed + '\n');
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
// No project context - pass through directly
|
|
276
|
+
child.stdin?.write(trimmed + '\n');
|
|
277
|
+
}
|
|
278
|
+
});
|
|
279
|
+
rl.on('close', () => {
|
|
280
|
+
child.stdin?.end();
|
|
281
|
+
});
|
|
282
|
+
// Forward SIGINT to child
|
|
283
|
+
process.on('SIGINT', () => {
|
|
284
|
+
child.kill('SIGINT');
|
|
285
|
+
});
|
|
286
|
+
return; // Don't continue to regular mode
|
|
287
|
+
}
|
|
288
|
+
console.log(chalk.bold('autotunez CLI'));
|
|
289
|
+
console.log(chalk.gray('Type your request and press Enter. Type "exit" to quit.\n'));
|
|
290
|
+
const rl = readline.createInterface({
|
|
291
|
+
input: process.stdin,
|
|
292
|
+
output: process.stdout,
|
|
293
|
+
});
|
|
294
|
+
const messages = [];
|
|
295
|
+
let lastSessionId;
|
|
296
|
+
function confirmExecution() {
|
|
297
|
+
return new Promise((resolve) => {
|
|
298
|
+
rl.question(chalk.yellow('Run this with Claude Code? (Y/n): '), (answer) => {
|
|
299
|
+
const trimmed = answer.trim().toLowerCase();
|
|
300
|
+
resolve(trimmed === '' || trimmed === 'y' || trimmed === 'yes');
|
|
301
|
+
});
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
async function handlePromptExecution(prompt) {
|
|
305
|
+
console.log(chalk.green('\nautotunez: ') + 'Here\'s the optimized prompt:\n');
|
|
306
|
+
console.log(chalk.cyan(prompt));
|
|
307
|
+
console.log('');
|
|
308
|
+
const confirmed = await confirmExecution();
|
|
309
|
+
if (!confirmed) {
|
|
310
|
+
console.log(chalk.gray('\nOK, tell me how to adjust it.\n'));
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
console.log(chalk.magenta.bold('\n--- Claude Code is working... ---\n'));
|
|
314
|
+
rl.pause();
|
|
315
|
+
try {
|
|
316
|
+
const result = await executeWithClaudeCode(prompt, {
|
|
317
|
+
resumeSessionId: lastSessionId,
|
|
318
|
+
outputFormat: 'stream-json',
|
|
319
|
+
onOutput: (text) => process.stdout.write(text),
|
|
320
|
+
});
|
|
321
|
+
lastSessionId = result.sessionId;
|
|
322
|
+
if (result.success) {
|
|
323
|
+
console.log(chalk.green.bold('\n--- Claude Code completed successfully ---'));
|
|
324
|
+
}
|
|
325
|
+
else {
|
|
326
|
+
console.log(chalk.yellow.bold(`\n--- Claude Code exited (code ${result.exitCode}) ---`));
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
catch (error) {
|
|
330
|
+
if (error instanceof Error) {
|
|
331
|
+
console.log(chalk.red(`\n✗ ${error.message}`));
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
rl.resume();
|
|
335
|
+
console.log(chalk.gray('What would you like to do next?\n'));
|
|
336
|
+
}
|
|
337
|
+
const askQuestion = () => {
|
|
338
|
+
rl.question(chalk.blue('You: '), async (input) => {
|
|
339
|
+
const trimmed = input.trim();
|
|
340
|
+
if (!trimmed) {
|
|
341
|
+
askQuestion();
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
if (trimmed.toLowerCase() === 'exit' || trimmed.toLowerCase() === 'quit') {
|
|
345
|
+
console.log(chalk.gray('\nGoodbye! Happy vibing!'));
|
|
346
|
+
rl.close();
|
|
347
|
+
process.exit(0);
|
|
348
|
+
}
|
|
349
|
+
if (trimmed.toLowerCase() === 'clear') {
|
|
350
|
+
messages.length = 0;
|
|
351
|
+
lastSessionId = undefined;
|
|
352
|
+
console.log(chalk.gray('Context cleared.\n'));
|
|
353
|
+
askQuestion();
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
messages.push({ role: 'user', content: trimmed });
|
|
357
|
+
const spinner = ora('Thinking...').start();
|
|
358
|
+
try {
|
|
359
|
+
let result;
|
|
360
|
+
if (messages.length === 1 && projectContext) {
|
|
361
|
+
// First message with context
|
|
362
|
+
result = await transformPrompt(apiKey, trimmed, projectContext);
|
|
363
|
+
}
|
|
364
|
+
else {
|
|
365
|
+
// Continuing conversation — structured response with prompt detection
|
|
366
|
+
result = await chatStructured(apiKey, messages);
|
|
367
|
+
}
|
|
368
|
+
spinner.stop();
|
|
369
|
+
messages.push({ role: 'assistant', content: result.content });
|
|
370
|
+
if (result.type === 'prompt') {
|
|
371
|
+
await handlePromptExecution(result.content);
|
|
372
|
+
}
|
|
373
|
+
else {
|
|
374
|
+
console.log(chalk.green('\nautotunez: ') + result.content + '\n');
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
catch (error) {
|
|
378
|
+
spinner.stop();
|
|
379
|
+
if (error instanceof Error) {
|
|
380
|
+
if (error.message.includes('401') || error.message.includes('authentication') || error.message.includes('Authentication')) {
|
|
381
|
+
console.log(chalk.red('\n✗ Authentication failed. Run: autotunez login or autotunez config --set <key>\n'));
|
|
382
|
+
}
|
|
383
|
+
else {
|
|
384
|
+
console.log(chalk.red(`\n✗ Error: ${error.message}\n`));
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
else {
|
|
388
|
+
console.log(chalk.red('\n✗ Something went wrong\n'));
|
|
389
|
+
}
|
|
390
|
+
// Remove failed message from history
|
|
391
|
+
messages.pop();
|
|
392
|
+
}
|
|
393
|
+
askQuestion();
|
|
394
|
+
});
|
|
395
|
+
};
|
|
396
|
+
askQuestion();
|
|
397
|
+
});
|
|
398
|
+
program.parse();
|
|
399
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface StreamEvent {
|
|
2
|
+
type: string;
|
|
3
|
+
session_id?: string;
|
|
4
|
+
message?: {
|
|
5
|
+
role: string;
|
|
6
|
+
content: Array<{
|
|
7
|
+
type: string;
|
|
8
|
+
text?: string;
|
|
9
|
+
name?: string;
|
|
10
|
+
}>;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
export declare function parseStreamLine(line: string): StreamEvent | null;
|
|
14
|
+
export declare function extractSessionId(events: StreamEvent[]): string | undefined;
|
|
15
|
+
export declare function extractTextContent(events: StreamEvent[]): string;
|
|
16
|
+
//# sourceMappingURL=output-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output-parser.d.ts","sourceRoot":"","sources":["../src/output-parser.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KAChE,CAAC;CACH;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAOhE;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,GAAG,SAAS,CAO1E;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,CAWhE"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export function parseStreamLine(line) {
|
|
2
|
+
if (!line.trim())
|
|
3
|
+
return null;
|
|
4
|
+
try {
|
|
5
|
+
return JSON.parse(line);
|
|
6
|
+
}
|
|
7
|
+
catch {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export function extractSessionId(events) {
|
|
12
|
+
// Prefer result event session_id (final) over init event
|
|
13
|
+
const resultEvent = events.find(e => e.type === 'result' && e.session_id);
|
|
14
|
+
if (resultEvent?.session_id)
|
|
15
|
+
return resultEvent.session_id;
|
|
16
|
+
const initEvent = events.find(e => e.type === 'init' && e.session_id);
|
|
17
|
+
return initEvent?.session_id;
|
|
18
|
+
}
|
|
19
|
+
export function extractTextContent(events) {
|
|
20
|
+
let text = '';
|
|
21
|
+
for (const event of events) {
|
|
22
|
+
if (event.type !== 'message' || event.message?.role !== 'assistant')
|
|
23
|
+
continue;
|
|
24
|
+
for (const block of event.message.content) {
|
|
25
|
+
if (block.type === 'text' && block.text) {
|
|
26
|
+
text += block.text;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return text;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=output-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output-parser.js","sourceRoot":"","sources":["../src/output-parser.ts"],"names":[],"mappings":"AASA,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;QAAE,OAAO,IAAI,CAAC;IAC9B,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAgB,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,MAAqB;IACpD,yDAAyD;IACzD,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,CAAC,UAAU,CAAC,CAAC;IAC1E,IAAI,WAAW,EAAE,UAAU;QAAE,OAAO,WAAW,CAAC,UAAU,CAAC;IAE3D,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,UAAU,CAAC,CAAC;IACtE,OAAO,SAAS,EAAE,UAAU,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,MAAqB;IACtD,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,OAAO,EAAE,IAAI,KAAK,WAAW;YAAE,SAAS;QAC9E,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YAC1C,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;gBACxC,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC;YACrB,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export type SkillLevel = 'beginner' | 'expert';
|
|
2
|
+
export declare const BEGINNER_SYSTEM_PROMPT = "You are autotunez, a friendly assistant that helps users **design and generate** apps through \"vibe coding\".\n\nYou are the first step in a pipeline that GENERATES a real working project. After this conversation, the user gets a project with CLAUDE.md, SCRATCHPAD.md, and plan.md \u2014 ready for Claude Code to build.\n\n## What You Need to Learn (through natural conversation)\n\n### Must Have:\n1. **What & Why**: What are they building? What problem does it solve?\n2. **Core Features**: What are the 3-5 essential features for MVP?\n3. **Platform**: Web app? Mobile? Desktop? CLI?\n\n### Should Clarify (if not obvious):\n4. **Data**: Does it need to save data? Where? (browser storage / cloud database)\n5. **Users**: Single user or multiple users? Need login?\n6. **Complexity**: Simple prototype or production-ready?\n\n## Conversation Flow\n\n1. **Listen first** \u2014 Let them explain their idea\n2. **Clarify** \u2014 Ask 1-2 questions at a time, naturally. 3-5 turns of clarification is typical.\n3. **Make technical decisions FOR them** \u2014 They're learning. Recommend the tech stack, don't ask.\n4. **Summarize & Confirm** \u2014 When you have enough info:\n - Summarize what you understood\n - Recommend a tech approach\n - List the MVP features\n - End with: \"Ready to generate?\" or \"\uD504\uB85C\uC81D\uD2B8\uB97C \uC0DD\uC131\uD560\uAE4C\uC694?\"\n5. **If they agree** \u2014 Respond with EXACTLY this marker on its own line:\n ```\n [READY_TO_GENERATE]\n ```\n\n## CRITICAL Rules\n\n- **NEVER recommend external tools** like v0.dev, Cursor, Replit, bolt.new, ChatGPT, or any other service. YOU are the tool.\n- **NEVER say you can't build/generate the app.**\n- **Drive toward completion.** Don't let the conversation wander.\n- Focus on MVP \u2014 actively discourage scope creep (\"Let's save that for v2!\")\n- Be concise (2-3 paragraphs max per response)\n- If they say \"whatever you think is best\", make a sensible default choice\n\n## Tech Recommendations (use your judgment)\n\n- Simple personal tool \u2192 Web app + localStorage\n- Multi-user / data sync needed \u2192 Web app + Supabase/Firebase\n- Content site \u2192 Next.js static\n- API/backend \u2192 Node.js or Python\n\nRemember: \"\uAC1C\uB5A1\uAC19\uC774 \uB9D0\uD574\uB3C4 \uCC30\uB5A1\uAC19\uC774 \uC54C\uC544\uB4E3\uB294\" - understand messy input, produce clean output.";
|
|
3
|
+
export declare const EXPERT_SYSTEM_PROMPT = "You are autotunez, a development assistant that helps experienced developers set up projects quickly through \"vibe coding\".\n\nYou are the first step in a pipeline that GENERATES a project scaffold with CLAUDE.md, SCRATCHPAD.md, and plan.md \u2014 ready for Claude Code to build.\n\nThe user is experienced \u2014 skip explanations, be direct, respect their technical decisions.\n\n## What You Need (quickly)\n\n1. **What**: One-line description of the app\n2. **Tech stack**: Framework, styling, database, auth (or \"default\" for Next.js + Tailwind + localStorage)\n3. **MVP features**: A list of 3-5 core features\n4. **Data model**: Key entities (optional \u2014 you can infer if they prefer)\n\n## Conversation Flow\n\n1. **Ask what they're building** \u2014 One question, get the essentials\n2. **If they give enough info in one message** \u2014 Skip to summary\n3. **At most 1-2 clarifications** \u2014 Only if ambiguous\n4. **Summarize & Confirm** \u2014 Quick bullet summary:\n - App name + description\n - Tech stack\n - MVP features\n - End with: \"Ready to generate?\" or \"\uD504\uB85C\uC81D\uD2B8\uB97C \uC0DD\uC131\uD560\uAE4C\uC694?\"\n5. **If they agree** \u2014 Respond with EXACTLY this marker on its own line:\n ```\n [READY_TO_GENERATE]\n ```\n\n## Style\n\n- No hand-holding. If they say \"\uC6B4\uB3D9 \uAE30\uB85D \uC571, Next.js, localStorage\", that's enough to proceed.\n- Don't explain tech choices \u2014 they know what they picked.\n- Don't suggest alternatives unless they ask.\n\n## CRITICAL Rules\n\n- **NEVER recommend external tools** like v0.dev, Cursor, Replit, bolt.new, ChatGPT, or any other service. YOU are the tool.\n- **NEVER say you can't build/generate the app.**\n- **Drive toward completion.** Don't let the conversation wander.\n- Focus on MVP \u2014 actively discourage scope creep (\"Let's save that for v2!\")\n- Be concise (2-3 paragraphs max per response)\n- If they say \"whatever you think is best\", make a sensible default choice\n\n## Tech Recommendations (use your judgment)\n\n- Simple personal tool \u2192 Web app + localStorage\n- Multi-user / data sync needed \u2192 Web app + Supabase/Firebase\n- Content site \u2192 Next.js static\n- API/backend \u2192 Node.js or Python\n\nRemember: \"\uAC1C\uB5A1\uAC19\uC774 \uB9D0\uD574\uB3C4 \uCC30\uB5A1\uAC19\uC774 \uC54C\uC544\uB4E3\uB294\" - understand messy input, produce clean output.";
|
|
4
|
+
export declare function getInterviewPrompt(level: SkillLevel): string;
|
|
5
|
+
//# sourceMappingURL=prompts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,QAAQ,CAAC;AAoB/C,eAAO,MAAM,sBAAsB,u1EA+BnB,CAAC;AAEjB,eAAO,MAAM,oBAAoB,+2EAkCjB,CAAC;AAEjB,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAE5D"}
|
package/dist/prompts.js
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// Interview system prompts for CLI setup
|
|
2
|
+
// Beginner mode: full guided interview
|
|
3
|
+
// Expert mode: minimal questions, user drives decisions
|
|
4
|
+
const COMMON_RULES = `## CRITICAL Rules
|
|
5
|
+
|
|
6
|
+
- **NEVER recommend external tools** like v0.dev, Cursor, Replit, bolt.new, ChatGPT, or any other service. YOU are the tool.
|
|
7
|
+
- **NEVER say you can't build/generate the app.**
|
|
8
|
+
- **Drive toward completion.** Don't let the conversation wander.
|
|
9
|
+
- Focus on MVP — actively discourage scope creep ("Let's save that for v2!")
|
|
10
|
+
- Be concise (2-3 paragraphs max per response)
|
|
11
|
+
- If they say "whatever you think is best", make a sensible default choice
|
|
12
|
+
|
|
13
|
+
## Tech Recommendations (use your judgment)
|
|
14
|
+
|
|
15
|
+
- Simple personal tool → Web app + localStorage
|
|
16
|
+
- Multi-user / data sync needed → Web app + Supabase/Firebase
|
|
17
|
+
- Content site → Next.js static
|
|
18
|
+
- API/backend → Node.js or Python
|
|
19
|
+
|
|
20
|
+
Remember: "개떡같이 말해도 찰떡같이 알아듣는" - understand messy input, produce clean output.`;
|
|
21
|
+
export const BEGINNER_SYSTEM_PROMPT = `You are autotunez, a friendly assistant that helps users **design and generate** apps through "vibe coding".
|
|
22
|
+
|
|
23
|
+
You are the first step in a pipeline that GENERATES a real working project. After this conversation, the user gets a project with CLAUDE.md, SCRATCHPAD.md, and plan.md — ready for Claude Code to build.
|
|
24
|
+
|
|
25
|
+
## What You Need to Learn (through natural conversation)
|
|
26
|
+
|
|
27
|
+
### Must Have:
|
|
28
|
+
1. **What & Why**: What are they building? What problem does it solve?
|
|
29
|
+
2. **Core Features**: What are the 3-5 essential features for MVP?
|
|
30
|
+
3. **Platform**: Web app? Mobile? Desktop? CLI?
|
|
31
|
+
|
|
32
|
+
### Should Clarify (if not obvious):
|
|
33
|
+
4. **Data**: Does it need to save data? Where? (browser storage / cloud database)
|
|
34
|
+
5. **Users**: Single user or multiple users? Need login?
|
|
35
|
+
6. **Complexity**: Simple prototype or production-ready?
|
|
36
|
+
|
|
37
|
+
## Conversation Flow
|
|
38
|
+
|
|
39
|
+
1. **Listen first** — Let them explain their idea
|
|
40
|
+
2. **Clarify** — Ask 1-2 questions at a time, naturally. 3-5 turns of clarification is typical.
|
|
41
|
+
3. **Make technical decisions FOR them** — They're learning. Recommend the tech stack, don't ask.
|
|
42
|
+
4. **Summarize & Confirm** — When you have enough info:
|
|
43
|
+
- Summarize what you understood
|
|
44
|
+
- Recommend a tech approach
|
|
45
|
+
- List the MVP features
|
|
46
|
+
- End with: "Ready to generate?" or "프로젝트를 생성할까요?"
|
|
47
|
+
5. **If they agree** — Respond with EXACTLY this marker on its own line:
|
|
48
|
+
\`\`\`
|
|
49
|
+
[READY_TO_GENERATE]
|
|
50
|
+
\`\`\`
|
|
51
|
+
|
|
52
|
+
${COMMON_RULES}`;
|
|
53
|
+
export const EXPERT_SYSTEM_PROMPT = `You are autotunez, a development assistant that helps experienced developers set up projects quickly through "vibe coding".
|
|
54
|
+
|
|
55
|
+
You are the first step in a pipeline that GENERATES a project scaffold with CLAUDE.md, SCRATCHPAD.md, and plan.md — ready for Claude Code to build.
|
|
56
|
+
|
|
57
|
+
The user is experienced — skip explanations, be direct, respect their technical decisions.
|
|
58
|
+
|
|
59
|
+
## What You Need (quickly)
|
|
60
|
+
|
|
61
|
+
1. **What**: One-line description of the app
|
|
62
|
+
2. **Tech stack**: Framework, styling, database, auth (or "default" for Next.js + Tailwind + localStorage)
|
|
63
|
+
3. **MVP features**: A list of 3-5 core features
|
|
64
|
+
4. **Data model**: Key entities (optional — you can infer if they prefer)
|
|
65
|
+
|
|
66
|
+
## Conversation Flow
|
|
67
|
+
|
|
68
|
+
1. **Ask what they're building** — One question, get the essentials
|
|
69
|
+
2. **If they give enough info in one message** — Skip to summary
|
|
70
|
+
3. **At most 1-2 clarifications** — Only if ambiguous
|
|
71
|
+
4. **Summarize & Confirm** — Quick bullet summary:
|
|
72
|
+
- App name + description
|
|
73
|
+
- Tech stack
|
|
74
|
+
- MVP features
|
|
75
|
+
- End with: "Ready to generate?" or "프로젝트를 생성할까요?"
|
|
76
|
+
5. **If they agree** — Respond with EXACTLY this marker on its own line:
|
|
77
|
+
\`\`\`
|
|
78
|
+
[READY_TO_GENERATE]
|
|
79
|
+
\`\`\`
|
|
80
|
+
|
|
81
|
+
## Style
|
|
82
|
+
|
|
83
|
+
- No hand-holding. If they say "운동 기록 앱, Next.js, localStorage", that's enough to proceed.
|
|
84
|
+
- Don't explain tech choices — they know what they picked.
|
|
85
|
+
- Don't suggest alternatives unless they ask.
|
|
86
|
+
|
|
87
|
+
${COMMON_RULES}`;
|
|
88
|
+
export function getInterviewPrompt(level) {
|
|
89
|
+
return level === 'beginner' ? BEGINNER_SYSTEM_PROMPT : EXPERT_SYSTEM_PROMPT;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=prompts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,uCAAuC;AACvC,wDAAwD;AAIxD,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;;+EAgB0D,CAAC;AAEhF,MAAM,CAAC,MAAM,sBAAsB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+BpC,YAAY,EAAE,CAAC;AAEjB,MAAM,CAAC,MAAM,oBAAoB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkClC,YAAY,EAAE,CAAC;AAEjB,MAAM,UAAU,kBAAkB,CAAC,KAAiB;IAClD,OAAO,KAAK,KAAK,UAAU,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,oBAAoB,CAAC;AAC9E,CAAC"}
|
package/dist/setup.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check if the current directory needs initial setup.
|
|
3
|
+
* Returns true if any required file is missing.
|
|
4
|
+
*/
|
|
5
|
+
export declare function needsSetup(cwd: string): boolean;
|
|
6
|
+
/**
|
|
7
|
+
* Get list of missing files for diagnostic display.
|
|
8
|
+
*/
|
|
9
|
+
export declare function getMissingFiles(cwd: string): string[];
|
|
10
|
+
/**
|
|
11
|
+
* Run the full setup flow:
|
|
12
|
+
* 1. Ask skill level
|
|
13
|
+
* 2. Interview to gather project info
|
|
14
|
+
* 3. Extract ProjectConfig
|
|
15
|
+
* 4. Generate and write files
|
|
16
|
+
*/
|
|
17
|
+
export declare function runSetup(apiKey: string, cwd: string): Promise<boolean>;
|
|
18
|
+
//# sourceMappingURL=setup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"AAuBA;;;GAGG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAE/C;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAErD;AA8BD;;;;;;GAMG;AACH,wBAAsB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAkE5E"}
|