@alexkroman1/aai-cli 0.12.3 → 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.
@@ -1,30 +0,0 @@
1
- #!/usr/bin/env node
2
- import * as p from "@clack/prompts";
3
- import { colorize } from "consola/utils";
4
- //#region _ui.ts
5
- /**
6
- * Unified CLI output using @clack/prompts style (◐ ◇ │).
7
- *
8
- * All commands should use these helpers instead of consola directly
9
- * so the output is visually consistent.
10
- */
11
- const log = {
12
- step: (msg) => p.log.step(msg),
13
- success: (msg) => p.log.success(msg),
14
- info: (msg) => p.log.info(msg),
15
- warn: (msg) => p.log.warn(msg),
16
- error: (msg) => p.log.error(msg),
17
- message: (msg) => p.log.message(msg)
18
- };
19
- /** Format a URL for display. */
20
- function fmtUrl(url) {
21
- return colorize("cyanBright", url);
22
- }
23
- /** Parse and validate a port string. Returns the numeric port or throws. */
24
- function parsePort(raw) {
25
- const port = Number.parseInt(raw, 10);
26
- if (Number.isNaN(port) || port < 0 || port > 65535) throw new Error(`Invalid port: ${raw}. Must be a number between 0 and 65535.`);
27
- return port;
28
- }
29
- //#endregion
30
- export { fmtUrl, log, parsePort };
@@ -1,34 +0,0 @@
1
- #!/usr/bin/env node
2
- import { a as getServerInfo } from "./_discover-DzsMlg3G.mjs";
3
- import { log } from "./_ui-DWGXImbO.mjs";
4
- import { n as apiError, r as apiRequest, t as HINT_INVALID_API_KEY } from "./_api-client-H4MFOr8j.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
- log.step(`Deleting ${slug}`);
26
- await runDelete({
27
- url: serverUrl,
28
- slug,
29
- apiKey
30
- });
31
- log.success(`Deleted ${serverUrl}/${slug}`);
32
- }
33
- //#endregion
34
- export { runDeleteCommand };
@@ -1,53 +0,0 @@
1
- #!/usr/bin/env node
2
- import { i as getApiKey, l as resolveServerUrl, s as readProjectConfig, u as writeProjectConfig } from "./_discover-DzsMlg3G.mjs";
3
- import { buildAgentBundle } from "./_bundler-DQtFVeww.mjs";
4
- import { fmtUrl, log } from "./_ui-DWGXImbO.mjs";
5
- import { n as apiError, r as apiRequest, t as HINT_INVALID_API_KEY } from "./_api-client-H4MFOr8j.mjs";
6
- //#region _deploy.ts
7
- async function runDeploy(opts) {
8
- const fetchFn = opts.fetch ?? globalThis.fetch.bind(globalThis);
9
- const body = JSON.stringify({
10
- ...opts.slug ? { slug: opts.slug } : {},
11
- env: opts.env,
12
- worker: opts.bundle.worker,
13
- clientFiles: opts.bundle.clientFiles
14
- });
15
- const resp = await apiRequest(`${opts.url}/deploy`, {
16
- method: "POST",
17
- body,
18
- apiKey: opts.apiKey,
19
- action: "deploy"
20
- }, fetchFn);
21
- if (resp.ok) return { slug: (await resp.json()).slug };
22
- const text = await resp.text();
23
- let hint;
24
- if (resp.status === 401) hint = HINT_INVALID_API_KEY;
25
- else if (resp.status === 413) hint = "Your bundle is too large. Try reducing dependencies or splitting your agent.";
26
- throw new Error(apiError("deploy", resp.status, text, hint).message);
27
- }
28
- //#endregion
29
- //#region deploy.ts
30
- async function runDeployCommand(opts) {
31
- const { cwd } = opts;
32
- const apiKey = await getApiKey();
33
- const projectConfig = await readProjectConfig(cwd);
34
- const serverUrl = resolveServerUrl(opts.server, projectConfig?.serverUrl);
35
- const bundle = await buildAgentBundle(cwd);
36
- const slug = projectConfig?.slug;
37
- log.step(`Deploying${slug ? ` ${slug}` : ""}…`);
38
- const deployed = await runDeploy({
39
- url: serverUrl,
40
- bundle,
41
- env: { ASSEMBLYAI_API_KEY: apiKey },
42
- ...slug ? { slug } : {},
43
- apiKey
44
- });
45
- await writeProjectConfig(cwd, {
46
- slug: deployed.slug,
47
- serverUrl
48
- });
49
- const agentUrl = `${serverUrl}/${deployed.slug}`;
50
- log.success(`Deployed ${fmtUrl(agentUrl)}`);
51
- }
52
- //#endregion
53
- export { runDeployCommand };
@@ -1,18 +0,0 @@
1
- #!/usr/bin/env node
2
- import { fmtUrl, log, parsePort } from "./_ui-DWGXImbO.mjs";
3
- import path from "node:path";
4
- import { createServer } from "vite";
5
- import { colorize } from "consola/utils";
6
- //#region dev.ts
7
- async function runDevCommand(opts) {
8
- const port = parsePort(opts.port);
9
- const agentName = path.basename(path.resolve(opts.cwd));
10
- await (await createServer({
11
- root: opts.cwd,
12
- server: { port }
13
- })).listen();
14
- log.success(`${colorize("bold", agentName)} running at ${fmtUrl(`http://localhost:${port}`)}`);
15
- log.info("Press Ctrl-C to stop");
16
- }
17
- //#endregion
18
- export { runDevCommand };
@@ -1,114 +0,0 @@
1
- #!/usr/bin/env node
2
- import { c as resolveCwd, n as ensureApiKeyInEnv, r as fileExists } from "./_discover-DzsMlg3G.mjs";
3
- import { n as listTemplates } from "./_templates-BDkbj3TM.mjs";
4
- import { log } from "./_ui-DWGXImbO.mjs";
5
- import path from "node:path";
6
- import fs from "node:fs/promises";
7
- import { errorMessage } from "@alexkroman1/aai/utils";
8
- import * as p from "@clack/prompts";
9
- import { colorize } from "consola/utils";
10
- import { execFile } from "node:child_process";
11
- import { promisify } from "node:util";
12
- //#region init.ts
13
- const execFileAsync = promisify(execFile);
14
- const DEFAULT_PROJECT_NAME = "my-voice-agent";
15
- const DEFAULT_TEMPLATE = "simple";
16
- /** Prompt for project name or return default when --yes is set. */
17
- async function promptProjectName(yes) {
18
- if (yes) return DEFAULT_PROJECT_NAME;
19
- const result = await p.text({
20
- message: "What is your project named?",
21
- placeholder: DEFAULT_PROJECT_NAME,
22
- defaultValue: DEFAULT_PROJECT_NAME
23
- });
24
- if (p.isCancel(result)) {
25
- p.cancel("Setup cancelled");
26
- process.exit(0);
27
- }
28
- return result || DEFAULT_PROJECT_NAME;
29
- }
30
- /** Prompt for template selection or return default when --yes is set. */
31
- async function promptTemplate(yes) {
32
- if (yes) return DEFAULT_TEMPLATE;
33
- const templates = await listTemplates();
34
- const result = await p.select({
35
- message: "Which template would you like to use?",
36
- options: templates.map((t) => ({
37
- value: t.name,
38
- label: t.name,
39
- hint: t.description
40
- })),
41
- initialValue: DEFAULT_TEMPLATE
42
- });
43
- if (p.isCancel(result)) {
44
- p.cancel("Setup cancelled");
45
- process.exit(0);
46
- }
47
- return result;
48
- }
49
- /** Enable corepack so pnpm is available (scaffold declares packageManager: pnpm). */
50
- async function ensurePnpm() {
51
- try {
52
- await execFileAsync("corepack", ["enable"]);
53
- } catch {}
54
- }
55
- /** Install deps with pnpm (scaffold declares packageManager: pnpm). */
56
- async function installDeps(cwd) {
57
- if (await fileExists(path.join(cwd, "node_modules"))) return;
58
- let pkgJson;
59
- try {
60
- pkgJson = JSON.parse(await fs.readFile(path.join(cwd, "package.json"), "utf-8"));
61
- } catch {
62
- pkgJson = {};
63
- }
64
- const deps = Object.keys(pkgJson.dependencies ?? {});
65
- const devDeps = Object.keys(pkgJson.devDependencies ?? {});
66
- if (deps.length === 0 && devDeps.length === 0) return;
67
- await ensurePnpm();
68
- const s = p.spinner();
69
- s.start("Installing dependencies with pnpm");
70
- try {
71
- await execFileAsync("pnpm", ["install", "--ignore-workspace"], { cwd });
72
- s.stop("Dependencies installed");
73
- } catch (err) {
74
- const msg = errorMessage(err);
75
- s.stop("Dependency install failed");
76
- log.warn(`pnpm install failed: ${msg}`);
77
- log.warn("Run `corepack enable && pnpm install` manually in the project directory.");
78
- }
79
- }
80
- /** Format the dev command for the "Next steps" note. */
81
- function devCommand() {
82
- return "aai dev";
83
- }
84
- async function runInitCommand(opts, extra) {
85
- if (!extra?.quiet) p.intro(colorize("cyanBright", "Create a new voice agent"));
86
- if (!opts.skipApi) await ensureApiKeyInEnv();
87
- const dir = opts.dir ?? await promptProjectName(opts.yes);
88
- const cwd = path.resolve(resolveCwd(), dir);
89
- if (!opts.force && await fileExists(path.join(cwd, "agent.ts"))) throw new Error(`agent.ts already exists in this directory. Use ${colorize("cyanBright", "--force")} to overwrite.`);
90
- const template = opts.template ?? await promptTemplate(opts.yes);
91
- const s = p.spinner();
92
- s.start(`Creating ${dir} from ${template} template`);
93
- const { runInit } = await import("./_init-CbMs9S2O.mjs");
94
- await runInit({
95
- targetDir: cwd,
96
- template
97
- });
98
- s.stop("Project created");
99
- await installDeps(cwd);
100
- if (!(opts.skipDeploy || extra?.quiet)) {
101
- const { runDeployCommand } = await import("./deploy-CLs8gLHV.mjs");
102
- await runDeployCommand({
103
- cwd,
104
- ...opts.server ? { server: opts.server } : {}
105
- });
106
- }
107
- if (!extra?.quiet) {
108
- log.success(`Created ${dir}`);
109
- log.info(`Next: cd ${dir} && ${devCommand()}`);
110
- }
111
- return cwd;
112
- }
113
- //#endregion
114
- export { runInitCommand };
@@ -1,46 +0,0 @@
1
- #!/usr/bin/env node
2
- import { a as getServerInfo, d as askPassword } from "./_discover-DzsMlg3G.mjs";
3
- import { log } from "./_ui-DWGXImbO.mjs";
4
- import { n as apiError, r as apiRequest, t as HINT_INVALID_API_KEY } from "./_api-client-H4MFOr8j.mjs";
5
- //#region secret.ts
6
- async function secretRequest(cwd, pathSuffix, init, server) {
7
- const { serverUrl, slug, apiKey } = await getServerInfo(cwd, server);
8
- const resp = await apiRequest(`${serverUrl}/${slug}/secret${pathSuffix}`, {
9
- ...init,
10
- apiKey,
11
- action: "secret"
12
- });
13
- if (!resp.ok) {
14
- const text = await resp.text();
15
- const hint = resp.status === 401 ? HINT_INVALID_API_KEY : void 0;
16
- throw apiError("secret", resp.status, text, hint);
17
- }
18
- return {
19
- resp,
20
- slug
21
- };
22
- }
23
- async function runSecretPut(cwd, name, server) {
24
- const value = await askPassword(`Enter value for ${name}`);
25
- if (!value) throw new Error("No value provided");
26
- const { slug } = await secretRequest(cwd, "", {
27
- method: "PUT",
28
- body: JSON.stringify({ [name]: value })
29
- }, server);
30
- log.success(`Set ${name} for ${slug}`);
31
- }
32
- async function runSecretDelete(cwd, name, server) {
33
- const { slug } = await secretRequest(cwd, `/${name}`, { method: "DELETE" }, server);
34
- log.success(`Deleted ${name} from ${slug}`);
35
- }
36
- async function runSecretList(cwd, server) {
37
- const { resp } = await secretRequest(cwd, "", void 0, server);
38
- const { vars } = await resp.json();
39
- if (vars.length === 0) log.info("No secrets set. Use `aai secret put <name>` to add one.");
40
- else {
41
- log.message(`${vars.length} secret${vars.length === 1 ? "" : "s"}:`);
42
- for (const name of vars) log.message(` ${name}`);
43
- }
44
- }
45
- //#endregion
46
- export { runSecretDelete, runSecretList, runSecretPut };
@@ -1,44 +0,0 @@
1
- #!/usr/bin/env node
2
- import { log } from "./_ui-DWGXImbO.mjs";
3
- import { existsSync } from "node:fs";
4
- import path from "node:path";
5
- import { execFileSync } from "node:child_process";
6
- //#region test.ts
7
- /**
8
- * `aai test` — run agent tests via vitest.
9
- */
10
- /**
11
- * Run vitest in the given project directory.
12
- *
13
- * Returns `true` if tests passed, `false` if no test files exist.
14
- * Throws on test failure.
15
- */
16
- function runVitest(cwd) {
17
- if (!(existsSync(path.join(cwd, "agent.test.ts")) || existsSync(path.join(cwd, "agent.test.js")))) return false;
18
- execFileSync("npx", [
19
- "vitest",
20
- "run",
21
- "--root",
22
- ".",
23
- existsSync(path.join(cwd, "agent.test.ts")) ? "agent.test.ts" : "agent.test.js"
24
- ], {
25
- cwd,
26
- stdio: "inherit",
27
- env: {
28
- ...process.env,
29
- NODE_OPTIONS: "--experimental-strip-types"
30
- }
31
- });
32
- return true;
33
- }
34
- /** Run agent tests. Used by `aai test`. */
35
- async function runTestCommand(cwd) {
36
- log.step("Running agent tests");
37
- if (!runVitest(cwd)) {
38
- log.info("No test file found. Create agent.test.ts to add tests.");
39
- return;
40
- }
41
- log.success("Tests passed");
42
- }
43
- //#endregion
44
- export { runTestCommand, runVitest };