@alexkroman1/aai-cli 5.10.1 → 5.12.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-DS2PUJcl.mjs → _agent-JGaAJ5j6.mjs} +3 -2
- package/dist/_agent.d.ts +1 -0
- package/dist/{_bundler-DC17suWN.mjs → _bundler-BvfPzf8J.mjs} +28 -9
- package/dist/_bundler.d.ts +16 -2
- package/dist/{_config-DMyolIk9.mjs → _config-riTmrwxX.mjs} +2 -2
- package/dist/_deploy.d.ts +0 -10
- package/dist/_dev-restart.d.ts +59 -0
- package/dist/{_dev-server-B3ivqyEd.mjs → _dev-server-BgXXSijx.mjs} +178 -89
- package/dist/_dev-server.d.ts +17 -0
- package/dist/{_init-CYLvYU-B.mjs → _init-Ca5Eg5pn.mjs} +2 -2
- package/dist/_preflight-BtfaYtbE.mjs +46 -0
- package/dist/_preflight.d.ts +57 -0
- package/dist/_slug-api-DXm7s9X5.mjs +50 -0
- package/dist/_slug-api.d.ts +16 -0
- package/dist/_studio-CXoY_Hsg.mjs +94 -0
- package/dist/_studio.d.ts +19 -16
- package/dist/{_templates-BWJOiWOO.mjs → _templates-CKYDgGyY.mjs} +18 -6
- package/dist/_templates.d.ts +10 -0
- package/dist/{_typecheck-gate-DB-PY0A3.mjs → _typecheck-gate-4v9UBZHh.mjs} +1 -1
- package/dist/{_ui-DfwfDbT-.mjs → _ui-u7T4YooX.mjs} +5 -1
- package/dist/_ui.d.ts +2 -0
- package/dist/{build-CACFbdQ4.mjs → build-BTOyN3H5.mjs} +4 -4
- package/dist/cli.d.ts +2 -1
- package/dist/cli.mjs +93 -32
- package/dist/{delete-DEZ7u3u4.mjs → delete-D3gZdSs-.mjs} +3 -3
- package/dist/{deploy-Ch0d_jje.mjs → deploy-Df6e7YFn.mjs} +21 -21
- package/dist/deploy.d.ts +0 -2
- package/dist/{dev-CdeRcYiQ.mjs → dev-DqIUtFfS.mjs} +2 -2
- package/dist/eject-DSldO60O.mjs +90 -0
- package/dist/eject.d.ts +33 -0
- package/dist/{init-GQsNWkLJ.mjs → init-B-04lRSV.mjs} +4 -4
- package/dist/{login-BeFUiU6M.mjs → login-CtimAsZk.mjs} +4 -15
- package/dist/login.d.ts +0 -9
- package/dist/project-config.d.ts +23 -0
- package/dist/project-config.mjs +3 -0
- package/dist/scaffold/CLAUDE.md +23 -0
- package/dist/scaffold/package.json +4 -3
- package/dist/scaffold/server.mjs +156 -0
- package/dist/{secret-4_dYyrpA.mjs → secret-LnFdg8SB.mjs} +7 -7
- package/dist/{storage-BTfErOOW.mjs → storage-Cjj3Pv6i.mjs} +2 -2
- package/dist/{studio-LNvXtWak.mjs → studio-Rl5Po2M6.mjs} +36 -169
- package/dist/{test-C-V98oC-.mjs → test-BtOzTcXE.mjs} +1 -1
- package/package.json +8 -3
- package/dist/_slug-api-fRNNR8tz.mjs +0 -27
package/dist/cli.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
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
|
-
import {
|
|
3
|
+
import { n as log, o as silenceOutput } from "./_ui-u7T4YooX.mjs";
|
|
4
4
|
import { a as errorMessage, l as resolveCwd, o as fileExists, t as AGENT_ENTRY } from "./_utils-8KKw-bzi.mjs";
|
|
5
5
|
import { existsSync, readFileSync } from "node:fs";
|
|
6
6
|
import path from "node:path";
|
|
7
7
|
import { fileURLToPath } from "node:url";
|
|
8
|
-
import { defineCommand, runMain } from "citty";
|
|
8
|
+
import { defineCommand, runMain, showUsage } from "citty";
|
|
9
9
|
//#region _cli-common.ts
|
|
10
10
|
/** Shared arg definitions for citty commands. */
|
|
11
11
|
const sharedArgs = {
|
|
@@ -55,11 +55,11 @@ function findUnknownFlags(rawArgs, argsDef) {
|
|
|
55
55
|
* A flag's comparison key: dashes dropped and lower-cased, with a leading
|
|
56
56
|
* `no` negation removed.
|
|
57
57
|
*
|
|
58
|
-
* citty accepts both `--
|
|
59
|
-
*
|
|
60
|
-
* spawns the kebab-case spelling. Comparing the literal text rejected
|
|
61
|
-
*
|
|
62
|
-
*
|
|
58
|
+
* citty accepts both `--allowPreviewSlug` and `--allow-preview-slug` for an
|
|
59
|
+
* arg declared as `allowPreviewSlug`, and the guest's in-sandbox Publish
|
|
60
|
+
* spawns the kebab-case spelling. Comparing the literal text rejected the
|
|
61
|
+
* kebab-case form as unknown and broke Publish for every studio user, so both
|
|
62
|
+
* sides are normalized to one key.
|
|
63
63
|
*/
|
|
64
64
|
function canonicalFlag(flag) {
|
|
65
65
|
return flag.replace(/^--?/, "").replace(/^no-/, "").replace(/-/g, "").toLowerCase();
|
|
@@ -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-Rl5Po2M6.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-Rl5Po2M6.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-Rl5Po2M6.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-Rl5Po2M6.mjs");
|
|
263
263
|
return executePublish({
|
|
264
264
|
cwd,
|
|
265
265
|
server: args.server,
|
|
@@ -286,6 +286,22 @@ function readCliVersion(dir) {
|
|
|
286
286
|
return "unknown";
|
|
287
287
|
}
|
|
288
288
|
const VERSION = readCliVersion(cliDir);
|
|
289
|
+
/**
|
|
290
|
+
* `aai secret put` for a subcommand, `aai` for the root — the name to put in
|
|
291
|
+
* front of `--help` when telling someone which usage to read.
|
|
292
|
+
*
|
|
293
|
+
* `meta` is a `Resolvable`, so it can be a function or a promise; only the
|
|
294
|
+
* plain-object form carries a name synchronously and anything else degrades
|
|
295
|
+
* to the binary name rather than blocking the error path on a resolve.
|
|
296
|
+
*/
|
|
297
|
+
function commandPath(cmd, parent) {
|
|
298
|
+
const nameOf = (c) => {
|
|
299
|
+
const meta = c?.meta;
|
|
300
|
+
return meta && typeof meta === "object" && "name" in meta && typeof meta.name === "string" ? meta.name : void 0;
|
|
301
|
+
};
|
|
302
|
+
const path = [nameOf(parent), nameOf(cmd)].filter((n) => n !== void 0).join(" ");
|
|
303
|
+
return path.startsWith("aai") ? path : `aai ${path}`.trim();
|
|
304
|
+
}
|
|
289
305
|
const init = defineCommand({
|
|
290
306
|
meta: {
|
|
291
307
|
name: "init",
|
|
@@ -317,7 +333,7 @@ const init = defineCommand({
|
|
|
317
333
|
},
|
|
318
334
|
async run({ args }) {
|
|
319
335
|
await runCommand(args, async (mode) => {
|
|
320
|
-
const { executeInit } = await import("./init-
|
|
336
|
+
const { executeInit } = await import("./init-B-04lRSV.mjs");
|
|
321
337
|
return executeInit({
|
|
322
338
|
dir: args.dir,
|
|
323
339
|
force: args.force,
|
|
@@ -346,7 +362,7 @@ const dev = defineCommand({
|
|
|
346
362
|
async run({ args }) {
|
|
347
363
|
await runCommand(args, async () => {
|
|
348
364
|
const cwd = await setup({ agent: true });
|
|
349
|
-
const { executeDev } = await import("./dev-
|
|
365
|
+
const { executeDev } = await import("./dev-DqIUtFfS.mjs");
|
|
350
366
|
return executeDev({
|
|
351
367
|
cwd,
|
|
352
368
|
port: args.port
|
|
@@ -362,8 +378,8 @@ const test = defineCommand({
|
|
|
362
378
|
args: { json: sharedArgs.json },
|
|
363
379
|
async run({ args }) {
|
|
364
380
|
await runCommand(args, async () => {
|
|
365
|
-
const cwd = await setup();
|
|
366
|
-
const { executeTest } = await import("./test-
|
|
381
|
+
const cwd = await setup({ agent: true });
|
|
382
|
+
const { executeTest } = await import("./test-BtOzTcXE.mjs");
|
|
367
383
|
return executeTest(cwd);
|
|
368
384
|
});
|
|
369
385
|
}
|
|
@@ -387,7 +403,7 @@ const build = defineCommand({
|
|
|
387
403
|
async run({ args }) {
|
|
388
404
|
await runCommand(args, async () => {
|
|
389
405
|
const cwd = await setup({ agent: true });
|
|
390
|
-
const { executeBuild } = await import("./build-
|
|
406
|
+
const { executeBuild } = await import("./build-BTOyN3H5.mjs");
|
|
391
407
|
return executeBuild({
|
|
392
408
|
cwd,
|
|
393
409
|
skipTests: args.skipTests,
|
|
@@ -396,6 +412,30 @@ const build = defineCommand({
|
|
|
396
412
|
});
|
|
397
413
|
}
|
|
398
414
|
});
|
|
415
|
+
const eject = defineCommand({
|
|
416
|
+
meta: {
|
|
417
|
+
name: "eject",
|
|
418
|
+
description: "Add the self-hosted server.mjs entrypoint to an older project"
|
|
419
|
+
},
|
|
420
|
+
args: {
|
|
421
|
+
force: {
|
|
422
|
+
type: "boolean",
|
|
423
|
+
alias: "f",
|
|
424
|
+
description: "Replace an existing server.mjs"
|
|
425
|
+
},
|
|
426
|
+
json: sharedArgs.json
|
|
427
|
+
},
|
|
428
|
+
async run({ args }) {
|
|
429
|
+
await runCommand(args, async () => {
|
|
430
|
+
const cwd = await setup({ agent: true });
|
|
431
|
+
const { executeEject } = await import("./eject-DSldO60O.mjs");
|
|
432
|
+
return executeEject({
|
|
433
|
+
cwd,
|
|
434
|
+
force: args.force
|
|
435
|
+
});
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
});
|
|
399
439
|
const deploy = defineCommand({
|
|
400
440
|
meta: {
|
|
401
441
|
name: "deploy",
|
|
@@ -405,10 +445,6 @@ const deploy = defineCommand({
|
|
|
405
445
|
args: {
|
|
406
446
|
server: sharedArgs.server,
|
|
407
447
|
json: sharedArgs.json,
|
|
408
|
-
allowMissingSecrets: {
|
|
409
|
-
type: "boolean",
|
|
410
|
-
description: "Deploy even when the agent's providers are missing credentials (the server warns instead of rejecting; set them afterwards with `aai secret put`)"
|
|
411
|
-
},
|
|
412
448
|
allowPreviewSlug: {
|
|
413
449
|
type: "boolean",
|
|
414
450
|
description: "Permit a `-preview`-suffixed slug (reserved for studio auto-previews; studio-internal — a slug you claim this way is subject to the preview reaper)"
|
|
@@ -421,11 +457,10 @@ const deploy = defineCommand({
|
|
|
421
457
|
async run({ args }) {
|
|
422
458
|
await runCommand(args, async () => {
|
|
423
459
|
const cwd = await setup({ agent: true });
|
|
424
|
-
const { executeDeploy } = await import("./deploy-
|
|
460
|
+
const { executeDeploy } = await import("./deploy-Df6e7YFn.mjs");
|
|
425
461
|
return executeDeploy({
|
|
426
462
|
cwd,
|
|
427
463
|
server: args.server,
|
|
428
|
-
allowMissingSecrets: args.allowMissingSecrets,
|
|
429
464
|
allowPreviewSlug: args.allowPreviewSlug,
|
|
430
465
|
skipTypecheck: args.skipTypecheck
|
|
431
466
|
});
|
|
@@ -444,7 +479,7 @@ const del = defineCommand({
|
|
|
444
479
|
async run({ args }) {
|
|
445
480
|
await runCommand(args, async () => {
|
|
446
481
|
const cwd = await setup();
|
|
447
|
-
const { executeDelete } = await import("./delete-
|
|
482
|
+
const { executeDelete } = await import("./delete-D3gZdSs-.mjs");
|
|
448
483
|
return executeDelete({
|
|
449
484
|
cwd,
|
|
450
485
|
server: args.server
|
|
@@ -475,7 +510,7 @@ const secret = defineCommand({
|
|
|
475
510
|
async run({ args }) {
|
|
476
511
|
await runCommand(args, async (mode) => {
|
|
477
512
|
const cwd = await setup();
|
|
478
|
-
const { executeSecretPut, NO_INPUT, readStdin } = await import("./secret-
|
|
513
|
+
const { executeSecretPut, NO_INPUT, readStdin } = await import("./secret-LnFdg8SB.mjs");
|
|
479
514
|
const value = mode === "json" ? await readStdin() : void 0;
|
|
480
515
|
if (mode === "json" && !value) throw new CliError(...NO_INPUT);
|
|
481
516
|
return executeSecretPut(cwd, args.name, value, args.server);
|
|
@@ -499,7 +534,7 @@ const secret = defineCommand({
|
|
|
499
534
|
async run({ args }) {
|
|
500
535
|
await runCommand(args, async () => {
|
|
501
536
|
const cwd = await setup();
|
|
502
|
-
const { executeSecretDelete } = await import("./secret-
|
|
537
|
+
const { executeSecretDelete } = await import("./secret-LnFdg8SB.mjs");
|
|
503
538
|
return executeSecretDelete(cwd, args.name, args.server);
|
|
504
539
|
});
|
|
505
540
|
}
|
|
@@ -516,7 +551,7 @@ const secret = defineCommand({
|
|
|
516
551
|
async run({ args }) {
|
|
517
552
|
await runCommand(args, async () => {
|
|
518
553
|
const cwd = await setup();
|
|
519
|
-
const { executeSecretList } = await import("./secret-
|
|
554
|
+
const { executeSecretList } = await import("./secret-LnFdg8SB.mjs");
|
|
520
555
|
return executeSecretList(cwd, args.server);
|
|
521
556
|
});
|
|
522
557
|
}
|
|
@@ -551,7 +586,7 @@ const storage = defineCommand({
|
|
|
551
586
|
},
|
|
552
587
|
async run({ args }) {
|
|
553
588
|
await runCommand(args, async () => {
|
|
554
|
-
const { executeStorageStatus } = await import("./storage-
|
|
589
|
+
const { executeStorageStatus } = await import("./storage-Cjj3Pv6i.mjs");
|
|
555
590
|
return executeStorageStatus(resolveStorageCwd(args.dir), args.server);
|
|
556
591
|
});
|
|
557
592
|
}
|
|
@@ -568,7 +603,7 @@ const storage = defineCommand({
|
|
|
568
603
|
},
|
|
569
604
|
async run({ args }) {
|
|
570
605
|
await runCommand(args, async () => {
|
|
571
|
-
const { executeStorageEnable } = await import("./storage-
|
|
606
|
+
const { executeStorageEnable } = await import("./storage-Cjj3Pv6i.mjs");
|
|
572
607
|
return executeStorageEnable(resolveStorageCwd(args.dir), args.server);
|
|
573
608
|
});
|
|
574
609
|
}
|
|
@@ -590,7 +625,7 @@ const storage = defineCommand({
|
|
|
590
625
|
},
|
|
591
626
|
async run({ args }) {
|
|
592
627
|
await runCommand(args, async () => {
|
|
593
|
-
const { executeStorageDisable } = await import("./storage-
|
|
628
|
+
const { executeStorageDisable } = await import("./storage-Cjj3Pv6i.mjs");
|
|
594
629
|
return executeStorageDisable(resolveStorageCwd(args.dir), {
|
|
595
630
|
server: args.server,
|
|
596
631
|
force: args.force
|
|
@@ -611,7 +646,7 @@ const login = defineCommand({
|
|
|
611
646
|
},
|
|
612
647
|
async run({ args }) {
|
|
613
648
|
await runCommand(args, async () => {
|
|
614
|
-
const { executeLogin } = await import("./login-
|
|
649
|
+
const { executeLogin } = await import("./login-CtimAsZk.mjs");
|
|
615
650
|
return executeLogin({ server: args.server });
|
|
616
651
|
});
|
|
617
652
|
}
|
|
@@ -624,7 +659,7 @@ const templates = defineCommand({
|
|
|
624
659
|
args: { json: sharedArgs.json },
|
|
625
660
|
async run({ args }) {
|
|
626
661
|
await runCommand(args, async (mode) => {
|
|
627
|
-
const { listTemplates } = await import("./_templates-
|
|
662
|
+
const { listTemplates } = await import("./_templates-CKYDgGyY.mjs");
|
|
628
663
|
const names = await listTemplates();
|
|
629
664
|
if (mode === "human") {
|
|
630
665
|
for (const name of names) log.message(name);
|
|
@@ -648,6 +683,7 @@ const mainCommand = defineCommand({
|
|
|
648
683
|
dev,
|
|
649
684
|
test,
|
|
650
685
|
build,
|
|
686
|
+
eject,
|
|
651
687
|
list,
|
|
652
688
|
pull,
|
|
653
689
|
push,
|
|
@@ -677,6 +713,31 @@ if (process.env.VITEST !== "true") {
|
|
|
677
713
|
process.argv.splice(2, 0, "publish");
|
|
678
714
|
};
|
|
679
715
|
/**
|
|
716
|
+
* Render usage the way the active output mode allows.
|
|
717
|
+
*
|
|
718
|
+
* citty calls `showUsage` from two places: the `--help` path, and its
|
|
719
|
+
* `catch` for a `CLIError` (a missing positional, an unknown subcommand) —
|
|
720
|
+
* where it writes the usage block to STDOUT and the reason to stderr. That
|
|
721
|
+
* second one breaks JSON mode's contract of exactly one result line on
|
|
722
|
+
* stdout, and JSON mode is auto-detected on a pipe: `aai secret put --json`
|
|
723
|
+
* put a usage block where a script's `jq` expected a result, with no JSON
|
|
724
|
+
* emitted at all. Every other failure path in this CLI converges on one
|
|
725
|
+
* emitter and gets this right.
|
|
726
|
+
*
|
|
727
|
+
* `--help` is explicitly still the human block whatever the mode — piping
|
|
728
|
+
* it into a pager is the normal way to read it, and it is not an error.
|
|
729
|
+
* The specific reason keeps going to stderr as citty already writes it, so
|
|
730
|
+
* nothing is lost to a human watching the terminal.
|
|
731
|
+
*/
|
|
732
|
+
const usageForMode = async (cmd, parent) => {
|
|
733
|
+
const argv = process.argv.slice(2);
|
|
734
|
+
if (argv.includes("--help") || argv.includes("-h") || getOutputMode({}) === "human") {
|
|
735
|
+
await showUsage(cmd, parent);
|
|
736
|
+
return;
|
|
737
|
+
}
|
|
738
|
+
await writeLine(`${JSON.stringify(fail("usage", `Invalid arguments for \`${commandPath(cmd, parent)}\`.`, `Run \`${commandPath(cmd, parent)} --help\` to see the arguments it accepts.`))}\n`);
|
|
739
|
+
};
|
|
740
|
+
/**
|
|
680
741
|
* Refuse an unrecognized flag instead of ignoring it.
|
|
681
742
|
*
|
|
682
743
|
* citty drops one silently, so `aai push --serverr=http://x` exited 0 having
|
|
@@ -690,7 +751,7 @@ if (process.env.VITEST !== "true") {
|
|
|
690
751
|
log.info("Run `aai <command> --help` to see the options it accepts.");
|
|
691
752
|
process.exit(1);
|
|
692
753
|
};
|
|
693
|
-
runDefault().then(assertKnownFlags).then(() => runMain(mainCommand)).catch((err) => {
|
|
754
|
+
runDefault().then(assertKnownFlags).then(() => runMain(mainCommand, { showUsage: usageForMode })).catch((err) => {
|
|
694
755
|
log.error(errorMessage(err));
|
|
695
756
|
process.exitCode = 1;
|
|
696
757
|
});
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { a as ok } from "./_output-CC300DzW.mjs";
|
|
3
|
-
import { n as log } from "./_ui-
|
|
4
|
-
import {
|
|
5
|
-
import { i as resolveDeployTarget, n as getServerInfo } from "./_agent-
|
|
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
6
|
import { n as apiRequest, t as HINT_NOT_DEPLOYED } from "./_api-client-B-upMGkc.mjs";
|
|
7
7
|
//#region delete.ts
|
|
8
8
|
async function runDelete(opts) {
|
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { a as ok } from "./_output-CC300DzW.mjs";
|
|
3
|
-
import { n as log, t as fmtUrl } from "./_ui-
|
|
3
|
+
import { n as log, r as notify, t as fmtUrl } from "./_ui-u7T4YooX.mjs";
|
|
4
4
|
import { a as errorMessage } from "./_utils-8KKw-bzi.mjs";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
5
|
+
import { s as updateProjectConfig } from "./_config-riTmrwxX.mjs";
|
|
6
|
+
import { i as evalWorkerConfig, t as buildAgentBundle } from "./_bundler-BvfPzf8J.mjs";
|
|
7
7
|
import { t as resolveServerEnv } from "./_server-common-DX8Bfrf5.mjs";
|
|
8
|
-
import { i as resolveDeployTarget } from "./_agent-
|
|
9
|
-
import { assertTypechecks } from "./_typecheck-gate-
|
|
8
|
+
import { i as resolveDeployTarget } from "./_agent-JGaAJ5j6.mjs";
|
|
9
|
+
import { assertTypechecks } from "./_typecheck-gate-4v9UBZHh.mjs";
|
|
10
10
|
import { n as apiRequest } from "./_api-client-B-upMGkc.mjs";
|
|
11
|
+
import { i as projectNameFromDir } from "./_studio-CXoY_Hsg.mjs";
|
|
11
12
|
import { gzipSync } from "node:zlib";
|
|
12
13
|
//#region _deploy.ts
|
|
13
14
|
async function runDeploy(opts) {
|
|
14
15
|
const body = gzipSync(JSON.stringify({
|
|
15
16
|
...opts.slug ? { slug: opts.slug } : {},
|
|
16
|
-
...opts.allowMissingSecrets ? { credentialPolicy: "warn" } : {},
|
|
17
17
|
...opts.allowPreviewSlug ? { allowPreviewSlug: true } : {},
|
|
18
18
|
env: opts.env,
|
|
19
19
|
worker: opts.bundle.worker,
|
|
20
20
|
clientFiles: opts.bundle.clientFiles
|
|
21
21
|
}));
|
|
22
|
-
|
|
22
|
+
return { slug: (await apiRequest(`${opts.url}/deploy`, {
|
|
23
23
|
method: "POST",
|
|
24
24
|
body,
|
|
25
25
|
headers: {
|
|
@@ -32,11 +32,7 @@ async function runDeploy(opts) {
|
|
|
32
32
|
...opts.slug ? {} : { retry: 0 },
|
|
33
33
|
...opts.retryDelay !== void 0 ? { retryDelay: opts.retryDelay } : {},
|
|
34
34
|
...opts.fetch ? { fetch: opts.fetch } : {}
|
|
35
|
-
});
|
|
36
|
-
return {
|
|
37
|
-
slug: data.slug,
|
|
38
|
-
...data.warnings ? { warnings: data.warnings } : {}
|
|
39
|
-
};
|
|
35
|
+
})).slug };
|
|
40
36
|
}
|
|
41
37
|
//#endregion
|
|
42
38
|
//#region deploy.ts
|
|
@@ -44,19 +40,24 @@ async function executeDeploy(opts) {
|
|
|
44
40
|
const { cwd } = opts;
|
|
45
41
|
const { config: projectConfig, serverUrl, apiKey } = await resolveDeployTarget(cwd, opts.server);
|
|
46
42
|
if (!opts.skipTypecheck) await assertTypechecks(cwd);
|
|
43
|
+
const preflightModule = import("./_preflight-BtfaYtbE.mjs");
|
|
47
44
|
const bundle = await buildAgentBundle(cwd, { minify: true });
|
|
48
|
-
const slug = projectConfig?.slug;
|
|
49
|
-
const
|
|
45
|
+
const slug = projectConfig?.slug ?? projectNameFromDir(cwd) ?? void 0;
|
|
46
|
+
const uploadEnv = {
|
|
47
|
+
ASSEMBLYAI_API_KEY: apiKey,
|
|
48
|
+
...await resolveServerEnv(cwd)
|
|
49
|
+
};
|
|
50
|
+
const { missingCredentialMessage, missingCredentials } = await preflightModule;
|
|
51
|
+
const config = await evalWorkerConfig(bundle.worker);
|
|
52
|
+
const missing = config ? missingCredentials(config, uploadEnv) : [];
|
|
53
|
+
const warnings = missing.length > 0 ? [missingCredentialMessage(missing)] : [];
|
|
54
|
+
for (const warning of warnings) notify("warn", warning);
|
|
50
55
|
log.step(`Deploying${slug ? ` ${slug}` : ""}…`);
|
|
51
56
|
const deployed = await runDeploy({
|
|
52
57
|
url: serverUrl,
|
|
53
58
|
bundle,
|
|
54
|
-
env:
|
|
55
|
-
ASSEMBLYAI_API_KEY: apiKey,
|
|
56
|
-
...env
|
|
57
|
-
},
|
|
59
|
+
env: uploadEnv,
|
|
58
60
|
...slug ? { slug } : {},
|
|
59
|
-
...opts.allowMissingSecrets ? { allowMissingSecrets: true } : {},
|
|
60
61
|
...opts.allowPreviewSlug ? { allowPreviewSlug: true } : {},
|
|
61
62
|
apiKey
|
|
62
63
|
});
|
|
@@ -73,12 +74,11 @@ async function executeDeploy(opts) {
|
|
|
73
74
|
serverUrl
|
|
74
75
|
})}`);
|
|
75
76
|
}
|
|
76
|
-
for (const warning of deployed.warnings ?? []) log.warn(warning);
|
|
77
77
|
log.success(`Deployed ${fmtUrl(agentUrl)}`);
|
|
78
78
|
return ok({
|
|
79
79
|
slug: deployed.slug,
|
|
80
80
|
url: agentUrl,
|
|
81
|
-
...
|
|
81
|
+
...warnings.length > 0 ? { warnings } : {}
|
|
82
82
|
});
|
|
83
83
|
}
|
|
84
84
|
//#endregion
|
package/dist/deploy.d.ts
CHANGED
|
@@ -7,8 +7,6 @@ type DeployData = {
|
|
|
7
7
|
export declare function executeDeploy(opts: {
|
|
8
8
|
cwd: string;
|
|
9
9
|
server?: string | undefined;
|
|
10
|
-
/** See DeployOpts.allowMissingSecrets (`--allow-missing-secrets`). */
|
|
11
|
-
allowMissingSecrets?: boolean | undefined;
|
|
12
10
|
/** See DeployOpts.allowPreviewSlug (`--allow-preview-slug`; studio-internal). */
|
|
13
11
|
allowPreviewSlug?: boolean | undefined;
|
|
14
12
|
/** `--skipTypecheck`: deploy without the tsc gate. */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { a as ok } from "./_output-CC300DzW.mjs";
|
|
3
|
-
import {
|
|
3
|
+
import { a as parsePort, n as log, r as notify, t as fmtUrl } from "./_ui-u7T4YooX.mjs";
|
|
4
4
|
import { i as errorDetail } from "./_utils-8KKw-bzi.mjs";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import { styleText } from "node:util";
|
|
@@ -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-BgXXSijx.mjs");
|
|
16
16
|
let cleanup;
|
|
17
17
|
let shuttingDown = false;
|
|
18
18
|
const onSignal = () => {
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { a as ok, t as CliError } from "./_output-CC300DzW.mjs";
|
|
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";
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
import fs from "node:fs/promises";
|
|
8
|
+
//#region eject.ts
|
|
9
|
+
/**
|
|
10
|
+
* `aai eject` — retrofit the self-hosted entrypoint into an existing project.
|
|
11
|
+
*
|
|
12
|
+
* Every project scaffolded from this CLI version onwards already has
|
|
13
|
+
* `server.mjs` and an `npm start` script: the scaffold ships them, so
|
|
14
|
+
* self-hosting is the default rather than something to opt into. This command
|
|
15
|
+
* exists for the projects that predate that — `aai init` before it, or a
|
|
16
|
+
* workspace pulled from a studio that was created earlier — where the files
|
|
17
|
+
* are simply missing.
|
|
18
|
+
*
|
|
19
|
+
* It COPIES from the scaffold rather than writing its own contents. Two
|
|
20
|
+
* definitions of "the self-hosted entrypoint" would drift, and the one nobody
|
|
21
|
+
* runs locally is the one that would rot; this way an ejected project is
|
|
22
|
+
* byte-identical to a freshly scaffolded one.
|
|
23
|
+
*/
|
|
24
|
+
/** The file `npm start` runs. Named once — the scaffold ships it under this name. */
|
|
25
|
+
const SERVER_ENTRY = "server.mjs";
|
|
26
|
+
/** The `scripts.start` value that runs {@link SERVER_ENTRY}. */
|
|
27
|
+
const START_SCRIPT = `node ${SERVER_ENTRY}`;
|
|
28
|
+
/**
|
|
29
|
+
* Add `scripts.start` unless the project already declares one.
|
|
30
|
+
*
|
|
31
|
+
* An existing `start` is left alone even under `--force`: `--force` is about
|
|
32
|
+
* replacing the entrypoint file, and silently rewriting the command a project
|
|
33
|
+
* boots with is a different, larger act. The mismatch is reported instead, so
|
|
34
|
+
* the choice stays the author's.
|
|
35
|
+
*/
|
|
36
|
+
async function ensureStartScript(cwd) {
|
|
37
|
+
const manifestPath = path.join(cwd, "package.json");
|
|
38
|
+
const manifest = await readJson(manifestPath);
|
|
39
|
+
if (!manifest) {
|
|
40
|
+
log.warn(`No package.json here — add "start": "${START_SCRIPT}" yourself to get \`npm start\`.`);
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
const existing = manifest.scripts?.start;
|
|
44
|
+
if (existing === START_SCRIPT) return false;
|
|
45
|
+
if (existing !== void 0) {
|
|
46
|
+
log.warn(`Kept your existing "start" script (${existing}) — run \`node ${SERVER_ENTRY}\`.`);
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
manifest.scripts = {
|
|
50
|
+
...manifest.scripts,
|
|
51
|
+
start: START_SCRIPT
|
|
52
|
+
};
|
|
53
|
+
await writeJson(manifestPath, manifest);
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* A missing scaffold source means a broken install (or an `AAI_TEMPLATES_DIR`
|
|
58
|
+
* pointed somewhere wrong), not anything the user did — so the message names
|
|
59
|
+
* the file and where it was looked for.
|
|
60
|
+
*
|
|
61
|
+
* Built here and thrown by the caller, the shape `build.ts` uses for the same
|
|
62
|
+
* reason: `useErrorCause` reads a `throw new Error` inside a `catch` as
|
|
63
|
+
* dropping the cause, and cannot see that `CliError` takes its options fourth.
|
|
64
|
+
*/
|
|
65
|
+
function scaffoldMissingError(source, err) {
|
|
66
|
+
return new CliError("scaffold_missing", `Could not read the scaffold's ${SERVER_ENTRY} at ${source}: ${errorMessage(err)}`, "Reinstall @alexkroman1/aai-cli.", { cause: err });
|
|
67
|
+
}
|
|
68
|
+
async function executeEject(opts) {
|
|
69
|
+
const { cwd, force } = opts;
|
|
70
|
+
const target = path.join(cwd, SERVER_ENTRY);
|
|
71
|
+
const overwritten = await fileExists(target);
|
|
72
|
+
if (overwritten && !force) throw new CliError("server_exists", `${SERVER_ENTRY} already exists — this project can already be self-hosted.`, `Run \`npm start\`, or re-run with --force to replace it with the current scaffold's copy.`);
|
|
73
|
+
const source = path.join(scaffoldDir(), SERVER_ENTRY);
|
|
74
|
+
try {
|
|
75
|
+
await fs.copyFile(source, target);
|
|
76
|
+
} catch (err) {
|
|
77
|
+
throw scaffoldMissingError(source, err);
|
|
78
|
+
}
|
|
79
|
+
const addedStartScript = await ensureStartScript(cwd);
|
|
80
|
+
log.success(`Wrote ${SERVER_ENTRY}${overwritten ? " (replaced)" : ""}`);
|
|
81
|
+
if (await fileExists(path.join(cwd, "client.tsx"))) log.info("This project has a custom UI: run `aai build` first so it is served.");
|
|
82
|
+
log.info("Next: npm start (PORT and HOST override the 127.0.0.1:3000 default)");
|
|
83
|
+
return ok({
|
|
84
|
+
file: target,
|
|
85
|
+
overwritten,
|
|
86
|
+
addedStartScript
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
//#endregion
|
|
90
|
+
export { executeEject };
|
package/dist/eject.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `aai eject` — retrofit the self-hosted entrypoint into an existing project.
|
|
3
|
+
*
|
|
4
|
+
* Every project scaffolded from this CLI version onwards already has
|
|
5
|
+
* `server.mjs` and an `npm start` script: the scaffold ships them, so
|
|
6
|
+
* self-hosting is the default rather than something to opt into. This command
|
|
7
|
+
* exists for the projects that predate that — `aai init` before it, or a
|
|
8
|
+
* workspace pulled from a studio that was created earlier — where the files
|
|
9
|
+
* are simply missing.
|
|
10
|
+
*
|
|
11
|
+
* It COPIES from the scaffold rather than writing its own contents. Two
|
|
12
|
+
* definitions of "the self-hosted entrypoint" would drift, and the one nobody
|
|
13
|
+
* runs locally is the one that would rot; this way an ejected project is
|
|
14
|
+
* byte-identical to a freshly scaffolded one.
|
|
15
|
+
*/
|
|
16
|
+
import { type CommandResult } from "./_output.ts";
|
|
17
|
+
/** The file `npm start` runs. Named once — the scaffold ships it under this name. */
|
|
18
|
+
export declare const SERVER_ENTRY = "server.mjs";
|
|
19
|
+
/** The `scripts.start` value that runs {@link SERVER_ENTRY}. */
|
|
20
|
+
export declare const START_SCRIPT = "node server.mjs";
|
|
21
|
+
type EjectData = {
|
|
22
|
+
/** Absolute path of the entrypoint written. */
|
|
23
|
+
file: string;
|
|
24
|
+
/** True when an existing `server.mjs` was replaced (`--force`). */
|
|
25
|
+
overwritten: boolean;
|
|
26
|
+
/** True when `scripts.start` was added to package.json by this run. */
|
|
27
|
+
addedStartScript: boolean;
|
|
28
|
+
};
|
|
29
|
+
export declare function executeEject(opts: {
|
|
30
|
+
cwd: string;
|
|
31
|
+
force?: boolean | undefined;
|
|
32
|
+
}): Promise<CommandResult<EjectData>>;
|
|
33
|
+
export {};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { a as ok } from "./_output-CC300DzW.mjs";
|
|
3
|
-
import { n as log,
|
|
3
|
+
import { n as log, s as unwrapCancel } from "./_ui-u7T4YooX.mjs";
|
|
4
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-
|
|
5
|
+
import { r as isDevMode, t as getMonorepoRoot } from "./_agent-JGaAJ5j6.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-Rl5Po2M6.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-Ca5Eg5pn.mjs");
|
|
98
98
|
const s = silent ? void 0 : p.spinner();
|
|
99
99
|
s?.start(`Creating ${dir}`);
|
|
100
100
|
await runInit({
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { a as ok, t as CliError } from "./_output-CC300DzW.mjs";
|
|
3
|
-
import { n as log } from "./_ui-
|
|
4
|
-
import { o as updateGlobalConfig, r as readGlobalConfig, t as approveServer } from "./_config-
|
|
5
|
-
import { a as resolveServerUrl } from "./_agent-
|
|
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";
|
|
6
|
+
import { linkConfirmationCode } from "@alexkroman1/aai/utils";
|
|
6
7
|
import { spawn } from "node:child_process";
|
|
7
8
|
import { setTimeout } from "node:timers/promises";
|
|
8
9
|
import { randomBytes } from "node:crypto";
|
|
@@ -115,18 +116,6 @@ function openerFor(platform) {
|
|
|
115
116
|
]];
|
|
116
117
|
return ["xdg-open", []];
|
|
117
118
|
}
|
|
118
|
-
/**
|
|
119
|
-
* Human-matchable confirmation derived from the link code — printed in the
|
|
120
|
-
* terminal AND shown on the browser approval gate (aai-studio-client's
|
|
121
|
-
* cli-link.ts derives the same value; keep the two in lockstep). Not a
|
|
122
|
-
* secret: both ends already hold the full code. It exists so someone who
|
|
123
|
-
* lands on an approval page they didn't cause has a concrete mismatch to
|
|
124
|
-
* notice ("what terminal?") instead of a bare Approve button.
|
|
125
|
-
*/
|
|
126
|
-
function linkConfirmationCode(code) {
|
|
127
|
-
const head = code.slice(0, 8).toUpperCase();
|
|
128
|
-
return `${head.slice(0, 4)}-${head.slice(4)}`;
|
|
129
|
-
}
|
|
130
119
|
/** Best-effort: the link URL is always printed, so a failure is fine. */
|
|
131
120
|
function defaultOpenBrowser(url) {
|
|
132
121
|
const [cmd, args] = openerFor(process.platform);
|
package/dist/login.d.ts
CHANGED
|
@@ -30,15 +30,6 @@ export type LoginDeps = {
|
|
|
30
30
|
/** Test seam — never set outside tests. */
|
|
31
31
|
timeoutMs?: number;
|
|
32
32
|
};
|
|
33
|
-
/**
|
|
34
|
-
* Human-matchable confirmation derived from the link code — printed in the
|
|
35
|
-
* terminal AND shown on the browser approval gate (aai-studio-client's
|
|
36
|
-
* cli-link.ts derives the same value; keep the two in lockstep). Not a
|
|
37
|
-
* secret: both ends already hold the full code. It exists so someone who
|
|
38
|
-
* lands on an approval page they didn't cause has a concrete mismatch to
|
|
39
|
-
* notice ("what terminal?") instead of a bare Approve button.
|
|
40
|
-
*/
|
|
41
|
-
export declare function linkConfirmationCode(code: string): string;
|
|
42
33
|
export declare function executeLogin(opts: {
|
|
43
34
|
server?: string | undefined;
|
|
44
35
|
}, deps?: LoginDeps): Promise<CommandResult<{
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The two on-disk formats a CLI invocation reads, as WRITERS other packages
|
|
3
|
+
* can call — the config home (`config.json`, which holds the API key) and a
|
|
4
|
+
* project's `.aai/project.json` pin.
|
|
5
|
+
*
|
|
6
|
+
* It exists for the studio guest. Publish materializes a workspace into a
|
|
7
|
+
* real project and then spawns this CLI against it
|
|
8
|
+
* (`aai-guest/studio-publish.ts`), which means writing both files first; it
|
|
9
|
+
* used to do that with `JSON.stringify`, so the shapes agreed by coincidence
|
|
10
|
+
* and nothing tied them to the schemas the CLI parses them back with. Two of
|
|
11
|
+
* this file's properties are not obvious from the JSON and were absent from
|
|
12
|
+
* the hand-written copies' successors-in-waiting: the config home is written
|
|
13
|
+
* 0600 through an atomic rename (so an older world-readable file is
|
|
14
|
+
* TIGHTENED rather than left), and the project pin is MERGED, never
|
|
15
|
+
* replaced — `.aai/project.json` also carries the studio link fields, and a
|
|
16
|
+
* writer that replaces the document drops them.
|
|
17
|
+
*
|
|
18
|
+
* Deliberately a thin re-export of `_config.ts` rather than a second
|
|
19
|
+
* implementation: the point is that there is one writer per format, not that
|
|
20
|
+
* there is a nicer one here.
|
|
21
|
+
*/
|
|
22
|
+
export type { GlobalConfig, ProjectConfig } from "./_config.ts";
|
|
23
|
+
export { updateProjectConfig, writeGlobalConfig as writeConfigHome } from "./_config.ts";
|