@struere/cli 0.2.7 → 0.2.9

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.
@@ -9,10 +9,10 @@ import { loadCredentials, getApiKey } from '../utils/credentials';
9
9
  import { ApiClient, ApiError } from '../utils/api';
10
10
  import { hasProject, loadProject } from '../utils/project';
11
11
  export const deployCommand = new Command('deploy')
12
- .description('Deploy agent to Struere Cloud')
13
- .option('-e, --env <environment>', 'Target environment (preview, staging, production)', 'preview')
12
+ .description('Deploy agent to production')
14
13
  .option('--dry-run', 'Show what would be deployed without deploying')
15
14
  .action(async (options) => {
15
+ const environment = 'production';
16
16
  const spinner = ora();
17
17
  const cwd = process.cwd();
18
18
  console.log();
@@ -57,7 +57,7 @@ export const deployCommand = new Command('deploy')
57
57
  console.log('Would deploy:');
58
58
  console.log(chalk.gray(' -'), `Agent: ${chalk.cyan(agent.name)}`);
59
59
  console.log(chalk.gray(' -'), `Version: ${chalk.cyan(agent.version)}`);
60
- console.log(chalk.gray(' -'), `Environment: ${chalk.cyan(options.env)}`);
60
+ console.log(chalk.gray(' -'), `Environment: ${chalk.cyan(environment)}`);
61
61
  console.log(chalk.gray(' -'), `Agent ID: ${chalk.cyan(project.agentId)}`);
62
62
  console.log();
63
63
  return;
@@ -89,13 +89,13 @@ export const deployCommand = new Command('deploy')
89
89
  }
90
90
  const bundle = await result.outputs[0].text();
91
91
  spinner.succeed(`Bundle created (${formatBytes(bundle.length)})`);
92
- spinner.start(`Deploying to ${options.env}`);
92
+ spinner.start(`Deploying to ${environment}`);
93
93
  try {
94
94
  const api = new ApiClient();
95
95
  const { deployment } = await api.deployAgent(project.agentId, {
96
96
  bundle,
97
97
  version: agent.version,
98
- environment: options.env,
98
+ environment: environment,
99
99
  metadata: {
100
100
  modelProvider: agent.model?.provider || 'anthropic',
101
101
  modelName: agent.model?.name || 'claude-sonnet-4-20250514',
@@ -103,7 +103,7 @@ export const deployCommand = new Command('deploy')
103
103
  bundleSize: bundle.length
104
104
  }
105
105
  });
106
- spinner.succeed(`Deployed to ${options.env}`);
106
+ spinner.succeed(`Deployed to ${environment}`);
107
107
  console.log();
108
108
  console.log(chalk.green('Success!'), 'Agent deployed');
109
109
  console.log();
@@ -1 +1 @@
1
- {"version":3,"file":"deploy.js","sourceRoot":"","sources":["../../src/commands/deploy.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"deploy.js","sourceRoot":"","sources":["../../src/commands/deploy.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAYnC,eAAO,MAAM,UAAU,SAwDnB,CAAA"}
1
+ {"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAYnC,eAAO,MAAM,UAAU,SAqKnB,CAAA"}
@@ -2,32 +2,32 @@ import { Command } from 'commander';
2
2
  import chalk from 'chalk';
3
3
  import ora from 'ora';
4
4
  import chokidar from 'chokidar';
5
- import { join } from 'path';
5
+ import { join, basename } from 'path';
6
6
  import { loadConfig } from '../utils/config';
7
7
  import { loadAgent } from '../utils/agent';
8
8
  import { loadCredentials, getApiKey } from '../utils/credentials';
9
- import { getSyncUrl } from '../utils/api';
10
- import { hasProject, loadProject } from '../utils/project';
9
+ import { ApiClient, ApiError, getSyncUrl } from '../utils/api';
10
+ import { hasProject, loadProject, saveProject } from '../utils/project';
11
+ import { performLogin } from './login';
11
12
  export const devCommand = new Command('dev')
12
- .description('Start development server with cloud sync')
13
- .option('-p, --port <port>', 'Port to run on', '3000')
14
- .option('-c, --channel <channel>', 'Channel to open (web, api)', 'web')
15
- .option('--no-open', 'Do not open browser')
16
- .option('--local', 'Run locally without cloud sync')
17
- .action(async (options) => {
13
+ .description('Sync agent to development environment')
14
+ .action(async () => {
18
15
  const spinner = ora();
19
16
  const cwd = process.cwd();
20
17
  console.log();
21
- console.log(chalk.bold('Struere Dev Server'));
18
+ console.log(chalk.bold('Struere Dev'));
22
19
  console.log();
20
+ let project = loadProject(cwd);
23
21
  if (!hasProject(cwd)) {
24
22
  console.log(chalk.yellow('No struere.json found'));
25
23
  console.log();
26
- console.log(chalk.gray('Run'), chalk.cyan('struere init'), chalk.gray('to initialize this project'));
27
- console.log();
28
- process.exit(1);
24
+ const setupResult = await interactiveSetup(cwd);
25
+ if (!setupResult) {
26
+ process.exit(0);
27
+ }
28
+ project = setupResult;
29
29
  }
30
- const project = loadProject(cwd);
30
+ project = loadProject(cwd);
31
31
  if (!project) {
32
32
  console.log(chalk.red('Failed to load struere.json'));
33
33
  process.exit(1);
@@ -35,8 +35,7 @@ export const devCommand = new Command('dev')
35
35
  console.log(chalk.gray('Agent:'), chalk.cyan(project.agent.name));
36
36
  console.log();
37
37
  spinner.start('Loading configuration');
38
- const config = await loadConfig(cwd);
39
- const port = parseInt(options.port) || config.port || 3000;
38
+ await loadConfig(cwd);
40
39
  spinner.succeed('Configuration loaded');
41
40
  spinner.start('Loading agent');
42
41
  let agent = await loadAgent(cwd);
@@ -50,16 +49,10 @@ export const devCommand = new Command('dev')
50
49
  console.log();
51
50
  process.exit(1);
52
51
  }
53
- await runCloudDev(agent, project, cwd, port, options, spinner);
54
- });
55
- async function runCloudDev(agent, project, cwd, port, options, spinner) {
56
- const credentials = loadCredentials();
57
- const apiKey = getApiKey();
58
52
  spinner.start('Connecting to Struere Cloud');
59
53
  const syncUrl = getSyncUrl();
60
54
  const ws = new WebSocket(`${syncUrl}/v1/dev/sync`);
61
55
  let cloudUrl = null;
62
- let sessionId = null;
63
56
  let isConnected = false;
64
57
  ws.onopen = () => {
65
58
  ws.send(JSON.stringify({
@@ -85,26 +78,22 @@ async function runCloudDev(agent, project, cwd, port, options, spinner) {
85
78
  case 'synced':
86
79
  isConnected = true;
87
80
  cloudUrl = data.url || null;
88
- sessionId = data.agentId || null;
89
- spinner.succeed('Connected to Struere Cloud');
81
+ spinner.succeed('Synced to development');
90
82
  console.log();
91
- console.log(chalk.gray('Mode:'), chalk.green('Cloud'));
92
- console.log(chalk.green('Agent running at'), chalk.cyan(cloudUrl));
93
- console.log(chalk.green('Local server at'), chalk.cyan(`http://localhost:${port}`));
83
+ console.log(chalk.green('Development URL:'), chalk.cyan(cloudUrl));
84
+ console.log();
85
+ console.log(chalk.gray('Watching for changes... Press Ctrl+C to stop'));
94
86
  console.log();
95
- spinner.start('Watching for changes');
96
87
  break;
97
88
  case 'log':
98
89
  const logColor = data.level === 'error' ? chalk.red
99
90
  : data.level === 'warn' ? chalk.yellow
100
91
  : data.level === 'debug' ? chalk.gray
101
92
  : chalk.blue;
102
- spinner.stop();
103
93
  console.log(logColor(`[${data.level}]`), data.message);
104
- spinner.start('Watching for changes');
105
94
  break;
106
95
  case 'error':
107
- spinner.fail(`Cloud error: ${data.message}`);
96
+ spinner.fail(`Error: ${data.message}`);
108
97
  if (data.code === 'INVALID_API_KEY' || data.code === 'NOT_AUTHENTICATED') {
109
98
  console.log();
110
99
  console.log(chalk.gray('Run'), chalk.cyan('struere login'), chalk.gray('to authenticate'));
@@ -113,75 +102,20 @@ async function runCloudDev(agent, project, cwd, port, options, spinner) {
113
102
  }
114
103
  };
115
104
  ws.onerror = () => {
116
- spinner.fail('WebSocket error');
117
- console.log(chalk.red('Connection error'));
105
+ spinner.fail('Connection error');
118
106
  };
119
107
  ws.onclose = () => {
120
108
  if (isConnected) {
121
- spinner.stop();
122
109
  console.log(chalk.yellow('Disconnected from cloud'));
123
110
  }
124
111
  };
125
- const server = Bun.serve({
126
- port,
127
- async fetch(req) {
128
- const url = new URL(req.url);
129
- if (url.pathname === '/health') {
130
- return Response.json({
131
- status: 'ok',
132
- agent: agent.name,
133
- mode: 'cloud',
134
- cloudUrl
135
- });
136
- }
137
- if (url.pathname === '/api/chat' && req.method === 'POST') {
138
- if (!cloudUrl || !sessionId) {
139
- return Response.json({ error: 'Not connected to cloud' }, { status: 503 });
140
- }
141
- const body = await req.json();
142
- const response = await fetch(`${process.env.STRUERE_GATEWAY_URL || 'https://gateway.struere.dev'}/v1/dev/${sessionId}/chat`, {
143
- method: 'POST',
144
- headers: {
145
- 'Content-Type': 'application/json',
146
- 'Authorization': `Bearer ${apiKey || credentials?.token}`
147
- },
148
- body: JSON.stringify(body)
149
- });
150
- if (body.stream) {
151
- return new Response(response.body, {
152
- headers: {
153
- 'Content-Type': 'text/event-stream',
154
- 'Cache-Control': 'no-cache',
155
- 'Connection': 'keep-alive'
156
- }
157
- });
158
- }
159
- const responseData = await response.json();
160
- return Response.json(responseData);
161
- }
162
- if (url.pathname === '/' && options.channel === 'web') {
163
- return new Response(getDevHtml(agent.name, 'cloud', cloudUrl), {
164
- headers: { 'Content-Type': 'text/html' },
165
- });
166
- }
167
- return new Response('Not Found', { status: 404 });
168
- }
169
- });
170
- if (options.channel === 'web' && options.open) {
171
- const openUrl = `http://localhost:${port}`;
172
- if (process.platform === 'darwin') {
173
- Bun.spawn(['open', openUrl]);
174
- }
175
- else if (process.platform === 'linux') {
176
- Bun.spawn(['xdg-open', openUrl]);
177
- }
178
- }
179
112
  const watcher = chokidar.watch([join(cwd, 'src'), join(cwd, 'struere.config.ts')], {
180
113
  ignoreInitial: true,
181
114
  ignored: /node_modules/,
182
115
  });
183
116
  watcher.on('change', async (path) => {
184
- spinner.text = `Syncing (${path.replace(cwd, '.')})`;
117
+ const relativePath = path.replace(cwd, '.');
118
+ console.log(chalk.gray(`Changed: ${relativePath}`));
185
119
  try {
186
120
  agent = await loadAgent(cwd);
187
121
  const bundle = await bundleAgent(cwd);
@@ -197,23 +131,20 @@ async function runCloudDev(agent, project, cwd, port, options, spinner) {
197
131
  }
198
132
  }
199
133
  catch (error) {
200
- spinner.fail(`Sync failed: ${error}`);
201
- spinner.start('Watching for changes');
134
+ console.log(chalk.red('Sync failed:'), error);
202
135
  }
203
136
  });
204
137
  process.on('SIGINT', () => {
205
138
  console.log();
206
- spinner.stop();
207
139
  if (ws.readyState === WebSocket.OPEN) {
208
140
  ws.send(JSON.stringify({ type: 'unsync' }));
209
141
  ws.close();
210
142
  }
211
143
  watcher.close();
212
- server.stop();
213
- console.log(chalk.gray('Server stopped'));
144
+ console.log(chalk.gray('Stopped'));
214
145
  process.exit(0);
215
146
  });
216
- }
147
+ });
217
148
  async function bundleAgent(cwd) {
218
149
  const result = await Bun.build({
219
150
  entrypoints: [join(cwd, 'src', 'agent.ts')],
@@ -234,185 +165,153 @@ function hashString(str) {
234
165
  }
235
166
  return Math.abs(hash).toString(16);
236
167
  }
237
- function getDevHtml(agentName, mode, cloudUrl) {
238
- const modeLabel = mode === 'cloud'
239
- ? `<span style="color: #22c55e;">Cloud</span>${cloudUrl ? ` - <a href="${cloudUrl}" target="_blank" style="color: #60a5fa;">${cloudUrl}</a>` : ''}`
240
- : '<span style="color: #eab308;">Local</span>';
241
- return `<!DOCTYPE html>
242
- <html lang="en">
243
- <head>
244
- <meta charset="UTF-8">
245
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
246
- <title>${agentName} - Dev</title>
247
- <style>
248
- * { box-sizing: border-box; margin: 0; padding: 0; }
249
- body { font-family: system-ui, -apple-system, sans-serif; background: #0a0a0a; color: #fafafa; height: 100vh; display: flex; flex-direction: column; }
250
- header { padding: 1rem; border-bottom: 1px solid #333; display: flex; justify-content: space-between; align-items: center; }
251
- header h1 { font-size: 1rem; font-weight: 500; }
252
- header .mode { font-size: 0.875rem; }
253
- header a { text-decoration: none; }
254
- #messages { flex: 1; overflow-y: auto; padding: 1rem; display: flex; flex-direction: column; gap: 0.75rem; }
255
- .message { max-width: 80%; padding: 0.75rem 1rem; border-radius: 0.75rem; line-height: 1.5; white-space: pre-wrap; }
256
- .message.user { align-self: flex-end; background: #2563eb; }
257
- .message.assistant { align-self: flex-start; background: #27272a; }
258
- .message.tool { align-self: flex-start; background: #1e3a5f; font-family: monospace; font-size: 0.875rem; border-left: 3px solid #3b82f6; }
259
- .message.streaming { opacity: 0.9; }
260
- form { padding: 1rem; border-top: 1px solid #333; display: flex; gap: 0.5rem; }
261
- input { flex: 1; padding: 0.75rem 1rem; background: #18181b; border: 1px solid #333; border-radius: 0.5rem; color: #fafafa; font-size: 1rem; outline: none; }
262
- input:focus { border-color: #2563eb; }
263
- input:disabled { opacity: 0.5; }
264
- button { padding: 0.75rem 1.5rem; background: #2563eb; border: none; border-radius: 0.5rem; color: white; font-size: 1rem; cursor: pointer; }
265
- button:hover { background: #1d4ed8; }
266
- button:disabled { opacity: 0.5; cursor: not-allowed; }
267
- .toggle-container { padding: 0.5rem 1rem; display: flex; align-items: center; gap: 0.5rem; border-top: 1px solid #333; }
268
- .toggle-container label { font-size: 0.875rem; color: #888; }
269
- .toggle-container input[type="checkbox"] { width: 1rem; height: 1rem; }
270
- </style>
271
- </head>
272
- <body>
273
- <header>
274
- <h1>${agentName}</h1>
275
- <span class="mode">${modeLabel}</span>
276
- </header>
277
- <div id="messages"></div>
278
- <div class="toggle-container">
279
- <input type="checkbox" id="stream-toggle" checked />
280
- <label for="stream-toggle">Enable streaming</label>
281
- </div>
282
- <form id="chat-form">
283
- <input type="text" id="input" placeholder="Type a message..." autocomplete="off" />
284
- <button type="submit">Send</button>
285
- </form>
286
- <script>
287
- const messages = document.getElementById('messages');
288
- const form = document.getElementById('chat-form');
289
- const input = document.getElementById('input');
290
- const button = form.querySelector('button');
291
- const streamToggle = document.getElementById('stream-toggle');
292
- let conversationId = null;
293
- let isProcessing = false;
294
-
295
- function addMessage(role, content, isStreaming = false) {
296
- const div = document.createElement('div');
297
- div.className = 'message ' + role + (isStreaming ? ' streaming' : '');
298
- div.textContent = content;
299
- messages.appendChild(div);
300
- messages.scrollTop = messages.scrollHeight;
301
- return div;
168
+ async function interactiveSetup(cwd) {
169
+ const spinner = ora();
170
+ let credentials = loadCredentials();
171
+ if (!credentials) {
172
+ console.log(chalk.gray('Authentication required'));
173
+ console.log();
174
+ credentials = await performLogin();
175
+ if (!credentials) {
176
+ console.log(chalk.red('Authentication failed'));
177
+ return null;
178
+ }
179
+ }
180
+ else {
181
+ console.log(chalk.green('✓'), 'Logged in as', chalk.cyan(credentials.user.name));
182
+ console.log();
302
183
  }
303
-
304
- function setProcessing(processing) {
305
- isProcessing = processing;
306
- input.disabled = processing;
307
- button.disabled = processing;
184
+ spinner.start('Fetching agents');
185
+ const api = new ApiClient();
186
+ let agents = [];
187
+ try {
188
+ const { agents: existingAgents } = await api.listAgents();
189
+ agents = existingAgents;
190
+ spinner.succeed(`Found ${agents.length} existing agent(s)`);
308
191
  }
309
-
310
- async function sendWithStreaming(message) {
311
- const assistantDiv = addMessage('assistant', '', true);
312
-
313
- const response = await fetch('/api/chat', {
314
- method: 'POST',
315
- headers: { 'Content-Type': 'application/json' },
316
- body: JSON.stringify({ message, conversationId, stream: true }),
317
- });
318
-
319
- const reader = response.body.getReader();
320
- const decoder = new TextDecoder();
321
- let buffer = '';
322
- let fullText = '';
323
-
324
- while (true) {
325
- const { done, value } = await reader.read();
326
- if (done) break;
327
-
328
- buffer += decoder.decode(value, { stream: true });
329
- const lines = buffer.split('\\n');
330
- buffer = lines.pop() || '';
331
-
332
- for (const line of lines) {
333
- if (line.startsWith('data: ')) {
334
- try {
335
- const data = JSON.parse(line.slice(6));
336
-
337
- if (data.conversationId) {
338
- conversationId = data.conversationId;
339
- }
340
-
341
- if (data.type === 'text-delta' && (data.textDelta || data.content)) {
342
- fullText += data.textDelta || data.content;
343
- assistantDiv.textContent = fullText;
344
- messages.scrollTop = messages.scrollHeight;
345
- } else if (data.type === 'tool-call-start') {
346
- addMessage('tool', 'Calling tool: ' + (data.toolName || data.toolCall?.name));
347
- } else if (data.type === 'tool-result') {
348
- const resultText = typeof data.toolResult === 'string'
349
- ? data.toolResult
350
- : JSON.stringify(data.toolResult || data.toolCall?.result, null, 2);
351
- addMessage('tool', 'Result: ' + resultText);
352
- } else if (data.type === 'finish') {
353
- assistantDiv.classList.remove('streaming');
354
- } else if (data.type === 'error') {
355
- assistantDiv.textContent = 'Error: ' + (data.error || data.message);
356
- assistantDiv.classList.remove('streaming');
357
- }
358
- } catch (e) {}
359
- }
192
+ catch (error) {
193
+ if (error instanceof ApiError && error.status === 401) {
194
+ spinner.fail('Session expired');
195
+ console.log();
196
+ console.log(chalk.gray('Run'), chalk.cyan('struere login'), chalk.gray('to re-authenticate'));
197
+ return null;
360
198
  }
361
- }
362
-
363
- if (!fullText) {
364
- assistantDiv.remove();
365
- }
199
+ spinner.succeed('Ready to create agent');
366
200
  }
367
-
368
- async function sendWithoutStreaming(message) {
369
- const res = await fetch('/api/chat', {
370
- method: 'POST',
371
- headers: { 'Content-Type': 'application/json' },
372
- body: JSON.stringify({ message, conversationId }),
373
- });
374
- const data = await res.json();
375
- conversationId = data.conversationId;
376
-
377
- if (data.toolCalls && data.toolCalls.length > 0) {
378
- for (const tc of data.toolCalls) {
379
- const resultText = typeof tc.result === 'string'
380
- ? tc.result
381
- : JSON.stringify(tc.result, null, 2);
382
- addMessage('tool', tc.name + ': ' + resultText);
201
+ console.log();
202
+ const choices = [
203
+ { value: 'link', label: 'Link to an existing agent' },
204
+ { value: 'create', label: 'Create a new agent' },
205
+ { value: 'cancel', label: 'Cancel' },
206
+ ];
207
+ if (agents.length === 0) {
208
+ choices.shift();
209
+ }
210
+ const action = await promptChoice('No agent configured. Would you like to:', choices);
211
+ if (action === 'cancel') {
212
+ console.log();
213
+ console.log(chalk.gray('Run'), chalk.cyan('struere init'), chalk.gray('when ready to set up'));
214
+ return null;
215
+ }
216
+ let selectedAgent = null;
217
+ if (action === 'link' && agents.length > 0) {
218
+ console.log();
219
+ const agentChoices = agents.map((a) => ({ value: a.id, label: `${a.name} (${a.slug})` }));
220
+ const agentId = await promptChoice('Select an agent:', agentChoices);
221
+ selectedAgent = agents.find((a) => a.id === agentId) || null;
222
+ }
223
+ else if (action === 'create') {
224
+ console.log();
225
+ const projectName = slugify(basename(cwd));
226
+ const name = await promptText('Agent name:', projectName);
227
+ const displayName = name
228
+ .split('-')
229
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
230
+ .join(' ');
231
+ spinner.start('Creating agent');
232
+ try {
233
+ const { agent } = await api.createAgent({
234
+ name: displayName,
235
+ slug: name,
236
+ description: `${displayName} Agent`,
237
+ });
238
+ selectedAgent = { id: agent.id, name: displayName, slug: name };
239
+ spinner.succeed(`Created agent "${name}"`);
240
+ }
241
+ catch (error) {
242
+ spinner.fail('Failed to create agent');
243
+ console.log();
244
+ if (error instanceof ApiError) {
245
+ console.log(chalk.red('Error:'), error.message);
246
+ }
247
+ else {
248
+ console.log(chalk.red('Error:'), error instanceof Error ? error.message : String(error));
249
+ }
250
+ return null;
383
251
  }
384
- }
385
-
386
- addMessage('assistant', data.response || data.content);
387
252
  }
388
-
389
- form.addEventListener('submit', async (e) => {
390
- e.preventDefault();
391
- if (isProcessing) return;
392
-
393
- const message = input.value.trim();
394
- if (!message) return;
395
-
396
- addMessage('user', message);
397
- input.value = '';
398
- setProcessing(true);
399
-
400
- try {
401
- if (streamToggle.checked) {
402
- await sendWithStreaming(message);
403
- } else {
404
- await sendWithoutStreaming(message);
253
+ if (!selectedAgent) {
254
+ return null;
255
+ }
256
+ const projectData = {
257
+ agentId: selectedAgent.id,
258
+ team: credentials.organization.slug,
259
+ agent: {
260
+ slug: selectedAgent.slug,
261
+ name: selectedAgent.name,
262
+ },
263
+ };
264
+ saveProject(cwd, projectData);
265
+ console.log(chalk.green('✓'), 'Created struere.json');
266
+ console.log();
267
+ return projectData;
268
+ }
269
+ function slugify(name) {
270
+ return name
271
+ .toLowerCase()
272
+ .replace(/[^a-z0-9]+/g, '-')
273
+ .replace(/^-+|-+$/g, '');
274
+ }
275
+ async function promptChoice(message, choices) {
276
+ console.log(chalk.gray(message));
277
+ console.log();
278
+ for (let i = 0; i < choices.length; i++) {
279
+ const prefix = i === 0 ? chalk.cyan('❯') : chalk.gray(' ');
280
+ console.log(`${prefix} ${i + 1}. ${choices[i].label}`);
281
+ }
282
+ console.log();
283
+ process.stdout.write(chalk.gray('Enter choice (1-' + choices.length + '): '));
284
+ const answer = await readLine();
285
+ const num = parseInt(answer, 10);
286
+ if (num >= 1 && num <= choices.length) {
287
+ return choices[num - 1].value;
288
+ }
289
+ return choices[0].value;
290
+ }
291
+ async function promptText(message, defaultValue) {
292
+ process.stdout.write(chalk.gray(`${message} `));
293
+ process.stdout.write(chalk.cyan(`(${defaultValue}) `));
294
+ const answer = await readLine();
295
+ return answer || defaultValue;
296
+ }
297
+ function readLine() {
298
+ return new Promise((resolve) => {
299
+ let buffer = '';
300
+ const onData = (chunk) => {
301
+ const str = chunk.toString();
302
+ buffer += str;
303
+ if (str.includes('\n') || str.includes('\r')) {
304
+ process.stdin.removeListener('data', onData);
305
+ process.stdin.pause();
306
+ process.stdin.setRawMode?.(false);
307
+ resolve(buffer.replace(/[\r\n]/g, '').trim());
308
+ }
309
+ };
310
+ if (process.stdin.isTTY) {
311
+ process.stdin.setRawMode?.(false);
405
312
  }
406
- } catch (err) {
407
- addMessage('assistant', 'Error: ' + err.message);
408
- } finally {
409
- setProcessing(false);
410
- }
313
+ process.stdin.resume();
314
+ process.stdin.on('data', onData);
411
315
  });
412
-
413
- input.focus();
414
- </script>
415
- </body>
416
- </html>`;
417
316
  }
418
317
  //# sourceMappingURL=dev.js.map