@alexkroman1/aai-cli 5.3.0 → 5.5.0

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.
Files changed (99) hide show
  1. package/README.md +51 -0
  2. package/dist/{_agent-D8zBb3M5.mjs → _agent-DMyOab9_.mjs} +2 -2
  3. package/dist/{_bundler-DFS4xxqE.mjs → _bundler-Cjaxa2wi.mjs} +1 -1
  4. package/dist/{_config-D3F9km8X.mjs → _config-5AEqhh-O.mjs} +2 -2
  5. package/dist/{_dev-server-BBUWo0sb.mjs → _dev-server-vV05Fnki.mjs} +3 -3
  6. package/dist/{_init-DU-sXH6S.mjs → _init-BZ9t_Kz-.mjs} +3 -56
  7. package/dist/{_slug-api-19R5kZ0U.mjs → _slug-api-DaqQJHk8.mjs} +1 -1
  8. package/dist/_templates-Bv8CR800.mjs +69 -0
  9. package/dist/_templates.d.ts +6 -0
  10. package/dist/{build-Xq1xxoSg.mjs → build-D_PgQOD4.mjs} +1 -1
  11. package/dist/cli.mjs +59 -17
  12. package/dist/{client-bundler-BWDkUeEP.mjs → client-bundler-yiWoXrgb.mjs} +3 -0
  13. package/dist/client-bundler.d.ts +9 -0
  14. package/dist/client-bundler.mjs +1 -1
  15. package/dist/{delete-kSXFLxek.mjs → delete-DXilFBb1.mjs} +1 -1
  16. package/dist/{deploy-Ci0X1gp2.mjs → deploy-1eaXcfUw.mjs} +3 -3
  17. package/dist/{dev-g7sGt8qX.mjs → dev-gVNdGFYY.mjs} +1 -1
  18. package/dist/{init-BjeK8crW.mjs → init-DoU4_txp.mjs} +3 -3
  19. package/dist/login-C59ZHzuO.mjs +109 -0
  20. package/dist/login.d.ts +34 -0
  21. package/dist/scaffold/CLAUDE.md +190 -120
  22. package/dist/scaffold/package.json +3 -3
  23. package/dist/{secret-DOva9OGk.mjs → secret-CGAIAbUx.mjs} +1 -1
  24. package/dist/{storage-vM6HjDZZ.mjs → storage-CnhOayhm.mjs} +1 -1
  25. package/dist/templates/code-interpreter/agent.ts +1 -2
  26. package/dist/templates/dispatch-center/agent.test.ts +3 -3
  27. package/dist/templates/dispatch-center/agent.ts +7 -7
  28. package/dist/templates/dispatch-center/client.tsx +7 -2
  29. package/dist/templates/dispatch-center/tools/incident_add_note.ts +1 -1
  30. package/dist/templates/dispatch-center/tools/incident_create.ts +1 -1
  31. package/dist/templates/dispatch-center/tools/incident_escalate.ts +1 -1
  32. package/dist/templates/dispatch-center/tools/incident_get.ts +1 -1
  33. package/dist/templates/dispatch-center/tools/incident_triage.ts +1 -1
  34. package/dist/templates/dispatch-center/tools/incident_update_status.ts +1 -1
  35. package/dist/templates/dispatch-center/tools/ops_protocols.ts +1 -1
  36. package/dist/templates/dispatch-center/tools/ops_run_scenario.ts +1 -1
  37. package/dist/templates/dispatch-center/tools/resources_dispatch.ts +1 -1
  38. package/dist/templates/dispatch-center/tools/resources_get_available.ts +1 -1
  39. package/dist/templates/dispatch-center/tools/resources_update_status.ts +1 -1
  40. package/dist/templates/embedded-assets/agent.ts +2 -3
  41. package/dist/templates/health-assistant/agent.ts +3 -4
  42. package/dist/templates/infocom-adventure/agent.ts +10 -12
  43. package/dist/templates/infocom-adventure/client.tsx +5 -5
  44. package/dist/templates/math-buddy/agent.ts +7 -6
  45. package/dist/templates/night-owl/agent.ts +2 -3
  46. package/dist/templates/personal-finance/agent.ts +1 -2
  47. package/dist/templates/pipeline-simple/agent.test.ts +13 -13
  48. package/dist/templates/pipeline-simple/agent.ts +5 -6
  49. package/dist/templates/pizza-ordering/agent.test.ts +13 -11
  50. package/dist/templates/pizza-ordering/agent.ts +5 -6
  51. package/dist/templates/retail/address.ts +29 -0
  52. package/dist/templates/retail/agent.test.ts +1030 -0
  53. package/dist/templates/retail/agent.ts +71 -0
  54. package/dist/templates/retail/authenticate.ts +34 -0
  55. package/dist/templates/retail/client.tsx +459 -0
  56. package/dist/templates/retail/refund.ts +19 -0
  57. package/dist/templates/retail/registry.test.ts +182 -0
  58. package/dist/templates/retail/resolve.test.ts +158 -0
  59. package/dist/templates/retail/resolve.ts +158 -0
  60. package/dist/templates/retail/seed.json +4260 -0
  61. package/dist/templates/retail/seed.test.ts +224 -0
  62. package/dist/templates/retail/shared.test.ts +192 -0
  63. package/dist/templates/retail/shared.ts +430 -0
  64. package/dist/templates/retail/store.test.ts +256 -0
  65. package/dist/templates/retail/store.ts +243 -0
  66. package/dist/templates/retail/swap.test.ts +186 -0
  67. package/dist/templates/retail/swap.ts +138 -0
  68. package/dist/templates/retail/system-prompt.md +111 -0
  69. package/dist/templates/retail/tools/cancel_pending_order.ts +82 -0
  70. package/dist/templates/retail/tools/exchange_delivered_order_items.ts +83 -0
  71. package/dist/templates/retail/tools/find_user_id_by_email.ts +32 -0
  72. package/dist/templates/retail/tools/find_user_id_by_name_zip.ts +38 -0
  73. package/dist/templates/retail/tools/get_item_details.ts +29 -0
  74. package/dist/templates/retail/tools/get_order_details.ts +41 -0
  75. package/dist/templates/retail/tools/get_product_details.ts +33 -0
  76. package/dist/templates/retail/tools/get_user_details.ts +44 -0
  77. package/dist/templates/retail/tools/list_all_product_types.ts +24 -0
  78. package/dist/templates/retail/tools/modify_pending_order_address.ts +46 -0
  79. package/dist/templates/retail/tools/modify_pending_order_items.ts +102 -0
  80. package/dist/templates/retail/tools/modify_pending_order_payment.ts +103 -0
  81. package/dist/templates/retail/tools/modify_user_address.ts +38 -0
  82. package/dist/templates/retail/tools/return_delivered_order_items.ts +101 -0
  83. package/dist/templates/retail/tools/transfer_to_human_agents.ts +22 -0
  84. package/dist/templates/simple/agent.test.ts +18 -0
  85. package/dist/templates/simple/agent.ts +3 -0
  86. package/dist/templates/solo-rpg/agent.test.ts +2 -2
  87. package/dist/templates/solo-rpg/agent.ts +1 -2
  88. package/dist/templates/solo-rpg/tools/action_roll.ts +1 -1
  89. package/dist/templates/solo-rpg/tools/load_game.ts +1 -1
  90. package/dist/templates/solo-rpg/tools/oracle.ts +1 -1
  91. package/dist/templates/solo-rpg/tools/save_game.ts +1 -1
  92. package/dist/templates/solo-rpg/tools/setup_character.ts +1 -1
  93. package/dist/templates/solo-rpg/tools/update_state.ts +1 -1
  94. package/dist/templates/web-researcher/agent.ts +1 -2
  95. package/dist/typecheck.d.ts +18 -0
  96. package/dist/typecheck.mjs +8 -0
  97. package/dist/worker-bundler.d.ts +9 -1
  98. package/dist/worker-bundler.mjs +8 -0
  99. package/package.json +3 -3
