@alexkroman1/aai-cli 0.12.2 → 1.0.2

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,40 @@
1
+ #!/usr/bin/env node
2
+ import { t as __exportAll } from "./rolldown-runtime-DacLjcLf.mjs";
3
+ import { log } from "@clack/prompts";
4
+ import { colorize } from "consola/utils";
5
+ //#region _ui.ts
6
+ var _ui_exports = /* @__PURE__ */ __exportAll({
7
+ fmtUrl: () => fmtUrl,
8
+ log: () => log$1,
9
+ parsePort: () => parsePort,
10
+ silenceOutput: () => silenceOutput
11
+ });
12
+ const noop = () => {};
13
+ let _delegate = log;
14
+ /** Log instance that delegates to clack (human mode) or no-ops (JSON mode). */
15
+ const log$1 = new Proxy(log, { get(_target, prop, receiver) {
16
+ return Reflect.get(_delegate, prop, receiver);
17
+ } });
18
+ /** Replace all log methods with no-ops. Call once in JSON mode. */
19
+ function silenceOutput() {
20
+ _delegate = {
21
+ info: noop,
22
+ success: noop,
23
+ error: noop,
24
+ warn: noop,
25
+ step: noop,
26
+ message: noop
27
+ };
28
+ }
29
+ /** Format a URL for display. */
30
+ function fmtUrl(url) {
31
+ return colorize("cyanBright", url);
32
+ }
33
+ /** Parse and validate a port string. Returns the numeric port or throws. */
34
+ function parsePort(raw) {
35
+ const port = Number.parseInt(raw, 10);
36
+ if (Number.isNaN(port) || port < 0 || port > 65535) throw new Error(`Invalid port: ${raw}. Must be a number between 0 and 65535.`);
37
+ return port;
38
+ }
39
+ //#endregion
40
+ export { silenceOutput as a, parsePort as i, fmtUrl as n, log$1 as r, _ui_exports as t };
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env node
2
+ import fs from "node:fs/promises";
3
+ import { consola } from "consola";
4
+ //#region _utils.ts
5
+ /** Resolve the working directory from INIT_CWD or process.cwd(). */
6
+ function resolveCwd() {
7
+ return process.env.INIT_CWD || process.cwd();
8
+ }
9
+ /** Validate that a module's default export is a valid agent definition. Throws if invalid. */
10
+ function validateAgentExport(mod) {
11
+ if (!mod?.name || typeof mod.name !== "string") throw new Error("agent.ts must export default agent({ name: ... })");
12
+ }
13
+ async function fileExists(p) {
14
+ try {
15
+ await fs.access(p);
16
+ return true;
17
+ } catch (error) {
18
+ consola.debug(`File access check failed for ${p}:`, error);
19
+ return false;
20
+ }
21
+ }
22
+ //#endregion
23
+ export { resolveCwd as n, validateAgentExport as r, fileExists as t };
package/dist/cli.mjs CHANGED
@@ -1,8 +1,11 @@
1
1
  #!/usr/bin/env node
2
- import { l as resolveCwd, n as ensureApiKeyInEnv, r as fileExists } from "./_discover-a8yIuqEp.mjs";
3
- import { readFileSync } from "node:fs";
2
+ import { i as getOutputMode, r as fail, t as CliError } from "./_output-BKdAJaM5.mjs";
3
+ import { a as silenceOutput } from "./_ui-r2t6_2eP.mjs";
4
+ import { n as resolveCwd, t as fileExists } from "./_utils-DZo3_J_v.mjs";
5
+ import { existsSync, readFileSync } from "node:fs";
4
6
  import path from "node:path";
5
7
  import { fileURLToPath } from "node:url";
8
+ import { errorMessage } from "@alexkroman1/aai";
6
9
  import { defineCommand, runMain } from "citty";
7
10
  //#region cli.ts
8
11
  /** Shared arg definitions for citty commands. */
