@alexkroman1/aai-cli 8.2.1 → 9.0.1

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 (90) hide show
  1. package/dist/_dev-env.d.ts +15 -2
  2. package/dist/{_dev-server-Dt3TCjhj.mjs → _dev-server-BAR8Ya43.mjs} +182 -55
  3. package/dist/_dev-server.d.ts +5 -30
  4. package/dist/_dev-typecheck.d.ts +38 -0
  5. package/dist/_dev-vite-config.d.ts +74 -0
  6. package/dist/_e2e-test-utils.d.ts +33 -1
  7. package/dist/_init-BNotRgV1.mjs +163 -0
  8. package/dist/_resource-commands.d.ts +0 -1
  9. package/dist/{build-BBxf8vom.mjs → build-DvDdSwAS.mjs} +1 -1
  10. package/dist/cli.mjs +22 -93
  11. package/dist/{delete-CPf347lo.mjs → delete-8pjH8n8n.mjs} +2 -1
  12. package/dist/{deploy-BqV6ShIe.mjs → deploy-CjU3e-3P.mjs} +3 -3
  13. package/dist/{dev-QuuOOUtv.mjs → dev-dFzdvwa7.mjs} +3 -2
  14. package/dist/dev.d.ts +2 -0
  15. package/dist/{eval-DfQ8cm5p.mjs → eval-DwNwdqmS.mjs} +1 -1
  16. package/dist/{init-Cp5GZg0B.mjs → init-DK7GpIF9.mjs} +7 -6
  17. package/dist/scaffold/.env.example +7 -4
  18. package/dist/scaffold/CLAUDE.md +152 -97
  19. package/dist/scaffold/global.d.ts +12 -0
  20. package/dist/scaffold/package.json +4 -4
  21. package/dist/scaffold/server.mjs +49 -2
  22. package/dist/scaffold/tsconfig.json +1 -0
  23. package/dist/scaffold/vitest.config.ts +24 -0
  24. package/dist/{studio-DUfCH9I8.mjs → studio-D3-HWIfk.mjs} +3 -3
  25. package/dist/templates/briefing-desk/agent.test.ts +3 -15
  26. package/dist/templates/briefing-desk/shared.ts +3 -3
  27. package/dist/templates/call-audit/agent.eval.test.ts +8 -1
  28. package/dist/templates/call-audit/agent.test.ts +0 -1
  29. package/dist/templates/call-audit/agent.ts +4 -3
  30. package/dist/templates/call-audit/client.tsx +4 -7
  31. package/dist/templates/call-audit/workflows/audit.ts +10 -1
  32. package/dist/templates/code-interpreter/agent.eval.test.ts +14 -43
  33. package/dist/templates/dispatch-center/agent.eval.test.ts +16 -26
  34. package/dist/templates/embedded-assets/agent.eval.test.ts +6 -16
  35. package/dist/templates/embedded-assets/agent.test.ts +3 -16
  36. package/dist/templates/health-assistant/agent.eval.test.ts +5 -15
  37. package/dist/templates/health-assistant/agent.test.ts +3 -14
  38. package/dist/templates/infocom-adventure/agent.eval.test.ts +6 -16
  39. package/dist/templates/infocom-adventure/agent.test.ts +3 -17
  40. package/dist/templates/link-digest/agent.test.ts +0 -14
  41. package/dist/templates/link-digest/agent.ts +9 -5
  42. package/dist/templates/link-digest/client.tsx +8 -6
  43. package/dist/templates/math-buddy/agent.eval.test.ts +11 -40
  44. package/dist/templates/night-owl/agent.eval.test.ts +15 -44
  45. package/dist/templates/night-owl/agent.test.ts +2 -15
  46. package/dist/templates/personal-finance/agent.eval.test.ts +10 -39
  47. package/dist/templates/pipeline-simple/agent.test.ts +73 -0
  48. package/dist/templates/pizza-ordering/agent.eval.test.ts +2 -17
  49. package/dist/templates/pizza-ordering/agent.test.ts +2 -17
  50. package/dist/templates/plan-and-execute/agent.eval.test.ts +2 -12
  51. package/dist/templates/plan-and-execute/agent.test.ts +3 -23
  52. package/dist/templates/plan-and-execute/shared.ts +1 -1
  53. package/dist/templates/podcast-digest/agent.test.ts +0 -1
  54. package/dist/templates/podcast-digest/client.tsx +3 -6
  55. package/dist/templates/podcast-digest/workflows/digest.ts +16 -8
  56. package/dist/templates/recap-workflow/agent.eval.test.ts +7 -14
  57. package/dist/templates/recap-workflow/agent.test.ts +3 -18
  58. package/dist/templates/recap-workflow/agent.ts +7 -5
  59. package/dist/templates/redline/agent.test.ts +0 -13
  60. package/dist/templates/redline/agent.ts +3 -2
  61. package/dist/templates/redline/client.tsx +9 -4
  62. package/dist/templates/research-workflow/agent.eval.test.ts +7 -14
  63. package/dist/templates/research-workflow/agent.test.ts +3 -15
  64. package/dist/templates/research-workflow/agent.ts +7 -5
  65. package/dist/templates/research-workflow/workflows/research.ts +8 -2
  66. package/dist/templates/retail/agent.eval.test.ts +10 -25
  67. package/dist/templates/retail/registry.test.ts +16 -13
  68. package/dist/templates/solo-rpg/agent.eval.test.ts +5 -15
  69. package/dist/templates/solo-rpg/agent.test.ts +17 -124
  70. package/dist/templates/solo-rpg/shared.ts +13 -61
  71. package/dist/templates/spoken-summary/agent.test.ts +0 -1
  72. package/dist/templates/spoken-summary/agent.ts +5 -4
  73. package/dist/templates/spoken-summary/client.tsx +4 -7
  74. package/dist/templates/support-line/agent.eval.test.ts +2 -12
  75. package/dist/templates/support-line/agent.test.ts +3 -22
  76. package/dist/templates/transcription-workflow/agent.ts +4 -4
  77. package/dist/templates/transcription-workflow/client.tsx +5 -5
  78. package/dist/templates/transcription-workflow/workflows/transcribe.ts +10 -1
  79. package/dist/templates/travel-concierge/agent.eval.test.ts +5 -15
  80. package/dist/templates/travel-concierge/agent.test.ts +3 -23
  81. package/dist/templates/web-researcher/agent.eval.test.ts +2 -5
  82. package/dist/test-CvwgeVSQ.mjs +181 -0
  83. package/dist/test.d.ts +33 -2
  84. package/package.json +4 -4
  85. package/dist/_init-BhEfQ6Yi.mjs +0 -93
  86. package/dist/storage-Bfs7QQWq.mjs +0 -66
  87. package/dist/storage.d.ts +0 -22
  88. package/dist/templates/solo-rpg/tools/load_game.ts +0 -37
  89. package/dist/templates/solo-rpg/tools/save_game.ts +0 -32
  90. package/dist/test-BvyT6sAc.mjs +0 -104