package/README.md ADDED
@@ -0,0 +1,51 @@
1
+ # @alexkroman1/aai-cli
2
+
3
+ The `aai` command — scaffold, run, test, and deploy aai voice agents.
4
+
5
+ ```sh
6
+ npm i -g @alexkroman1/aai-cli # or: npx @alexkroman1/aai-cli@latest
7
+ ```
8
+
9
+ ## Commands
10
+
11
+ | Command | What it does |
12
+ | --- | --- |
13
+ | `aai init [dir]` | Scaffold a new agent project (`--template <name>`, `--yes`) |
14
+ | `aai templates` | List the shipped project templates |
15
+ | `aai dev` | Local dev server: loads `agent.ts`, rebuilds on change, serves the browser client (`--port`) |
16
+ | `aai test` | Run the project's vitest suite |
17
+ | `aai build` | Bundle without deploying (type-checks first; `--skipTypecheck` opts out) |
18
+ | `aai deploy` | Bundle and deploy to the platform (uploads `.env` as agent secrets) |
19
+ | `aai delete` | Remove a deployed agent |
20
+ | `aai secret put\|delete\|list` | Manage a deployed agent's secrets |
21
+ | `aai storage status\|enable\|disable` | Manage the agent's opt-in SQL database (`ctx.db`) |
22
+
23
+ Every command accepts `--json` for machine-readable output (auto-detected
24
+ when stdout is not a TTY). `aai <command> --help` shows flags.
25
+
26
+ ## Typical flow
27
+
28
+ ```sh
29
+ aai init my-agent --template pizza-ordering
30
+ cd my-agent
31
+ # put ASSEMBLYAI_API_KEY=... in .env
32
+ aai dev # talk to it at the printed URL
33
+ aai deploy # ship it; .env values become the agent's secrets
34
+ ```
35
+
36
+ Deploys type-check the project, preflight required credentials (a missing
37
+ provider key fails the deploy instead of the first call), and print the
38
+ agent's public URL.
39
+
40
+ ## Notes
41
+
42
+ - A bare `aai` in a project directory offers to deploy (TTY-confirmed);
43
+ outside one it runs `init`.
44
+ - `--server <url>` targets a self-hosted platform; the origin is remembered
45
+ in your user config after explicit approval.
46
+ - The API key is stored `0600` in your user config dir (`AAI_CONFIG_DIR`
47
+ overrides the location).
48
+
49
+ ## Documentation
50
+
51
+ SDK API reference: <https://alexkroman.github.io/agent/>
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { a as serverOrigin, i as readProjectConfig, n as ensureApiKey, r as readGlobalConfig, t as approveServer } from "./_config-D3F9km8X.mjs";
2
+ import { a as readProjectConfig, i as readGlobalConfig, n as ensureApiKey, o as serverOrigin, t as approveServer } from "./_config-5AEqhh-O.mjs";
3
3
  import { existsSync } from "node:fs";