@@ -22,6 +25,10 @@ const sharedArgs = {
22
25
  type: "boolean",
23
26
  alias: "y",
24
27
  description: "Accept defaults (no prompts)"
28
+ },
29
+ json: {
30
+ type: "boolean",
31
+ description: "Output JSON (auto-detected in non-TTY)"
25
32
  }
26
33
  };
27
34
  const cliDir = path.dirname(fileURLToPath(import.meta.url));
@@ -33,30 +40,44 @@ function findPkgJson(dir) {
33
40
  }
34
41
  }
35
42
  const VERSION = JSON.parse(findPkgJson(cliDir)).version;
36
- async function ensureAgent(cwd, yes) {
37
- if (!await fileExists(path.join(cwd, "agent.ts"))) {
38
- const { runInitCommand } = await import("./init-BYX6pxjd.mjs");
39
- return runInitCommand({ yes }, { quiet: true });
43
+ /** Shared command setup: resolve cwd, optionally require agent.ts. */
44
+ async function setup(opts) {
45
+ const cwd = resolveCwd();
46
+ if (opts?.agent) {
47
+ if (!await fileExists(path.join(cwd, "agent.ts"))) throw new Error("No agent.ts found in the current directory. Run `aai init` first.");
40
48
  }
41
49
  return cwd;
42
50
  }
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;
49
- }
50
51
  /** Catch command errors and display a clean message instead of a raw stack trace. */
51
- async function handleErrors(fn) {
52
+ async function handleErrors(mode, fn) {
52
53
  try {
53
54
  await fn();
54
55
  } catch (err) {
55
- const { log } = await import("./_ui-DWGXImbO.mjs");
56
- log.error(err instanceof Error ? err.message : String(err));
56
+ const code = err instanceof CliError ? err.code : "command_failed";
57
+ const hint = err instanceof CliError ? err.hint : void 0;
58
+ if (mode === "json") {
59
+ const result = fail(code, errorMessage(err), hint);
60
+ process.stdout.write(`${JSON.stringify(result)}\n`);
61
+ process.exit(1);
62
+ }
63
+ const { log } = await import("./_ui-r2t6_2eP.mjs").then((n) => n.t);
64
+ log.error(errorMessage(err));
57
65
  process.exit(1);
58
66
  }
59
67
  }
68
+ /**
69
+ * Run a command body with standard error handling, output mode resolution, and withOutput wrapping.
70
+ * `setYes` controls whether json mode sets `args.yes = true` (default true for most commands).
71
+ */
72
+ async function runCommand(args, fn, opts = {}) {
73
+ const mode = getOutputMode(args);
74
+ if (mode === "json") {
75
+ silenceOutput();
76
+ if (opts.setYes !== false) args.yes = true;
77
+ }
78
+ const { withOutput } = await import("./_output-BKdAJaM5.mjs").then((n) => n.n);
79
+ await handleErrors(mode, () => withOutput(mode, () => fn(mode), () => {}));
80
+ }
60
81
  const init = defineCommand({
61
82
  meta: {
62
83
  name: "init",
@@ -68,18 +89,19 @@ const init = defineCommand({
68
89
  description: "Project directory",
69
90
  required: false
70
91
  },
71
- template: {
72
- type: "string",
73
- alias: "t",
74
- description: "Template to use"
75
- },
76
92
  force: {
77
93
  type: "boolean",
78
94
  alias: "f",
79
95
  description: "Overwrite existing files"
80
96
  },
97
+ template: {
98
+ type: "string",
99
+ alias: "t",
100
+ description: "Template to use (e.g. pizza-ordering)"
101
+ },
81
102
  server: sharedArgs.server,
82
103
  yes: sharedArgs.yes,
104
+ json: sharedArgs.json,
83
105
  skipApi: {
84
106
  type: "boolean",
85
107
  description: "Skip API key check"
@@ -90,17 +112,17 @@ const init = defineCommand({
90
112
  }
91
113
  },
92
114
  async run({ args }) {
93
- await handleErrors(async () => {
94
- const { runInitCommand } = await import("./init-BYX6pxjd.mjs");
95
- await runInitCommand({
115
+ await runCommand(args, async (mode) => {
116
+ const { executeInit } = await import("./init-DJQVk0Gw.mjs");
117
+ return executeInit({
96
118
  dir: args.dir,
97
- template: args.template,
98
119
  force: args.force,
120
+ template: args.template,
99
121
  yes: args.yes,
100
122
  skipApi: args.skipApi,
101
123
  skipDeploy: args.skipDeploy,
102
124
  server: args.server
103
- });
125
+ }, mode === "json" ? { silent: true } : void 0);
104
126
  });
105
127
  }
106
128
  });
@@ -112,16 +134,14 @@ const dev = defineCommand({
112
134
  args: {
113
135
  port: sharedArgs.port,
114
136
  server: sharedArgs.server,
115
- yes: sharedArgs.yes
137
+ yes: sharedArgs.yes,
138
+ json: sharedArgs.json
116
139
  },
117
140
  async run({ args }) {
118
- await handleErrors(async () => {
119
- const cwd = await setup(args, {
120
- agent: true,
121
- apiKey: true
122
- });
123
- const { runDevCommand } = await import("./dev-DEZKrw8v.mjs");
124
- await runDevCommand({
141
+ await runCommand(args, async () => {
142
+ const cwd = await setup({ agent: true });
143
+ const { executeDev } = await import("./dev-Wmola4F6.mjs");
144
+ return executeDev({
125
145
  cwd,
126
146
  port: args.port
127
147
  });
@@ -133,12 +153,13 @@ const test = defineCommand({
133
153
  name: "test",
134
154
  description: "Run agent tests"
135
155
  },
136
- async run() {
137
- await handleErrors(async () => {
156
+ args: { json: sharedArgs.json },
157
+ async run({ args }) {
158
+ await runCommand(args, async () => {
138
159
  const cwd = await setup();
139
- const { runTestCommand } = await import("./test-CYoqKJP0.mjs");
140
- await runTestCommand(cwd);
141
- });
160
+ const { executeTest } = await import("./test-DhQ4aznR.mjs");
161
+ return executeTest(cwd);
162
+ }, { setYes: false });
142
163
  }
143
164
  });
144
165
  const build = defineCommand({
@@ -149,20 +170,21 @@ const build = defineCommand({
149
170
  args: {
150
171
  server: sharedArgs.server,
151
172
  yes: sharedArgs.yes,
173
+ json: sharedArgs.json,
152
174
  skipTests: {
153
175
  type: "boolean",
154
176
  description: "Skip running tests before build"
155
177
  }
156
178
  },
157
179
  async run({ args }) {
158
- await handleErrors(async () => {
159
- const cwd = await setup(args, { agent: true });
180
+ await runCommand(args, async () => {
181
+ const cwd = await setup({ agent: true });
160
182
  if (!args.skipTests) {
161
- const { runVitest } = await import("./test-CYoqKJP0.mjs");
183
+ const { runVitest } = await import("./test-DhQ4aznR.mjs");
162
184
  runVitest(cwd);
163
185
  }
164
- const { runBuildCommand } = await import("./_bundler-2yKukgnU.mjs");
165
- await runBuildCommand(cwd);
186
+ const { executeBuild } = await import("./_bundler-DgRDzBzD.mjs");
187
+ return executeBuild(cwd);
166
188
  });
167
189
  }
168
190
  });
@@ -173,20 +195,16 @@ const deploy = defineCommand({
173
195
  },
174
196
  args: {
175
197
  server: sharedArgs.server,
176
- dryRun: {
177
- type: "boolean",
178
- description: "Validate and bundle without deploying"
179
- },
180
- yes: sharedArgs.yes
198
+ yes: sharedArgs.yes,
199
+ json: sharedArgs.json
181
200
  },
182
201
  async run({ args }) {
183
- await handleErrors(async () => {
184
- const cwd = await setup(args, { agent: true });
185
- const { runDeployCommand } = await import("./deploy-CnscqVZv.mjs");
186
- await runDeployCommand({
202
+ await runCommand(args, async () => {
203
+ const cwd = await setup({ agent: true });
204
+ const { executeDeploy } = await import("./deploy-CmY2AtML.mjs");
205
+ return executeDeploy({
187
206
  cwd,
188
- ...args.server ? { server: args.server } : {},
189
- ...args.dryRun ? { dryRun: args.dryRun } : {}
207
+ ...args.server ? { server: args.server } : {}
190
208
  });
191
209
  });
192
210
  }
@@ -196,16 +214,19 @@ const del = defineCommand({
196
214
  name: "delete",
197
215
  description: "Remove a deployed agent"
198
216
  },
199
- args: { server: sharedArgs.server },
217
+ args: {
218
+ server: sharedArgs.server,
219
+ json: sharedArgs.json
220
+ },
200
221
  async run({ args }) {
201
- await handleErrors(async () => {
222
+ await runCommand(args, async () => {
202
223
  const cwd = await setup();
203
- const { runDeleteCommand } = await import("./delete-BvRel3Tw.mjs");
204
- await runDeleteCommand({
224
+ const { executeDelete } = await import("./delete-CaiAsY1S.mjs");
225
+ return executeDelete({
205
226
  cwd,
206
227
  ...args.server ? { server: args.server } : {}
207
228
  });
208
- });
229
+ }, { setYes: false });
209
230
  }
210
231
  });
211
232
  const secret = defineCommand({
@@ -219,17 +240,27 @@ const secret = defineCommand({
219
240
  name: "put",
220
241
  description: "Create or update a secret"
221
242
  },
222
- args: { name: {
223
- type: "positional",
224
- description: "Secret name",
225
- required: true
226
- } },
243
+ args: {
244
+ name: {
245
+ type: "positional",
246
+ description: "Secret name",
247
+ required: true
248
+ },
249
+ server: sharedArgs.server,
250
+ json: sharedArgs.json
251
+ },
227
252
  async run({ args }) {
228
- await handleErrors(async () => {
229
- const cwd = await setup(void 0, { apiKey: true });
230
- const { runSecretPut } = await import("./secret-DLosn47q.mjs");
231
- await runSecretPut(cwd, args.name);
232
- });
253
+ await runCommand(args, async (mode) => {
254
+ const cwd = await setup();
255
+ const { executeSecretPut, readStdin } = await import("./secret-lSaf6Uax.mjs");
256
+ const value = mode === "json" ? await readStdin() : void 0;
257
+ if (mode === "json" && !value) {
258
+ const result = fail("no_input", "No value provided", "Pipe secret value to stdin");
259
+ process.stdout.write(`${JSON.stringify(result)}\n`);
260
+ process.exit(1);
261
+ }
262
+ return executeSecretPut(cwd, args.name, value, args.server);
263
+ }, { setYes: false });
233
264
  }
234
265
  }),
235
266
  delete: defineCommand({
@@ -237,17 +268,21 @@ const secret = defineCommand({
237
268
  name: "delete",
238
269
  description: "Delete a secret"
239
270
  },
240
- args: { name: {
241
- type: "positional",
242
- description: "Secret name",
243
- required: true
244
- } },
271
+ args: {
272
+ name: {
273
+ type: "positional",
274
+ description: "Secret name",
275
+ required: true
276
+ },
277
+ server: sharedArgs.server,
278
+ json: sharedArgs.json
279
+ },
245
280
  async run({ args }) {
246
- await handleErrors(async () => {
247
- const cwd = await setup(void 0, { apiKey: true });
248
- const { runSecretDelete } = await import("./secret-DLosn47q.mjs");
249
- await runSecretDelete(cwd, args.name);
250
- });
281
+ await runCommand(args, async () => {
282
+ const cwd = await setup();
283
+ const { executeSecretDelete } = await import("./secret-lSaf6Uax.mjs");
284
+ return executeSecretDelete(cwd, args.name, args.server);
285
+ }, { setYes: false });
251
286
  }
252
287
  }),
253
288
  list: defineCommand({
@@ -255,12 +290,16 @@ const secret = defineCommand({
255
290
  name: "list",
256
291
  description: "List all secrets"
257
292
  },
258
- async run() {
259
- await handleErrors(async () => {
260
- const cwd = await setup(void 0, { apiKey: true });
261
- const { runSecretList } = await import("./secret-DLosn47q.mjs");
262
- await runSecretList(cwd);
263
- });
293
+ args: {
294
+ server: sharedArgs.server,
295
+ json: sharedArgs.json
296
+ },
297
+ async run({ args }) {
298
+ await runCommand(args, async () => {
299
+ const cwd = await setup();
300
+ const { executeSecretList } = await import("./secret-lSaf6Uax.mjs");
301
+ return executeSecretList(cwd, args.server);
302
+ }, { setYes: false });
264
303
  }
265
304
  })
266
305
  }
@@ -289,8 +328,12 @@ if (process.env.VITEST !== "true") {
289
328
  "-h",
290
329
  "-V"
291
330
  ]);
292
- if (!sub || sub.startsWith("-") && !helpFlags.has(sub)) process.argv.splice(2, 0, "init");
293
- runMain(mainCommand);
331
+ if (!sub || sub.startsWith("-") && !helpFlags.has(sub)) {
332
+ const defaultCmd = existsSync(path.join(resolveCwd(), "agent.ts")) ? "deploy" : "init";
333
+ process.argv.splice(2, 0, defaultCmd);
334
+ }
335
+ const cmd = process.argv[2];
336
+ (helpFlags.has(cmd ?? "") || cmd === "test" || cmd === "build" ? Promise.resolve() : import("./_config-Dv-T6uRj.mjs").then((n) => n.t).then((m) => m.ensureApiKey())).then(() => runMain(mainCommand));
294
337
  }
295
338
  //#endregion
296
339
  export { mainCommand };
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env node
2
+ import { a as ok } from "./_output-BKdAJaM5.mjs";
3
+ import { r as log } from "./_ui-r2t6_2eP.mjs";
4
+ import { getServerInfo } from "./_agent-CzbSa09n.mjs";
5
+ import { t as apiRequestOrThrow } from "./_api-client-CFfjWfNa.mjs";
6
+ //#region _delete.ts
7
+ async function runDelete(opts) {
8
+ await apiRequestOrThrow(`${opts.url}/${opts.slug}`, {
9
+ method: "DELETE",
10
+ apiKey: opts.apiKey,
11
+ action: "delete"
12
+ }, {
13
+ hints: { 404: "The agent may not be deployed. Check `.aai/project.json` for the correct slug." },
14
+ fetch: opts.fetch
15
+ });
16
+ }
17
+ //#endregion
18
+ //#region delete.ts
19
+ /** Execute delete and return structured result. */
20
+ async function executeDelete(opts) {
21
+ const { cwd } = opts;
22
+ const { serverUrl, slug, apiKey } = await getServerInfo(cwd, opts.server);
23
+ log.step(`Deleting ${slug}`);
24
+ await runDelete({
25
+ url: serverUrl,
26
+ slug,
27
+ apiKey
28
+ });
29
+ log.success(`Deleted ${serverUrl}/${slug}`);
30
+ return ok({ slug });
31
+ }
32
+ //#endregion
33
+ export { executeDelete };
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env node
2
+ import { a as ok } from "./_output-BKdAJaM5.mjs";
3
+ import { n as fmtUrl, r as log } from "./_ui-r2t6_2eP.mjs";
4
+ import { i as writeProjectConfig, n as ensureApiKey, r as readProjectConfig } from "./_config-Dv-T6uRj.mjs";
5
+ import { resolveServerUrl } from "./_agent-CzbSa09n.mjs";
6
+ import { buildAgentBundle } from "./_bundler-DgRDzBzD.mjs";
7
+ import { t as resolveServerEnv } from "./_server-common-Pdb-KUSK.mjs";
8
+ import { t as apiRequestOrThrow } from "./_api-client-CFfjWfNa.mjs";
9
+ //#region _deploy.ts
10
+ async function runDeploy(opts) {
11
+ const body = JSON.stringify({
12
+ ...opts.slug ? { slug: opts.slug } : {},
13
+ env: opts.env,
14
+ worker: opts.bundle.worker,
15
+ clientFiles: opts.bundle.clientFiles,
16
+ agentConfig: opts.bundle.agentConfig
17
+ });
18
+ return { slug: (await (await apiRequestOrThrow(`${opts.url}/deploy`, {
19
+ method: "POST",
20
+ body,
21
+ apiKey: opts.apiKey,
22
+ action: "deploy"
23
+ }, {
24
+ hints: { 413: "Your bundle is too large. Try reducing dependencies or splitting your agent." },
25
+ fetch: opts.fetch
26
+ })).json()).slug };
27
+ }
28
+ //#endregion
29
+ //#region deploy.ts
30
+ async function executeDeploy(opts) {
31
+ const { cwd } = opts;
32
+ const projectConfig = await readProjectConfig(cwd);
33
+ const serverUrl = resolveServerUrl(opts.server, projectConfig?.serverUrl);
34
+ const bundle = await buildAgentBundle(cwd);
35
+ const slug = projectConfig?.slug;
36
+ const apiKey = await ensureApiKey();
37
+ const env = await resolveServerEnv(cwd);
38
+ log.step(`Deploying${slug ? ` ${slug}` : ""}…`);
39
+ const deployed = await runDeploy({
40
+ url: serverUrl,
41
+ bundle,
42
+ env: {
43
+ ...env,
44
+ ASSEMBLYAI_API_KEY: apiKey
45
+ },
46
+ ...slug ? { slug } : {},
47
+ apiKey
48
+ });
49
+ await writeProjectConfig(cwd, {
50
+ slug: deployed.slug,
51
+ serverUrl
52
+ });
53
+ const agentUrl = `${serverUrl}/${deployed.slug}`;
54
+ log.success(`Deployed ${fmtUrl(agentUrl)}`);
55
+ return ok({
56
+ slug: deployed.slug,
57
+ url: agentUrl
58
+ });
59
+ }
60
+ //#endregion
61
+ export { executeDeploy };
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env node
2
+ import { a as ok } from "./_output-BKdAJaM5.mjs";
3
+ import { i as parsePort, n as fmtUrl, r as log } from "./_ui-r2t6_2eP.mjs";
4
+ import path from "node:path";
5
+ import { colorize } from "consola/utils";
6
+ //#region dev.ts
7
+ /**
8
+ * Start the dev server and return the result.
9
+ * The process stays alive after this returns — caller handles signals.
10
+ */
11
+ async function executeDev(opts) {
12
+ const port = parsePort(opts.port);
13
+ const agentName = path.basename(path.resolve(opts.cwd));
14
+ const { startDevServer } = await import("./_dev-server-Cag4LlkI.mjs");
15
+ const cleanup = await startDevServer({
16
+ cwd: opts.cwd,
17
+ port
18
+ });
19
+ const url = `http://localhost:${port}`;
20
+ log.success(`${colorize("bold", agentName)} running at ${fmtUrl(url)}`);
21
+ log.info("Press Ctrl-C to stop");
22
+ const onSignal = () => {
23
+ cleanup().finally(() => process.exit(0));
24
+ };
25
+ process.on("SIGINT", onSignal);
26
+ process.on("SIGTERM", onSignal);
27
+ return ok({ url });
28
+ }
29
+ //#endregion
30
+ export { executeDev };