@@ -0,0 +1,163 @@
1
+ #!/usr/bin/env node
2
+ import { c as isEexist, l as readJson, p as writeJson } from "./_utils-B8QmtFhK.mjs";
3
+ import { r as isDevMode, t as getMonorepoRoot } from "./_agent-BTwZJu4P.mjs";
4
+ import { REPO_URL, downloadAndMergeTemplate } from "./_templates-4WcKOjS5.mjs";
5
+ import path from "node:path";
6
+ import fs from "node:fs/promises";
7
+ //#region _init.ts
8
+ function readmeContent(slug) {
9
+ return `# ${slug}
10
+
11
+ A voice agent built with [aai](${REPO_URL}).
12
+
13
+ ## Getting started
14
+
15
+ \`\`\`sh
16
+ npm install # Install dependencies
17
+ aai dev # Run locally (opens browser)
18
+ aai publish # Publish to production (and sync to the studio)
19
+ \`\`\`
20
+
21
+ ## Secrets
22
+
23
+ Access secrets in your agent via \`ctx.env.MY_KEY\`.
24
+
25
+ **Local development** — add secrets to \`.env\` (auto-loaded by \`aai dev\`):
26
+
27
+ \`\`\`sh
28
+ ALPHA_VANTAGE_KEY=sk-abc123
29
+ MY_API_KEY=secret-value
30
+ \`\`\`
31
+
32
+ **Production** — set secrets on the server:
33
+
34
+ \`\`\`sh
35
+ aai secret put MY_KEY # Set a secret (prompts for value)
36
+ aai secret list # List secret names
37
+ aai secret delete MY_KEY # Remove a secret
38
+ \`\`\`
39
+
40
+ `;
41
+ }
42
+ /**
43
+ * Map from npm package name to directory name under packages/.
44
+ * Used to rewrite published version ranges to link: paths in dev mode.
45
+ */
46
+ const WORKSPACE_PKG_DIRS = {
47
+ "@alexkroman1/aai": "aai",
48
+ "@alexkroman1/aai-cli": "aai-cli",
49
+ "@alexkroman1/aai-runtime": "aai-runtime",
50
+ "@alexkroman1/aai-ui": "aai-ui"
51
+ };
52
+ /** Rewrite workspace deps to link: paths so pnpm links to local source. */
53
+ async function patchPackageJsonForWorkspace(targetDir) {
54
+ const pkgPath = path.join(targetDir, "package.json");
55
+ const pkgJson = await readJson(pkgPath);
56
+ if (!pkgJson) return;
57
+ pkgJson.name = path.basename(targetDir);
58
+ delete pkgJson.packageManager;
59
+ const root = getMonorepoRoot();
60
+ if (!root) return;
61
+ const packagesDir = path.join(root, "packages");
62
+ for (const field of ["dependencies", "devDependencies"]) {
63
+ const deps = pkgJson[field];
64
+ if (!deps) continue;
65
+ for (const key of Object.keys(deps)) {
66
+ const dir = WORKSPACE_PKG_DIRS[key];
67
+ if (dir) deps[key] = `link:${path.relative(targetDir, path.join(packagesDir, dir))}`;
68
+ }
69
+ }
70
+ await writeJson(pkgPath, pkgJson);
71
+ await pinSharedDeps(targetDir, packagesDir, pkgJson);
72
+ }
73
+ /**
74
+ * Code-unit ordering, never `localeCompare`.
75
+ *
76
+ * With no explicit locale that answers to the runtime's ICU default, so the same
77
+ * project would scaffold a differently-ordered file on a different machine —
78
+ * which is the reason the repo's own generated artifacts sort this way too.
79
+ */
80
+ function compareNames(a, b) {
81
+ if (a === b) return 0;
82
+ return a < b ? -1 : 1;
83
+ }
84
+ /**
85
+ * Pin every THIRD-PARTY dependency this project shares with a linked workspace
86
+ * package to the copy that workspace package resolved.
87
+ *
88
+ * Linking is what makes this necessary, and it only bites in dev mode. The
89
+ * project's `@alexkroman1/*` deps become `link:` paths, so the SDK's types come
90
+ * out of the WORKSPACE's `node_modules` — while the project installs its own
91
+ * copy of anything it also declares. Two copies of a structurally identical
92
+ * library are two NOMINALLY different types to TypeScript, and the error runs to
93
+ * a hundred lines of `Type 'AnyActorLogic' is not assignable to type
94
+ * 'AnyActorLogic'` with two absolute paths in it.
95
+ *
96
+ * Measured: `aai init --template support-line` produced exactly that. The
97
+ * workspace lockfile pinned `xstate@5.32.5`, the fresh project resolved
98
+ * `^5.32.5` to `5.32.6`, the CLI's typecheck gate failed, and the deploy was
99
+ * REFUSED — `"deployed": false` with the whole error as a warning. One
100
+ * `overrides` entry fixes it; verified end to end.
101
+ *
102
+ * A published install has no such problem, which is why this is dev-mode only:
103
+ * a user's project and the published SDK both ask for `^5.32.5` and pnpm
104
+ * resolves ONE copy. Nothing here changes what a user gets.
105
+ *
106
+ * Written to `pnpm-workspace.yaml` rather than `pnpm.overrides` in the manifest:
107
+ * the scaffold ships that file, which makes the project its own workspace root,
108
+ * and pnpm 10+ reads overrides from there. Verified both ways — the manifest
109
+ * spelling installed `5.32.6` anyway.
110
+ */
111
+ async function pinSharedDeps(targetDir, packagesDir, pkgJson) {
112
+ const declared = {
113
+ ...pkgJson.dependencies,
114
+ ...pkgJson.devDependencies
115
+ };
116
+ const linked = Object.entries(WORKSPACE_PKG_DIRS).filter(([name]) => name in declared).map(([, dir]) => dir);
117
+ const pins = /* @__PURE__ */ new Map();
118
+ for (const name of Object.keys(declared)) {
119
+ if (name in WORKSPACE_PKG_DIRS) continue;
120
+ for (const dir of linked) {
121
+ const manifest = await readJson(path.join(packagesDir, dir, "node_modules", name, "package.json"));
122
+ if (typeof manifest?.version === "string") {
123
+ pins.set(name, manifest.version);
124
+ break;
125
+ }
126
+ }
127
+ }
128
+ if (pins.size === 0) return;
129
+ const file = path.join(targetDir, "pnpm-workspace.yaml");
130
+ let existing;
131
+ try {
132
+ existing = await fs.readFile(file, "utf-8");
133
+ } catch {
134
+ return;
135
+ }
136
+ const block = [...pins].sort(([a], [b]) => compareNames(a, b)).map(([name, version]) => ` "${name}": "${version}"`).join("\n");
137
+ await fs.writeFile(file, `${existing.trimEnd()}\n\n# Added by \`aai init\` in DEV MODE only — see pinSharedDeps in\n# packages/aai-cli/_init.ts. The @alexkroman1/* packages above are LINKED to
138
+ # this checkout, so anything they and this project both depend on has to be
139
+ # ONE copy: two copies of xstate are two incompatible sets of types, and the
140
+ # typecheck gate refuses the deploy.\noverrides:\n${block}\n`);
141
+ }
142
+ async function runInit(opts) {
143
+ const { targetDir, template } = opts;
144
+ await downloadAndMergeTemplate(template, targetDir);
145
+ if (isDevMode()) {
146
+ await patchPackageJsonForWorkspace(targetDir);
147
+ try {
148
+ await fs.unlink(path.join(targetDir, ".npmrc"));
149
+ } catch {}
150
+ }
151
+ try {
152
+ await fs.copyFile(path.join(targetDir, ".env.example"), path.join(targetDir, ".env"), fs.constants.COPYFILE_EXCL);
153
+ } catch {}
154
+ const readmePath = path.join(targetDir, "README.md");
155
+ const slug = path.basename(path.resolve(targetDir));
156
+ try {
157
+ await fs.writeFile(readmePath, readmeContent(slug), { flag: "wx" });
158
+ } catch (err) {
159
+ if (!isEexist(err)) throw err;
160
+ }
161
+ }
162
+ //#endregion
163
+ export { runInit };
@@ -20,4 +20,3 @@ export declare const logs: import("citty").CommandDef<{
20
20
  readonly description: "Output JSON (auto-detected in non-TTY)";
21
21
  };