4
4
  import path from "node:path";
5
5
  import { fileURLToPath } from "node:url";
@@ -92,4 +92,4 @@ async function getServerInfo(cwd, explicitServer) {
92
92
  };
93
93
  }
94
94
  //#endregion
95
- export { resolveDeployTarget as i, getServerInfo as n, isDevMode as r, getMonorepoRoot as t };
95
+ export { resolveServerUrl as a, resolveDeployTarget as i, getServerInfo as n, isDevMode as r, getMonorepoRoot as t };
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { u as validateAgentExport } from "./_utils-Ch0J4s6a.mjs";
3
- import { t as buildClient } from "./client-bundler-BWDkUeEP.mjs";
3
+ import { t as buildClient } from "./client-bundler-yiWoXrgb.mjs";
4
4
  import { buildWorker } from "./worker-bundler.mjs";
5
5
  import path from "node:path";
6
6
  import { pathToFileURL } from "node:url";
@@ -115,10 +115,10 @@ async function ensureApiKey(configDir) {
115
115
  await trySaveApiKey(dir, config, envKey);
116
116
  return envKey;
117
117
  }
118
- if (!process.stdin.isTTY) throw new CliError("no_api_key", "No API key configured and no TTY to prompt for one.", "Set the ASSEMBLYAI_API_KEY environment variable, or run `aai` interactively once to save a key.");
118
+ if (!process.stdin.isTTY) throw new CliError("no_api_key", "No API key configured and no TTY to prompt for one.", "Set the ASSEMBLYAI_API_KEY environment variable, or run `aai login` interactively once to save a key.");
119
119
  const apiKey = unwrapCancel(await p.password({ message: "Enter your AssemblyAI API key" }), "Setup cancelled");
120
120
  await trySaveApiKey(dir, config, apiKey);
121
121
  return apiKey;
122
122
  }
123
123
  //#endregion
124
- export { serverOrigin as a, readProjectConfig as i, ensureApiKey as n, writeProjectConfig as o, readGlobalConfig as r, approveServer as t };
124
+ export { readProjectConfig as a, writeProjectConfig as c, readGlobalConfig as i, ensureApiKey as n, serverOrigin as o, getConfigDir as r, writeGlobalConfig as s, approveServer as t };
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import { n as log } from "./_ui-8kOEB-JH.mjs";
3
3
  import { a as errorMessage, r as errorCode } from "./_utils-Ch0J4s6a.mjs";
4
- import { n as fallbackHtmlPlugin } from "./client-bundler-BWDkUeEP.mjs";
4
+ import { n as fallbackHtmlPlugin } from "./client-bundler-yiWoXrgb.mjs";
5
5
  import { buildWorker } from "./worker-bundler.mjs";
6
- import { n as createWorkerEvaluator } from "./_bundler-DFS4xxqE.mjs";
7
- import { n as ensureApiKey } from "./_config-D3F9km8X.mjs";
6
+ import { n as createWorkerEvaluator } from "./_bundler-Cjaxa2wi.mjs";
7
+ import { n as ensureApiKey } from "./_config-5AEqhh-O.mjs";
8
8
  import { t as resolveServerEnv } from "./_server-common-CnaP_Urf.mjs";
