@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
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The deploy-time credential preflight — the classic dev/prod failure, caught
|
|
3
|
+
* before the upload instead of at the deployed agent's first session.
|
|
4
|
+
*
|
|
5
|
+
* An agent that ran locally on shell-exported provider keys dies after deploy
|
|
6
|
+
* with what looks like a provider outage: `aai dev` falls back to the shell
|
|
7
|
+
* (`withHostCredentialFallback`), and the platform never will. Naming the key
|
|
8
|
+
* here turns that into one line of output while the developer is still in the
|
|
9
|
+
* directory that owns the `.env`.
|
|
10
|
+
*
|
|
11
|
+
* **This lives in the CLI because the agent's config does.** The platform
|
|
12
|
+
* stores no description of a bundle and never evaluates one (see "The
|
|
13
|
+
* platform stores no agent config" in packages/aai-server/CLAUDE.md), so the
|
|
14
|
+
* only place that knows an agent needs `CARTESIA_API_KEY` is the process that
|
|
15
|
+
* just built it.
|
|
16
|
+
*
|
|
17
|
+
* **It WARNS, and must not be turned into a hard failure.** The CLI sees the
|
|
18
|
+
* env it is about to upload; it cannot see what is already stored against the
|
|
19
|
+
* slug from an earlier `aai secret put`, so a key the platform holds looks
|
|
20
|
+
* missing from here. The server-side check this replaced could see both and
|
|
21
|
+
* so could reject — moving the config to where it is authored costs that
|
|
22
|
+
* accuracy, and a false rejection is worse than a false warning: it blocks a
|
|
23
|
+
* deploy that would have worked.
|
|
24
|
+
*/
|
|
25
|
+
import { requiredProviderEnvVars } from "@alexkroman1/aai/runtime";
|
|
26
|
+
/**
|
|
27
|
+
* The config shape read out of a bundle's `__aaiConfig` export: the provider
|
|
28
|
+
* descriptors the credential derivation needs, plus the agent's declared
|
|
29
|
+
* `requiredEnv`. Deliberately structural rather than the SDK's `AgentConfig` —
|
|
30
|
+
* the export comes from the USER's installed SDK, which may be older or newer
|
|
31
|
+
* than this CLI's, so anything beyond these is not ours to assume.
|
|
32
|
+
*
|
|
33
|
+
* **The `__aaiConfig` export, not the bundle's default export.** They look
|
|
34
|
+
* interchangeable — `evalWorkerBundle` already returns the `AgentDef`, and
|
|
35
|
+
* `agentEnvWarnings` (`_dev-server.ts`) derives the same key set from one —
|
|
36
|
+
* but `__aaiConfig` is `toAgentConfig(def)`, which has run
|
|
37
|
+
* `normalizeAgentConveniences` and `defaultProviders`. A def written with an
|
|
38
|
+
* author shorthand (`llm: "gpt-5"`) still carries a STRING there, and
|
|
39
|
+
* `descriptorKind` reads a string as no kind at all, so deriving from the raw
|
|
40
|
+
* def silently omits that provider's key. The normalized config is what the
|
|
41
|
+
* runtime will actually resolve against, so it is what the preflight checks.
|
|
42
|
+
*/
|
|
43
|
+
export type PreflightConfig = Parameters<typeof requiredProviderEnvVars>[0] & {
|
|
44
|
+
requiredEnv?: readonly string[] | undefined;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Env var names the agent needs that the env being uploaded doesn't supply.
|
|
48
|
+
* Empty values count as missing — an empty credential authenticates nothing.
|
|
49
|
+
*
|
|
50
|
+
* Two sources: provider credentials derived from the stt/llm/tts/s2s
|
|
51
|
+
* descriptors (the same registry-backed derivation the runtime resolves keys
|
|
52
|
+
* with), and the agent's own declared `requiredEnv` — an `agent()` field for
|
|
53
|
+
* custom keys tools read from `ctx.env`, which no static derivation can see.
|
|
54
|
+
*/
|
|
55
|
+
export declare function missingCredentials(config: PreflightConfig, env: Record<string, string>): string[];
|
|
56
|
+
/** One line naming the missing keys and what to do about them. */
|
|
57
|
+
export declare function missingCredentialMessage(missing: string[]): string;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { n as getServerInfo } from "./_agent-JGaAJ5j6.mjs";
|
|
3
|
+
import { n as apiRequest, t as HINT_NOT_DEPLOYED } from "./_api-client-B-upMGkc.mjs";
|
|
4
|
+
//#region _slug-api.ts
|
|
5
|
+
/**
|
|
6
|
+
* Authenticated request against a deployed agent's slug-scoped resource
|
|
7
|
+
* (`${serverUrl}/${slug}${resourcePath}`) — the one shape every per-agent
|
|
8
|
+
* command (secret, storage) shares, including the standard "not deployed"
|
|
9
|
+
* 404 hint.
|
|
10
|
+
*
|
|
11
|
+
* Its own module (rather than living beside `getServerInfo` in `_agent.ts`)
|
|
12
|
+
* so tests can mock `_agent.ts`/`_api-client.ts` while this composition
|
|
13
|
+
* stays real — an intra-module call would bypass those mocks.
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* A SECRET request, routed to the project when this directory is linked to
|
|
17
|
+
* one and to the bare slug otherwise.
|
|
18
|
+
*
|
|
19
|
+
* A studio project deploys TWO agents — production and preview — and a
|
|
20
|
+
* secret has to reach both or the preview fails at its first session while
|
|
21
|
+
* production works. The project route fans out server-side
|
|
22
|
+
* (`aai-studio-server/studio-secrets.ts`); this CLI used to write the
|
|
23
|
+
* production slug alone, so a key set here was missing from the preview the
|
|
24
|
+
* user's own `aai publish` had created. An unlinked directory has one agent
|
|
25
|
+
* and keeps the per-slug route, which is the platform primitive underneath.
|
|
26
|
+
*/
|
|
27
|
+
async function secretRequest(cwd, resourcePath, init, server) {
|
|
28
|
+
const { serverUrl, slug, apiKey, studioProject } = await getServerInfo(cwd, server);
|
|
29
|
+
return {
|
|
30
|
+
data: await apiRequest(studioProject ? `${serverUrl}/studio/projects/${encodeURIComponent(studioProject)}/secret${resourcePath}` : `${serverUrl}/${slug}/secret${resourcePath}`, {
|
|
31
|
+
...init,
|
|
32
|
+
apiKey,
|
|
33
|
+
hints: { 404: HINT_NOT_DEPLOYED }
|
|
34
|
+
}),
|
|
35
|
+
target: studioProject ?? slug
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
async function slugRequest(cwd, resourcePath, init, server) {
|
|
39
|
+
const { serverUrl, slug, apiKey } = await getServerInfo(cwd, server);
|
|
40
|
+
return {
|
|
41
|
+
data: await apiRequest(`${serverUrl}/${slug}${resourcePath}`, {
|
|
42
|
+
...init,
|
|
43
|
+
apiKey,
|
|
44
|
+
hints: { 404: HINT_NOT_DEPLOYED }
|
|
45
|
+
}),
|
|
46
|
+
slug
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
//#endregion
|
|
50
|
+
export { slugRequest as n, secretRequest as t };
|
package/dist/_slug-api.d.ts
CHANGED
|
@@ -9,6 +9,22 @@ import { type ApiRequestOptions } from "./_api-client.ts";
|
|
|
9
9
|
* so tests can mock `_agent.ts`/`_api-client.ts` while this composition
|
|
10
10
|
* stays real — an intra-module call would bypass those mocks.
|
|
11
11
|
*/
|
|
12
|
+
/**
|
|
13
|
+
* A SECRET request, routed to the project when this directory is linked to
|
|
14
|
+
* one and to the bare slug otherwise.
|
|
15
|
+
*
|
|
16
|
+
* A studio project deploys TWO agents — production and preview — and a
|
|
17
|
+
* secret has to reach both or the preview fails at its first session while
|
|
18
|
+
* production works. The project route fans out server-side
|
|
19
|
+
* (`aai-studio-server/studio-secrets.ts`); this CLI used to write the
|
|
20
|
+
* production slug alone, so a key set here was missing from the preview the
|
|
21
|
+
* user's own `aai publish` had created. An unlinked directory has one agent
|
|
22
|
+
* and keeps the per-slug route, which is the platform primitive underneath.
|
|
23
|
+
*/
|
|
24
|
+
export declare function secretRequest<T = unknown>(cwd: string, resourcePath: string, init: Pick<ApiRequestOptions, "method" | "body" | "action">, server?: string): Promise<{
|
|
25
|
+
data: T;
|
|
26
|
+
target: string;
|
|
27
|
+
}>;
|
|
12
28
|
export declare function slugRequest<T = unknown>(cwd: string, resourcePath: string, init: Pick<ApiRequestOptions, "method" | "body" | "action">, server?: string): Promise<{
|
|
13
29
|
data: T;
|
|
14
30
|
slug: string;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { n as apiRequest } from "./_api-client-B-upMGkc.mjs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { MAX_SLUG_LENGTH, PREVIEW_SLUG_SUFFIX, VALID_SLUG_RE } from "@alexkroman1/aai/utils";
|
|
5
|
+
import { slugifyName } from "@alexkroman1/aai/slugify";
|
|
6
|
+
import { isLocalOnlyFile, snapshotWorkspaceFiles } from "@alexkroman1/aai/workspace-files";
|
|
7
|
+
//#region _studio.ts
|
|
8
|
+
/**
|
|
9
|
+
* Internals of the studio-workspace commands (`aai list/pull/push/publish`):
|
|
10
|
+
* the local source-file walk and the thin clients for the platform's
|
|
11
|
+
* `/studio/projects` routes. The workspace is the single source of truth —
|
|
12
|
+
* these helpers only move files between a local directory and the project's
|
|
13
|
+
* workspace row; production deploys happen exclusively through the studio's
|
|
14
|
+
* Publish route (which runs the deploy machinery in the project's sandbox).
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Snapshot the local project into a workspace file map.
|
|
18
|
+
*
|
|
19
|
+
* The walk, the caps, the skip rules and the strict UTF-8 decode all come
|
|
20
|
+
* from the SDK (`@alexkroman1/aai/workspace-files`), which is also what the
|
|
21
|
+
* guest's end-of-turn sync uses — the two write the same map from opposite
|
|
22
|
+
* ends, and a disagreement between them is not an error but a file silently
|
|
23
|
+
* dropped here and resurrected there.
|
|
24
|
+
*
|
|
25
|
+
* `isLocalOnlyFile` is the one rule this side adds: `.env` rides the secret
|
|
26
|
+
* routes and lockfiles are install output, so neither belongs in a row.
|
|
27
|
+
*/
|
|
28
|
+
function collectSourceFiles(dir) {
|
|
29
|
+
return snapshotWorkspaceFiles(dir, {
|
|
30
|
+
subject: "Project",
|
|
31
|
+
skipFile: isLocalOnlyFile
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* A studio project name derived from a directory name, or null if unusable.
|
|
36
|
+
*
|
|
37
|
+
* The normalization is the platform's own (`slugifyName`), not a local
|
|
38
|
+
* regex. This used to strip `[^a-z0-9-_]` by hand, which differs from the
|
|
39
|
+
* studio's slugifier on exactly the names people give agents: `Café
|
|
40
|
+
* Ordering` reduced to `caf-ordering` here and `cafe-ordering` there, so the
|
|
41
|
+
* same directory produced a different project depending on whether it was
|
|
42
|
+
* created by `aai push` or by typing the name into the studio.
|
|
43
|
+
*
|
|
44
|
+
* A `-preview` suffix is deliberately unusable. Publishing a project deploys
|
|
45
|
+
* it under the project's own name, so a `*-preview` project would claim a
|
|
46
|
+
* slug the studio's orphan-preview sweep reaps hourly — deleting the agent,
|
|
47
|
+
* its app-database schema, and its secrets on a schedule the user never
|
|
48
|
+
* asked for. Refusing the name is recoverable (rename the directory); losing
|
|
49
|
+
* a published agent to the reaper is not.
|
|
50
|
+
*/
|
|
51
|
+
function projectNameFromDir(dir) {
|
|
52
|
+
const name = slugifyName(path.basename(dir), MAX_SLUG_LENGTH);
|
|
53
|
+
if (name.endsWith(PREVIEW_SLUG_SUFFIX)) return null;
|
|
54
|
+
return VALID_SLUG_RE.test(name) ? name : null;
|
|
55
|
+
}
|
|
56
|
+
/** The shareable studio URL for a project — what every command prints. */
|
|
57
|
+
function studioProjectUrl(serverUrl, project) {
|
|
58
|
+
return `${serverUrl}/studio/chat/${project}`;
|
|
59
|
+
}
|
|
60
|
+
function listStudioProjects(serverUrl, apiKey) {
|
|
61
|
+
return apiRequest(`${serverUrl}/studio/projects`, {
|
|
62
|
+
apiKey,
|
|
63
|
+
action: "list"
|
|
64
|
+
}).then((res) => res.projects);
|
|
65
|
+
}
|
|
66
|
+
/** Fetch a project, or null when it doesn't exist (the push existence probe). */
|
|
67
|
+
function fetchStudioProject(serverUrl, apiKey, project) {
|
|
68
|
+
return apiRequest(`${serverUrl}/studio/projects/${encodeURIComponent(project)}`, {
|
|
69
|
+
apiKey,
|
|
70
|
+
action: "pull",
|
|
71
|
+
allow404: true
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
/** `PUT /studio/projects/:project/source` — the atomic whole-tree push. */
|
|
75
|
+
function pushStudioSource(serverUrl, apiKey, project, body) {
|
|
76
|
+
return apiRequest(`${serverUrl}/studio/projects/${encodeURIComponent(project)}/source`, {
|
|
77
|
+
apiKey,
|
|
78
|
+
action: "push",
|
|
79
|
+
method: "PUT",
|
|
80
|
+
body,
|
|
81
|
+
hints: { 409: "The studio has newer changes. Run `aai pull` to fetch them, or `aai push --force` to overwrite." }
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
/** `POST /studio/projects/:project/deploy` — Publish, in the project's sandbox. */
|
|
85
|
+
function publishStudioProject(serverUrl, apiKey, project) {
|
|
86
|
+
return apiRequest(`${serverUrl}/studio/projects/${encodeURIComponent(project)}/deploy`, {
|
|
87
|
+
apiKey,
|
|
88
|
+
action: "publish",
|
|
89
|
+
method: "POST",
|
|
90
|
+
retry: 0
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
//#endregion
|
|
94
|
+
export { publishStudioProject as a, projectNameFromDir as i, fetchStudioProject as n, pushStudioSource as o, listStudioProjects as r, studioProjectUrl as s, collectSourceFiles as t };
|
package/dist/_studio.d.ts
CHANGED
|
@@ -6,27 +6,30 @@
|
|
|
6
6
|
* workspace row; production deploys happen exclusively through the studio's
|
|
7
7
|
* Publish route (which runs the deploy machinery in the project's sandbox).
|
|
8
8
|
*/
|
|
9
|
+
import { type WorkspaceSnapshot } from "@alexkroman1/aai/workspace-files";
|
|
9
10
|
/**
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
11
|
+
* Snapshot the local project into a workspace file map.
|
|
12
|
+
*
|
|
13
|
+
* The walk, the caps, the skip rules and the strict UTF-8 decode all come
|
|
14
|
+
* from the SDK (`@alexkroman1/aai/workspace-files`), which is also what the
|
|
15
|
+
* guest's end-of-turn sync uses — the two write the same map from opposite
|
|
16
|
+
* ends, and a disagreement between them is not an error but a file silently
|
|
17
|
+
* dropped here and resurrected there.
|
|
18
|
+
*
|
|
19
|
+
* `isLocalOnlyFile` is the one rule this side adds: `.env` rides the secret
|
|
20
|
+
* routes and lockfiles are install output, so neither belongs in a row.
|
|
14
21
|
*/
|
|
15
|
-
export declare
|
|
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 and non-text files skipped with a
|
|
21
|
-
* warning rather than failing the whole push.
|
|
22
|
-
*/
|
|
23
|
-
export declare function collectSourceFiles(dir: string): Promise<{
|
|
24
|
-
files: Record<string, string>;
|
|
25
|
-
warnings: string[];
|
|
26
|
-
}>;
|
|
22
|
+
export declare function collectSourceFiles(dir: string): Promise<WorkspaceSnapshot>;
|
|
27
23
|
/**
|
|
28
24
|
* A studio project name derived from a directory name, or null if unusable.
|
|
29
25
|
*
|
|
26
|
+
* The normalization is the platform's own (`slugifyName`), not a local
|
|
27
|
+
* regex. This used to strip `[^a-z0-9-_]` by hand, which differs from the
|
|
28
|
+
* studio's slugifier on exactly the names people give agents: `Café
|
|
29
|
+
* Ordering` reduced to `caf-ordering` here and `cafe-ordering` there, so the
|
|
30
|
+
* same directory produced a different project depending on whether it was
|
|
31
|
+
* created by `aai push` or by typing the name into the studio.
|
|
32
|
+
*
|
|
30
33
|
* A `-preview` suffix is deliberately unusable. Publishing a project deploys
|
|
31
34
|
* it under the project's own name, so a `*-preview` project would claim a
|
|
32
35
|
* slug the studio's orphan-preview sweep reaps hourly — deleting the agent,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { a as errorMessage } from "./_utils-8KKw-bzi.mjs";
|
|
3
|
-
import { t as getMonorepoRoot } from "./_agent-
|
|
3
|
+
import { t as getMonorepoRoot } from "./_agent-JGaAJ5j6.mjs";
|
|
4
4
|
import { existsSync } from "node:fs";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import fs from "node:fs/promises";
|
|
@@ -119,6 +119,18 @@ async function readJsonFile(file) {
|
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
121
|
/**
|
|
122
|
+
* Directory holding the base scaffold — the files every project gets
|
|
123
|
+
* underneath its template (package.json, tsconfig, `server.mjs`, …).
|
|
124
|
+
*
|
|
125
|
+
* Exported so `aai eject` can copy one file out of it rather than carrying a
|
|
126
|
+
* second copy of that file's contents: the scaffold is the single definition
|
|
127
|
+
* of the self-hosted entrypoint, and a project retrofitted with `eject` gets
|
|
128
|
+
* byte-identical output to one `aai init` scaffolded.
|
|
129
|
+
*/
|
|
130
|
+
function scaffoldDir() {
|
|
131
|
+
return path.join(resolveTemplatesDir(), "scaffold");
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
122
134
|
* Layer the base scaffold (package.json, tsconfig, …) into targetDir
|
|
123
135
|
* WITHOUT overwriting anything already there. Shared by `aai init`
|
|
124
136
|
* (underneath a template) and `aai pull` (underneath the studio workspace
|
|
@@ -130,14 +142,14 @@ async function readJsonFile(file) {
|
|
|
130
142
|
* {@link layerScaffoldManifest}.
|
|
131
143
|
*/
|
|
132
144
|
async function layerScaffold(targetDir) {
|
|
133
|
-
const
|
|
134
|
-
if (!existsSync(
|
|
135
|
-
await fs.cp(
|
|
145
|
+
const dir = scaffoldDir();
|
|
146
|
+
if (!existsSync(dir)) return;
|
|
147
|
+
await fs.cp(dir, targetDir, {
|
|
136
148
|
recursive: true,
|
|
137
149
|
force: false,
|
|
138
150
|
errorOnExist: false
|
|
139
151
|
});
|
|
140
|
-
await layerScaffoldManifest(
|
|
152
|
+
await layerScaffoldManifest(dir, targetDir);
|
|
141
153
|
}
|
|
142
154
|
/**
|
|
143
155
|
* Copy a template into targetDir, merging scaffold files underneath.
|
|
@@ -154,4 +166,4 @@ async function downloadAndMergeTemplate(template, targetDir) {
|
|
|
154
166
|
await layerScaffold(targetDir);
|
|
155
167
|
}
|
|
156
168
|
//#endregion
|
|
157
|
-
export { REPO_URL, downloadAndMergeTemplate, layerScaffold, listTemplates };
|
|
169
|
+
export { REPO_URL, downloadAndMergeTemplate, layerScaffold, listTemplates, scaffoldDir };
|
package/dist/_templates.d.ts
CHANGED
|
@@ -35,6 +35,16 @@ type Manifest = Record<string, unknown>;
|
|
|
35
35
|
* Returns null when nothing was missing, so the common case writes no file.
|
|
36
36
|
*/
|
|
37
37
|
export declare function mergeScaffoldManifest(existing: Manifest, scaffold: Manifest): Manifest | null;
|
|
38
|
+
/**
|
|
39
|
+
* Directory holding the base scaffold — the files every project gets
|
|
40
|
+
* underneath its template (package.json, tsconfig, `server.mjs`, …).
|
|
41
|
+
*
|
|
42
|
+
* Exported so `aai eject` can copy one file out of it rather than carrying a
|
|
43
|
+
* second copy of that file's contents: the scaffold is the single definition
|
|
44
|
+
* of the self-hosted entrypoint, and a project retrofitted with `eject` gets
|
|
45
|
+
* byte-identical output to one `aai init` scaffolded.
|
|
46
|
+
*/
|
|
47
|
+
export declare function scaffoldDir(): string;
|
|
38
48
|
/**
|
|
39
49
|
* Layer the base scaffold (package.json, tsconfig, …) into targetDir
|
|
40
50
|
* WITHOUT overwriting anything already there. Shared by `aai init`
|
|
@@ -37,6 +37,10 @@ function notify(level, message) {
|
|
|
37
37
|
}
|
|
38
38
|
process.stderr.write(`${message}\n`);
|
|
39
39
|
}
|
|
40
|
+
/** Whether `silenceOutput()` has been called — i.e. we are in JSON mode. */
|
|
41
|
+
function outputSilenced() {
|
|
42
|
+
return silenced;
|
|
43
|
+
}
|
|
40
44
|
/**
|
|
41
45
|
* Unwrap a clack prompt result, exiting cleanly if the user cancelled.
|
|
42
46
|
* `message` lets the caller name what was cancelled (e.g. "Setup cancelled").
|
|
@@ -65,4 +69,4 @@ function parsePort(raw) {
|
|
|
65
69
|
return port;
|
|
66
70
|
}
|
|
67
71
|
//#endregion
|
|
68
|
-
export {
|
|
72
|
+
export { parsePort as a, outputSilenced as i, log as n, silenceOutput as o, notify as r, unwrapCancel as s, fmtUrl as t };
|
package/dist/_ui.d.ts
CHANGED
|
@@ -23,6 +23,8 @@ export declare function silenceOutput(): void;
|
|
|
23
23
|
* line — while a human tailing the log sees what happened.
|
|
24
24
|
*/
|
|
25
25
|
export declare function notify(level: "error" | "warn" | "info" | "success", message: string): void;
|
|
26
|
+
/** Whether `silenceOutput()` has been called — i.e. we are in JSON mode. */
|
|
27
|
+
export declare function outputSilenced(): boolean;
|
|
26
28
|
/**
|
|
27
29
|
* Unwrap a clack prompt result, exiting cleanly if the user cancelled.
|
|
28
30
|
* `message` lets the caller name what was cancelled (e.g. "Setup cancelled").
|
|
@@ -1,9 +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 { r as evalWorkerBundle, t as buildAgentBundle } from "./_bundler-
|
|
5
|
-
import { assertTypechecks } from "./_typecheck-gate-
|
|
6
|
-
import { classifyVitestError, runVitest } from "./test-
|
|
3
|
+
import { n as log } from "./_ui-u7T4YooX.mjs";
|
|
4
|
+
import { r as evalWorkerBundle, t as buildAgentBundle } from "./_bundler-BvfPzf8J.mjs";
|
|
5
|
+
import { assertTypechecks } from "./_typecheck-gate-4v9UBZHh.mjs";
|
|
6
|
+
import { classifyVitestError, runVitest } from "./test-BtOzTcXE.mjs";
|
|
7
7
|
//#region build.ts
|
|
8
8
|
/**
|
|
9
9
|
* `aai build` — bundle the agent without deploying, behind the same gates
|
package/dist/cli.d.ts
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
import { type ArgsDef, type CommandDef } from "citty";
|
|
2
|
+
export declare const mainCommand: CommandDef<ArgsDef>;
|