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/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"}
@@ -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"}
@@ -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"}