9
9
  import { createRequire } from "node:module";
10
10
  import { existsSync } from "node:fs";
@@ -1,62 +1,9 @@
1
1
  #!/usr/bin/env node
2
- import { a as errorMessage, c as readJson, d as writeJson, s as isEexist } from "./_utils-Ch0J4s6a.mjs";
3
- import { r as isDevMode, t as getMonorepoRoot } from "./_agent-D8zBb3M5.mjs";
4
- import { existsSync } from "node:fs";
2
+ import { c as readJson, d as writeJson, s as isEexist } from "./_utils-Ch0J4s6a.mjs";
3
+ import { r as isDevMode, t as getMonorepoRoot } from "./_agent-DMyOab9_.mjs";
4
+ import { REPO_URL, downloadAndMergeTemplate } from "./_templates-Bv8CR800.mjs";
5
5
  import path from "node:path";
6
6
  import fs from "node:fs/promises";
7
- const REPO_URL = `https://github.com/alexkroman/agent`;
8
- /**
9
- * Templates as shipped inside the published tarball, copied into `dist/` by
10
- * `bundle-templates.mjs` at build time — so this resolves to `dist/` for a
11
- * published CLI and to the (template-less) package root when running source
12
- * in the monorepo, where the branch above wins.
13
- *
14
- * They used to be fetched at `init` time with giget from
15
- * `github:alexkroman/agent/packages/aai-templates#main`. That required a
16
- * network for every `init`, and pinned templates to `main` regardless of the
17
- * CLI version the user had installed, so a template written against a newer
18
- * SDK could land in a project resolving an older one. Bundling pins the two
19
- * together by construction. It also puts the templates inside the studio's
20
- * guest sandbox, which has the CLI in its baked toolchain but no way to fetch
21
- * anything from GitHub.
22
- */
23
- function bundledTemplatesDir() {
24
- return import.meta.dirname;
25
- }
26
- /** Resolve the templates root — env override, then monorepo, then bundled. */
27
- function resolveTemplatesDir() {
28
- const override = process.env.AAI_TEMPLATES_DIR;
29
- if (override) return override;
30
- const monorepoRoot = getMonorepoRoot();
31
- if (monorepoRoot) return path.join(monorepoRoot, "packages", "aai-templates");
32
- return bundledTemplatesDir();
33
- }
34
- /**
35
- * Copy a template into targetDir, merging scaffold files underneath.
36
- */
37
- async function downloadAndMergeTemplate(template, targetDir) {
38
- const root = resolveTemplatesDir();
39
- const templatesDir = path.join(root, "templates");
40
- let available;
41
- try {
42
- available = await fs.readdir(templatesDir, { withFileTypes: true });
43
- } catch (err) {
44
- throw new Error(`Templates directory is missing or unreadable at ${templatesDir} (incomplete @alexkroman1/aai-cli install?): ${errorMessage(err)}`, { cause: err });
45
- }
46
- const names = available.filter((e) => e.isDirectory()).map((e) => e.name);
47
- if (!names.includes(template)) throw new Error(`Unknown template "${template}". Available templates: ${names.join(", ")}`);
48
- await fs.cp(path.join(templatesDir, template), targetDir, {
49
- recursive: true,
50
- force: true
51
- });
52
- const scaffoldDir = path.join(root, "scaffold");
53
- if (existsSync(scaffoldDir)) await fs.cp(scaffoldDir, targetDir, {
54
- recursive: true,
55
- force: false,
56
- errorOnExist: false
57
- });
58
- }
59
- //#endregion
60
7
  //#region _init.ts
