@alexkroman1/aai-cli 5.12.0 → 5.13.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 (34) hide show
  1. package/dist/{_agent-JGaAJ5j6.mjs → _agent-C8Jk-ZcP.mjs} +1 -1
  2. package/dist/{_api-client-B-upMGkc.mjs → _api-client-BX8Qv51n.mjs} +2 -1
  3. package/dist/{_bundler-BvfPzf8J.mjs → _bundler-BuIyDdvs.mjs} +2 -2
  4. package/dist/{_config-riTmrwxX.mjs → _config-CzwAWOWr.mjs} +1 -1
  5. package/dist/{_dev-server-BgXXSijx.mjs → _dev-server-Ch7K8e8i.mjs} +5 -5
  6. package/dist/{_init-Ca5Eg5pn.mjs → _init-CbkrE2wq.mjs} +3 -3
  7. package/dist/{_server-common-DX8Bfrf5.mjs → _server-common-61fL__39.mjs} +1 -1
  8. package/dist/{_slug-api-DXm7s9X5.mjs → _slug-api-D30zPmsn.mjs} +2 -2
  9. package/dist/{_studio-CXoY_Hsg.mjs → _studio-D2ciIhbi.mjs} +1 -1
  10. package/dist/{_templates-CKYDgGyY.mjs → _templates-B1kt3BGt.mjs} +2 -2
  11. package/dist/{_utils-8KKw-bzi.mjs → _utils-0DHbcqUb.mjs} +2 -2
  12. package/dist/{build-BTOyN3H5.mjs → build-DQJ1ZSm9.mjs} +2 -2
  13. package/dist/cli.mjs +20 -20
  14. package/dist/{client-bundler-DONm-khu.mjs → client-bundler-C9qXL8A2.mjs} +1 -1
  15. package/dist/client-bundler.mjs +1 -1
  16. package/dist/{delete-D3gZdSs-.mjs → delete-DCRX3d96.mjs} +3 -3
  17. package/dist/{deploy-Df6e7YFn.mjs → deploy-DjsEV-40.mjs} +10 -9
  18. package/dist/{dev-DqIUtFfS.mjs → dev-CvPH5dbF.mjs} +2 -2
  19. package/dist/{eject-DSldO60O.mjs → eject-LgBRfnbH.mjs} +2 -2
  20. package/dist/{init-B-04lRSV.mjs → init-BppxMR8r.mjs} +4 -4
  21. package/dist/{login-CtimAsZk.mjs → login-BQQaxJhL.mjs} +2 -2
  22. package/dist/project-config.mjs +1 -1
  23. package/dist/scaffold/CLAUDE.md +60 -10
  24. package/dist/scaffold/package.json +3 -3
  25. package/dist/{secret-LnFdg8SB.mjs → secret-Ds9dvqAj.mjs} +1 -1
  26. package/dist/{storage-Cjj3Pv6i.mjs → storage-DbrQSHFk.mjs} +1 -1
  27. package/dist/{studio-Rl5Po2M6.mjs → studio-GSFd4s5O.mjs} +6 -6
  28. package/dist/templates/dispatch-center/shared.ts +13 -15
  29. package/dist/templates/pizza-ordering/agent.test.ts +3 -0
  30. package/dist/templates/retail/store.ts +11 -17
  31. package/dist/templates/solo-rpg/agent.test.ts +3 -0
  32. package/dist/{test-BtOzTcXE.mjs → test-2LWBcXvY.mjs} +1 -1
  33. package/dist/typecheck.mjs +1 -1
  34. package/package.json +3 -3
@@ -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-riTmrwxX.mjs";
2
+ import { a as serverOrigin, i as readProjectConfig, n as ensureApiKey, r as readGlobalConfig, t as approveServer } from "./_config-CzwAWOWr.mjs";
3
3
  import { existsSync } from "node:fs";
4
4
  import path from "node:path";
5
5
  import { fileURLToPath } from "node:url";
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env node
2
+ import { omitUndefined } from "@alexkroman1/aai/utils";
2
3
  import { FetchError, ofetch } from "ofetch";
3
4
  //#region _api-client.ts