22
22
  }>;
23
- export declare const storage: import("citty").CommandDef<import("citty").ArgsDef>;
@@ -3,7 +3,7 @@ import { a as ok, t as CliError } from "./_output-CKkmWs7i.mjs";
3
3
  import { n as log, r as notify } from "./_ui-u7T4YooX.mjs";
4
4
  import { r as evalWorkerBundle, t as buildAgentBundle } from "./_bundler-CDuYl5Gb.mjs";
5
5
  import { assertTypechecks } from "./_typecheck-gate-BXvUNnfs.mjs";
6
- import { classifyVitestError, runVitest } from "./test-BvyT6sAc.mjs";
6
+ import { classifyVitestError, runVitest } from "./test-CvwgeVSQ.mjs";
7
7
  import path from "node:path";
8
8
  import fs from "node:fs/promises";
9
9
  import { agentConfigWarnings } from "@alexkroman1/aai/manifest";
package/dist/cli.mjs CHANGED
@@ -306,81 +306,17 @@ const secret = defineCommand({
306
306
  function resolveDirArg(cwd, dir) {
307
307
  return dir ? path.resolve(cwd, dir) : cwd;
308
308
  }
309
- /**
310
- * The optional `[dir]` positional the project-scoped subcommands share.
311
- *
312
- * Named for what it is rather than for `storage`, which was the only group
313
- * that had one when it was written — `logs` takes the same positional and
314
- * read as borrowing another command's arg.
315
- */
316
- const dirArg = {
317
- type: "positional",
318
- description: "Project directory",
319
- required: false
320
- };
321
- const storageStatus = defineExec({
322
- meta: {
323
- name: "status",
324
- description: "Show whether storage is enabled"
325
- },
326
- args: {
327
- dir: dirArg,
328
- server: sharedArgs.server,
329
- json: sharedArgs.json
330
- },
331
- cwd: "any",
332
- async run({ args, cwd }) {
333
- const { executeStorageStatus } = await import("./storage-Bfs7QQWq.mjs");
334
- return executeStorageStatus(resolveDirArg(cwd, args.dir), args.server);
335
- }
336
- });
337
- const storageEnable = defineExec({
338
- meta: {
339
- name: "enable",
340
- description: "Enable the agent's app database"
341
- },
342
- args: {
343
- dir: dirArg,
344
- server: sharedArgs.server,
345
- json: sharedArgs.json
346
- },
347
- cwd: "any",
348
- async run({ args, cwd }) {
349
- const { executeStorageEnable } = await import("./storage-Bfs7QQWq.mjs");
350
- return executeStorageEnable(resolveDirArg(cwd, args.dir), args.server);
351
- }
352
- });
353
- const storageDisable = defineExec({
354
- meta: {
355
- name: "disable",
356
- description: "Disable storage and DROP the database schema with all its data"
357
- },
358
- args: {
359
- dir: dirArg,
360
- force: {
361
- type: "boolean",
362
- alias: "f",
363
- description: "Skip confirmation prompt"
364
- },
365
- server: sharedArgs.server,
366
- json: sharedArgs.json
367
- },
368
- cwd: "any",
369
- async run({ args, cwd }) {
370
- const { executeStorageDisable } = await import("./storage-Bfs7QQWq.mjs");
371
- return executeStorageDisable(resolveDirArg(cwd, args.dir), {
372
- server: args.server,
373
- force: args.force
374
- });
375
- }
376
- });
377
309
  const logs = defineExec({
378
310
  meta: {
379
311
  name: "logs",
380
312
  description: "Show what the deployed agent has printed"
381
313
  },
382
314
  args: {
383
- dir: dirArg,
315
+ dir: {
316
+ type: "positional",
317
+ description: "Project directory",
318
+ required: false
319
+ },
384
320
  follow: {
385
321
  type: "boolean",
386
322
  alias: "f",
@@ -398,17 +334,6 @@ const logs = defineExec({
398
334
  });
399
335
  }
400
336
  });
401
- const storage = defineCommand({
402
- meta: {
403
- name: "storage",
404
- description: "Manage the agent's app database"
405
- },
406
- subCommands: {
407
- status: storageStatus,
408
- enable: storageEnable,
409
- disable: storageDisable
410
- }
411
- });
412
337
  //#endregion
413
338
  //#region _studio-commands.ts
414
339
  /**
@@ -433,7 +358,7 @@ const list = defineExec({
433
358
  },
434
359
  cwd: "any",
435
360
  async run({ args, cwd }) {
436
- const { executeList } = await import("./studio-DUfCH9I8.mjs");
361
+ const { executeList } = await import("./studio-D3-HWIfk.mjs");
437
362
  return executeList({
438
363
  cwd,
439
364
  server: args.server
@@ -466,7 +391,7 @@ const pull = defineExec({
466
391
  },
467
392
  cwd: "any",
468
393
  async run({ args, cwd }) {
469
- const { executePull } = await import("./studio-DUfCH9I8.mjs");
394
+ const { executePull } = await import("./studio-D3-HWIfk.mjs");
470
395
  return executePull({
471
396
  cwd,
472
397
  project: args.project,
@@ -488,7 +413,7 @@ const push = defineExec({
488
413
  },
489
414
  cwd: "agent",
490
415
  async run({ args, cwd }) {
491
- const { executePush } = await import("./studio-DUfCH9I8.mjs");
416
+ const { executePush } = await import("./studio-D3-HWIfk.mjs");
492
417
  return executePush({
493
418
  cwd,
494
419
  server: args.server,
@@ -512,7 +437,7 @@ const publish = defineExec({
512
437
  },
513
438
  cwd: "agent",
514
439
  async run({ args, cwd }) {
515
- const { executePublish } = await import("./studio-DUfCH9I8.mjs");
440
+ const { executePublish } = await import("./studio-D3-HWIfk.mjs");
516
441
  return executePublish({
517
442
  cwd,
518
443
  server: args.server,
@@ -722,7 +647,7 @@ const mainCommand = defineCommand({
722
647
  },
723
648
  cwd: "none",
724
649
  async run({ args, mode }) {
725
- const { executeInit } = await import("./init-Cp5GZg0B.mjs");
650
+ const { executeInit } = await import("./init-DK7GpIF9.mjs");
726
651
  return executeInit({
727
652
  dir: args.dir,
728
653
  force: args.force,
@@ -745,14 +670,19 @@ const mainCommand = defineCommand({
745
670
  description: "Port to listen on",
746
671
  default: "3000"
747
672
  },
673
+ watch: {
674
+ type: "boolean",
675
+ description: "Restart on file changes (also AAI_DEV_WATCH=1)"
676
+ },
748
677
  json: sharedArgs.json
749
678
  },
750
679
  cwd: "agent",
751
680
  async run({ args, cwd }) {
752
- const { executeDev } = await import("./dev-QuuOOUtv.mjs");
681
+ const { executeDev } = await import("./dev-dFzdvwa7.mjs");
753
682
  return executeDev({
754
683
  cwd,
755
- port: args.port
684
+ port: args.port,
685
+ watch: args.watch
756
686
  });
757
687
  }
758
688
  }),
@@ -764,7 +694,7 @@ const mainCommand = defineCommand({
764
694
  args: { json: sharedArgs.json },
765
695
  cwd: "agent",
766
696
  async run({ cwd }) {
767
- const { executeTest } = await import("./test-BvyT6sAc.mjs");
697
+ const { executeTest } = await import("./test-CvwgeVSQ.mjs");
768
698
  return executeTest(cwd);
769
699
  }
770
700
  }),
@@ -776,7 +706,7 @@ const mainCommand = defineCommand({
776
706
  args: { json: sharedArgs.json },
777
707
  cwd: "agent",
778
708
  async run({ cwd }) {
779
- const { executeEval } = await import("./eval-DfQ8cm5p.mjs");
709
+ const { executeEval } = await import("./eval-DwNwdqmS.mjs");
780
710
  return executeEval(cwd);
781
711
  }
782
712
  }),
@@ -798,7 +728,7 @@ const mainCommand = defineCommand({
798
728
  },
799
729
  cwd: "agent",
800
730
  async run({ args, cwd }) {
801
- const { executeBuild } = await import("./build-BBxf8vom.mjs");
731
+ const { executeBuild } = await import("./build-DvDdSwAS.mjs");
802
732
  return executeBuild({
803
733
  cwd,
804
734
  skipTests: args.skipTests,
@@ -830,7 +760,7 @@ const mainCommand = defineCommand({
830
760
  },
831
761
  cwd: "agent",
832
762
  async run({ args, cwd }) {
833
- const { executeDeploy } = await import("./deploy-BqV6ShIe.mjs");
763
+ const { executeDeploy } = await import("./deploy-CjU3e-3P.mjs");
834
764
  return executeDeploy({
835
765
  cwd,
836
766
  server: args.server,
@@ -850,7 +780,7 @@ const mainCommand = defineCommand({
850
780
  },
851
781
  cwd: "any",
852
782
  async run({ args, cwd }) {
853
- const { executeDelete } = await import("./delete-CPf347lo.mjs");
783
+ const { executeDelete } = await import("./delete-8pjH8n8n.mjs");
854
784
  return executeDelete({
855
785
  cwd,
856
786
  server: args.server
@@ -874,7 +804,6 @@ const mainCommand = defineCommand({
874
804
  }),
875
805
  secret,
876
806
  logs,
877
- storage,
878
807
  workflow,
879
808
  templates: defineExec({
880
809
  meta: {
@@ -4,6 +4,7 @@ import { n as log } from "./_ui-u7T4YooX.mjs";
4
4
  import { l as writeProjectConfig } from "./_config-CmJOFsAP.mjs";
5
5
  import { a as resolveDeployTarget, i as requireDeployedSlug } from "./_agent-BTwZJu4P.mjs";
6
6
  import { d as apiTestSeam, l as HINT_NOT_DEPLOYED, s as studioProjectApiUrl, u as apiRequest } from "./_studio-CKrsixd0.mjs";
7
+ import { omitUndefined } from "@alexkroman1/aai/utils";
7
8
  //#region delete.ts
8
9
  async function runDelete(opts) {
9
10
  await apiRequest(`${opts.url}/${opts.slug}`, {
@@ -37,7 +38,7 @@ async function executeDelete(opts) {
37
38
  await writeProjectConfig(cwd, { serverUrl });
38
39
  return ok({
39
40
  project,
40
- ...config.slug ? { slug: config.slug } : {}
41
+ ...omitUndefined({ slug: config.slug })
41
42
  });
42
43
  }
43
44
  const slug = requireDeployedSlug(config);
@@ -8,12 +8,12 @@ import { t as resolveServerEnv } from "./_server-common-6e0QI4mq.mjs";
8
8
  import { a as resolveDeployTarget } from "./_agent-BTwZJu4P.mjs";
9
9
  import { assertTypechecks } from "./_typecheck-gate-BXvUNnfs.mjs";
10
10
  import { d as apiTestSeam, f as checkedResponse, i as projectNameFromDir, u as apiRequest } from "./_studio-CKrsixd0.mjs";
11
- import { isRecord } from "@alexkroman1/aai/utils";
11
+ import { isRecord, omitUndefined } from "@alexkroman1/aai/utils";
12
12
  import { gzipSync } from "node:zlib";
13
13
  //#region _deploy.ts
14
14
  async function runDeploy(opts) {
15
15
  const body = gzipSync(JSON.stringify({
16
- ...opts.slug ? { slug: opts.slug } : {},
16
+ ...omitUndefined({ slug: opts.slug }),
17
17
  ...opts.allowPreviewSlug ? { allowPreviewSlug: true } : {},
18
18
  env: opts.env,
19
19
  worker: opts.bundle.worker,
@@ -56,7 +56,7 @@ async function executeDeploy(opts) {
56
56
  url: serverUrl,
57
57
  bundle,
58
58
  env: uploadEnv,
59
- ...slug ? { slug } : {},
59
+ ...omitUndefined({ slug }),
60
60
  ...opts.allowPreviewSlug ? { allowPreviewSlug: true } : {},
61
61
  apiKey
62
62
  });
@@ -12,7 +12,7 @@ import { styleText } from "node:util";
12
12
  async function executeDev(opts) {
13
13
  const port = parsePort(opts.port);
14
14
  const agentName = path.basename(path.resolve(opts.cwd));
15
- const { startDevServer } = await import("./_dev-server-Dt3TCjhj.mjs");
15
+ const { startDevServer } = await import("./_dev-server-BAR8Ya43.mjs");
16
16
  let cleanup;
17
17
  let shuttingDown = false;
18
18
  const onSignal = () => {
@@ -28,7 +28,8 @@ async function executeDev(opts) {
28
28
  process.on("SIGTERM", onSignal);
29
29
  cleanup = await startDevServer({
30
30
  cwd: opts.cwd,
31
- port
31
+ port,
32
+ watch: opts.watch
32
33
  });
33
34
  const url = `http://localhost:${port}`;
34
35
  log.success(`${styleText("bold", agentName)} running at ${fmtUrl(url)}`);
package/dist/dev.d.ts CHANGED
@@ -9,5 +9,7 @@ type DevData = {
9
9
  export declare function executeDev(opts: {
10
10
  cwd: string;
11
11
  port: string;
12
+ /** `--watch`. Undefined leaves the decision to `AAI_DEV_WATCH`. */
13
+ watch?: boolean | undefined;
12
14
  }): Promise<CommandResult<DevData>>;
13
15
  export {};
@@ -2,7 +2,7 @@
2
2
  import { a as ok, n as fail } from "./_output-CKkmWs7i.mjs";
3
3
  import { n as log } from "./_ui-u7T4YooX.mjs";
4
4
  import { t as resolveServerEnv } from "./_server-common-6e0QI4mq.mjs";
5
- import { classifyVitestError, runVitest } from "./test-BvyT6sAc.mjs";
5
+ import { classifyVitestError, runVitest } from "./test-CvwgeVSQ.mjs";
6
6
  //#region eval.ts
7
7
  /**
8
8
  * `aai eval` — run the agent's behaviour evals via vitest.
@@ -1,9 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import { a as ok } from "./_output-CKkmWs7i.mjs";
3
3
  import { n as log, s as unwrapCancel } from "./_ui-u7T4YooX.mjs";
4
- import { d as resolveCwd, l as readJson, o as errorMessage, s as fileExists, t as AGENT_ENTRY } from "./_utils-B8QmtFhK.mjs";
4
+ import { d as resolveCwd, l as readJson, o as errorMessage$1, s as fileExists, t as AGENT_ENTRY } from "./_utils-B8QmtFhK.mjs";
5
5
  import { r as isDevMode, t as getMonorepoRoot } from "./_agent-BTwZJu4P.mjs";
6
6
  import path from "node:path";
7
+ import { omitUndefined } from "@alexkroman1/aai/utils";
7
8
  import { styleText } from "node:util";
8
9
  import * as p from "@clack/prompts";
9
10
  import { execa } from "execa";
@@ -84,7 +85,7 @@ async function installDeps(cwd, warn, silent) {
84
85
  }, () => runPnpmInstall(cwd));
85
86
  return true;
86
87
  } catch (err) {
87
- warn(`pnpm install failed: ${errorMessage(err)}`);
88
+ warn(`pnpm install failed: ${errorMessage$1(err)}`);
88
89
  warn("Install pnpm (`npm install -g pnpm`), then run `pnpm install` in the project.");
89
90
  return false;
90
91
  }
@@ -105,11 +106,11 @@ function collectWarnings() {
105
106
  }
106
107
  /** Publish after init and return deploy metadata if successful. */
107
108
  async function tryPublish(cwd, server, warn) {
108
- const { executePublish } = await import("./studio-DUfCH9I8.mjs");
109
+ const { executePublish } = await import("./studio-D3-HWIfk.mjs");
109
110
  try {
110
111
  const result = await executePublish({
111
112
  cwd,
112
- ...server ? { server } : {}
113
+ ...omitUndefined({ server })
113
114
  });
114
115
  if (result.ok) return {
115
116
  slug: result.data.slug,
@@ -119,14 +120,14 @@ async function tryPublish(cwd, server, warn) {
119
120
  warn(`Publish failed: ${result.error}`);
120
121
  return null;
121
122
  } catch (err) {
122
- warn(`Publish failed: ${errorMessage(err)}`);
123
+ warn(`Publish failed: ${errorMessage$1(err)}`);
123
124
  warn("Your project was still created — run `aai publish` in it to retry.");
124
125
  return null;
125
126
  }
126
127
  }
127
128
  /** Scaffold the project, optionally showing a spinner. */
128
129
  async function scaffoldProject(dir, cwd, template, silent) {
129
- const { runInit } = await import("./_init-BhEfQ6Yi.mjs");
130
+ const { runInit } = await import("./_init-BNotRgV1.mjs");
130
131
  await withSpinner(silent, {
131
132
  start: `Creating ${dir}`,
132
133
  done: "Project created",
@@ -12,10 +12,13 @@
12
12
 
13
13
  # --- Durable workflows and uploads -----------------------------------------
14
14
  #
15
- # A durable run needs a database; `api.upload(file)` needs a database AND
16
- # somewhere to put the bytes. A DEPLOYED agent gets both from the platform
17
- # (`aai storage enable`), so these four are the LOCAL equivalents and none of
18
- # them is needed by an agent that has no workflow.
15
+ # A DEPLOYED agent's runs are durable with no setup the platform keeps them
16
+ # on its own database. `api.upload(file)` is the exception: an upload's record
17
+ # needs a database YOU supply, so without a DATABASE_URL the bytes live only as
18
+ # long as the sandbox even though the runs reading them do not.
19
+ #
20
+ # These four are the LOCAL equivalents, and none is needed by an agent that has
21
+ # no workflow.
19
22
  #
20
23
  # All three storage keys or none: two of three resolves to nothing and refuses
21
24
  # by name rather than half-working. Nothing creates the bucket for you — a