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.
@@ -0,0 +1,14 @@
1
+ export interface AgentResponse {
2
+ type: 'clarification' | 'prompt';
3
+ content: string;
4
+ }
5
+ export declare function transformPrompt(apiKey: string, userInput: string, context?: string): Promise<AgentResponse>;
6
+ export declare function chat(apiKey: string, messages: Array<{
7
+ role: 'user' | 'assistant';
8
+ content: string;
9
+ }>): Promise<string>;
10
+ export declare function chatStructured(apiKey: string, messages: Array<{
11
+ role: 'user' | 'assistant';
12
+ content: string;
13
+ }>): Promise<AgentResponse>;
14
+ //# sourceMappingURL=agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAqEA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,eAAe,GAAG,QAAQ,CAAC;IACjC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,eAAe,CACnC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,aAAa,CAAC,CA4DxB;AAED,wBAAsB,IAAI,CACxB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,GAC/D,OAAO,CAAC,MAAM,CAAC,CAmBjB;AAED,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,GAC/D,OAAO,CAAC,aAAa,CAAC,CAkCxB"}
package/dist/agent.js ADDED
@@ -0,0 +1,163 @@
1
+ import { ApiClient } from './api-client.js';
2
+ import { getAuthToken, getServerUrl } from './config.js';
3
+ async function getAnthropicClient(apiKey) {
4
+ const { default: AnthropicSDK } = await import('@anthropic-ai/sdk');
5
+ return new AnthropicSDK({ apiKey });
6
+ }
7
+ const SYSTEM_PROMPT = `You are autotunez CLI, a development assistant that helps users with "vibe coding".
8
+
9
+ Your role is to transform messy user input into clean, actionable prompts for Claude Code.
10
+
11
+ ## How to Respond
12
+
13
+ 1. **If the request is clear enough** → Transform it into a well-structured prompt
14
+ 2. **If the request is vague** → Ask a clarifying question to better understand what the user wants
15
+ 3. **If you detect scope creep** → Gently push back toward MVP
16
+
17
+ You may ask MULTIPLE rounds of clarifying questions across the conversation. Each time the user responds, decide:
18
+ - Still unclear? → Ask another clarifying question
19
+ - Clear enough now? → Produce the transformed prompt
20
+
21
+ ## Prompt Transformation Rules
22
+
23
+ When transforming user input:
24
+ - Add specific file paths if you can infer them
25
+ - Include verification steps
26
+ - Add "Keep it simple" if the task seems prone to over-engineering
27
+ - Reference existing code patterns when relevant
28
+
29
+ ## Output Format
30
+
31
+ If proceeding with transformation:
32
+ \`\`\`prompt
33
+ [The transformed, clean prompt ready for Claude Code]
34
+ \`\`\`
35
+
36
+ If asking for clarification:
37
+ Just ask your question naturally, no special format needed.
38
+
39
+ ## Examples
40
+
41
+ User: "make it look better"
42
+ → Ask: "Which part of the UI? The homepage, a specific component, or the overall styling?"
43
+
44
+ User: "add a login page"
45
+ → Transform:
46
+ \`\`\`prompt
47
+ Add a login page with email/password fields.
48
+ - Create app/login/page.tsx
49
+ - Simple form with email and password inputs
50
+ - Submit button
51
+ - Link to signup page
52
+ - Keep it simple, no auth logic yet - just the UI
53
+ \`\`\`
54
+
55
+ User: "the button doesn't work"
56
+ → Ask: "Which button? And what happens when you click it - nothing, an error, or wrong behavior?"
57
+
58
+ ## Guidelines from vibe-guide.md
59
+
60
+ - Specific input → Specific output
61
+ - MVP first, always
62
+ - One task per conversation
63
+ - Keep it simple - avoid over-engineering
64
+
65
+ Remember: "개떡같이 말해도 찰떡같이 알아듣는" - understand messy input, produce clean output.`;
66
+ export async function transformPrompt(apiKey, userInput, context) {
67
+ // Server-mode: use autotunez server API
68
+ const authToken = getAuthToken();
69
+ if (authToken) {
70
+ const apiClient = new ApiClient({
71
+ authToken,
72
+ serverUrl: getServerUrl(),
73
+ });
74
+ return apiClient.transform(userInput, context || '');
75
+ }
76
+ // Legacy mode: direct Anthropic SDK
77
+ const client = await getAnthropicClient(apiKey);
78
+ const messages = [];
79
+ if (context) {
80
+ messages.push({
81
+ role: 'user',
82
+ content: `Context about the project:\n${context}`,
83
+ });
84
+ messages.push({
85
+ role: 'assistant',
86
+ content: 'Got it, I understand the project context. What would you like to work on?',
87
+ });
88
+ }
89
+ messages.push({
90
+ role: 'user',
91
+ content: userInput,
92
+ });
93
+ const response = await client.messages.create({
94
+ model: 'claude-sonnet-4-20250514',
95
+ max_tokens: 1024,
96
+ system: SYSTEM_PROMPT,
97
+ messages,
98
+ });
99
+ const content = response.content[0];
100
+ if (content.type !== 'text') {
101
+ throw new Error('Unexpected response type');
102
+ }
103
+ const text = content.text;
104
+ // Check if response contains a transformed prompt
105
+ const promptMatch = text.match(/```prompt\n([\s\S]*?)```/);
106
+ if (promptMatch) {
107
+ return {
108
+ type: 'prompt',
109
+ content: promptMatch[1].trim(),
110
+ };
111
+ }
112
+ // Otherwise it's a clarification question
113
+ return {
114
+ type: 'clarification',
115
+ content: text.trim(),
116
+ };
117
+ }
118
+ export async function chat(apiKey, messages) {
119
+ const client = await getAnthropicClient(apiKey);
120
+ const response = await client.messages.create({
121
+ model: 'claude-sonnet-4-20250514',
122
+ max_tokens: 1024,
123
+ system: SYSTEM_PROMPT,
124
+ messages: messages.map((m) => ({
125
+ role: m.role,
126
+ content: m.content,
127
+ })),
128
+ });
129
+ const content = response.content[0];
130
+ if (content.type !== 'text') {
131
+ throw new Error('Unexpected response type');
132
+ }
133
+ return content.text;
134
+ }
135
+ export async function chatStructured(apiKey, messages) {
136
+ // Server-mode: use autotunez server API
137
+ const authToken = getAuthToken();
138
+ if (authToken) {
139
+ const apiClient = new ApiClient({
140
+ authToken,
141
+ serverUrl: getServerUrl(),
142
+ });
143
+ // Use last user message as input, previous messages as history
144
+ const lastUserMsg = [...messages].reverse().find((m) => m.role === 'user');
145
+ const history = messages.slice(0, -1);
146
+ return apiClient.transform(lastUserMsg?.content || '', '', // claudeMd is loaded in index.ts; here we pass history
147
+ undefined, history);
148
+ }
149
+ // Legacy mode: direct Anthropic SDK
150
+ const text = await chat(apiKey, messages);
151
+ const promptMatch = text.match(/```prompt\n([\s\S]*?)```/);
152
+ if (promptMatch) {
153
+ return {
154
+ type: 'prompt',
155
+ content: promptMatch[1].trim(),
156
+ };
157
+ }
158
+ return {
159
+ type: 'clarification',
160
+ content: text.trim(),
161
+ };
162
+ }
163
+ //# sourceMappingURL=agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import type { InterviewResponse, ExtractResponse, ScaffoldResponse, TransformResponse, FixResponse, AuthResponse, ProjectConfig } from '@autotunez/shared';
2
+ export declare class ApiClient {
3
+ private baseUrl;
4
+ private authToken;
5
+ constructor(options?: {
6
+ serverUrl?: string;
7
+ authToken?: string;
8
+ });
9
+ setAuthToken(token: string): void;
10
+ private request;
11
+ register(email: string, password: string): Promise<AuthResponse>;
12
+ login(email: string, password: string): Promise<AuthResponse>;
13
+ interview(messages: Array<{
14
+ role: 'user' | 'assistant';
15
+ content: string;
16
+ }>, mode: 'beginner' | 'expert'): Promise<InterviewResponse>;
17
+ extract(messages: Array<{
18
+ role: 'user' | 'assistant';
19
+ content: string;
20
+ }>): Promise<ExtractResponse>;
21
+ scaffold(config: ProjectConfig): Promise<ScaffoldResponse>;
22
+ transform(input: string, claudeMd: string, scratchpad?: string, conversationHistory?: Array<{
23
+ role: 'user' | 'assistant';
24
+ content: string;
25
+ }>): Promise<TransformResponse>;
26
+ fix(error: string, errorType: 'typecheck' | 'build' | 'test' | 'lint', claudeMd: string): Promise<FixResponse>;
27
+ }
28
+ //# sourceMappingURL=api-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAEV,iBAAiB,EAEjB,eAAe,EAEf,gBAAgB,EAEhB,iBAAiB,EAEjB,WAAW,EAGX,YAAY,EAEZ,aAAa,EACd,MAAM,mBAAmB,CAAC;AAI3B,qBAAa,SAAS;IACpB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,SAAS,CAAqB;gBAGpC,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO;IAS1D,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;YAInB,OAAO;IA0Cf,QAAQ,CACZ,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,YAAY,CAAC;IAQlB,KAAK,CACT,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,YAAY,CAAC;IAUlB,SAAS,CACb,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,EAChE,IAAI,EAAE,UAAU,GAAG,QAAQ,GAC1B,OAAO,CAAC,iBAAiB,CAAC;IAOvB,OAAO,CACX,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,GAC/D,OAAO,CAAC,eAAe,CAAC;IAOrB,QAAQ,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAO1D,SAAS,CACb,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,MAAM,EACnB,mBAAmB,CAAC,EAAE,KAAK,CAAC;QAC1B,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;QAC3B,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC,GACD,OAAO,CAAC,iBAAiB,CAAC;IAOvB,GAAG,CACP,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,WAAW,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,EAClD,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,WAAW,CAAC;CAOxB"}
@@ -0,0 +1,69 @@
1
+ // Server API client for autotunez CLI
2
+ // Replaces direct Anthropic SDK calls with server API calls
3
+ const DEFAULT_SERVER_URL = 'https://autotunez.vercel.app';
4
+ export class ApiClient {
5
+ baseUrl;
6
+ authToken;
7
+ constructor(options = {}) {
8
+ this.baseUrl = (options.serverUrl || DEFAULT_SERVER_URL).replace(/\/$/, '');
9
+ this.authToken = options.authToken;
10
+ }
11
+ setAuthToken(token) {
12
+ this.authToken = token;
13
+ }
14
+ async request(path, body, requiresAuth = true) {
15
+ const headers = {
16
+ 'Content-Type': 'application/json',
17
+ };
18
+ if (requiresAuth) {
19
+ if (!this.authToken) {
20
+ throw new Error('Not logged in. Run: autotunez login');
21
+ }
22
+ headers['Authorization'] = `Bearer ${this.authToken}`;
23
+ }
24
+ const response = await fetch(`${this.baseUrl}${path}`, {
25
+ method: 'POST',
26
+ headers,
27
+ body: JSON.stringify(body),
28
+ });
29
+ if (!response.ok) {
30
+ const error = await response.json().catch(() => ({
31
+ code: 'NETWORK_ERROR',
32
+ message: `Server returned ${response.status}: ${response.statusText}`,
33
+ }));
34
+ if (response.status === 401) {
35
+ throw new Error(`Authentication failed: ${error.message}. Run: autotunez login`);
36
+ }
37
+ throw new Error(`API error (${error.code}): ${error.message}`);
38
+ }
39
+ return response.json();
40
+ }
41
+ // --- Auth (no auth token needed) ---
42
+ async register(email, password) {
43
+ return this.request('/api/v1/auth/register', { email, password }, false);
44
+ }
45
+ async login(email, password) {
46
+ return this.request('/api/v1/auth/login', { email, password }, false);
47
+ }
48
+ // --- Protected endpoints ---
49
+ async interview(messages, mode) {
50
+ return this.request('/api/v1/interview', { messages, mode });
51
+ }
52
+ async extract(messages) {
53
+ return this.request('/api/v1/extract', { messages });
54
+ }
55
+ async scaffold(config) {
56
+ return this.request('/api/v1/scaffold', { config });
57
+ }
58
+ async transform(input, claudeMd, scratchpad, conversationHistory) {
59
+ return this.request('/api/v1/transform', { input, claudeMd, scratchpad, conversationHistory });
60
+ }
61
+ async fix(error, errorType, claudeMd) {
62
+ return this.request('/api/v1/fix', {
63
+ error,
64
+ errorType,
65
+ claudeMd,
66
+ });
67
+ }
68
+ }
69
+ //# sourceMappingURL=api-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ interface Config {
2
+ apiKey?: string;
3
+ authToken?: string;
4
+ serverUrl?: string;
5
+ }
6
+ export declare function loadConfig(): Config;
7
+ export declare function saveConfig(config: Config): void;
8
+ export declare function getApiKey(): string | undefined;
9
+ export declare function setApiKey(apiKey: string): void;
10
+ export declare function clearApiKey(): void;
11
+ export declare function promptForApiKey(): Promise<string>;
12
+ export declare function validateApiKey(key: string): boolean;
13
+ export declare function getAuthToken(): string | undefined;
14
+ export declare function setAuthToken(token: string): void;
15
+ export declare function clearAuthToken(): void;
16
+ export declare function getServerUrl(): string | undefined;
17
+ export {};
18
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAQA,UAAU,MAAM;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,UAAU,IAAI,MAAM,CAUnC;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAK/C;AAED,wBAAgB,SAAS,IAAI,MAAM,GAAG,SAAS,CAG9C;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAI9C;AAED,wBAAgB,WAAW,IAAI,IAAI,CAIlC;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC,CAYvD;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED,wBAAgB,YAAY,IAAI,MAAM,GAAG,SAAS,CAEjD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAIhD;AAED,wBAAgB,cAAc,IAAI,IAAI,CAIrC;AAED,wBAAgB,YAAY,IAAI,MAAM,GAAG,SAAS,CAEjD"}
package/dist/config.js ADDED
@@ -0,0 +1,70 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import * as os from 'os';
4
+ import * as readline from 'readline';
5
+ const CONFIG_DIR = path.join(os.homedir(), '.autotunez');
6
+ const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
7
+ export function loadConfig() {
8
+ try {
9
+ if (fs.existsSync(CONFIG_FILE)) {
10
+ const data = fs.readFileSync(CONFIG_FILE, 'utf-8');
11
+ return JSON.parse(data);
12
+ }
13
+ }
14
+ catch {
15
+ // Ignore errors, return empty config
16
+ }
17
+ return {};
18
+ }
19
+ export function saveConfig(config) {
20
+ if (!fs.existsSync(CONFIG_DIR)) {
21
+ fs.mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });
22
+ }
23
+ fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2), { mode: 0o600 });
24
+ }
25
+ export function getApiKey() {
26
+ const config = loadConfig();
27
+ return config.apiKey;
28
+ }
29
+ export function setApiKey(apiKey) {
30
+ const config = loadConfig();
31
+ config.apiKey = apiKey;
32
+ saveConfig(config);
33
+ }
34
+ export function clearApiKey() {
35
+ const config = loadConfig();
36
+ delete config.apiKey;
37
+ saveConfig(config);
38
+ }
39
+ export async function promptForApiKey() {
40
+ const rl = readline.createInterface({
41
+ input: process.stdin,
42
+ output: process.stdout,
43
+ });
44
+ return new Promise((resolve) => {
45
+ rl.question('Enter your Anthropic API key (sk-ant-...): ', (answer) => {
46
+ rl.close();
47
+ resolve(answer.trim());
48
+ });
49
+ });
50
+ }
51
+ export function validateApiKey(key) {
52
+ return key.startsWith('sk-ant-') && key.length > 20;
53
+ }
54
+ export function getAuthToken() {
55
+ return loadConfig().authToken;
56
+ }
57
+ export function setAuthToken(token) {
58
+ const config = loadConfig();
59
+ config.authToken = token;
60
+ saveConfig(config);
61
+ }
62
+ export function clearAuthToken() {
63
+ const config = loadConfig();
64
+ delete config.authToken;
65
+ saveConfig(config);
66
+ }
67
+ export function getServerUrl() {
68
+ return loadConfig().serverUrl;
69
+ }
70
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ import { spawn } from 'child_process';
2
+ export interface ExecutorOptions {
3
+ cwd?: string;
4
+ skipPermissions?: boolean;
5
+ resumeSessionId?: string;
6
+ outputFormat?: 'text' | 'stream-json';
7
+ onOutput?: (line: string) => void;
8
+ timeoutMs?: number;
9
+ }
10
+ export interface InteractiveOptions {
11
+ cwd?: string;
12
+ resumeSessionId?: string;
13
+ }
14
+ export interface InstallCheckResult {
15
+ installed: boolean;
16
+ version?: string;
17
+ }
18
+ export interface AuthCheckResult {
19
+ authenticated: boolean;
20
+ error?: string;
21
+ }
22
+ export interface LoginResult {
23
+ success: boolean;
24
+ }
25
+ export interface ExecutionResult {
26
+ exitCode: number;
27
+ success: boolean;
28
+ output: string;
29
+ sessionId?: string;
30
+ }
31
+ export declare function executeWithClaudeCode(prompt: string, options?: ExecutorOptions): Promise<ExecutionResult>;
32
+ /**
33
+ * Spawn Claude Code in interactive mode.
34
+ * Returns the child process so the caller can write to stdin and receive stdout/stderr directly.
35
+ * stdin is piped (for sending refined prompts), stdout/stderr are inherited (direct to terminal).
36
+ */
37
+ export declare function spawnInteractiveClaude(options?: InteractiveOptions): ReturnType<typeof spawn>;
38
+ /**
39
+ * Check if Claude Code CLI is installed.
40
+ */
41
+ export declare function checkClaudeCodeInstalled(): Promise<InstallCheckResult>;
42
+ /**
43
+ * Check if Claude Code is authenticated (can make API calls).
44
+ */
45
+ export declare function checkClaudeCodeAuth(): Promise<AuthCheckResult>;
46
+ /**
47
+ * Run Claude Code in interactive mode to trigger OAuth login flow.
48
+ * This will open a browser for the user to authenticate.
49
+ */
50
+ export declare function runClaudeLogin(): Promise<LoginResult>;
51
+ //# sourceMappingURL=executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../src/executor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAGtC,MAAM,WAAW,eAAe;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,GAAG,aAAa,CAAC;IACtC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,aAAa,EAAE,OAAO,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,eAAe,CAAC,CA6F1B;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,GAAE,kBAAuB,GAC/B,UAAU,CAAC,OAAO,KAAK,CAAC,CAc1B;AAED;;GAEG;AACH,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,kBAAkB,CAAC,CA8B5E;AAED;;GAEG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,eAAe,CAAC,CA8BpE;AAED;;;GAGG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,WAAW,CAAC,CAc3D"}
@@ -0,0 +1,181 @@
1
+ import { spawn } from 'child_process';
2
+ import { parseStreamLine, extractSessionId } from './output-parser.js';
3
+ export async function executeWithClaudeCode(prompt, options = {}) {
4
+ return new Promise((resolve, reject) => {
5
+ const args = ['-p'];
6
+ if (options.skipPermissions) {
7
+ args.push('--dangerously-skip-permissions');
8
+ }
9
+ if (options.resumeSessionId) {
10
+ args.push('--resume', options.resumeSessionId);
11
+ }
12
+ if (options.outputFormat === 'stream-json') {
13
+ args.push('--output-format', 'stream-json');
14
+ }
15
+ args.push(prompt);
16
+ const child = spawn('claude', args, {
17
+ cwd: options.cwd || process.cwd(),
18
+ stdio: ['ignore', 'pipe', 'pipe'],
19
+ env: process.env,
20
+ });
21
+ let output = '';
22
+ const events = [];
23
+ const onOutput = options.onOutput || ((line) => process.stdout.write(line));
24
+ // Swallow SIGINT during execution — child gets it via process group,
25
+ // but we don't want Node to exit autotunez
26
+ const sigintHandler = () => { };
27
+ process.on('SIGINT', sigintHandler);
28
+ let timer;
29
+ if (options.timeoutMs) {
30
+ timer = setTimeout(() => {
31
+ child.kill('SIGTERM');
32
+ }, options.timeoutMs);
33
+ }
34
+ if (child.stdout) {
35
+ child.stdout.on('data', (data) => {
36
+ const text = data.toString();
37
+ output += text;
38
+ onOutput(text);
39
+ if (options.outputFormat === 'stream-json') {
40
+ for (const line of text.split('\n')) {
41
+ const event = parseStreamLine(line);
42
+ if (event)
43
+ events.push(event);
44
+ }
45
+ }
46
+ });
47
+ }
48
+ if (child.stderr) {
49
+ child.stderr.on('data', (data) => {
50
+ output += data.toString();
51
+ });
52
+ }
53
+ child.on('error', (err) => {
54
+ if (timer)
55
+ clearTimeout(timer);
56
+ process.removeListener('SIGINT', sigintHandler);
57
+ if (err.code === 'ENOENT') {
58
+ reject(new Error("Claude Code CLI not found. Install it with 'npm install -g @anthropic-ai/claude-code' and make sure 'claude' is in your PATH."));
59
+ }
60
+ else {
61
+ reject(new Error(`Failed to start Claude Code: ${err.message}. Try running 'claude --version' to check your installation.`));
62
+ }
63
+ });
64
+ child.on('close', (code, signal) => {
65
+ if (timer)
66
+ clearTimeout(timer);
67
+ process.removeListener('SIGINT', sigintHandler);
68
+ const sessionId = options.outputFormat === 'stream-json'
69
+ ? extractSessionId(events)
70
+ : undefined;
71
+ if (signal === 'SIGINT') {
72
+ resolve({ exitCode: 130, success: false, output, sessionId });
73
+ }
74
+ else if (signal === 'SIGTERM') {
75
+ resolve({ exitCode: 143, success: false, output, sessionId });
76
+ }
77
+ else {
78
+ resolve({ exitCode: code ?? 1, success: code === 0, output, sessionId });
79
+ }
80
+ });
81
+ });
82
+ }
83
+ /**
84
+ * Spawn Claude Code in interactive mode.
85
+ * Returns the child process so the caller can write to stdin and receive stdout/stderr directly.
86
+ * stdin is piped (for sending refined prompts), stdout/stderr are inherited (direct to terminal).
87
+ */
88
+ export function spawnInteractiveClaude(options = {}) {
89
+ const args = [];
90
+ if (options.resumeSessionId) {
91
+ args.push('--resume', options.resumeSessionId);
92
+ }
93
+ const child = spawn('claude', args, {
94
+ cwd: options.cwd || process.cwd(),
95
+ stdio: ['pipe', 'inherit', 'inherit'],
96
+ env: process.env,
97
+ });
98
+ return child;
99
+ }
100
+ /**
101
+ * Check if Claude Code CLI is installed.
102
+ */
103
+ export async function checkClaudeCodeInstalled() {
104
+ return new Promise((resolve) => {
105
+ const child = spawn('claude', ['--version'], {
106
+ stdio: ['ignore', 'pipe', 'pipe'],
107
+ });
108
+ let version = '';
109
+ if (child.stdout) {
110
+ child.stdout.on('data', (data) => {
111
+ version += data.toString().trim();
112
+ });
113
+ }
114
+ child.on('error', (err) => {
115
+ if (err.code === 'ENOENT') {
116
+ resolve({ installed: false });
117
+ }
118
+ else {
119
+ resolve({ installed: false });
120
+ }
121
+ });
122
+ child.on('close', (code) => {
123
+ if (code === 0) {
124
+ resolve({ installed: true, version: version || undefined });
125
+ }
126
+ else {
127
+ resolve({ installed: false });
128
+ }
129
+ });
130
+ });
131
+ }
132
+ /**
133
+ * Check if Claude Code is authenticated (can make API calls).
134
+ */
135
+ export async function checkClaudeCodeAuth() {
136
+ return new Promise((resolve) => {
137
+ const child = spawn('claude', ['-p', 'hi'], {
138
+ stdio: ['ignore', 'pipe', 'pipe'],
139
+ });
140
+ let stderr = '';
141
+ if (child.stderr) {
142
+ child.stderr.on('data', (data) => {
143
+ stderr += data.toString();
144
+ });
145
+ }
146
+ child.on('error', (err) => {
147
+ if (err.code === 'ENOENT') {
148
+ resolve({ authenticated: false, error: 'Claude Code not installed' });
149
+ }
150
+ else {
151
+ resolve({ authenticated: false, error: err.message });
152
+ }
153
+ });
154
+ child.on('close', (code) => {
155
+ if (code === 0) {
156
+ resolve({ authenticated: true });
157
+ }
158
+ else {
159
+ resolve({ authenticated: false, error: stderr || 'Authentication failed' });
160
+ }
161
+ });
162
+ });
163
+ }
164
+ /**
165
+ * Run Claude Code in interactive mode to trigger OAuth login flow.
166
+ * This will open a browser for the user to authenticate.
167
+ */
168
+ export async function runClaudeLogin() {
169
+ return new Promise((resolve) => {
170
+ const child = spawn('claude', [], {
171
+ stdio: 'inherit',
172
+ });
173
+ child.on('error', () => {
174
+ resolve({ success: false });
175
+ });
176
+ child.on('close', (code) => {
177
+ resolve({ success: code === 0 });
178
+ });
179
+ });
180
+ }
181
+ //# sourceMappingURL=executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.js","sourceRoot":"","sources":["../src/executor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}