4
5
  /**
@@ -25,7 +26,7 @@ async function apiRequest(url, opts) {
25
26
  Authorization: `Bearer ${opts.apiKey}`,
26
27
  ...opts.headers
27
28
  },
28
- ...opts.body !== void 0 ? { body: opts.body } : {},
29
+ ...omitUndefined({ body: opts.body }),
29
30
  retry: opts.retry ?? 2,
30
31
  retryDelay: opts.retryDelay ?? 300
31
32
  });
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { u as validateAgentExport } from "./_utils-8KKw-bzi.mjs";
3
- import { t as buildClient } from "./client-bundler-DONm-khu.mjs";
2
+ import { u as validateAgentExport } from "./_utils-0DHbcqUb.mjs";
3
+ import { t as buildClient } from "./client-bundler-C9qXL8A2.mjs";
4
4
  import { buildWorker } from "./worker-bundler.mjs";
5
5
  import path from "node:path";
6
6
  import { pathToFileURL } from "node:url";
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { t as CliError } from "./_output-CC300DzW.mjs";
3
- import { a as errorMessage, c as readJson, d as writeJson } from "./_utils-8KKw-bzi.mjs";
3
+ import { a as errorMessage, c as readJson, d as writeJson } from "./_utils-0DHbcqUb.mjs";
4
4
  import { mkdtempSync } from "node:fs";
5
5
  import path from "node:path";
6
6
  import fs from "node:fs/promises";
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import { i as outputSilenced, n as log, r as notify } from "./_ui-u7T4YooX.mjs";
3
- import { a as errorMessage, r as errorCode } from "./_utils-8KKw-bzi.mjs";
4
- import { n as fallbackHtmlPlugin } from "./client-bundler-DONm-khu.mjs";
3
+ import { a as errorMessage, r as errorCode } from "./_utils-0DHbcqUb.mjs";
4
+ import { n as fallbackHtmlPlugin } from "./client-bundler-C9qXL8A2.mjs";
5
5
  import { buildWorker } from "./worker-bundler.mjs";
6
- import { n as ensureApiKey } from "./_config-riTmrwxX.mjs";
7
- import { n as createWorkerEvaluator } from "./_bundler-BvfPzf8J.mjs";
8
- import { t as resolveServerEnv } from "./_server-common-DX8Bfrf5.mjs";
6
+ import { n as ensureApiKey } from "./_config-CzwAWOWr.mjs";
7
+ import { n as createWorkerEvaluator } from "./_bundler-BuIyDdvs.mjs";
8
+ import { t as resolveServerEnv } from "./_server-common-61fL__39.mjs";
9
9
  import { existsSync } from "node:fs";
10
10
  import path from "node:path";
11
11
  import { setTimeout } from "node:timers/promises";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import { c as readJson, d as writeJson, s as isEexist } from "./_utils-8KKw-bzi.mjs";
3
- import { r as isDevMode, t as getMonorepoRoot } from "./_agent-JGaAJ5j6.mjs";
4
- import { REPO_URL, downloadAndMergeTemplate } from "./_templates-CKYDgGyY.mjs";
2
+ import { c as readJson, d as writeJson, s as isEexist } from "./_utils-0DHbcqUb.mjs";
3
+ import { r as isDevMode, t as getMonorepoRoot } from "./_agent-C8Jk-ZcP.mjs";
4
+ import { REPO_URL, downloadAndMergeTemplate } from "./_templates-B1kt3BGt.mjs";
5
5
  import path from "node:path";
6
6
  import fs from "node:fs/promises";
7
7
  //#region _init.ts
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { r as errorCode } from "./_utils-8KKw-bzi.mjs";
2
+ import { r as errorCode } from "./_utils-0DHbcqUb.mjs";
3
3
  import path from "node:path";
4
4
  import { parseEnv } from "node:util";
5
5
  import fs from "node:fs/promises";
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { n as getServerInfo } from "./_agent-JGaAJ5j6.mjs";
3
- import { n as apiRequest, t as HINT_NOT_DEPLOYED } from "./_api-client-B-upMGkc.mjs";
2
+ import { n as getServerInfo } from "./_agent-C8Jk-ZcP.mjs";
3
+ import { n as apiRequest, t as HINT_NOT_DEPLOYED } from "./_api-client-BX8Qv51n.mjs";
4
4
  //#region _slug-api.ts
5
5
  /**
6
6
  * Authenticated request against a deployed agent's slug-scoped resource
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { n as apiRequest } from "./_api-client-B-upMGkc.mjs";
2
+ import { n as apiRequest } from "./_api-client-BX8Qv51n.mjs";
3
3
  import path from "node:path";
4
4
  import { MAX_SLUG_LENGTH, PREVIEW_SLUG_SUFFIX, VALID_SLUG_RE } from "@alexkroman1/aai/utils";
5
5
  import { slugifyName } from "@alexkroman1/aai/slugify";
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { a as errorMessage } from "./_utils-8KKw-bzi.mjs";
3
- import { t as getMonorepoRoot } from "./_agent-JGaAJ5j6.mjs";
2
+ import { a as errorMessage } from "./_utils-0DHbcqUb.mjs";
3
+ import { t as getMonorepoRoot } from "./_agent-C8Jk-ZcP.mjs";
4
4
  import { existsSync } from "node:fs";
5
5
  import path from "node:path";
6
6
  import fs from "node:fs/promises";
@@ -2,7 +2,7 @@
2
2
  import { readFileSync } from "node:fs";
3
3
  import path from "node:path";
4
4
  import fs from "node:fs/promises";
5
- import { errorDetail, errorMessage, errorMessage as errorMessage$1 } from "@alexkroman1/aai/utils";
5
+ import { errorDetail, errorMessage, errorMessage as errorMessage$1, omitUndefined } from "@alexkroman1/aai/utils";
6
6
  //#region _utils.ts
7
7
  /**
8
8
  * The file that marks a directory as an agent project — the single source
@@ -93,7 +93,7 @@ async function writeJson(filePath, data, opts = {}) {
93
93
  ...opts.mode !== void 0 ? { mode: 448 } : {}
94
94
  });
95
95
  const tmpPath = `${filePath}.${process.pid}.${Math.random().toString(36).slice(2)}.tmp`;
96
- await fs.writeFile(tmpPath, `${JSON.stringify(data, null, 2)}\n`, { ...opts.mode !== void 0 ? { mode: opts.mode } : {} });
96
+ await fs.writeFile(tmpPath, `${JSON.stringify(data, null, 2)}\n`, omitUndefined({ mode: opts.mode }));
97
97
  try {
98
98
  await fs.rename(tmpPath, filePath);
99
99
  } catch (err) {
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import { a as ok, t as CliError } from "./_output-CC300DzW.mjs";
3
3
  import { n as log } from "./_ui-u7T4YooX.mjs";
4
- import { r as evalWorkerBundle, t as buildAgentBundle } from "./_bundler-BvfPzf8J.mjs";
4
+ import { r as evalWorkerBundle, t as buildAgentBundle } from "./_bundler-BuIyDdvs.mjs";
5
5
  import { assertTypechecks } from "./_typecheck-gate-4v9UBZHh.mjs";
6
- import { classifyVitestError, runVitest } from "./test-BtOzTcXE.mjs";
6
+ import { classifyVitestError, runVitest } from "./test-2LWBcXvY.mjs";
7
7
  //#region build.ts
8
8
  /**
9
9
  * `aai build` — bundle the agent without deploying, behind the same gates
package/dist/cli.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { i as installStdoutGuard, n as fail, o as writeLine, r as getOutputMode, t as CliError } from "./_output-CC300DzW.mjs";
3
3
  import { n as log, o as silenceOutput } from "./_ui-u7T4YooX.mjs";
4
- import { a as errorMessage, l as resolveCwd, o as fileExists, t as AGENT_ENTRY } from "./_utils-8KKw-bzi.mjs";
4
+ import { a as errorMessage, l as resolveCwd, o as fileExists, t as AGENT_ENTRY } from "./_utils-0DHbcqUb.mjs";
5
5
  import { existsSync, readFileSync } from "node:fs";
6
6
  import path from "node:path";
7
7
  import { fileURLToPath } from "node:url";
@@ -166,7 +166,7 @@ const list = defineCommand({
166
166
  async run({ args }) {
167
167
  await runCommand(args, async () => {
168
168
  const cwd = resolveCwd();
169
- const { executeList } = await import("./studio-Rl5Po2M6.mjs");
169
+ const { executeList } = await import("./studio-GSFd4s5O.mjs");
170
170
  return executeList({
171
171
  cwd,
172
172
  server: args.server
@@ -201,7 +201,7 @@ const pull = defineCommand({
201
201
  async run({ args }) {
202
202
  await runCommand(args, async () => {
203
203
  const cwd = resolveCwd();
204
- const { executePull } = await import("./studio-Rl5Po2M6.mjs");
204
+ const { executePull } = await import("./studio-GSFd4s5O.mjs");
205
205
  return executePull({
206
206
  cwd,
207
207
  project: args.project,
@@ -229,7 +229,7 @@ const push = defineCommand({
229
229
  async run({ args }) {
230
230
  await runCommand(args, async () => {
231
231
  const cwd = await setup({ agent: true });
232
- const { executePush } = await import("./studio-Rl5Po2M6.mjs");
232
+ const { executePush } = await import("./studio-GSFd4s5O.mjs");
233
233
  return executePush({
234
234
  cwd,
235
235
  server: args.server,
@@ -259,7 +259,7 @@ const publish = defineCommand({
259
259
  async run({ args }) {
260
260
  await runCommand(args, async () => {
261
261
  const cwd = await setup({ agent: true });
262
- const { executePublish } = await import("./studio-Rl5Po2M6.mjs");
262
+ const { executePublish } = await import("./studio-GSFd4s5O.mjs");
263
263
  return executePublish({
264
264
  cwd,
265
265
  server: args.server,
@@ -333,7 +333,7 @@ const init = defineCommand({
333
333
  },
334
334
  async run({ args }) {
335
335
  await runCommand(args, async (mode) => {
336
- const { executeInit } = await import("./init-B-04lRSV.mjs");
336
+ const { executeInit } = await import("./init-BppxMR8r.mjs");
337
337
  return executeInit({
338
338
  dir: args.dir,
339
339
  force: args.force,
@@ -362,7 +362,7 @@ const dev = defineCommand({
362
362
  async run({ args }) {
363
363
  await runCommand(args, async () => {
364
364
  const cwd = await setup({ agent: true });
365
- const { executeDev } = await import("./dev-DqIUtFfS.mjs");
365
+ const { executeDev } = await import("./dev-CvPH5dbF.mjs");
366
366
  return executeDev({
367
367
  cwd,
368
368
  port: args.port
@@ -379,7 +379,7 @@ const test = defineCommand({
379
379
  async run({ args }) {
380
380
  await runCommand(args, async () => {
381
381
  const cwd = await setup({ agent: true });
382
- const { executeTest } = await import("./test-BtOzTcXE.mjs");
382
+ const { executeTest } = await import("./test-2LWBcXvY.mjs");
383
383
  return executeTest(cwd);
384
384
  });
385
385
  }
@@ -403,7 +403,7 @@ const build = defineCommand({
403
403
  async run({ args }) {
404
404
  await runCommand(args, async () => {
405
405
  const cwd = await setup({ agent: true });
406
- const { executeBuild } = await import("./build-BTOyN3H5.mjs");
406
+ const { executeBuild } = await import("./build-DQJ1ZSm9.mjs");
407
407
  return executeBuild({
408
408
  cwd,
409
409
  skipTests: args.skipTests,
@@ -428,7 +428,7 @@ const eject = defineCommand({
428
428
  async run({ args }) {
429
429
  await runCommand(args, async () => {
430
430
  const cwd = await setup({ agent: true });
431
- const { executeEject } = await import("./eject-DSldO60O.mjs");
431
+ const { executeEject } = await import("./eject-LgBRfnbH.mjs");
432
432
  return executeEject({
433
433
  cwd,
434
434
  force: args.force
@@ -457,7 +457,7 @@ const deploy = defineCommand({
457
457
  async run({ args }) {
458
458
  await runCommand(args, async () => {
459
459
  const cwd = await setup({ agent: true });
460
- const { executeDeploy } = await import("./deploy-Df6e7YFn.mjs");
460
+ const { executeDeploy } = await import("./deploy-DjsEV-40.mjs");
461
461
  return executeDeploy({
462
462
  cwd,
463
463
  server: args.server,
@@ -479,7 +479,7 @@ const del = defineCommand({
479
479
  async run({ args }) {
480
480
  await runCommand(args, async () => {
481
481
  const cwd = await setup();
482
- const { executeDelete } = await import("./delete-D3gZdSs-.mjs");
482
+ const { executeDelete } = await import("./delete-DCRX3d96.mjs");
483
483
  return executeDelete({
484
484
  cwd,
485
485
  server: args.server
@@ -510,7 +510,7 @@ const secret = defineCommand({
510
510
  async run({ args }) {
511
511
  await runCommand(args, async (mode) => {
512
512
  const cwd = await setup();
513
- const { executeSecretPut, NO_INPUT, readStdin } = await import("./secret-LnFdg8SB.mjs");
513
+ const { executeSecretPut, NO_INPUT, readStdin } = await import("./secret-Ds9dvqAj.mjs");
514
514
  const value = mode === "json" ? await readStdin() : void 0;
515
515
  if (mode === "json" && !value) throw new CliError(...NO_INPUT);
516
516
  return executeSecretPut(cwd, args.name, value, args.server);
@@ -534,7 +534,7 @@ const secret = defineCommand({
534
534
  async run({ args }) {
535
535
  await runCommand(args, async () => {
536
536
  const cwd = await setup();
537
- const { executeSecretDelete } = await import("./secret-LnFdg8SB.mjs");
537
+ const { executeSecretDelete } = await import("./secret-Ds9dvqAj.mjs");
538
538
  return executeSecretDelete(cwd, args.name, args.server);
539
539
  });
540
540
  }
@@ -551,7 +551,7 @@ const secret = defineCommand({
551
551
  async run({ args }) {
552
552
  await runCommand(args, async () => {
553
553
  const cwd = await setup();
554
- const { executeSecretList } = await import("./secret-LnFdg8SB.mjs");
554
+ const { executeSecretList } = await import("./secret-Ds9dvqAj.mjs");
555
555
  return executeSecretList(cwd, args.server);
556
556
  });
557
557
  }
@@ -586,7 +586,7 @@ const storage = defineCommand({
586
586
  },
587
587
  async run({ args }) {
588
588
  await runCommand(args, async () => {
589
- const { executeStorageStatus } = await import("./storage-Cjj3Pv6i.mjs");
589
+ const { executeStorageStatus } = await import("./storage-DbrQSHFk.mjs");
590
590
  return executeStorageStatus(resolveStorageCwd(args.dir), args.server);
591
591
  });
592
592
  }
@@ -603,7 +603,7 @@ const storage = defineCommand({
603
603
  },
604
604
  async run({ args }) {
605
605
  await runCommand(args, async () => {
606
- const { executeStorageEnable } = await import("./storage-Cjj3Pv6i.mjs");
606
+ const { executeStorageEnable } = await import("./storage-DbrQSHFk.mjs");
607
607
  return executeStorageEnable(resolveStorageCwd(args.dir), args.server);
608
608
  });
609
609
  }
@@ -625,7 +625,7 @@ const storage = defineCommand({
625
625
  },
626
626
  async run({ args }) {
627
627
  await runCommand(args, async () => {
628
- const { executeStorageDisable } = await import("./storage-Cjj3Pv6i.mjs");
628
+ const { executeStorageDisable } = await import("./storage-DbrQSHFk.mjs");
629
629
  return executeStorageDisable(resolveStorageCwd(args.dir), {
630
630
  server: args.server,
631
631
  force: args.force
@@ -646,7 +646,7 @@ const login = defineCommand({
646
646
  },
647
647
  async run({ args }) {
648
648
  await runCommand(args, async () => {
649
- const { executeLogin } = await import("./login-CtimAsZk.mjs");
649
+ const { executeLogin } = await import("./login-BQQaxJhL.mjs");
650
650
  return executeLogin({ server: args.server });
651
651
  });
652
652
  }
@@ -659,7 +659,7 @@ const templates = defineCommand({
659
659
  args: { json: sharedArgs.json },
660
660
  async run({ args }) {
661
661
  await runCommand(args, async (mode) => {
662
- const { listTemplates } = await import("./_templates-CKYDgGyY.mjs");
662
+ const { listTemplates } = await import("./_templates-B1kt3BGt.mjs");
663
663
  const names = await listTemplates();
664
664
  if (mode === "human") {
665
665
  for (const name of names) log.message(name);
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { a as errorMessage$1, o as fileExists } from "./_utils-8KKw-bzi.mjs";
2
+ import { a as errorMessage$1, o as fileExists } from "./_utils-0DHbcqUb.mjs";
3
3
  import { t as withPreservedNodeEnv } from "./_vite-env-Dg_QlVv0.mjs";
4
4
  import { existsSync, unlinkSync, writeFileSync } from "node:fs";
5
5
  import path from "node:path";
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- import { t as buildClient } from "./client-bundler-DONm-khu.mjs";
2
+ import { t as buildClient } from "./client-bundler-C9qXL8A2.mjs";
3
3
  export { buildClient };
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import { a as ok } from "./_output-CC300DzW.mjs";
3
3
  import { n as log } from "./_ui-u7T4YooX.mjs";
4
- import { l as writeProjectConfig } from "./_config-riTmrwxX.mjs";
5
- import { i as resolveDeployTarget, n as getServerInfo } from "./_agent-JGaAJ5j6.mjs";
6
- import { n as apiRequest, t as HINT_NOT_DEPLOYED } from "./_api-client-B-upMGkc.mjs";
4
+ import { l as writeProjectConfig } from "./_config-CzwAWOWr.mjs";
5
+ import { i as resolveDeployTarget, n as getServerInfo } from "./_agent-C8Jk-ZcP.mjs";
6
+ import { n as apiRequest, t as HINT_NOT_DEPLOYED } from "./_api-client-BX8Qv51n.mjs";
7
7
  //#region delete.ts
8
8
  async function runDelete(opts) {
9
9
  await apiRequest(`${opts.url}/${opts.slug}`, {
@@ -1,14 +1,15 @@
1
1
  #!/usr/bin/env node
2
2
  import { a as ok } from "./_output-CC300DzW.mjs";
3
3
  import { n as log, r as notify, t as fmtUrl } from "./_ui-u7T4YooX.mjs";
4
- import { a as errorMessage } from "./_utils-8KKw-bzi.mjs";
5
- import { s as updateProjectConfig } from "./_config-riTmrwxX.mjs";
6
- import { i as evalWorkerConfig, t as buildAgentBundle } from "./_bundler-BvfPzf8J.mjs";
7
- import { t as resolveServerEnv } from "./_server-common-DX8Bfrf5.mjs";
8
- import { i as resolveDeployTarget } from "./_agent-JGaAJ5j6.mjs";
4
+ import { a as errorMessage$1 } from "./_utils-0DHbcqUb.mjs";
5
+ import { s as updateProjectConfig } from "./_config-CzwAWOWr.mjs";
6
+ import { i as evalWorkerConfig, t as buildAgentBundle } from "./_bundler-BuIyDdvs.mjs";
7
+ import { t as resolveServerEnv } from "./_server-common-61fL__39.mjs";
8
+ import { i as resolveDeployTarget } from "./_agent-C8Jk-ZcP.mjs";
9
9
  import { assertTypechecks } from "./_typecheck-gate-4v9UBZHh.mjs";
10
- import { n as apiRequest } from "./_api-client-B-upMGkc.mjs";
11
- import { i as projectNameFromDir } from "./_studio-CXoY_Hsg.mjs";
10
+ import { n as apiRequest } from "./_api-client-BX8Qv51n.mjs";
11
+ import { i as projectNameFromDir } from "./_studio-D2ciIhbi.mjs";
12
+ import { omitUndefined } from "@alexkroman1/aai/utils";
12
13
  import { gzipSync } from "node:zlib";
13
14
  //#region _deploy.ts
14
15
  async function runDeploy(opts) {
@@ -30,7 +31,7 @@ async function runDeploy(opts) {
30
31
  action: "deploy",
31
32
  hints: { 413: "Your bundle is too large. Try reducing dependencies or splitting your agent." },
32
33
  ...opts.slug ? {} : { retry: 0 },
33
- ...opts.retryDelay !== void 0 ? { retryDelay: opts.retryDelay } : {},
34
+ ...omitUndefined({ retryDelay: opts.retryDelay }),
34
35
  ...opts.fetch ? { fetch: opts.fetch } : {}
35
36
  })).slug };
36
37
  }
@@ -68,7 +69,7 @@ async function executeDeploy(opts) {
68
69
  serverUrl
69
70
  });
70
71
  } catch (err) {
71
- log.warn(`Deployed as ${deployed.slug}, but couldn't save .aai/project.json: ${errorMessage(err)}\n Write it manually so future deploys reuse this slug:
72
+ log.warn(`Deployed as ${deployed.slug}, but couldn't save .aai/project.json: ${errorMessage$1(err)}\n Write it manually so future deploys reuse this slug:
72
73
  ${JSON.stringify({
73
74
  slug: deployed.slug,
74
75
  serverUrl
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { a as ok } from "./_output-CC300DzW.mjs";
3
3
  import { a as parsePort, n as log, r as notify, t as fmtUrl } from "./_ui-u7T4YooX.mjs";
4
- import { i as errorDetail } from "./_utils-8KKw-bzi.mjs";
4
+ import { i as errorDetail } from "./_utils-0DHbcqUb.mjs";
5
5
  import path from "node:path";
6
6
  import { styleText } from "node:util";
7
7
  //#region dev.ts
@@ -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-BgXXSijx.mjs");
15
+ const { startDevServer } = await import("./_dev-server-Ch7K8e8i.mjs");
16
16
  let cleanup;
17
17
  let shuttingDown = false;
18
18
  const onSignal = () => {
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { a as ok, t as CliError } from "./_output-CC300DzW.mjs";
3
3
  import { n as log } from "./_ui-u7T4YooX.mjs";
4
- import { a as errorMessage, c as readJson, d as writeJson, o as fileExists } from "./_utils-8KKw-bzi.mjs";
5
- import { scaffoldDir } from "./_templates-CKYDgGyY.mjs";
4
+ import { a as errorMessage, c as readJson, d as writeJson, o as fileExists } from "./_utils-0DHbcqUb.mjs";
5
+ import { scaffoldDir } from "./_templates-B1kt3BGt.mjs";
6
6
  import path from "node:path";
7
7
  import fs from "node:fs/promises";
8
8
  //#region eject.ts
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { a as ok } from "./_output-CC300DzW.mjs";
3
3
  import { n as log, s as unwrapCancel } from "./_ui-u7T4YooX.mjs";
4
- import { a as errorMessage, c as readJson, l as resolveCwd, o as fileExists, t as AGENT_ENTRY } from "./_utils-8KKw-bzi.mjs";
5
- import { r as isDevMode, t as getMonorepoRoot } from "./_agent-JGaAJ5j6.mjs";
4
+ import { a as errorMessage, c as readJson, l as resolveCwd, o as fileExists, t as AGENT_ENTRY } from "./_utils-0DHbcqUb.mjs";
5
+ import { r as isDevMode, t as getMonorepoRoot } from "./_agent-C8Jk-ZcP.mjs";
6
6
  import path from "node:path";
7
7
  import { styleText } from "node:util";
8
8
  import * as p from "@clack/prompts";
@@ -75,7 +75,7 @@ function resolveTargetDir(dir) {
75
75
  }
76
76
  /** Publish after init and return deploy metadata if successful. */
