@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.
- package/dist/{_agent-JGaAJ5j6.mjs → _agent-C8Jk-ZcP.mjs} +1 -1
- package/dist/{_api-client-B-upMGkc.mjs → _api-client-BX8Qv51n.mjs} +2 -1
- package/dist/{_bundler-BvfPzf8J.mjs → _bundler-BuIyDdvs.mjs} +2 -2
- package/dist/{_config-riTmrwxX.mjs → _config-CzwAWOWr.mjs} +1 -1
- package/dist/{_dev-server-BgXXSijx.mjs → _dev-server-Ch7K8e8i.mjs} +5 -5
- package/dist/{_init-Ca5Eg5pn.mjs → _init-CbkrE2wq.mjs} +3 -3
- package/dist/{_server-common-DX8Bfrf5.mjs → _server-common-61fL__39.mjs} +1 -1
- package/dist/{_slug-api-DXm7s9X5.mjs → _slug-api-D30zPmsn.mjs} +2 -2
- package/dist/{_studio-CXoY_Hsg.mjs → _studio-D2ciIhbi.mjs} +1 -1
- package/dist/{_templates-CKYDgGyY.mjs → _templates-B1kt3BGt.mjs} +2 -2
- package/dist/{_utils-8KKw-bzi.mjs → _utils-0DHbcqUb.mjs} +2 -2
- package/dist/{build-BTOyN3H5.mjs → build-DQJ1ZSm9.mjs} +2 -2
- package/dist/cli.mjs +20 -20
- package/dist/{client-bundler-DONm-khu.mjs → client-bundler-C9qXL8A2.mjs} +1 -1
- package/dist/client-bundler.mjs +1 -1
- package/dist/{delete-D3gZdSs-.mjs → delete-DCRX3d96.mjs} +3 -3
- package/dist/{deploy-Df6e7YFn.mjs → deploy-DjsEV-40.mjs} +10 -9
- package/dist/{dev-DqIUtFfS.mjs → dev-CvPH5dbF.mjs} +2 -2
- package/dist/{eject-DSldO60O.mjs → eject-LgBRfnbH.mjs} +2 -2
- package/dist/{init-B-04lRSV.mjs → init-BppxMR8r.mjs} +4 -4
- package/dist/{login-CtimAsZk.mjs → login-BQQaxJhL.mjs} +2 -2
- package/dist/project-config.mjs +1 -1
- package/dist/scaffold/CLAUDE.md +60 -10
- package/dist/scaffold/package.json +3 -3
- package/dist/{secret-LnFdg8SB.mjs → secret-Ds9dvqAj.mjs} +1 -1
- package/dist/{storage-Cjj3Pv6i.mjs → storage-DbrQSHFk.mjs} +1 -1
- package/dist/{studio-Rl5Po2M6.mjs → studio-GSFd4s5O.mjs} +6 -6
- package/dist/templates/dispatch-center/shared.ts +13 -15
- package/dist/templates/pizza-ordering/agent.test.ts +3 -0
- package/dist/templates/retail/store.ts +11 -17
- package/dist/templates/solo-rpg/agent.test.ts +3 -0
- package/dist/{test-BtOzTcXE.mjs → test-2LWBcXvY.mjs} +1 -1
- package/dist/typecheck.mjs +1 -1
- 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-
|
|
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
|
-
...
|
|
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-
|
|
3
|
-
import { t as buildClient } from "./client-bundler-
|
|
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-
|
|
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-
|
|
4
|
-
import { n as fallbackHtmlPlugin } from "./client-bundler-
|
|
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-
|
|
7
|
-
import { n as createWorkerEvaluator } from "./_bundler-
|
|
8
|
-
import { t as resolveServerEnv } from "./_server-common-
|
|
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-
|
|
3
|
-
import { r as isDevMode, t as getMonorepoRoot } from "./_agent-
|
|
4
|
-
import { REPO_URL, downloadAndMergeTemplate } from "./_templates-
|
|
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,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { n as getServerInfo } from "./_agent-
|
|
3
|
-
import { n as apiRequest, t as HINT_NOT_DEPLOYED } from "./_api-client-
|
|
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-
|
|
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-
|
|
3
|
-
import { t as getMonorepoRoot } from "./_agent-
|
|
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`, {
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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";
|
package/dist/client-bundler.mjs
CHANGED
|
@@ -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-
|
|
5
|
-
import { i as resolveDeployTarget, n as getServerInfo } from "./_agent-
|
|
6
|
-
import { n as apiRequest, t as HINT_NOT_DEPLOYED } from "./_api-client-
|
|
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-
|
|
5
|
-
import { s as updateProjectConfig } from "./_config-
|
|
6
|
-
import { i as evalWorkerConfig, t as buildAgentBundle } from "./_bundler-
|
|
7
|
-
import { t as resolveServerEnv } from "./_server-common-
|
|
8
|
-
import { i as resolveDeployTarget } from "./_agent-
|
|
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-
|
|
11
|
-
import { i as projectNameFromDir } from "./_studio-
|
|
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
|
-
...
|
|
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-
|
|
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-
|
|
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-
|
|
5
|
-
import { scaffoldDir } from "./_templates-
|
|
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-
|
|
5
|
-
import { r as isDevMode, t as getMonorepoRoot } from "./_agent-
|
|
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-
|
|
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-
|
|
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-
|
|
5
|
-
import { a as resolveServerUrl } from "./_agent-
|
|
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";
|
package/dist/project-config.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { c as writeGlobalConfig, s as updateProjectConfig } from "./_config-
|
|
2
|
+
import { c as writeGlobalConfig, s as updateProjectConfig } from "./_config-CzwAWOWr.mjs";
|
|
3
3
|
export { updateProjectConfig, writeGlobalConfig as writeConfigHome };
|
package/dist/scaffold/CLAUDE.md
CHANGED
|
@@ -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
|
|
209
|
-
|
|
210
|
-
|
|
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,
|
|
636
|
-
|
|
637
|
-
|
|
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
|
|
647
|
-
| `remember` | Save a confirmed fact to session notes
|
|
648
|
-
| `recall` | Read session notes saved with `remember`
|
|
649
|
-
| `calculate` | Safe arithmetic evaluator, no code execution
|
|
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.
|
|
16
|
-
"@alexkroman1/aai-ui": "^5.
|
|
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.
|
|
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-
|
|
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-
|
|
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-
|
|
5
|
-
import { t as resolveServerEnv } from "./_server-common-
|
|
6
|
-
import { i as resolveDeployTarget } from "./_agent-
|
|
7
|
-
import { layerScaffold } from "./_templates-
|
|
8
|
-
import { n as apiRequest } from "./_api-client-
|
|
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-
|
|
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
|
|
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.
|
|
210
|
-
*
|
|
211
|
-
*
|
|
212
|
-
*
|
|
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
|
|
223
|
+
export function updateState<R>(
|
|
218
224
|
ctx: ToolContext,
|
|
219
225
|
mutator: (state: DispatchState) => R | Promise<R>,
|
|
220
226
|
): Promise<R> {
|
|
221
|
-
|
|
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
|
|
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.
|
|
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
|
|
166
|
-
*
|
|
167
|
-
* hazard you
|
|
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
|
-
|
|
171
|
+
function updateState<R>(
|
|
170
172
|
ctx: ToolContext,
|
|
171
173
|
mutator: (state: RetailState) => R | Promise<R>,
|
|
172
174
|
): Promise<R> {
|
|
173
|
-
|
|
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-
|
|
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";
|
package/dist/typecheck.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as errorMessage, n as binFromPackageJson } from "./_utils-
|
|
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.
|
|
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.
|
|
47
|
-
"@alexkroman1/aai-ui": "5.
|
|
46
|
+
"@alexkroman1/aai": "5.13.0",
|
|
47
|
+
"@alexkroman1/aai-ui": "5.13.0"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"playwright": "^1.61.1",
|