@alexkroman1/aai-cli 5.5.1 → 5.6.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/README.md +16 -7
- package/dist/{_agent-DMyOab9_.mjs → _agent-BB1ZaZsX.mjs} +3 -3
- package/dist/_agent.d.ts +3 -1
- package/dist/{_api-client-MenP4-O7.mjs → _api-client-B6_uvuLs.mjs} +1 -0
- package/dist/_api-client.d.ts +6 -0
- package/dist/_cli-common.d.ts +38 -0
- package/dist/{_config-5AEqhh-O.mjs → _config-PIC0nzRu.mjs} +29 -3
- package/dist/_config.d.ts +9 -1
- package/dist/_deploy.d.ts +7 -0
- package/dist/{_dev-server-vV05Fnki.mjs → _dev-server-CGptLIAm.mjs} +2 -2
- package/dist/{_init-BZ9t_Kz-.mjs → _init-BPFM4uBH.mjs} +3 -3
- package/dist/{_slug-api-DaqQJHk8.mjs → _slug-api-dcaQ_Uho.mjs} +2 -2
- package/dist/_studio-commands.d.ts +73 -0
- package/dist/_studio.d.ts +55 -0
- package/dist/{_templates-Bv8CR800.mjs → _templates-jmjgdgcd.mjs} +19 -8
- package/dist/_templates.d.ts +9 -0
- package/dist/{_typecheck-gate-9IHWDnl1.mjs → _typecheck-gate-DvE8S3aQ.mjs} +1 -1
- package/dist/{build-D_PgQOD4.mjs → build-BXwDB78d.mjs} +1 -1
- package/dist/cli.mjs +163 -34
- package/dist/delete-BaHgd9cN.mjs +51 -0
- package/dist/delete.d.ts +9 -2
- package/dist/{deploy-1eaXcfUw.mjs → deploy-D-O-Q_mW.mjs} +7 -5
- package/dist/deploy.d.ts +2 -0
- package/dist/{dev-gVNdGFYY.mjs → dev-C5P8amSg.mjs} +1 -1
- package/dist/{init-DoU4_txp.mjs → init-BGlOhIOl.mjs} +15 -14
- package/dist/login-B6IhXski.mjs +117 -0
- package/dist/login.d.ts +33 -20
- package/dist/scaffold/package.json +4 -4
- package/dist/{secret-CGAIAbUx.mjs → secret-_bHo4rqt.mjs} +1 -1
- package/dist/{storage-CnhOayhm.mjs → storage-MWiVx_mV.mjs} +1 -1
- package/dist/studio-CsRn2J1a.mjs +284 -0
- package/dist/studio.d.ts +52 -0
- package/package.json +4 -4
- package/dist/delete-DXilFBb1.mjs +0 -29
- package/dist/login-C59ZHzuO.mjs +0 -109
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @alexkroman1/aai-cli
|
|
2
2
|
|
|
3
|
-
The `aai` command — scaffold, run, test, and
|
|
3
|
+
The `aai` command — scaffold, run, test, and publish aai voice agents.
|
|
4
4
|
|
|
5
5
|
```sh
|
|
6
6
|
npm i -g @alexkroman1/aai-cli # or: npx @alexkroman1/aai-cli@latest
|
|
@@ -15,7 +15,10 @@ npm i -g @alexkroman1/aai-cli # or: npx @alexkroman1/aai-cli@latest
|
|
|
15
15
|
| `aai dev` | Local dev server: loads `agent.ts`, rebuilds on change, serves the browser client (`--port`) |
|
|
16
16
|
| `aai test` | Run the project's vitest suite |
|
|
17
17
|
| `aai build` | Bundle without deploying (type-checks first; `--skipTypecheck` opts out) |
|
|
18
|
-
| `aai
|
|
18
|
+
| `aai list` | List your studio projects |
|
|
19
|
+
| `aai pull <project>` | Pull a studio project into a local directory, ready for `aai dev` |
|
|
20
|
+
| `aai push` | Sync this project's source to its studio workspace (fast-forward-checked; `--force` overwrites) |
|
|
21
|
+
| `aai publish` | Push, then deploy to production — the studio's Publish button from the terminal (`.env` syncs as agent secrets) |
|
|
19
22
|
| `aai delete` | Remove a deployed agent |
|
|
20
23
|
| `aai secret put\|delete\|list` | Manage a deployed agent's secrets |
|
|
21
24
|
| `aai storage status\|enable\|disable` | Manage the agent's opt-in SQL database (`ctx.db`) |
|
|
@@ -30,16 +33,22 @@ aai init my-agent --template pizza-ordering
|
|
|
30
33
|
cd my-agent
|
|
31
34
|
# put ASSEMBLYAI_API_KEY=... in .env
|
|
32
35
|
aai dev # talk to it at the printed URL
|
|
33
|
-
aai
|
|
36
|
+
aai publish # ship it; .env values become the agent's secrets
|
|
34
37
|
```
|
|
35
38
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
agent
|
|
39
|
+
Every published agent is also a **studio project**: publishing prints a
|
|
40
|
+
studio link where the same source can be edited in the browser (with the
|
|
41
|
+
coding agent), and `aai pull` brings those edits back to your machine.
|
|
42
|
+
`push`/`pull` are fast-forward-only — an edit made in the studio since your
|
|
43
|
+
last pull surfaces as a conflict instead of being overwritten.
|
|
44
|
+
|
|
45
|
+
Publishes type-check the project locally, then build and deploy inside the
|
|
46
|
+
project's sandbox — byte-for-byte the studio's Publish path — preflight
|
|
47
|
+
required credentials, and print the agent's public URL.
|
|
39
48
|
|
|
40
49
|
## Notes
|
|
41
50
|
|
|
42
|
-
- A bare `aai` in a project directory offers to
|
|
51
|
+
- A bare `aai` in a project directory offers to publish (TTY-confirmed);
|
|
43
52
|
outside one it runs `init`.
|
|
44
53
|
- `--server <url>` targets a self-hosted platform; the origin is remembered
|
|
45
54
|
in your user config after explicit approval.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as readProjectConfig, i as readGlobalConfig, n as ensureApiKey, o as serverOrigin, t as approveServer } from "./_config-
|
|
2
|
+
import { a as readProjectConfig, i as readGlobalConfig, n as ensureApiKey, o as serverOrigin, t as approveServer } from "./_config-PIC0nzRu.mjs";
|
|
3
3
|
import { existsSync } from "node:fs";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
@@ -83,8 +83,8 @@ async function resolveDeployTarget(cwd, explicitServer) {
|
|
|
83
83
|
/** Like resolveDeployTarget, but requires an existing deployment (project config). */
|
|
84
84
|
async function getServerInfo(cwd, explicitServer) {
|
|
85
85
|
const { config, serverUrl, apiKey } = await resolveDeployTarget(cwd, explicitServer);
|
|
86
|
-
if (!config) throw new Error("
|
|
87
|
-
if (!VALID_SLUG_RE.test(config.slug)) throw new Error(`Invalid slug in .aai/project.json: ${JSON.stringify(config.slug)}\n Expected lowercase letters, digits, \`-\`, \`_\` (2-64 chars). Fix the file or run \`aai
|
|
86
|
+
if (!config?.slug) throw new Error("This project has no deployed agent — run `aai publish` first");
|
|
87
|
+
if (!VALID_SLUG_RE.test(config.slug)) throw new Error(`Invalid slug in .aai/project.json: ${JSON.stringify(config.slug)}\n Expected lowercase letters, digits, \`-\`, \`_\` (2-64 chars). Fix the file or run \`aai publish\` to create a fresh deployment.`);
|
|
88
88
|
return {
|
|
89
89
|
serverUrl,
|
|
90
90
|
slug: config.slug,
|
package/dist/_agent.d.ts
CHANGED
|
@@ -25,8 +25,10 @@ export declare function resolveServerUrl(explicit?: string, configUrl?: string,
|
|
|
25
25
|
*/
|
|
26
26
|
export declare function resolveDeployTarget(cwd: string, explicitServer?: string): Promise<{
|
|
27
27
|
config: {
|
|
28
|
-
slug
|
|
28
|
+
slug?: string | undefined;
|
|
29
29
|
serverUrl: string;
|
|
30
|
+
studioProject?: string | undefined;
|
|
31
|
+
studioSourceHash?: string | undefined;
|
|
30
32
|
} | null;
|
|
31
33
|
serverUrl: string;
|
|
32
34
|
apiKey: string;
|
package/dist/_api-client.d.ts
CHANGED
|
@@ -28,6 +28,12 @@ export type ApiRequestOptions = {
|
|
|
28
28
|
retryDelay?: number;
|
|
29
29
|
/** Optional fetch implementation for testing. Defaults to globalThis.fetch. */
|
|
30
30
|
fetch?: typeof globalThis.fetch;
|
|
31
|
+
/**
|
|
32
|
+
* Resolve `null` on a 404 instead of throwing — for existence probes
|
|
33
|
+
* ("is there a studio project with this name?") where absence is an
|
|
34
|
+
* answer, not a failure.
|
|
35
|
+
*/
|
|
36
|
+
allow404?: boolean;
|
|
31
37
|
};
|
|
32
38
|
/**
|
|
33
39
|
* Send an authenticated request to the platform API and return the parsed
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { type CommandResult, type OutputMode } from "./_output.ts";
|
|
2
|
+
/** Shared arg definitions for citty commands. */
|
|
3
|
+
export declare const sharedArgs: {
|
|
4
|
+
readonly server: {
|
|
5
|
+
readonly type: "string";
|
|
6
|
+
readonly alias: "s";
|
|
7
|
+
readonly description: "Platform server URL";
|
|
8
|
+
};
|
|
9
|
+
readonly yes: {
|
|
10
|
+
readonly type: "boolean";
|
|
11
|
+
readonly alias: "y";
|
|
12
|
+
readonly description: "Accept defaults (no prompts)";
|
|
13
|
+
};
|
|
14
|
+
readonly json: {
|
|
15
|
+
readonly type: "boolean";
|
|
16
|
+
readonly description: "Output JSON (auto-detected in non-TTY)";
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
/** Shared command setup: resolve cwd, optionally require agent.ts. */
|
|
20
|
+
export declare function setup(opts?: {
|
|
21
|
+
agent?: boolean;
|
|
22
|
+
}): Promise<string>;
|
|
23
|
+
/**
|
|
24
|
+
* Run a command body with standard output-mode resolution, error handling,
|
|
25
|
+
* and result emission.
|
|
26
|
+
*
|
|
27
|
+
* - API key acquisition is owned by `resolveDeployTarget`/`getServerInfo`
|
|
28
|
+
* inside the commands that talk to the platform — after the server-trust
|
|
29
|
+
* check, so an untrusted `serverUrl` is refused without prompting for a
|
|
30
|
+
* key, and commands with no platform traffic never prompt at all.
|
|
31
|
+
*
|
|
32
|
+
* A thrown error and a returned `fail(...)` converge here on one emitter:
|
|
33
|
+
* human mode logs the message, JSON mode writes exactly one result line,
|
|
34
|
+
* and both exit 1.
|
|
35
|
+
*/
|
|
36
|
+
export declare function runCommand(args: {
|
|
37
|
+
json?: boolean | undefined;
|
|
38
|
+
}, fn: (mode: OutputMode) => Promise<CommandResult<unknown>>): Promise<void>;
|
|
@@ -18,8 +18,17 @@ import { z } from "zod";
|
|
|
18
18
|
* that isn't an approved http(s) origin.
|
|
19
19
|
*/
|
|
20
20
|
const ProjectConfigSchema = z.object({
|
|
21
|
-
slug
|
|
22
|
-
|
|
21
|
+
/** Deployed agent slug — absent for a pulled project never published. */
|
|
22
|
+
slug: z.string().optional(),
|
|
23
|
+
serverUrl: z.string(),
|
|
24
|
+
/** Studio project this directory is linked to (`aai pull`/`aai push`). */
|
|
25
|
+
studioProject: z.string().optional(),
|
|
26
|
+
/**
|
|
27
|
+
* The workspace files hash at the last pull/push — `aai push` sends it
|
|
28
|
+
* back as the fast-forward token, so an edit made in the studio since
|
|
29
|
+
* then surfaces as a 409 instead of being silently overwritten.
|
|
30
|
+
*/
|
|
31
|
+
studioSourceHash: z.string().optional()
|
|
23
32
|
});
|
|
24
33
|
/**
|
|
25
34
|
* Resolve the global config directory (the platform-conventional env-paths
|
|
@@ -53,6 +62,23 @@ async function writeProjectConfig(agentDir, data) {
|
|
|
53
62
|
await writeJson(path.join(agentDir, ".aai", "project.json"), data);
|
|
54
63
|
}
|
|
55
64
|
/**
|
|
65
|
+
* Merge `patch` into the existing project config rather than replacing the
|
|
66
|
+
* file — a publish recording its `slug` must not drop the studio link
|
|
67
|
+
* fields a pull wrote, and vice versa.
|
|
68
|
+
*/
|
|
69
|
+
async function updateProjectConfig(agentDir, patch) {
|
|
70
|
+
let existing = null;
|
|
71
|
+
try {
|
|
72
|
+
existing = await readProjectConfig(agentDir);
|
|
73
|
+
} catch {}
|
|
74
|
+
const merged = {
|
|
75
|
+
...existing,
|
|
76
|
+
...patch
|
|
77
|
+
};
|
|
78
|
+
await writeProjectConfig(agentDir, merged);
|
|
79
|
+
return merged;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
56
82
|
* Origin of `url`, or `null` when it is not an absolute http(s) URL.
|
|
57
83
|
*
|
|
58
84
|
* Non-HTTP schemes are rejected rather than returned: `new URL()` yields the
|
|
@@ -121,4 +147,4 @@ async function ensureApiKey(configDir) {
|
|
|
121
147
|
return apiKey;
|
|
122
148
|
}
|
|
123
149
|
//#endregion
|
|
124
|
-
export { readProjectConfig as a,
|
|
150
|
+
export { readProjectConfig as a, writeGlobalConfig as c, readGlobalConfig as i, ensureApiKey as n, serverOrigin as o, getConfigDir as r, updateProjectConfig as s, approveServer as t };
|
package/dist/_config.d.ts
CHANGED
|
@@ -11,8 +11,10 @@ import { z } from "zod";
|
|
|
11
11
|
* that isn't an approved http(s) origin.
|
|
12
12
|
*/
|
|
13
13
|
declare const ProjectConfigSchema: z.ZodObject<{
|
|
14
|
-
slug: z.ZodString
|
|
14
|
+
slug: z.ZodOptional<z.ZodString>;
|
|
15
15
|
serverUrl: z.ZodString;
|
|
16
|
+
studioProject: z.ZodOptional<z.ZodString>;
|
|
17
|
+
studioSourceHash: z.ZodOptional<z.ZodString>;
|
|
16
18
|
}, z.core.$strip>;
|
|
17
19
|
/**
|
|
18
20
|
* Resolve the global config directory (the platform-conventional env-paths
|
|
@@ -27,6 +29,12 @@ export declare function getConfigDir(): string;
|
|
|
27
29
|
export type ProjectConfig = z.infer<typeof ProjectConfigSchema>;
|
|
28
30
|
export declare function readProjectConfig(agentDir: string): Promise<ProjectConfig | null>;
|
|
29
31
|
export declare function writeProjectConfig(agentDir: string, data: ProjectConfig): Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* Merge `patch` into the existing project config rather than replacing the
|
|
34
|
+
* file — a publish recording its `slug` must not drop the studio link
|
|
35
|
+
* fields a pull wrote, and vice versa.
|
|
36
|
+
*/
|
|
37
|
+
export declare function updateProjectConfig(agentDir: string, patch: Partial<ProjectConfig> & Pick<ProjectConfig, "serverUrl">): Promise<ProjectConfig>;
|
|
30
38
|
export type GlobalConfig = {
|
|
31
39
|
apiKey?: string;
|
|
32
40
|
/**
|
package/dist/_deploy.d.ts
CHANGED
|
@@ -15,6 +15,13 @@ export type DeployOpts = {
|
|
|
15
15
|
* panel needs a deployed slug to attach secrets to).
|
|
16
16
|
*/
|
|
17
17
|
allowMissingSecrets?: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Ask the server to permit a `-preview`-suffixed slug (`aai deploy
|
|
20
|
+
* --allow-preview-slug`). That suffix is reserved for the studio's
|
|
21
|
+
* auto-preview deploys — the server rejects it otherwise — and this is set
|
|
22
|
+
* by the studio's own in-guest deploy, not by ordinary users.
|
|
23
|
+
*/
|
|
24
|
+
allowPreviewSlug?: boolean;
|
|
18
25
|
/** Retry delay override for tests (0 = no real sleeps on retry paths). */
|
|
19
26
|
retryDelay?: number;
|
|
20
27
|
/** Optional fetch implementation for testing. Defaults to globalThis.fetch. */
|
|
@@ -4,7 +4,7 @@ import { a as errorMessage, r as errorCode } from "./_utils-Ch0J4s6a.mjs";
|
|
|
4
4
|
import { n as fallbackHtmlPlugin } from "./client-bundler-yiWoXrgb.mjs";
|
|
5
5
|
import { buildWorker } from "./worker-bundler.mjs";
|
|
6
6
|
import { n as createWorkerEvaluator } from "./_bundler-Cjaxa2wi.mjs";
|
|
7
|
-
import { n as ensureApiKey } from "./_config-
|
|
7
|
+
import { n as ensureApiKey } from "./_config-PIC0nzRu.mjs";
|
|
8
8
|
import { t as resolveServerEnv } from "./_server-common-CnaP_Urf.mjs";
|
|
9
9
|
import { createRequire } from "node:module";
|
|
10
10
|
import { existsSync } from "node:fs";
|
|
@@ -44,7 +44,7 @@ function agentEnvWarnings(agentDef, env, shellEnv = process.env) {
|
|
|
44
44
|
const missing = required.filter((name) => !(env[name] || shellEnv[name]));
|
|
45
45
|
if (missing.length > 0) warnings.push(`Missing provider credential${s(missing)}: ${missing.join(", ")}. Set ${them(missing)} in .env or the environment.`);
|
|
46
46
|
const shellOnly = required.filter((name) => !env[name] && shellEnv[name]);
|
|
47
|
-
if (shellOnly.length > 0) warnings.push(`${shellOnly.join(", ")} resolved from your shell, not .env — deployed agents won't have ${them(shellOnly)}. Declare ${them(shellOnly)} in .env before \`aai
|
|
47
|
+
if (shellOnly.length > 0) warnings.push(`${shellOnly.join(", ")} resolved from your shell, not .env — deployed agents won't have ${them(shellOnly)}. Declare ${them(shellOnly)} in .env before \`aai publish\`.`);
|
|
48
48
|
const declared = (agentDef.requiredEnv ?? []).filter((name) => !env[name]);
|
|
49
49
|
if (declared.length > 0) warnings.push(`Missing requiredEnv key${s(declared)} declared by the agent: ${declared.join(", ")}. Set ${them(declared)} in .env — ctx.env will not contain ${them(declared)} otherwise.`);
|
|
50
50
|
return warnings;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { c as readJson, d as writeJson, s as isEexist } from "./_utils-Ch0J4s6a.mjs";
|
|
3
|
-
import { r as isDevMode, t as getMonorepoRoot } from "./_agent-
|
|
4
|
-
import { REPO_URL, downloadAndMergeTemplate } from "./_templates-
|
|
3
|
+
import { r as isDevMode, t as getMonorepoRoot } from "./_agent-BB1ZaZsX.mjs";
|
|
4
|
+
import { REPO_URL, downloadAndMergeTemplate } from "./_templates-jmjgdgcd.mjs";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import fs from "node:fs/promises";
|
|
7
7
|
//#region _init.ts
|
|
@@ -15,7 +15,7 @@ A voice agent built with [aai](${REPO_URL}).
|
|
|
15
15
|
\`\`\`sh
|
|
16
16
|
npm install # Install dependencies
|
|
17
17
|
aai dev # Run locally (opens browser)
|
|
18
|
-
aai
|
|
18
|
+
aai publish # Publish to production (and sync to the studio)
|
|
19
19
|
\`\`\`
|
|
20
20
|
|
|
21
21
|
## Secrets
|
|
@@ -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-BB1ZaZsX.mjs";
|
|
3
|
+
import { n as apiRequest, t as HINT_NOT_DEPLOYED } from "./_api-client-B6_uvuLs.mjs";
|
|
4
4
|
//#region _slug-api.ts
|
|
5
5
|
/**
|
|
6
6
|
* Authenticated request against a deployed agent's slug-scoped resource
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
export declare const list: import("citty").CommandDef<{
|
|
2
|
+
readonly server: {
|
|
3
|
+
readonly type: "string";
|
|
4
|
+
readonly alias: "s";
|
|
5
|
+
readonly description: "Platform server URL";
|
|
6
|
+
};
|
|
7
|
+
readonly json: {
|
|
8
|
+
readonly type: "boolean";
|
|
9
|
+
readonly description: "Output JSON (auto-detected in non-TTY)";
|
|
10
|
+
};
|
|
11
|
+
}>;
|
|
12
|
+
export declare const pull: import("citty").CommandDef<{
|
|
13
|
+
readonly project: {
|
|
14
|
+
readonly type: "positional";
|
|
15
|
+
readonly description: "Studio project name (see `aai list`)";
|
|
16
|
+
readonly required: true;
|
|
17
|
+
};
|
|
18
|
+
readonly dir: {
|
|
19
|
+
readonly type: "positional";
|
|
20
|
+
readonly description: "Target directory (default: the project name)";
|
|
21
|
+
readonly required: false;
|
|
22
|
+
};
|
|
23
|
+
readonly force: {
|
|
24
|
+
readonly type: "boolean";
|
|
25
|
+
readonly alias: "f";
|
|
26
|
+
readonly description: "Overwrite files in a non-empty directory";
|
|
27
|
+
};
|
|
28
|
+
readonly server: {
|
|
29
|
+
readonly type: "string";
|
|
30
|
+
readonly alias: "s";
|
|
31
|
+
readonly description: "Platform server URL";
|
|
32
|
+
};
|
|
33
|
+
readonly json: {
|
|
34
|
+
readonly type: "boolean";
|
|
35
|
+
readonly description: "Output JSON (auto-detected in non-TTY)";
|
|
36
|
+
};
|
|
37
|
+
}>;
|
|
38
|
+
export declare const push: import("citty").CommandDef<{
|
|
39
|
+
readonly force: {
|
|
40
|
+
readonly type: "boolean";
|
|
41
|
+
readonly alias: "f";
|
|
42
|
+
readonly description: "Overwrite studio-side changes instead of failing the fast-forward check";
|
|
43
|
+
};
|
|
44
|
+
readonly server: {
|
|
45
|
+
readonly type: "string";
|
|
46
|
+
readonly alias: "s";
|
|
47
|
+
readonly description: "Platform server URL";
|
|
48
|
+
};
|
|
49
|
+
readonly json: {
|
|
50
|
+
readonly type: "boolean";
|
|
51
|
+
readonly description: "Output JSON (auto-detected in non-TTY)";
|
|
52
|
+
};
|
|
53
|
+
}>;
|
|
54
|
+
export declare const publish: import("citty").CommandDef<{
|
|
55
|
+
readonly force: {
|
|
56
|
+
readonly type: "boolean";
|
|
57
|
+
readonly alias: "f";
|
|
58
|
+
readonly description: "Overwrite studio-side changes instead of failing the fast-forward check";
|
|
59
|
+
};
|
|
60
|
+
readonly server: {
|
|
61
|
+
readonly type: "string";
|
|
62
|
+
readonly alias: "s";
|
|
63
|
+
readonly description: "Platform server URL";
|
|
64
|
+
};
|
|
65
|
+
readonly json: {
|
|
66
|
+
readonly type: "boolean";
|
|
67
|
+
readonly description: "Output JSON (auto-detected in non-TTY)";
|
|
68
|
+
};
|
|
69
|
+
readonly skipTypecheck: {
|
|
70
|
+
readonly type: "boolean";
|
|
71
|
+
readonly description: "Skip type checking before publishing";
|
|
72
|
+
};
|
|
73
|
+
}>;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internals of the studio-workspace commands (`aai list/pull/push/publish`):
|
|
3
|
+
* the local source-file walk and the thin clients for the platform's
|
|
4
|
+
* `/studio/projects` routes. The workspace is the single source of truth —
|
|
5
|
+
* these helpers only move files between a local directory and the project's
|
|
6
|
+
* workspace row; production deploys happen exclusively through the studio's
|
|
7
|
+
* Publish route (which runs the deploy machinery in the project's sandbox).
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Mirrors of the studio workspace caps (`aai-studio-server/studio-limits.ts`)
|
|
11
|
+
* — by value, like `aai-guest/limits.ts`, since the CLI cannot depend on the
|
|
12
|
+
* private server package. The server re-validates every push; these exist so
|
|
13
|
+
* an oversized file is a named warning locally instead of a rejected upload.
|
|
14
|
+
*/
|
|
15
|
+
export declare const MAX_STUDIO_FILE_BYTES = 256000;
|
|
16
|
+
export declare const MAX_STUDIO_FILES = 100;
|
|
17
|
+
/**
|
|
18
|
+
* Walk a local project into the path→content record a workspace stores —
|
|
19
|
+
* the CLI-side twin of the guest's `snapshotWorkspace`: same ignored
|
|
20
|
+
* directories, same caps, oversized files skipped with a warning rather
|
|
21
|
+
* than failing the whole push.
|
|
22
|
+
*/
|
|
23
|
+
export declare function collectSourceFiles(dir: string): Promise<{
|
|
24
|
+
files: Record<string, string>;
|
|
25
|
+
warnings: string[];
|
|
26
|
+
}>;
|
|
27
|
+
/** A studio project name derived from a directory name, or null if unusable. */
|
|
28
|
+
export declare function projectNameFromDir(dir: string): string | null;
|
|
29
|
+
/** The shareable studio URL for a project — what every command prints. */
|
|
30
|
+
export declare function studioProjectUrl(serverUrl: string, project: string): string;
|
|
31
|
+
/** `GET /studio/projects/:project` — see `projectPayload` server-side. */
|
|
32
|
+
export type StudioProject = {
|
|
33
|
+
files: Record<string, string>;
|
|
34
|
+
sourceHash: string;
|
|
35
|
+
deployedSlug?: string;
|
|
36
|
+
unpublished?: boolean;
|
|
37
|
+
};
|
|
38
|
+
export declare function listStudioProjects(serverUrl: string, apiKey: string): Promise<string[]>;
|
|
39
|
+
/** Fetch a project, or null when it doesn't exist (the push existence probe). */
|
|
40
|
+
export declare function fetchStudioProject(serverUrl: string, apiKey: string, project: string): Promise<StudioProject | null>;
|
|
41
|
+
/** `PUT /studio/projects/:project/source` — the atomic whole-tree push. */
|
|
42
|
+
export declare function pushStudioSource(serverUrl: string, apiKey: string, project: string, body: {
|
|
43
|
+
files: Record<string, string>;
|
|
44
|
+
baseHash?: string | undefined;
|
|
45
|
+
}): Promise<{
|
|
46
|
+
sourceHash: string;
|
|
47
|
+
created: boolean;
|
|
48
|
+
}>;
|
|
49
|
+
/** `POST /studio/projects/:project/deploy` — Publish, in the project's sandbox. */
|
|
50
|
+
export declare function publishStudioProject(serverUrl: string, apiKey: string, project: string): Promise<{
|
|
51
|
+
ok: true;
|
|
52
|
+
slug: string;
|
|
53
|
+
url: string;
|
|
54
|
+
output: string;
|
|
55
|
+
}>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { a as errorMessage } from "./_utils-Ch0J4s6a.mjs";
|
|
3
|
-
import { t as getMonorepoRoot } from "./_agent-
|
|
3
|
+
import { t as getMonorepoRoot } from "./_agent-BB1ZaZsX.mjs";
|
|
4
4
|
import { existsSync } from "node:fs";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import fs from "node:fs/promises";
|
|
@@ -47,6 +47,22 @@ async function listTemplates(root = resolveTemplatesDir()) {
|
|
|
47
47
|
return available.filter((e) => e.isDirectory()).map((e) => e.name).sort();
|
|
48
48
|
}
|
|
49
49
|
/**
|
|
50
|
+
* Layer the base scaffold (package.json, tsconfig, …) into targetDir
|
|
51
|
+
* WITHOUT overwriting anything already there. Shared by `aai init`
|
|
52
|
+
* (underneath a template) and `aai pull` (underneath the studio workspace
|
|
53
|
+
* files — the workspace stores source, and the scaffold completes it into a
|
|
54
|
+
* runnable project the same way the guest's `ensureProjectShape` does
|
|
55
|
+
* before an in-sandbox build).
|
|
56
|
+
*/
|
|
57
|
+
async function layerScaffold(targetDir) {
|
|
58
|
+
const scaffoldDir = path.join(resolveTemplatesDir(), "scaffold");
|
|
59
|
+
if (existsSync(scaffoldDir)) await fs.cp(scaffoldDir, targetDir, {
|
|
60
|
+
recursive: true,
|
|
61
|
+
force: false,
|
|
62
|
+
errorOnExist: false
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
50
66
|
* Copy a template into targetDir, merging scaffold files underneath.
|
|
51
67
|
*/
|
|
52
68
|
async function downloadAndMergeTemplate(template, targetDir) {
|
|
@@ -58,12 +74,7 @@ async function downloadAndMergeTemplate(template, targetDir) {
|
|
|
58
74
|
recursive: true,
|
|
59
75
|
force: true
|
|
60
76
|
});
|
|
61
|
-
|
|
62
|
-
if (existsSync(scaffoldDir)) await fs.cp(scaffoldDir, targetDir, {
|
|
63
|
-
recursive: true,
|
|
64
|
-
force: false,
|
|
65
|
-
errorOnExist: false
|
|
66
|
-
});
|
|
77
|
+
await layerScaffold(targetDir);
|
|
67
78
|
}
|
|
68
79
|
//#endregion
|
|
69
|
-
export { REPO_URL, downloadAndMergeTemplate, listTemplates };
|
|
80
|
+
export { REPO_URL, downloadAndMergeTemplate, layerScaffold, listTemplates };
|
package/dist/_templates.d.ts
CHANGED
|
@@ -21,6 +21,15 @@ export declare function bundledTemplatesDir(): string;
|
|
|
21
21
|
* can never drift.
|
|
22
22
|
*/
|
|
23
23
|
export declare function listTemplates(root?: string): Promise<string[]>;
|
|
24
|
+
/**
|
|
25
|
+
* Layer the base scaffold (package.json, tsconfig, …) into targetDir
|
|
26
|
+
* WITHOUT overwriting anything already there. Shared by `aai init`
|
|
27
|
+
* (underneath a template) and `aai pull` (underneath the studio workspace
|
|
28
|
+
* files — the workspace stores source, and the scaffold completes it into a
|
|
29
|
+
* runnable project the same way the guest's `ensureProjectShape` does
|
|
30
|
+
* before an in-sandbox build).
|
|
31
|
+
*/
|
|
32
|
+
export declare function layerScaffold(targetDir: string): Promise<void>;
|
|
24
33
|
/**
|
|
25
34
|
* Copy a template into targetDir, merging scaffold files underneath.
|
|
26
35
|
*/
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { n as log, o as CliError, u as ok } from "./_ui-8kOEB-JH.mjs";
|
|
3
3
|
import { r as evalWorkerBundle, t as buildAgentBundle } from "./_bundler-Cjaxa2wi.mjs";
|
|
4
|
-
import {
|
|
4
|
+
import { assertTypechecks } from "./_typecheck-gate-DvE8S3aQ.mjs";
|
|
5
5
|
import { classifyVitestError, runVitest } from "./test-3Gq4pqH_.mjs";
|
|
6
6
|
//#region build.ts
|
|
7
7
|
/**
|