77
77
  async function tryPublish(cwd, server) {
78
- const { executePublish } = await import("./studio-Rl5Po2M6.mjs");
78
+ const { executePublish } = await import("./studio-GSFd4s5O.mjs");
79
79
  try {
80
80
  const result = await executePublish({
81
81
  cwd,
@@ -94,7 +94,7 @@ async function tryPublish(cwd, server) {
94
94
  }
95
95
  /** Scaffold the project, optionally showing a spinner. */
96
96
  async function scaffoldProject(dir, cwd, template, silent) {
97
- const { runInit } = await import("./_init-Ca5Eg5pn.mjs");
97
+ const { runInit } = await import("./_init-CbkrE2wq.mjs");
98
98
  const s = silent ? void 0 : p.spinner();
99
99
  s?.start(`Creating ${dir}`);
100
100
  await runInit({
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { a as ok, t as CliError } from "./_output-CC300DzW.mjs";
3
3
  import { n as log } from "./_ui-u7T4YooX.mjs";
4
- import { o as updateGlobalConfig, r as readGlobalConfig, t as approveServer } from "./_config-riTmrwxX.mjs";
5
- import { a as resolveServerUrl } from "./_agent-JGaAJ5j6.mjs";
4
+ import { o as updateGlobalConfig, r as readGlobalConfig, t as approveServer } from "./_config-CzwAWOWr.mjs";
5
+ import { a as resolveServerUrl } from "./_agent-C8Jk-ZcP.mjs";
6
6
  import { linkConfirmationCode } from "@alexkroman1/aai/utils";
7
7
  import { spawn } from "node:child_process";
8
8
  import { setTimeout } from "node:timers/promises";
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- import { c as writeGlobalConfig, s as updateProjectConfig } from "./_config-riTmrwxX.mjs";
2
+ import { c as writeGlobalConfig, s as updateProjectConfig } from "./_config-CzwAWOWr.mjs";
3
3
  export { updateProjectConfig, writeGlobalConfig as writeConfigHome };
@@ -205,9 +205,9 @@ that stage — the rest keep the default.
205
205
  from `@alexkroman1/aai`, next to `agent()`) selects AssemblyAI's
206
206
  speech-to-speech Voice Agent API: STT, the LLM loop, and TTS run
207
207
  service-side in one socket. Fewer moving parts, but you cannot choose the
208
- model, swap a provider, or tune a stage. There is no way to reach S2S by
209
- omission — only the `s2s` field selects it, and it is mutually exclusive
210
- with the `stt`/`llm`/`tts` triple.
208
+ model or swap a provider. There is no way to reach S2S by omission — only
209
+ the `s2s` field selects it, and it is mutually exclusive with the
210
+ `stt`/`llm`/`tts` triple.
211
211
 
212
212
  ```ts
213
213
  import { agent, assemblyAIS2s } from "@alexkroman1/aai";
@@ -218,6 +218,33 @@ export default agent({
218
218
  });
219
219
  ```
220
220
 
221
+ The descriptor takes three optional knobs, all forwarded only when set:
222
+
223
+ ```ts
224
+ import { agent, assemblyAIS2s } from "@alexkroman1/aai";
225
+
226
+ export default agent({
227
+ name: "My Agent",
228
+ sttPrompt: "Callers spell order numbers one character at a time.",
229
+ s2s: assemblyAIS2s({
230
+ voice: "michael",
231
+ languages: ["en"],
232
+ keyterms: ["Acme Rewards", "SKU"],
233
+ }),
234
+ });
235
+ ```
236
+
237
+ - `voice` — the agent's voice. Unset uses the service default.
238
+ - `languages` — **leave it unset for multilingual calls**: unset means
239
+ "detect per turn", so pinning `["en"]` on a line that takes other
240
+ languages disables detection for every caller. Pin it when the line
241
+ really is monolingual — on a benchmark run that plus a transcription
242
+ prompt took a caller's spelled first name from 1 of 6 attempts correct
243
+ to 6 of 6.
244
+ - `keyterms` — product names and proper nouns to bias transcription
245
+ toward. Use `sttPrompt` (above, and honoured in **both** modes) for
246
+ prose guidance and `keyterms` for a term list.
247
+
221
248
  **Prefer pipeline mode** — the default — unless the user specifically
222
249
  asks for the speech-to-speech API. Nearly every template ships this way, and
223
250
  it is what AssemblyAI Build defaults to. The host runs the LLM loop locally
@@ -444,6 +471,28 @@ ctx.messages: readonly Message[] // conversation history [{role, c
444
471
  ctx.sessionId: string // unique session ID
445
472
  ctx.send(event: string, data: unknown): void // push custom event to browser client (silently dropped over 64 KB JSON)
446
473
  ctx.generate(opts): Promise<{ text, object? }> // one-shot LLM call (host-side)
474
+ // with a `schema`, `object` is REQUIRED and typed by it
475
+ ctx.signal: AbortSignal // aborts on barge-in, reset, session stop, or this call's timeout
476
+ ```
477
+
478
+ **Pass `ctx.signal` to anything slow.** It is always present — no `?.`
479
+ needed — and forwarding it is what makes a tool stop work the caller has
480
+ already interrupted:
481
+
482
+ ```ts
483
+ import { tool } from "@alexkroman1/aai";
484
+ import { z } from "zod";
485
+
486
+ export const lookup = tool({
487
+ description: "Look up an order",
488
+ inputSchema: z.object({ id: z.string() }),
489
+ execute: async ({ id }, ctx) => {
490
+ const res = await fetch(`https://api.example.com/orders/${id}`, {
491
+ signal: ctx.signal,
492
+ });
493
+ return await res.json();
494
+ },
495
+ });
447
496
  ```
448
497
 
449
498
  **Typing `ctx.state` is optional.** `ctx.state` is untyped by default, and
@@ -632,9 +681,10 @@ export default agent({
632
681
 
633
682
  ## Built-in tools
634
683
 
635
- Enable via `builtinTools` in `agent()`. When `builtinTools` is omitted, the
636
- cognitive defaults (`think`, `remember`, `recall`, `calculate`) are enabled;
637
- set `builtinTools` explicitly (including `[]`) to override.
684
+ Enable via `builtinTools` in `agent()`. **When `builtinTools` is omitted, none
685
+ are enabled** omitting the field and passing `[]` mean the same thing. Name
686
+ the ones you want; a built-in is something an agent asks for rather than
687
+ something it has to notice and switch off.
638
688
 
639
689
  | Tool | Description | Params |
640
690
  | --- | --- | --- |
@@ -643,10 +693,10 @@ set `builtinTools` explicitly (including `[]`) to override.
643
693
  | `get_page_design` | Fetch URL's raw HTML + CSS (style blocks and linked stylesheets) to study/mimic a site's design | `url` |
644
694
  | `fetch_json` | HTTP GET a JSON API | `url`, `headers?` |
645
695
  | `run_code` | Execute JS in the agent's sandbox — same authority as the agent's own tool code, output is what it logs (5s timeout) | `code` |
646
- | `think` | Private reasoning scratchpad, no side effects (on by default) | `thought` |
647
- | `remember` | Save a confirmed fact to session notes (on by default) | `key`, `value` |
648
- | `recall` | Read session notes saved with `remember` (on by default) | `key?` |
649
- | `calculate` | Safe arithmetic evaluator, no code execution (on by default) | `expression` |
696
+ | `think` | Private reasoning scratchpad, no side effects | `thought` |
697
+ | `remember` | Save a confirmed fact to session notes | `key`, `value` |
698
+ | `recall` | Read session notes saved with `remember` | `key?` |
699
+ | `calculate` | Safe arithmetic evaluator, no code execution | `expression` |
650
700
 
651
701
  **Every builtin in this table is a tool the MODEL calls — not a function
652
702
  your code can call.** Listing one in `builtinTools` adds it to the model's
@@ -12,15 +12,15 @@
12
12
  "publish:agent": "aai publish"
13
13
  },
14
14
  "dependencies": {
15
- "@alexkroman1/aai": "^5.12.0",
16
- "@alexkroman1/aai-ui": "^5.12.0",
15
+ "@alexkroman1/aai": "^5.13.0",
16
+ "@alexkroman1/aai-ui": "^5.13.0",
17
17
  "react": "^19.2.8",
18
18
  "react-dom": "^19.2.8",
19
19
  "tailwindcss": "^4.0.0",
20
20
  "zod": "^4.4.3"
21
21
  },
22
22
  "devDependencies": {
23
- "@alexkroman1/aai-cli": "^5.12.0",
23
+ "@alexkroman1/aai-cli": "^5.13.0",
24
24
  "@tailwindcss/vite": "^4.3.3",
25
25
  "@types/node": "^26.1.1",
26
26
  "@types/react": "^19.2.17",
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { a as ok, n as fail } from "./_output-CC300DzW.mjs";
3
3
  import { n as log, s as unwrapCancel } from "./_ui-u7T4YooX.mjs";
4
- import { t as secretRequest } from "./_slug-api-DXm7s9X5.mjs";
4
+ import { t as secretRequest } from "./_slug-api-D30zPmsn.mjs";
5
5
  import * as p from "@clack/prompts";
6
6
  import { text } from "node:stream/consumers";
7
7
  //#region secret.ts
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { a as ok, n as fail } from "./_output-CC300DzW.mjs";
3
3
  import { n as log } from "./_ui-u7T4YooX.mjs";
4
- import { n as slugRequest } from "./_slug-api-DXm7s9X5.mjs";
4
+ import { n as slugRequest } from "./_slug-api-D30zPmsn.mjs";
5
5
  import * as p from "@clack/prompts";
6
6
  //#region storage.ts
7
7
  async function storageRequest(cwd, init, server) {
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import { a as ok, t as CliError } from "./_output-CC300DzW.mjs";
3
3
  import { n as log, t as fmtUrl } from "./_ui-u7T4YooX.mjs";
4
- import { s as updateProjectConfig } from "./_config-riTmrwxX.mjs";
5
- import { t as resolveServerEnv } from "./_server-common-DX8Bfrf5.mjs";
6
- import { i as resolveDeployTarget } from "./_agent-JGaAJ5j6.mjs";
7
- import { layerScaffold } from "./_templates-CKYDgGyY.mjs";
8
- import { n as apiRequest } from "./_api-client-B-upMGkc.mjs";
9
- import { a as publishStudioProject, i as projectNameFromDir, n as fetchStudioProject, o as pushStudioSource, r as listStudioProjects, s as studioProjectUrl, t as collectSourceFiles } from "./_studio-CXoY_Hsg.mjs";
4
+ import { s as updateProjectConfig } from "./_config-CzwAWOWr.mjs";
5
+ import { t as resolveServerEnv } from "./_server-common-61fL__39.mjs";
6
+ import { i as resolveDeployTarget } from "./_agent-C8Jk-ZcP.mjs";
7
+ import { layerScaffold } from "./_templates-B1kt3BGt.mjs";
8
+ import { n as apiRequest } from "./_api-client-BX8Qv51n.mjs";
9
+ import { a as publishStudioProject, i as projectNameFromDir, n as fetchStudioProject, o as pushStudioSource, r as listStudioProjects, s as studioProjectUrl, t as collectSourceFiles } from "./_studio-D2ciIhbi.mjs";
10
10
  import path from "node:path";
11
11
  import { mkdir, readdir, writeFile } from "node:fs/promises";
12
12
  //#region studio.ts
@@ -1,6 +1,7 @@
1
1
  // ─── Types ───────────────────────────────────────────────────────────────────
2
2
 
3
3
  import type { ToolContext } from "@alexkroman1/aai";
4
+ import { createKeyedLock, withLock } from "@alexkroman1/aai";
4
5
 
5
6
  export const SEVERITIES = ["critical", "urgent", "moderate", "minor"] as const;
6
7
  export type Severity = (typeof SEVERITIES)[number];
@@ -198,7 +199,7 @@ function pruneState(state: DispatchState): void {
198
199
  }
199
200
  }
200
201
 
201
- const sessionLocks = new Map<string, Promise<unknown>>();
202
+ const sessionLock = createKeyedLock();
202
203
 
203
204
  /**
204
205
  * Serialized update of the session's dispatch state.
@@ -206,33 +207,30 @@ const sessionLocks = new Map<string, Promise<unknown>>();
206
207
  * The LLM loop executes parallel tool calls concurrently. The state lives in
207
208
  * `ctx.state` now (one shared object, no snapshot/save round-trip), but a
208
209
  * mutator may be async, and two interleaving async mutators can each observe
209
- * the other's half-applied changes. This per-session promise chain makes
210
- * each update run against the previous one's finished result. It also
211
- * centralizes the shared bookkeeping every mutating tool needs: pruning and
212
- * alert-level recalculation.
210
+ * the other's half-applied changes. Holding the session's key makes each
211
+ * update run against the previous one's finished result. It also centralizes
212
+ * the shared bookkeeping every mutating tool needs: pruning and alert-level
213
+ * recalculation.
214
+ *
215
+ * `createKeyedLock` rather than a hand-rolled promise chain per session: the
216
+ * SDK's drops each key's entry once its chain drains (so a long-running agent
217
+ * does not accumulate one per session id) and does it by ownership, which is
218
+ * the part a hand-rolled chain gets wrong.
213
219
  *
214
220
  * There is no post-save callback: pushing the board to the client used to
215
221
  * need one, and `syncState` now does it after every tool call.
216
222
  */
217
- export async function updateState<R>(
223
+ export function updateState<R>(
218
224
  ctx: ToolContext,
219
225
  mutator: (state: DispatchState) => R | Promise<R>,
220
226
  ): Promise<R> {
221
- const prev = sessionLocks.get(ctx.sessionId) ?? Promise.resolve();
222
- const run = prev.then(async () => {
227
+ return withLock(sessionLock, ctx.sessionId, async () => {
223
228
  const state = getState(ctx);
224
229
  const result = await mutator(state);
225
230
  pruneState(state);
226
231
  recalculateAlertLevel(state);
227
232
  return result;
228
233
  });
229
- // Keep the chain alive across failures, and drop it once idle.
230
- const tail = run.catch(() => {});
231
- sessionLocks.set(ctx.sessionId, tail);
232
- tail.then(() => {
233
- if (sessionLocks.get(ctx.sessionId) === tail) sessionLocks.delete(ctx.sessionId);
234
- });
235
- return run;
236
234
  }
237
235
 
238
236
  // ─── Incident helpers ────────────────────────────────────────────────────────
@@ -21,6 +21,9 @@ function makeCtx(sessionId = "session-a") {
21
21
  generate: () => Promise.reject(new Error("generate not available in tests")),
22
22
  messages: [],
23
23
  sessionId,
24
+ // Never aborts — a test has no turn to cancel. `ctx.signal` is always
25
+ // present at runtime, so a stub supplies one rather than omitting it.
26
+ signal: new AbortController().signal,
24
27
  send: (event, data) => {
25
28
  sent.push({ event, data });
26
29
  },
@@ -1,5 +1,5 @@
1
1
  import type { ToolContext } from "@alexkroman1/aai";
2
- import { tool } from "@alexkroman1/aai";
2
+ import { createKeyedLock, tool, withLock } from "@alexkroman1/aai";
3
3
  import type { z } from "zod";
4
4
  import seedJson from "./seed.json";
5
5
  import type {
@@ -151,34 +151,28 @@ export function requireOwnOrder(state: RetailState, orderId: string): Order | Er
151
151
 
152
152
  // ─── Serialized state updates ────────────────────────────────────────────────
153
153
 
154
- const sessionLocks = new Map<string, Promise<unknown>>();
154
+ const sessionLock = createKeyedLock();
155
155
 
156
156
  /**
157
157
  * Serialized update of the session's store.
158
158
  *
159
159
  * The LLM loop can execute parallel tool calls, and a mutator may be async —
160
160
  * two interleaving async mutators can each observe the other's half-applied
161
- * changes. This per-session promise chain runs each update against the previous
162
- * one's finished result.
161
+ * changes. Holding the session's key runs each update against the previous
162
+ * one's finished result. `createKeyedLock` is the SDK's primitive for exactly
163
+ * this; the hand-rolled promise chain it replaced also had to remember to drop
164
+ * each key's entry by ownership once idle.
163
165
  *
164
166
  * NOT exported, unlike dispatch-center's equivalent. `retailTool` is the only
165
- * caller, so a tool body cannot re-enter it — which would chain the inner call
166
- * on a tail that only resolves once the inner call finishes, i.e. deadlock. A
167
- * hazard you can't reach beats a hazard you documented.
167
+ * caller, so a tool body cannot re-enter it — which would wait on a key only
168
+ * the outer call can release, i.e. deadlock. A hazard you can't reach beats a
169
+ * hazard you documented.
168
170
  */
169
- async function updateState<R>(
171
+ function updateState<R>(
170
172
  ctx: ToolContext,
171
173
  mutator: (state: RetailState) => R | Promise<R>,
172
174
  ): Promise<R> {
173
- const previous = sessionLocks.get(ctx.sessionId) ?? Promise.resolve();
174
- const run = previous.then(() => mutator(getState(ctx)));
175
- // Keep the chain alive across failures, and drop it once idle.
176
- const tail = run.catch(() => {});
177
- sessionLocks.set(ctx.sessionId, tail);
178
- tail.then(() => {
179
- if (sessionLocks.get(ctx.sessionId) === tail) sessionLocks.delete(ctx.sessionId);
180
- });
181
- return run;
175
+ return withLock(sessionLock, ctx.sessionId, async () => mutator(getState(ctx)));
182
176
  }
183
177
 
184
178
  // ─── The tool wrapper ────────────────────────────────────────────────────────
@@ -54,6 +54,9 @@ function makeCtx(sessionId = "session-a", db: Db = makeDb().db): ToolContext {
54
54
  generate: () => Promise.reject(new Error("generate not available in tests")),
55
55
  messages: [],
56
56
  sessionId,
57
+ // Never aborts — a test has no turn to cancel. `ctx.signal` is always
58
+ // present at runtime, so a stub supplies one rather than omitting it.
59
+ signal: new AbortController().signal,
57
60
  send: vi.fn(),
58
61
  };
59
62
  }
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { a as ok, n as fail } from "./_output-CC300DzW.mjs";
3
3
  import { n as log } from "./_ui-u7T4YooX.mjs";
4
- import { a as errorMessage, n as binFromPackageJson, r as errorCode } from "./_utils-8KKw-bzi.mjs";
4
+ import { a as errorMessage, n as binFromPackageJson, r as errorCode } from "./_utils-0DHbcqUb.mjs";
5
5
  import { createRequire } from "node:module";
6
6
  import { existsSync } from "node:fs";
7
7
  import path from "node:path";
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { a as errorMessage, n as binFromPackageJson } from "./_utils-8KKw-bzi.mjs";
2
+ import { a as errorMessage, n as binFromPackageJson } from "./_utils-0DHbcqUb.mjs";
3
3
  import { existsSync, readFileSync } from "node:fs";
4
4
  import path from "node:path";
5
5
  import { spawn } from "node:child_process";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alexkroman1/aai-cli",
3
- "version": "5.12.0",
3
+ "version": "5.13.0",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "aai": "bin.mjs"
@@ -43,8 +43,8 @@
43
43
  "p-timeout": "^7.0.1",
44
44
  "vite": "^8.1.5",
45
45
  "zod": "^4.4.3",
46
- "@alexkroman1/aai": "5.12.0",
47
- "@alexkroman1/aai-ui": "5.12.0"
46
+ "@alexkroman1/aai": "5.13.0",
47
+ "@alexkroman1/aai-ui": "5.13.0"
48
48
  },
49
49
  "devDependencies": {
50
50
  "playwright": "^1.61.1",