@alexkroman1/aai-cli 0.10.2 → 0.10.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { l as resolveCwd, n as fileExists, t as ensureApiKeyInEnv } from "./_discover-D7HCLa_N.mjs";
2
+ import { l as resolveCwd, n as ensureApiKeyInEnv, r as fileExists } from "./_discover-DiRl7b_K.mjs";
3
3
  import { readFileSync } from "node:fs";
4
4
  import path from "node:path";
5
5
  import { fileURLToPath } from "node:url";
@@ -35,9 +35,17 @@ function findPkgJson(dir) {
35
35
  const VERSION = JSON.parse(findPkgJson(cliDir)).version;
36
36
  async function ensureAgent(cwd, yes) {
37
37
  if (!await fileExists(path.join(cwd, "agent.ts"))) {
38
- const { runInitCommand } = await import("./init-COkINbH_.mjs");
39
- await runInitCommand({ yes }, { quiet: true });
38
+ const { runInitCommand } = await import("./init-BAYELcXE.mjs");
39
+ return runInitCommand({ yes }, { quiet: true });
40
40
  }
41
+ return cwd;
42
+ }
43
+ /** Shared command setup: resolve cwd, optionally scaffold agent and check API key. */
44
+ async function setup(args, opts) {
45
+ let cwd = resolveCwd();
46
+ if (opts?.agent) cwd = await ensureAgent(cwd, args?.yes);
47
+ if (opts?.apiKey) await ensureApiKeyInEnv();
48
+ return cwd;
41
49
  }
42
50
  const init = defineCommand({
43
51
  meta: {
@@ -71,7 +79,7 @@ const init = defineCommand({
71
79
  }
72
80
  },
73
81
  async run({ args }) {
74
- const { runInitCommand } = await import("./init-COkINbH_.mjs");
82
+ const { runInitCommand } = await import("./init-BAYELcXE.mjs");
75
83
  await runInitCommand({
76
84
  dir: args.dir,
77
85
  template: args.template,
@@ -88,31 +96,18 @@ const dev = defineCommand({
88
96
  description: "Start a local development server"
89
97
  },
90
98
  args: {
91
- port: {
92
- type: "string",
93
- alias: "p",
94
- description: "Port to listen on",
95
- default: "3000"
96
- },
97
- check: {
98
- type: "boolean",
99
- description: "Start server, verify health, then exit"
100
- },
101
- yes: {
102
- type: "boolean",
103
- alias: "y",
104
- description: "Accept defaults (no prompts)"
105
- }
99
+ port: sharedArgs.port,
100
+ yes: sharedArgs.yes
106
101
  },
107
102
  async run({ args }) {
108
- const cwd = resolveCwd();
109
- await ensureAgent(cwd, args.yes);
110
- await ensureApiKeyInEnv();
111
- const { runDevCommand } = await import("./dev-DCtHG1pz.mjs");
103
+ const cwd = await setup(args, {
104
+ agent: true,
105
+ apiKey: true
106
+ });
107
+ const { runDevCommand } = await import("./dev-CBKWhwaQ.mjs");
112
108
  await runDevCommand({
113
109
  cwd,
114
- port: args.port,
115
- ...args.check ? { check: args.check } : {}
110
+ port: args.port
116
111
  });
117
112
  }
118
113
  });
@@ -122,8 +117,8 @@ const test = defineCommand({
122
117
  description: "Run agent tests"
123
118
  },
124
119
  async run() {
125
- const cwd = resolveCwd();
126
- const { runTestCommand } = await import("./test-9fFn9DCf.mjs");
120
+ const cwd = await setup();
121
+ const { runTestCommand } = await import("./test-CuMTKw38.mjs");
127
122
  await runTestCommand(cwd);
128
123
  }
129
124
  });
@@ -133,24 +128,19 @@ const build = defineCommand({
133
128
  description: "Bundle and validate (no server or deploy)"
134
129
  },
135
130
  args: {
136
- yes: {
137
- type: "boolean",
138
- alias: "y",
139
- description: "Accept defaults (no prompts)"
140
- },
131
+ yes: sharedArgs.yes,
141
132
  skipTests: {
142
133
  type: "boolean",
143
134
  description: "Skip running tests before build"
144
135
  }
145
136
  },
146
137
  async run({ args }) {
147
- const cwd = resolveCwd();
148
- await ensureAgent(cwd, args.yes);
138
+ const cwd = await setup(args, { agent: true });
149
139
  if (!args.skipTests) {
150
- const { runVitest } = await import("./test-9fFn9DCf.mjs");
140
+ const { runVitest } = await import("./test-CuMTKw38.mjs");
151
141
  runVitest(cwd);
152
142
  }
153
- const { runBuildCommand } = await import("./_build-aW_zyPpr.mjs");
143
+ const { runBuildCommand } = await import("./_bundler-BM-vnJUp.mjs");
154
144
  await runBuildCommand(cwd);
155
145
  }
156
146
  });
@@ -160,25 +150,16 @@ const deploy = defineCommand({
160
150
  description: "Bundle and deploy to production"
161
151
  },
162
152
  args: {
163
- server: {
164
- type: "string",
165
- alias: "s",
166
- description: "Server URL"
167
- },
153
+ server: sharedArgs.server,
168
154
  dryRun: {
169
155
  type: "boolean",
170
156
  description: "Validate and bundle without deploying"
171
157
  },
172
- yes: {
173
- type: "boolean",
174
- alias: "y",
175
- description: "Accept defaults (no prompts)"
176
- }
158
+ yes: sharedArgs.yes
177
159
  },
178
160
  async run({ args }) {
179
- const cwd = resolveCwd();
180
- await ensureAgent(cwd, args.yes);
181
- const { runDeployCommand } = await import("./deploy-DB0PeNtc.mjs");
161
+ const cwd = await setup(args, { agent: true });
162
+ const { runDeployCommand } = await import("./deploy-C2s4C_ff.mjs");
182
163
  await runDeployCommand({
183
164
  cwd,
184
165
  ...args.server ? { server: args.server } : {},
@@ -191,48 +172,16 @@ const del = defineCommand({
191
172
  name: "delete",
192
173
  description: "Remove a deployed agent"
193
174
  },
194
- args: { server: {
195
- type: "string",
196
- alias: "s",
197
- description: "Server URL"
198
- } },
175
+ args: { server: sharedArgs.server },
199
176
  async run({ args }) {
200
- const cwd = resolveCwd();
201
- const { runDeleteCommand } = await import("./delete-DxECFYOp.mjs");
177
+ const cwd = await setup();
178
+ const { runDeleteCommand } = await import("./delete-CSPF9vdh.mjs");
202
179
  await runDeleteCommand({
203
180
  cwd,
204
181
  ...args.server ? { server: args.server } : {}
205
182
  });
206
183
  }
207
184
  });
208
- const start = defineCommand({
209
- meta: {
210
- name: "start",
211
- description: "Start production server from build"
212
- },
213
- args: {
214
- port: {
215
- type: "string",
216
- alias: "p",
217
- description: "Port to listen on",
218
- default: "3000"
219
- },
220
- yes: {
221
- type: "boolean",
222
- alias: "y",
223
- description: "Accept defaults (no prompts)"
224
- }
225
- },
226
- async run({ args }) {
227
- const cwd = resolveCwd();
228
- await ensureApiKeyInEnv();
229
- const { runStartCommand } = await import("./start-DQypQkOq.mjs");
230
- await runStartCommand({
231
- cwd,
232
- port: args.port
233
- });
234
- }
235
- });
236
185
  const secret = defineCommand({
237
186
  meta: {
238
187
  name: "secret",
@@ -250,9 +199,8 @@ const secret = defineCommand({
250
199
  required: true
251
200
  } },
252
201
  async run({ args }) {
253
- const cwd = resolveCwd();
254
- await ensureApiKeyInEnv();
255
- const { runSecretPut } = await import("./secret-Zzv7fJ_3.mjs");
202
+ const cwd = await setup(void 0, { apiKey: true });
203
+ const { runSecretPut } = await import("./secret-CRLbxN5P.mjs");
256
204
  await runSecretPut(cwd, args.name);
257
205
  }
258
206
  }),
@@ -267,9 +215,8 @@ const secret = defineCommand({
267
215
  required: true
268
216
  } },
269
217
  async run({ args }) {
270
- const cwd = resolveCwd();
271
- await ensureApiKeyInEnv();
272
- const { runSecretDelete } = await import("./secret-Zzv7fJ_3.mjs");
218
+ const cwd = await setup(void 0, { apiKey: true });
219
+ const { runSecretDelete } = await import("./secret-CRLbxN5P.mjs");
273
220
  await runSecretDelete(cwd, args.name);
274
221
  }
275
222
  }),
@@ -279,73 +226,13 @@ const secret = defineCommand({
279
226
  description: "List secret names"
280
227
  },
281
228
  async run() {
282
- const cwd = resolveCwd();
283
- await ensureApiKeyInEnv();
284
- const { runSecretList } = await import("./secret-Zzv7fJ_3.mjs");
229
+ const cwd = await setup(void 0, { apiKey: true });
230
+ const { runSecretList } = await import("./secret-CRLbxN5P.mjs");
285
231
  await runSecretList(cwd);
286
232
  }
287
233
  })
288
234
  }
289
235
  });
290
- const rag = defineCommand({
291
- meta: {
292
- name: "rag",
293
- description: "Ingest a site's llms-full.txt into the vector store"
294
- },
295
- args: {
296
- url: {
297
- type: "positional",
298
- description: "URL to ingest",
299
- required: true
300
- },
301
- server: {
302
- type: "string",
303
- alias: "s",
304
- description: "Server URL"
305
- },
306
- chunkSize: {
307
- type: "string",
308
- description: "Max chunk size in tokens",
309
- default: "512"
310
- },
311
- yes: {
312
- type: "boolean",
313
- alias: "y",
314
- description: "Accept defaults (no prompts)"
315
- }
316
- },
317
- async run({ args }) {
318
- const cwd = resolveCwd();
319
- await ensureApiKeyInEnv();
320
- const { runRagCommand } = await import("./rag-BNfrEr4A.mjs");
321
- await runRagCommand({
322
- url: args.url,
323
- cwd,
324
- ...args.server ? { server: args.server } : {},
325
- chunkSize: args.chunkSize
326
- });
327
- }
328
- });
329
- const doctor = defineCommand({
330
- meta: {
331
- name: "doctor",
332
- description: "Check environment health and diagnose issues"
333
- },
334
- args: { port: {
335
- type: "string",
336
- alias: "p",
337
- description: "Port to check availability",
338
- default: "3000"
339
- } },
340
- async run({ args }) {
341
- const cwd = resolveCwd();
342
- const { runDoctorCommand } = await import("./doctor-bWuArZi6.mjs");
343
- await runDoctorCommand({
344
- cwd,
345
- port: args.port
346
- });
347
- }
348
- });
349
236
  const generate = defineCommand({
350
237
  meta: {
351
238
  name: "generate",
@@ -357,9 +244,8 @@ const generate = defineCommand({
357
244
  required: true
358
245
  } },
359
246
  async run({ args }) {
360
- const cwd = resolveCwd();
361
- await ensureApiKeyInEnv();
362
- const { runGenerateCommand } = await import("./generate-D7zJtqoC.mjs");
247
+ const cwd = await setup(void 0, { apiKey: true });
248
+ const { runGenerateCommand } = await import("./generate-DQt7C4zz.mjs");
363
249
  await runGenerateCommand({
364
250
  cwd,
365
251
  prompt: args.prompt
@@ -377,48 +263,25 @@ const run = defineCommand({
377
263
  description: "What to build",
378
264
  required: true
379
265
  },
380
- server: {
381
- type: "string",
382
- alias: "s",
383
- description: "Server URL"
384
- }
266
+ server: sharedArgs.server
385
267
  },
386
268
  async run({ args }) {
387
- await ensureAgent(resolveCwd(), true);
388
- await ensureApiKeyInEnv();
389
- const cwd = resolveCwd();
390
- const { runGenerateCommand } = await import("./generate-D7zJtqoC.mjs");
269
+ const cwd = await setup({ yes: true }, {
270
+ agent: true,
271
+ apiKey: true
272
+ });
273
+ const { runGenerateCommand } = await import("./generate-DQt7C4zz.mjs");
391
274
  await runGenerateCommand({
392
275
  cwd,
393
276
  prompt: args.prompt
394
277
  });
395
- const { runDeployCommand } = await import("./deploy-DB0PeNtc.mjs");
278
+ const { runDeployCommand } = await import("./deploy-C2s4C_ff.mjs");
396
279
  await runDeployCommand({
397
280
  cwd,
398
281
  ...args.server ? { server: args.server } : {}
399
282
  });
400
283
  }
401
284
  });
402
- const link = defineCommand({
403
- meta: {
404
- name: "link",
405
- description: "Link local workspace packages into the current project (dev only)"
406
- },
407
- async run() {
408
- const { runLinkCommand } = await import("./_link-D6mmDQ0B.mjs");
409
- runLinkCommand(resolveCwd());
410
- }
411
- });
412
- const unlink = defineCommand({
413
- meta: {
414
- name: "unlink",
415
- description: "Restore published package versions (reverses aai link)"
416
- },
417
- async run() {
418
- const { runUnlinkCommand } = await import("./_link-D6mmDQ0B.mjs");
419
- runUnlinkCommand(resolveCwd());
420
- }
421
- });
422
285
  const mainCommand = defineCommand({
423
286
  meta: {
424
287
  name: "aai",
@@ -432,14 +295,9 @@ const mainCommand = defineCommand({
432
295
  build,
433
296
  deploy,
434
297
  delete: del,
435
- start,
436
298
  secret,
437
- rag,
438
299
  generate,
439
- run,
440
- link,
441
- unlink,
442
- doctor
300
+ run
443
301
  }
444
302
  });
445
303
  if (process.env.VITEST !== "true") {
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env node
2
+ import { o as getServerInfo } from "./_discover-DiRl7b_K.mjs";
3
+ import { consola } from "./_ui-Cu-v_Bzz.mjs";
4
+ import { n as apiError, r as apiRequest, t as HINT_INVALID_API_KEY } from "./_api-client-Br1a_Dsp.mjs";
5
+ //#region _delete.ts
6
+ async function runDelete(opts) {
7
+ const fetchFn = opts.fetch ?? globalThis.fetch.bind(globalThis);
8
+ const resp = await apiRequest(`${opts.url}/${opts.slug}`, {
9
+ method: "DELETE",
10
+ apiKey: opts.apiKey,
11
+ action: "delete"
12
+ }, fetchFn);
13
+ if (resp.ok) return;
14
+ const text = await resp.text();
15
+ let hint;
16
+ if (resp.status === 401) hint = HINT_INVALID_API_KEY;
17
+ else if (resp.status === 404) hint = "The agent may not be deployed. Check `.aai/project.json` for the correct slug.";
18
+ throw apiError("delete", resp.status, text, hint);
19
+ }
20
+ //#endregion
21
+ //#region delete.ts
22
+ async function runDeleteCommand(opts) {
23
+ const { cwd } = opts;
24
+ const { serverUrl, slug, apiKey } = await getServerInfo(cwd, opts.server);
25
+ consola.start(`Delete ${slug}`);
26
+ await runDelete({
27
+ url: serverUrl,
28
+ slug,
29
+ apiKey
30
+ });
31
+ consola.success(`Deleted ${serverUrl}/${slug}`);
32
+ }
33
+ //#endregion
34
+ export { runDeleteCommand };
@@ -0,0 +1,92 @@
1
+ #!/usr/bin/env node
2
+ import { a as getApiKey, c as readProjectConfig, d as writeProjectConfig, i as generateSlug, u as resolveServerUrl } from "./_discover-DiRl7b_K.mjs";
3
+ import { buildAgentBundle } from "./_bundler-BM-vnJUp.mjs";
4
+ import { consola } from "./_ui-Cu-v_Bzz.mjs";
5
+ import { n as apiError, r as apiRequest, t as HINT_INVALID_API_KEY } from "./_api-client-Br1a_Dsp.mjs";
6
+ //#region _deploy.ts
7
+ const MAX_SLUG_RETRIES = 20;
8
+ async function attempt(fetchFn, url, slug, body, apiKey) {
9
+ const resp = await apiRequest(`${url}/${slug}/deploy`, {
10
+ method: "POST",
11
+ body,
12
+ apiKey,
13
+ action: "deploy"
14
+ }, fetchFn);
15
+ if (resp.ok) return {
16
+ ok: true,
17
+ slug
18
+ };
19
+ const text = await resp.text();
20
+ if (resp.status === 403 && text.includes("owned by another")) return {
21
+ ok: false,
22
+ retry: true
23
+ };
24
+ let hint;
25
+ if (resp.status === 401) hint = HINT_INVALID_API_KEY;
26
+ else if (resp.status === 403 && text.includes("Slug")) hint = "This slug is already taken. Set a different slug in .aai/project.json.";
27
+ else if (resp.status === 413) hint = "Your bundle is too large. Try reducing dependencies or splitting your agent.";
28
+ return {
29
+ ok: false,
30
+ retry: false,
31
+ error: apiError("deploy", resp.status, text, hint).message
32
+ };
33
+ }
34
+ async function runDeploy(opts) {
35
+ const fetchFn = opts.fetch ?? globalThis.fetch.bind(globalThis);
36
+ const body = JSON.stringify({
37
+ env: opts.env,
38
+ worker: opts.bundle.worker,
39
+ clientFiles: opts.bundle.clientFiles
40
+ });
41
+ let slug = opts.slug;
42
+ for (let i = 0; i < MAX_SLUG_RETRIES; i++) {
43
+ const result = await attempt(fetchFn, opts.url, slug, body, opts.apiKey);
44
+ if (result.ok) return { slug: result.slug };
45
+ if (!result.retry) throw new Error(result.error);
46
+ slug = generateSlug();
47
+ }
48
+ throw new Error(`could not find an available agent slug after ${MAX_SLUG_RETRIES} attempts`);
49
+ }
50
+ //#endregion
51
+ //#region deploy.ts
52
+ async function deployBundle(opts) {
53
+ const { bundle, serverUrl, apiKey, cwd } = opts;
54
+ let { slug } = opts;
55
+ consola.start(`Deploy ${slug}`);
56
+ slug = (await runDeploy({
57
+ url: serverUrl,
58
+ bundle,
59
+ env: { ASSEMBLYAI_API_KEY: apiKey },
60
+ slug,
61
+ apiKey
62
+ })).slug;
63
+ await writeProjectConfig(cwd, {
64
+ slug,
65
+ serverUrl
66
+ });
67
+ const agentUrl = `${serverUrl}/${slug}`;
68
+ consola.success(`Ready ${agentUrl}`);
69
+ return agentUrl;
70
+ }
71
+ async function runDeployCommand(opts) {
72
+ const { cwd } = opts;
73
+ const dryRun = opts.dryRun ?? false;
74
+ const apiKey = dryRun ? "" : await getApiKey();
75
+ const projectConfig = await readProjectConfig(cwd);
76
+ const serverUrl = resolveServerUrl(opts.server, projectConfig?.serverUrl);
77
+ const slug = projectConfig?.slug ?? generateSlug();
78
+ const bundle = await buildAgentBundle(cwd);
79
+ if (dryRun) {
80
+ consola.info(`Dry run: would deploy as ${slug}`);
81
+ return;
82
+ }
83
+ await deployBundle({
84
+ bundle,
85
+ serverUrl,
86
+ apiKey,
87
+ slug,
88
+ cwd
89
+ });
90
+ }
91
+ //#endregion
92
+ export { runDeployCommand };
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env node
2
+ import { consola, parsePort } from "./_ui-Cu-v_Bzz.mjs";
3
+ import path from "node:path";
4
+ import { createServer } from "vite";
5
+ import * as p from "@clack/prompts";
6
+ import { colorize } from "consola/utils";
7
+ //#region dev.ts
8
+ async function runDevCommand(opts) {
9
+ const port = parsePort(opts.port);
10
+ const agentName = path.basename(path.resolve(opts.cwd));
11
+ await (await createServer({
12
+ root: opts.cwd,
13
+ server: { port }
14
+ })).listen();
15
+ const url = colorize("blueBright", `http://localhost:${port}`);
16
+ p.note(`Agent: ${colorize("bold", agentName)}\nLocal: ${url}`, "aai dev");
17
+ consola.info("Press Ctrl-C to stop");
18
+ }
19
+ //#endregion
20
+ export { runDevCommand };
@@ -1,14 +1,19 @@
1
1
  #!/usr/bin/env node
2
- import { i as getApiKey } from "./_discover-D7HCLa_N.mjs";
2
+ import { a as getApiKey } from "./_discover-DiRl7b_K.mjs";
3
3
  import path from "node:path";
4
4
  import fs from "node:fs/promises";
5
5
  import { consola } from "consola";
6
6
  import { z } from "zod";
7
- import { colorize } from "consola/utils";
8
- import { execFile } from "node:child_process";
7
+ import { errorMessage } from "@alexkroman1/aai/utils";
9
8
  import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
10
9
  import { generateText, stepCountIs } from "ai";
10
+ import { execFile } from "node:child_process";
11
11
  import { promisify } from "node:util";
12
+ /** Max characters per line when reading files. */
13
+ const MAX_LINE_LENGTH = 2e3;
14
+ /** Max output bytes for shell commands (50 KB). */
15
+ const MAX_OUTPUT_BYTES = 50 * 1024;
16
+ //#endregion
12
17
  //#region _generate-tools.ts
13
18
  const execFileAsync = promisify(execFile);
14
19
  const SKIP_DIRS = new Set([
@@ -18,9 +23,6 @@ const SKIP_DIRS = new Set([
18
23
  "dist",
19
24
  "coverage"
20
25
  ]);
21
- const MAX_READ_LINES = 2e3;
22
- const MAX_LINE_LENGTH = 2e3;
23
- const MAX_OUTPUT_BYTES = 50 * 1024;
24
26
  function safePath(workDir, filePath) {
25
27
  const abs = path.resolve(workDir, filePath);
26
28
  if (!abs.startsWith(workDir + path.sep) && abs !== workDir) return null;
@@ -36,7 +38,7 @@ function formatGrepOutput(workDir, stdout) {
36
38
  const file = path.relative(workDir, line.slice(0, sep));
37
39
  const lineNum = line.slice(sep + 1, sep2);
38
40
  let text = line.slice(sep2 + 1);
39
- if (text.length > MAX_LINE_LENGTH) text = `${text.slice(0, MAX_LINE_LENGTH)}...`;
41
+ if (text.length > 2e3) text = `${text.slice(0, MAX_LINE_LENGTH)}...`;
40
42
  const entries = byFile.get(file) ?? [];
41
43
  entries.push(` Line ${lineNum}: ${text}`);
42
44
  byFile.set(file, entries);
@@ -53,17 +55,17 @@ function formatExecError(err) {
53
55
  const e = err;
54
56
  return `Exit code ${e.code}\n${`${e.stdout}\n${e.stderr}`.trim()}`;
55
57
  }
56
- return `Error: ${err instanceof Error ? err.message : String(err)}`;
58
+ return `Error: ${errorMessage(err)}`;
57
59
  }
58
60
  function truncateOutput(output) {
59
61
  if (!output) return "(no output)";
60
- if (output.length > MAX_OUTPUT_BYTES) return `${output.slice(0, MAX_OUTPUT_BYTES)}\n...(truncated, ${output.length} bytes total)`;
62
+ if (output.length > 51200) return `${output.slice(0, MAX_OUTPUT_BYTES)}\n...(truncated, ${output.length} bytes total)`;
61
63
  return output;
62
64
  }
63
65
  function readFileWithLineNumbers(content, offset, limit) {
64
66
  const allLines = content.split("\n");
65
67
  const startLine = Math.max(1, offset ?? 1);
66
- const maxLines = limit ?? MAX_READ_LINES;
68
+ const maxLines = limit ?? 2e3;
67
69
  const endLine = Math.min(allLines.length, startLine + maxLines - 1);
68
70
  const lines = allLines.slice(startLine - 1, endLine);
69
71
  let output = "";
@@ -71,9 +73,9 @@ function readFileWithLineNumbers(content, offset, limit) {
71
73
  let truncatedByBytes = false;
72
74
  for (let i = 0; i < lines.length; i++) {
73
75
  const raw = lines[i] ?? "";
74
- const text = raw.length > MAX_LINE_LENGTH ? `${raw.slice(0, MAX_LINE_LENGTH)}... (truncated)` : raw;
76
+ const text = raw.length > 2e3 ? `${raw.slice(0, MAX_LINE_LENGTH)}... (truncated)` : raw;
75
77
  const numbered = `${startLine + i}: ${text}\n`;
76
- if (bytes + numbered.length > MAX_OUTPUT_BYTES) {
78
+ if (bytes + numbered.length > 51200) {
77
79
  truncatedByBytes = true;
78
80
  break;
79
81
  }
@@ -188,7 +190,7 @@ function makeSearchTools(workDir) {
188
190
  return files.join("\n") + truncated;
189
191
  } catch (err) {
190
192
  if (isRgNoMatch(err)) return "No files found matching pattern.";
191
- return `Error running glob: ${err instanceof Error ? err.message : String(err)}`;
193
+ return `Error running glob: ${errorMessage(err)}`;
192
194
  }
193
195
  }
194
196
  },
@@ -220,7 +222,7 @@ function makeSearchTools(workDir) {
220
222
  return formatGrepOutput(workDir, stdout);
221
223
  } catch (err) {
222
224
  if (isRgNoMatch(err)) return "No matches found.";
223
- return `Error running grep: ${err instanceof Error ? err.message : String(err)}`;
225
+ return `Error running grep: ${errorMessage(err)}`;
224
226
  }
225
227
  }
226
228
  },
@@ -304,9 +306,9 @@ const SYSTEM_PROMPT = `You are a pragmatic, expert coding agent that builds voic
304
306
  function toolLabel(name, input) {
305
307
  const icon = TOOL_ICONS[name] ?? "•";
306
308
  const file = input.filePath ?? input.path ?? input.pattern ?? "";
307
- if (name === "bash") return `${icon} ${colorize("cyanBright", name)} ${colorize("dim", String(input.command ?? "").slice(0, 60))}`;
308
- if (file) return `${icon} ${colorize("cyanBright", name)} ${file}`;
309
- return `${icon} ${colorize("cyanBright", name)}`;
309
+ if (name === "bash") return `${icon} ${name} ${String(input.command ?? "").slice(0, 60)}`;
310
+ if (file) return `${icon} ${name} ${file}`;
311
+ return `${icon} ${name}`;
310
312
  }
311
313
  function formatDuration(ms) {
312
314
  if (ms < 1) return "<1ms";
@@ -314,23 +316,16 @@ function formatDuration(ms) {
314
316
  return `${(ms / 1e3).toFixed(1)}s`;
315
317
  }
316
318
  function printCode(filePath, content) {
317
- const lang = path.extname(filePath).slice(1) || "text";
318
319
  const lines = content.split("\n");
319
320
  const maxLines = 40;
320
321
  const truncated = lines.length > maxLines;
321
- const shown = truncated ? lines.slice(0, maxLines) : lines;
322
- console.log(colorize("dim", ` ┌── ${filePath} (${lang})`));
323
- for (const line of shown) console.log(colorize("dim", ` │ ${line}`));
324
- if (truncated) console.log(colorize("dim", ` │ ... (${lines.length - maxLines} more lines)`));
325
- console.log(colorize("dim", " └──"));
326
- }
327
- function printBox(text) {
328
- const lines = text.split("\n");
329
- return [
330
- colorize("dim", " ┌──"),
331
- ...lines.map((line) => colorize("dim", ` │ ${line}`)),
332
- colorize("dim", " └──")
333
- ].join("\n");
322
+ const shown = truncated ? lines.slice(0, maxLines).join("\n") : content;
323
+ const suffix = truncated ? `\n... (${lines.length - maxLines} more lines)` : "";
324
+ consola$1.box({
325
+ title: filePath,
326
+ message: shown + suffix,
327
+ style: { borderColor: "dim" }
328
+ });
334
329
  }
335
330
  function maybeShowCode(toolName, input) {
336
331
  if ((toolName === "write" || toolName === "edit") && input) {
@@ -374,18 +369,18 @@ async function runGenerateCommand(opts) {
374
369
  const input = toolCall.input;
375
370
  const label = toolLabel(toolCall.toolName, input ?? {});
376
371
  const time = formatDuration(durationMs);
377
- const ok = "success" in rest && rest.success;
378
- const mark = ok ? colorize("greenBright", "✔") : colorize("redBright", "✖");
379
- console.log(`${mark} ${label} ${colorize("dim", time)}`);
380
- if (ok) maybeShowCode(toolCall.toolName, input);
372
+ if ("success" in rest && rest.success) {
373
+ consola$1.success(`${label} ${time}`);
374
+ maybeShowCode(toolCall.toolName, input);
375
+ } else consola$1.fail(`${label} ${time}`);
381
376
  },
382
377
  onStepFinish: ({ finishReason, text }) => {
383
- if (finishReason === "stop" && text) console.log(printBox(text));
378
+ if (finishReason === "stop" && text) consola$1.box(text);
384
379
  }
385
380
  });
386
- consola$1.success(`Done ${colorize("dim", `(${result.steps.length} steps, ${result.usage.totalTokens} tokens)`)}`);
381
+ consola$1.success(`Done (${result.steps.length} steps, ${result.usage.totalTokens} tokens)`);
387
382
  } catch (err) {
388
- consola$1.error(err instanceof Error ? err.message : String(err));
383
+ consola$1.error(errorMessage(err));
389
384
  process.exitCode = 1;
390
385
  }
391
386
  }