@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/_api-client-Br1a_Dsp.mjs +36 -0
- package/dist/_bundler-BM-vnJUp.mjs +117 -0
- package/dist/{_discover-D7HCLa_N.mjs → _discover-DiRl7b_K.mjs} +51 -28
- package/dist/_init-CVkKf8t_.mjs +56 -0
- package/dist/_templates-s5MYfWS9.mjs +63 -0
- package/dist/_ui-Cu-v_Bzz.mjs +13 -0
- package/dist/cli.mjs +49 -191
- package/dist/delete-CSPF9vdh.mjs +34 -0
- package/dist/deploy-C2s4C_ff.mjs +92 -0
- package/dist/dev-CBKWhwaQ.mjs +20 -0
- package/dist/{generate-D7zJtqoC.mjs → generate-DQt7C4zz.mjs} +33 -38
- package/dist/init-BAYELcXE.mjs +112 -0
- package/dist/secret-CRLbxN5P.mjs +44 -0
- package/dist/{test-9fFn9DCf.mjs → test-CuMTKw38.mjs} +8 -10
- package/package.json +8 -13
- package/dist/_build-aW_zyPpr.mjs +0 -176
- package/dist/_init-CweK2mJJ.mjs +0 -108
- package/dist/_link-D6mmDQ0B.mjs +0 -49
- package/dist/_server-common-B6EXxxB2.mjs +0 -105
- package/dist/_ui-C9IvR7Fh.mjs +0 -50
- package/dist/delete-DxECFYOp.mjs +0 -40
- package/dist/deploy-DB0PeNtc.mjs +0 -90
- package/dist/dev-DCtHG1pz.mjs +0 -60
- package/dist/doctor-bWuArZi6.mjs +0 -215
- package/dist/init-COkINbH_.mjs +0 -61
- package/dist/rag-BNfrEr4A.mjs +0 -178
- package/dist/secret-Zzv7fJ_3.mjs +0 -50
- package/dist/start-DQypQkOq.mjs +0 -23
package/dist/cli.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { l as resolveCwd, n as
|
|
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-
|
|
39
|
-
|
|
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-
|
|
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
|
-
|
|
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 =
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
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 =
|
|
126
|
-
const { runTestCommand } = await import("./test-
|
|
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 =
|
|
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-
|
|
140
|
+
const { runVitest } = await import("./test-CuMTKw38.mjs");
|
|
151
141
|
runVitest(cwd);
|
|
152
142
|
}
|
|
153
|
-
const { runBuildCommand } = await import("./
|
|
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 =
|
|
180
|
-
await
|
|
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 =
|
|
201
|
-
const { runDeleteCommand } = await import("./delete-
|
|
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 =
|
|
254
|
-
await
|
|
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 =
|
|
271
|
-
await
|
|
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 =
|
|
283
|
-
await
|
|
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 =
|
|
361
|
-
await
|
|
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
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
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-
|
|
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 {
|
|
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 {
|
|
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 >
|
|
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: ${
|
|
58
|
+
return `Error: ${errorMessage(err)}`;
|
|
57
59
|
}
|
|
58
60
|
function truncateOutput(output) {
|
|
59
61
|
if (!output) return "(no output)";
|
|
60
|
-
if (output.length >
|
|
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 ??
|
|
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 >
|
|
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 >
|
|
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: ${
|
|
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: ${
|
|
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} ${
|
|
308
|
-
if (file) return `${icon} ${
|
|
309
|
-
return `${icon} ${
|
|
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) :
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
}
|
|
327
|
-
|
|
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
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
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)
|
|
378
|
+
if (finishReason === "stop" && text) consola$1.box(text);
|
|
384
379
|
}
|
|
385
380
|
});
|
|
386
|
-
consola$1.success(`Done
|
|
381
|
+
consola$1.success(`Done (${result.steps.length} steps, ${result.usage.totalTokens} tokens)`);
|
|
387
382
|
} catch (err) {
|
|
388
|
-
consola$1.error(
|
|
383
|
+
consola$1.error(errorMessage(err));
|
|
389
384
|
process.exitCode = 1;
|
|
390
385
|
}
|
|
391
386
|
}
|