61
8
  function readmeContent(slug) {
62
9
  return `# ${slug}
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { n as getServerInfo } from "./_agent-D8zBb3M5.mjs";
2
+ import { n as getServerInfo } from "./_agent-DMyOab9_.mjs";
3
3
  import { n as apiRequest, t as HINT_NOT_DEPLOYED } from "./_api-client-MenP4-O7.mjs";
4
4
  //#region _slug-api.ts
5
5
  /**
@@ -0,0 +1,69 @@
1
+ #!/usr/bin/env node
2
+ import { a as errorMessage } from "./_utils-Ch0J4s6a.mjs";
3
+ import { t as getMonorepoRoot } from "./_agent-DMyOab9_.mjs";
4
+ import { existsSync } from "node:fs";
5
+ import path from "node:path";
6
+ import fs from "node:fs/promises";
7
+ const REPO_URL = `https://github.com/alexkroman/agent`;
8
+ /**
9
+ * Templates as shipped inside the published tarball, copied into `dist/` by
10
+ * `bundle-templates.mjs` at build time — so this resolves to `dist/` for a
11
+ * published CLI and to the (template-less) package root when running source
12
+ * in the monorepo, where the branch above wins.
13
+ *
14
+ * They used to be fetched at `init` time with giget from
15
+ * `github:alexkroman/agent/packages/aai-templates#main`. That required a
16
+ * network for every `init`, and pinned templates to `main` regardless of the
17
+ * CLI version the user had installed, so a template written against a newer
18
+ * SDK could land in a project resolving an older one. Bundling pins the two
19
+ * together by construction. It also puts the templates inside the studio's
20
+ * guest sandbox, which has the CLI in its baked toolchain but no way to fetch
21
+ * anything from GitHub.
22
+ */
23
+ function bundledTemplatesDir() {
24
+ return import.meta.dirname;
25
+ }
26
+ /** Resolve the templates root — env override, then monorepo, then bundled. */
27
+ function resolveTemplatesDir() {
28
+ const override = process.env.AAI_TEMPLATES_DIR;
29
+ if (override) return override;
30
+ const monorepoRoot = getMonorepoRoot();
31
+ if (monorepoRoot) return path.join(monorepoRoot, "packages", "aai-templates");
32
+ return bundledTemplatesDir();
33
+ }
34
+ /**
35
+ * List the shipped template names (sorted). Backs `aai templates` and the
36
+ * unknown-template error, so the discoverable list and the validated list
37
+ * can never drift.
38
+ */
39
+ async function listTemplates(root = resolveTemplatesDir()) {
40
+ const templatesDir = path.join(root, "templates");
41
+ let available;
42
+ try {
43
+ available = await fs.readdir(templatesDir, { withFileTypes: true });
44
+ } catch (err) {
45
+ throw new Error(`Templates directory is missing or unreadable at ${templatesDir} (incomplete @alexkroman1/aai-cli install?): ${errorMessage(err)}`, { cause: err });
46
+ }
47
+ return available.filter((e) => e.isDirectory()).map((e) => e.name).sort();
48
+ }
49
+ /**
50
+ * Copy a template into targetDir, merging scaffold files underneath.
51
+ */
52
+ async function downloadAndMergeTemplate(template, targetDir) {
53
+ const root = resolveTemplatesDir();
54
+ const templatesDir = path.join(root, "templates");
55
+ const names = await listTemplates(root);
56
+ if (!names.includes(template)) throw new Error(`Unknown template "${template}". Available templates: ${names.join(", ")}`);
57
+ await fs.cp(path.join(templatesDir, template), targetDir, {
58
+ recursive: true,
59
+ force: true
60
+ });
61
+ const scaffoldDir = path.join(root, "scaffold");
62
+ if (existsSync(scaffoldDir)) await fs.cp(scaffoldDir, targetDir, {
63
+ recursive: true,
64
+ force: false,
65
+ errorOnExist: false
66
+ });
67
+ }
68
+ //#endregion
69
+ export { REPO_URL, downloadAndMergeTemplate, listTemplates };
@@ -15,6 +15,12 @@ export declare const REPO_URL = "https://github.com/alexkroman/agent";
15
15
  * anything from GitHub.
16
16
  */
17
17
  export declare function bundledTemplatesDir(): string;
18
+ /**
19
+ * List the shipped template names (sorted). Backs `aai templates` and the
20
+ * unknown-template error, so the discoverable list and the validated list
21
+ * can never drift.
22
+ */
23
+ export declare function listTemplates(root?: string): Promise<string[]>;
18
24
  /**
19
25
  * Copy a template into targetDir, merging scaffold files underneath.
20
26
  */
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { n as log, o as CliError, u as ok } from "./_ui-8kOEB-JH.mjs";
3
- import { r as evalWorkerBundle, t as buildAgentBundle } from "./_bundler-DFS4xxqE.mjs";
3
+ import { r as evalWorkerBundle, t as buildAgentBundle } from "./_bundler-Cjaxa2wi.mjs";
4
4
  import { t as assertTypechecks } from "./_typecheck-gate-9IHWDnl1.mjs";
5
5
  import { classifyVitestError, runVitest } from "./test-3Gq4pqH_.mjs";
6
6
  //#region build.ts
package/dist/cli.mjs CHANGED
@@ -68,7 +68,10 @@ async function runCommand(args, fn) {
68
68
  } catch (err) {
69
69
  const code = err instanceof CliError ? err.code : "command_failed";
70
70
  const hint = err instanceof CliError ? err.hint : void 0;
71
- if (mode === "human") log.error(errorMessage(err));
71
+ if (mode === "human") {
72
+ log.error(errorMessage(err));
73
+ if (hint) log.info(hint);
74
+ }
72
75
  result = fail(code, errorMessage(err), hint);
73
76
  }
74
77
  if (mode === "json") await writeLine(`${JSON.stringify(result)}\n`);
@@ -93,7 +96,7 @@ const init = defineCommand({
93
96
  template: {
94
97
  type: "string",
95
98
  alias: "t",
96
- description: "Template to use (e.g. pizza-ordering)"
99
+ description: "Template to use (run `aai templates` for the list)"
97
100
  },
98
101
  server: sharedArgs.server,
99
102
  yes: sharedArgs.yes,
@@ -105,7 +108,7 @@ const init = defineCommand({
105
108
  },
106
109
  async run({ args }) {
107
110
  await runCommand(args, async (mode) => {
108
- const { executeInit } = await import("./init-BjeK8crW.mjs");
111
+ const { executeInit } = await import("./init-DoU4_txp.mjs");
109
112
  return executeInit({
110
113
  dir: args.dir,
111
114
  force: args.force,
@@ -134,7 +137,7 @@ const dev = defineCommand({
134
137
  async run({ args }) {
135
138
  await runCommand(args, async () => {
136
139
  const cwd = await setup({ agent: true });
137
- const { executeDev } = await import("./dev-g7sGt8qX.mjs");
140
+ const { executeDev } = await import("./dev-gVNdGFYY.mjs");
138
141
  return executeDev({
139
142
  cwd,
140
143
  port: args.port
@@ -175,7 +178,7 @@ const build = defineCommand({
175
178
  async run({ args }) {
176
179
  await runCommand(args, async () => {
177
180
  const cwd = await setup({ agent: true });
178
- const { executeBuild } = await import("./build-Xq1xxoSg.mjs");
181
+ const { executeBuild } = await import("./build-D_PgQOD4.mjs");
179
182
  return executeBuild({
180
183
  cwd,
181
184
  skipTests: args.skipTests,
@@ -204,7 +207,7 @@ const deploy = defineCommand({
204
207
  async run({ args }) {
205
208
  await runCommand(args, async () => {
206
209
  const cwd = await setup({ agent: true });
207
- const { executeDeploy } = await import("./deploy-Ci0X1gp2.mjs");
210
+ const { executeDeploy } = await import("./deploy-1eaXcfUw.mjs");
208
211
  return executeDeploy({
209
212
  cwd,
210
213
  server: args.server,
@@ -226,7 +229,7 @@ const del = defineCommand({
226
229
  async run({ args }) {
227
230
  await runCommand(args, async () => {
228
231
  const cwd = await setup();
229
- const { executeDelete } = await import("./delete-kSXFLxek.mjs");
232
+ const { executeDelete } = await import("./delete-DXilFBb1.mjs");
230
233
  return executeDelete({
231
234
  cwd,
232
235
  server: args.server
@@ -257,7 +260,7 @@ const secret = defineCommand({
257
260
  async run({ args }) {
258
261
  await runCommand(args, async (mode) => {
259
262
  const cwd = await setup();
260
- const { executeSecretPut, NO_INPUT, readStdin } = await import("./secret-DOva9OGk.mjs");
263
+ const { executeSecretPut, NO_INPUT, readStdin } = await import("./secret-CGAIAbUx.mjs");
261
264
  const value = mode === "json" ? await readStdin() : void 0;
262
265
  if (mode === "json" && !value) throw new CliError(...NO_INPUT);
263
266
  return executeSecretPut(cwd, args.name, value, args.server);
@@ -281,7 +284,7 @@ const secret = defineCommand({
281
284
  async run({ args }) {
282
285
  await runCommand(args, async () => {
283
286
  const cwd = await setup();
284
- const { executeSecretDelete } = await import("./secret-DOva9OGk.mjs");
287
+ const { executeSecretDelete } = await import("./secret-CGAIAbUx.mjs");
285
288
  return executeSecretDelete(cwd, args.name, args.server);
286
289
  });
287
290
  }
@@ -298,7 +301,7 @@ const secret = defineCommand({
298
301
  async run({ args }) {
299
302
  await runCommand(args, async () => {
300
303
  const cwd = await setup();
301
- const { executeSecretList } = await import("./secret-DOva9OGk.mjs");
304
+ const { executeSecretList } = await import("./secret-CGAIAbUx.mjs");
302
305
  return executeSecretList(cwd, args.server);
303
306
  });
304
307
  }
@@ -318,7 +321,7 @@ const storageDir = {
318
321
  const storage = defineCommand({
319
322
  meta: {
320
323
  name: "storage",
321
- description: "Manage the agent's database (storage)"
324
+ description: "Manage the agent's app database"
322
325
  },
323
326
  subCommands: {
324
327
  status: defineCommand({
@@ -333,7 +336,7 @@ const storage = defineCommand({
333
336
  },
334
337
  async run({ args }) {
335
338
  await runCommand(args, async () => {
336
- const { executeStorageStatus } = await import("./storage-vM6HjDZZ.mjs");
339
+ const { executeStorageStatus } = await import("./storage-CnhOayhm.mjs");
337
340
  return executeStorageStatus(resolveStorageCwd(args.dir), args.server);
338
341
  });
339
342
  }
@@ -341,7 +344,7 @@ const storage = defineCommand({
341
344
  enable: defineCommand({
342
345
  meta: {
343
346
  name: "enable",
344
- description: "Enable the agent's database (storage)"
347
+ description: "Enable the agent's app database"
345
348
  },
346
349
  args: {
347
350
  dir: storageDir,
@@ -350,7 +353,7 @@ const storage = defineCommand({
350
353
  },
351
354
  async run({ args }) {
352
355
  await runCommand(args, async () => {
353
- const { executeStorageEnable } = await import("./storage-vM6HjDZZ.mjs");
356
+ const { executeStorageEnable } = await import("./storage-CnhOayhm.mjs");
354
357
  return executeStorageEnable(resolveStorageCwd(args.dir), args.server);
355
358
  });
356
359
  }
@@ -358,7 +361,7 @@ const storage = defineCommand({
358
361
  disable: defineCommand({
359
362
  meta: {
360
363
  name: "disable",
361
- description: "Disable storage (DROPS the database schema and all its data)"
364
+ description: "Disable storage and DROP the database schema with all its data"
362
365
  },
363
366
  args: {
364
367
  dir: storageDir,
@@ -372,7 +375,7 @@ const storage = defineCommand({
372
375
  },
373
376
  async run({ args }) {
374
377
  await runCommand(args, async () => {
375
- const { executeStorageDisable } = await import("./storage-vM6HjDZZ.mjs");
378
+ const { executeStorageDisable } = await import("./storage-CnhOayhm.mjs");
376
379
  return executeStorageDisable(resolveStorageCwd(args.dir), {
377
380
  server: args.server,
378
381
  force: args.force
@@ -382,6 +385,43 @@ const storage = defineCommand({
382
385
  })
383
386
  }
384
387
  });
388
+ const login = defineCommand({
389
+ meta: {
390
+ name: "login",
391
+ description: "Sign in with your email and save your API key"
392
+ },
393
+ args: {
394
+ server: sharedArgs.server,
395
+ json: sharedArgs.json
396
+ },
397
+ async run({ args }) {
398
+ await runCommand(args, async () => {
399
+ const { executeLogin } = await import("./login-C59ZHzuO.mjs");
400
+ return executeLogin({ server: args.server });
401
+ });
402
+ }
403
+ });
404
+ const templates = defineCommand({
405
+ meta: {
406
+ name: "templates",
407
+ description: "List available project templates"
408
+ },
409
+ args: { json: sharedArgs.json },
410
+ async run({ args }) {
411
+ await runCommand(args, async (mode) => {
412
+ const { listTemplates } = await import("./_templates-Bv8CR800.mjs");
413
+ const names = await listTemplates();
414
+ if (mode === "human") {
415
+ for (const name of names) log.message(name);
416
+ log.info("Scaffold one with `aai init --template <name>`.");
417
+ }
418
+ return {
419
+ ok: true,
420
+ data: { templates: names }
421
+ };
422
+ });
423
+ }
424
+ });
385
425
  const mainCommand = defineCommand({
386
426
  meta: {
387
427
  name: "aai",
@@ -395,8 +435,10 @@ const mainCommand = defineCommand({
395
435
  build,
396
436
  deploy,
397
437
  delete: del,
438
+ login,
398
439
  secret,
399
- storage
440
+ storage,
441
+ templates
400
442
  }
401
443
  });
402
444
  if (process.env.VITEST !== "true") {
@@ -95,6 +95,9 @@ const DEDUPED_PEERS = ["react", "react-dom"];
95
95
  * Build the client SPA with Vite if `client.tsx` exists.
96
96
  * Returns a map of relative file paths to string contents for deploy,
97
97
  * or `{}` when the project has no `client.tsx`.
98
+ *
99
+ * @internal — build hook for aai-server/the studio; not a supported public
100
+ * API and not covered by semver.
98
101
  */
99
102
  async function buildClient(cwd, opts = {}) {
100
103
  if (!await fileExists(path.join(cwd, "client.tsx"))) return {};
@@ -1,4 +1,10 @@
1
1
  import { type PluginOption } from "vite";
2
+ /**
3
+ * Options for client SPA bundling.
4
+ *
5
+ * @internal — build hook for aai-server/the studio; not a supported public
6
+ * API and not covered by semver.
7
+ */
2
8
  export type BuildClientOptions = {
3
9
  /**
4
10
  * Plugins to inject instead of relying on the project's `vite.config.ts`
@@ -17,5 +23,8 @@ export type BuildClientOptions = {
17
23
  * Build the client SPA with Vite if `client.tsx` exists.
18
24
  * Returns a map of relative file paths to string contents for deploy,
19
25
  * or `{}` when the project has no `client.tsx`.
26
+ *
27
+ * @internal — build hook for aai-server/the studio; not a supported public
28
+ * API and not covered by semver.
20
29
  */
21
30
  export declare function buildClient(cwd: string, opts?: BuildClientOptions): Promise<Record<string, string>>;
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- import { t as buildClient } from "./client-bundler-BWDkUeEP.mjs";
2
+ import { t as buildClient } from "./client-bundler-yiWoXrgb.mjs";
3
3
  export { buildClient };
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { n as log, u as ok } from "./_ui-8kOEB-JH.mjs";
3
- import { n as getServerInfo } from "./_agent-D8zBb3M5.mjs";
3
+ import { n as getServerInfo } from "./_agent-DMyOab9_.mjs";
4
4
  import { n as apiRequest, t as HINT_NOT_DEPLOYED } from "./_api-client-MenP4-O7.mjs";
5
5
  //#region delete.ts
6
6
  async function runDelete(opts) {
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import { n as log, t as fmtUrl, u as ok } from "./_ui-8kOEB-JH.mjs";
3
3
  import { a as errorMessage } from "./_utils-Ch0J4s6a.mjs";
4
- import { t as buildAgentBundle } from "./_bundler-DFS4xxqE.mjs";
5
- import { o as writeProjectConfig } from "./_config-D3F9km8X.mjs";
4
+ import { t as buildAgentBundle } from "./_bundler-Cjaxa2wi.mjs";
5
+ import { c as writeProjectConfig } from "./_config-5AEqhh-O.mjs";
6
6
  import { t as resolveServerEnv } from "./_server-common-CnaP_Urf.mjs";
7
- import { i as resolveDeployTarget } from "./_agent-D8zBb3M5.mjs";
7
+ import { i as resolveDeployTarget } from "./_agent-DMyOab9_.mjs";
8
8
  import { t as assertTypechecks } from "./_typecheck-gate-9IHWDnl1.mjs";
9
9
  import { n as apiRequest } from "./_api-client-MenP4-O7.mjs";
10
10
  import { gzipSync } from "node:zlib";
@@ -11,7 +11,7 @@ import { styleText } from "node:util";
11
11
  async function executeDev(opts) {
12
12
  const port = parsePort(opts.port);
13
13
  const agentName = path.basename(path.resolve(opts.cwd));
14
- const { startDevServer } = await import("./_dev-server-BBUWo0sb.mjs");
14
+ const { startDevServer } = await import("./_dev-server-vV05Fnki.mjs");
15
15
  let cleanup;
16
16
  let shuttingDown = false;
17
17
  const onSignal = () => {
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { a as unwrapCancel, n as log, u as ok } from "./_ui-8kOEB-JH.mjs";
3
3
  import { a as errorMessage, c as readJson, l as resolveCwd, o as fileExists, t as AGENT_ENTRY } from "./_utils-Ch0J4s6a.mjs";
4
- import { r as isDevMode, t as getMonorepoRoot } from "./_agent-D8zBb3M5.mjs";
4
+ import { r as isDevMode, t as getMonorepoRoot } from "./_agent-DMyOab9_.mjs";
5
5
  import path from "node:path";
6
6
  import { styleText } from "node:util";
7
7
  import * as p from "@clack/prompts";
@@ -74,7 +74,7 @@ function resolveTargetDir(dir) {
74
74
  }
75
75
  /** Run deploy after init and return deploy metadata if successful. */
76
76
  async function tryDeploy(cwd, server) {
77
- const { executeDeploy } = await import("./deploy-Ci0X1gp2.mjs");
77
+ const { executeDeploy } = await import("./deploy-1eaXcfUw.mjs");
78
78
  try {
79
79
  const result = await executeDeploy({
80
80
  cwd,
@@ -92,7 +92,7 @@ async function tryDeploy(cwd, server) {
92
92
  }
93
93
  /** Scaffold the project, optionally showing a spinner. */
94
94
  async function scaffoldProject(dir, cwd, template, silent) {
95
- const { runInit } = await import("./_init-DU-sXH6S.mjs");
95
+ const { runInit } = await import("./_init-BZ9t_Kz-.mjs");
96
96
  const s = silent ? void 0 : p.spinner();
97
97
  s?.start(`Creating ${dir}`);
98
98
  await runInit({