@alexkroman1/aai-cli 5.8.0 → 5.8.1
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/{_init-D7JIT-IJ.mjs → _init-Dei2JRmn.mjs} +1 -1
- package/dist/{_templates-Bt6u9_68.mjs → _templates-BfyRyE7z.mjs} +78 -1
- package/dist/_templates.d.ts +18 -0
- package/dist/cli.mjs +6 -6
- package/dist/{init-BT-IU9AR.mjs → init-BpBbttOv.mjs} +2 -2
- package/dist/scaffold/CLAUDE.md +1 -1
- package/dist/scaffold/package.json +3 -3
- package/dist/{studio-sXvYUxr5.mjs → studio-_UBBvh5V.mjs} +1 -1
- package/package.json +3 -3
|
@@ -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
3
|
import { r as isDevMode, t as getMonorepoRoot } from "./_agent-2nVugrN3.mjs";
|
|
4
|
-
import { REPO_URL, downloadAndMergeTemplate } from "./_templates-
|
|
4
|
+
import { REPO_URL, downloadAndMergeTemplate } from "./_templates-BfyRyE7z.mjs";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import fs from "node:fs/promises";
|
|
7
7
|
//#region _init.ts
|
|
@@ -46,6 +46,78 @@ async function listTemplates(root = resolveTemplatesDir()) {
|
|
|
46
46
|
}
|
|
47
47
|
return available.filter((e) => e.isDirectory()).map((e) => e.name).sort();
|
|
48
48
|
}
|
|
49
|
+
/** package.json fields merged key-by-key rather than whole. */
|
|
50
|
+
const MERGED_MANIFEST_FIELDS = [
|
|
51
|
+
"dependencies",
|
|
52
|
+
"devDependencies",
|
|
53
|
+
"scripts"
|
|
54
|
+
];
|
|
55
|
+
function isRecord(value) {
|
|
56
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Fill a manifest's gaps from the scaffold's, `existing` always winning.
|
|
60
|
+
*
|
|
61
|
+
* The same rule the file layering uses, one level deeper: a top-level field
|
|
62
|
+
* the manifest already declares is left alone, and for the three map fields
|
|
63
|
+
* it is each ENTRY that is left alone. Per-entry matters both ways — a
|
|
64
|
+
* workspace manifest pins its `dependencies` to exact installed versions and
|
|
65
|
+
* must keep them, while a single agent-added `devDependencies` entry must not
|
|
66
|
+
* shadow the whole toolchain block.
|
|
67
|
+
*
|
|
68
|
+
* Returns null when nothing was missing, so the common case writes no file.
|
|
69
|
+
*/
|
|
70
|
+
function mergeScaffoldManifest(existing, scaffold) {
|
|
71
|
+
const merged = { ...existing };
|
|
72
|
+
let changed = false;
|
|
73
|
+
for (const [key, value] of Object.entries(scaffold)) {
|
|
74
|
+
const mine = merged[key];
|
|
75
|
+
if (mine === void 0) {
|
|
76
|
+
merged[key] = value;
|
|
77
|
+
changed = true;
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
if (!MERGED_MANIFEST_FIELDS.includes(key)) continue;
|
|
81
|
+
if (!(isRecord(mine) && isRecord(value))) continue;
|
|
82
|
+
const entries = { ...mine };
|
|
83
|
+
for (const [dep, spec] of Object.entries(value)) {
|
|
84
|
+
if (dep in entries) continue;
|
|
85
|
+
entries[dep] = spec;
|
|
86
|
+
changed = true;
|
|
87
|
+
}
|
|
88
|
+
merged[key] = entries;
|
|
89
|
+
}
|
|
90
|
+
return changed ? merged : null;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Merge the scaffold's package.json UNDER the one already in `targetDir`.
|
|
94
|
+
*
|
|
95
|
+
* The file-level layering below can only skip a manifest that already exists,
|
|
96
|
+
* and for `aai pull` that manifest is the studio workspace's — which declares
|
|
97
|
+
* its runtime dependencies and nothing else. Toolchain packages are baked into
|
|
98
|
+
* the guest sandbox, so the workspace deliberately never names them (see
|
|
99
|
+
* aai-guest/studio-project-shape.ts); on a laptop nothing bakes them, so
|
|
100
|
+
* `pnpm install` fetched no `vite`, no `@vitejs/plugin-react`, no
|
|
101
|
+
* `@tailwindcss/vite`, and `aai dev` died resolving the vite.config.ts the
|
|
102
|
+
* very same layering had just written. Completing the manifest is the same job
|
|
103
|
+
* as completing the file tree.
|
|
104
|
+
*/
|
|
105
|
+
async function layerScaffoldManifest(scaffoldDir, targetDir) {
|
|
106
|
+
const target = path.join(targetDir, "package.json");
|
|
107
|
+
const [mine, theirs] = await Promise.all([readJsonFile(target), readJsonFile(path.join(scaffoldDir, "package.json"))]);
|
|
108
|
+
if (!(mine && theirs)) return;
|
|
109
|
+
const merged = mergeScaffoldManifest(mine, theirs);
|
|
110
|
+
if (merged) await fs.writeFile(target, `${JSON.stringify(merged, null, 2)}\n`, "utf-8");
|
|
111
|
+
}
|
|
112
|
+
/** Parse a JSON file, or null when it is missing or unparseable. */
|
|
113
|
+
async function readJsonFile(file) {
|
|
114
|
+
try {
|
|
115
|
+
const parsed = JSON.parse(await fs.readFile(file, "utf-8"));
|
|
116
|
+
return isRecord(parsed) ? parsed : null;
|
|
117
|
+
} catch {
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
49
121
|
/**
|
|
50
122
|
* Layer the base scaffold (package.json, tsconfig, …) into targetDir
|
|
51
123
|
* WITHOUT overwriting anything already there. Shared by `aai init`
|
|
@@ -53,14 +125,19 @@ async function listTemplates(root = resolveTemplatesDir()) {
|
|
|
53
125
|
* files — the workspace stores source, and the scaffold completes it into a
|
|
54
126
|
* runnable project the same way the guest's `ensureProjectShape` does
|
|
55
127
|
* before an in-sandbox build).
|
|
128
|
+
*
|
|
129
|
+
* package.json is the one file merged rather than skipped — see
|
|
130
|
+
* {@link layerScaffoldManifest}.
|
|
56
131
|
*/
|
|
57
132
|
async function layerScaffold(targetDir) {
|
|
58
133
|
const scaffoldDir = path.join(resolveTemplatesDir(), "scaffold");
|
|
59
|
-
if (existsSync(scaffoldDir))
|
|
134
|
+
if (!existsSync(scaffoldDir)) return;
|
|
135
|
+
await fs.cp(scaffoldDir, targetDir, {
|
|
60
136
|
recursive: true,
|
|
61
137
|
force: false,
|
|
62
138
|
errorOnExist: false
|
|
63
139
|
});
|
|
140
|
+
await layerScaffoldManifest(scaffoldDir, targetDir);
|
|
64
141
|
}
|
|
65
142
|
/**
|
|
66
143
|
* Copy a template into targetDir, merging scaffold files underneath.
|
package/dist/_templates.d.ts
CHANGED
|
@@ -21,6 +21,20 @@ export declare function bundledTemplatesDir(): string;
|
|
|
21
21
|
* can never drift.
|
|
22
22
|
*/
|
|
23
23
|
export declare function listTemplates(root?: string): Promise<string[]>;
|
|
24
|
+
type Manifest = Record<string, unknown>;
|
|
25
|
+
/**
|
|
26
|
+
* Fill a manifest's gaps from the scaffold's, `existing` always winning.
|
|
27
|
+
*
|
|
28
|
+
* The same rule the file layering uses, one level deeper: a top-level field
|
|
29
|
+
* the manifest already declares is left alone, and for the three map fields
|
|
30
|
+
* it is each ENTRY that is left alone. Per-entry matters both ways — a
|
|
31
|
+
* workspace manifest pins its `dependencies` to exact installed versions and
|
|
32
|
+
* must keep them, while a single agent-added `devDependencies` entry must not
|
|
33
|
+
* shadow the whole toolchain block.
|
|
34
|
+
*
|
|
35
|
+
* Returns null when nothing was missing, so the common case writes no file.
|
|
36
|
+
*/
|
|
37
|
+
export declare function mergeScaffoldManifest(existing: Manifest, scaffold: Manifest): Manifest | null;
|
|
24
38
|
/**
|
|
25
39
|
* Layer the base scaffold (package.json, tsconfig, …) into targetDir
|
|
26
40
|
* WITHOUT overwriting anything already there. Shared by `aai init`
|
|
@@ -28,9 +42,13 @@ export declare function listTemplates(root?: string): Promise<string[]>;
|
|
|
28
42
|
* files — the workspace stores source, and the scaffold completes it into a
|
|
29
43
|
* runnable project the same way the guest's `ensureProjectShape` does
|
|
30
44
|
* before an in-sandbox build).
|
|
45
|
+
*
|
|
46
|
+
* package.json is the one file merged rather than skipped — see
|
|
47
|
+
* {@link layerScaffoldManifest}.
|
|
31
48
|
*/
|
|
32
49
|
export declare function layerScaffold(targetDir: string): Promise<void>;
|
|
33
50
|
/**
|
|
34
51
|
* Copy a template into targetDir, merging scaffold files underneath.
|
|
35
52
|
*/
|
|
36
53
|
export declare function downloadAndMergeTemplate(template: string, targetDir: string): Promise<void>;
|
|
54
|
+
export {};
|
package/dist/cli.mjs
CHANGED
|
@@ -165,7 +165,7 @@ const list = defineCommand({
|
|
|
165
165
|
async run({ args }) {
|
|
166
166
|
await runCommand(args, async () => {
|
|
167
167
|
const cwd = resolveCwd();
|
|
168
|
-
const { executeList } = await import("./studio-
|
|
168
|
+
const { executeList } = await import("./studio-_UBBvh5V.mjs");
|
|
169
169
|
return executeList({
|
|
170
170
|
cwd,
|
|
171
171
|
server: args.server
|
|
@@ -200,7 +200,7 @@ const pull = defineCommand({
|
|
|
200
200
|
async run({ args }) {
|
|
201
201
|
await runCommand(args, async () => {
|
|
202
202
|
const cwd = resolveCwd();
|
|
203
|
-
const { executePull } = await import("./studio-
|
|
203
|
+
const { executePull } = await import("./studio-_UBBvh5V.mjs");
|
|
204
204
|
return executePull({
|
|
205
205
|
cwd,
|
|
206
206
|
project: args.project,
|
|
@@ -228,7 +228,7 @@ const push = defineCommand({
|
|
|
228
228
|
async run({ args }) {
|
|
229
229
|
await runCommand(args, async () => {
|
|
230
230
|
const cwd = await setup({ agent: true });
|
|
231
|
-
const { executePush } = await import("./studio-
|
|
231
|
+
const { executePush } = await import("./studio-_UBBvh5V.mjs");
|
|
232
232
|
return executePush({
|
|
233
233
|
cwd,
|
|
234
234
|
server: args.server,
|
|
@@ -258,7 +258,7 @@ const publish = defineCommand({
|
|
|
258
258
|
async run({ args }) {
|
|
259
259
|
await runCommand(args, async () => {
|
|
260
260
|
const cwd = await setup({ agent: true });
|
|
261
|
-
const { executePublish } = await import("./studio-
|
|
261
|
+
const { executePublish } = await import("./studio-_UBBvh5V.mjs");
|
|
262
262
|
return executePublish({
|
|
263
263
|
cwd,
|
|
264
264
|
server: args.server,
|
|
@@ -316,7 +316,7 @@ const init = defineCommand({
|
|
|
316
316
|
},
|
|
317
317
|
async run({ args }) {
|
|
318
318
|
await runCommand(args, async (mode) => {
|
|
319
|
-
const { executeInit } = await import("./init-
|
|
319
|
+
const { executeInit } = await import("./init-BpBbttOv.mjs");
|
|
320
320
|
return executeInit({
|
|
321
321
|
dir: args.dir,
|
|
322
322
|
force: args.force,
|
|
@@ -623,7 +623,7 @@ const templates = defineCommand({
|
|
|
623
623
|
args: { json: sharedArgs.json },
|
|
624
624
|
async run({ args }) {
|
|
625
625
|
await runCommand(args, async (mode) => {
|
|
626
|
-
const { listTemplates } = await import("./_templates-
|
|
626
|
+
const { listTemplates } = await import("./_templates-BfyRyE7z.mjs");
|
|
627
627
|
const names = await listTemplates();
|
|
628
628
|
if (mode === "human") {
|
|
629
629
|
for (const name of names) log.message(name);
|
|
@@ -74,7 +74,7 @@ function resolveTargetDir(dir) {
|
|
|
74
74
|
}
|
|
75
75
|
/** Publish after init and return deploy metadata if successful. */
|
|
76
76
|
async function tryPublish(cwd, server) {
|
|
77
|
-
const { executePublish } = await import("./studio-
|
|
77
|
+
const { executePublish } = await import("./studio-_UBBvh5V.mjs");
|
|
78
78
|
try {
|
|
79
79
|
const result = await executePublish({
|
|
80
80
|
cwd,
|
|
@@ -93,7 +93,7 @@ async function tryPublish(cwd, server) {
|
|
|
93
93
|
}
|
|
94
94
|
/** Scaffold the project, optionally showing a spinner. */
|
|
95
95
|
async function scaffoldProject(dir, cwd, template, silent) {
|
|
96
|
-
const { runInit } = await import("./_init-
|
|
96
|
+
const { runInit } = await import("./_init-Dei2JRmn.mjs");
|
|
97
97
|
const s = silent ? void 0 : p.spinner();
|
|
98
98
|
s?.start(`Creating ${dir}`);
|
|
99
99
|
await runInit({
|
package/dist/scaffold/CLAUDE.md
CHANGED
|
@@ -196,7 +196,7 @@ export default agent({
|
|
|
196
196
|
|
|
197
197
|
**Prefer pipeline mode** — the default — unless the user specifically
|
|
198
198
|
asks for the speech-to-speech API. Nearly every template ships this way, and
|
|
199
|
-
it is what
|
|
199
|
+
it is what AssemblyAI Build defaults to. The host runs the LLM loop locally
|
|
200
200
|
(Vercel AI SDK) with your chosen STT, LLM, and TTS. You want explicit
|
|
201
201
|
providers when:
|
|
202
202
|
|
|
@@ -11,15 +11,15 @@
|
|
|
11
11
|
"publish:agent": "aai publish"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@alexkroman1/aai": "^5.8.
|
|
15
|
-
"@alexkroman1/aai-ui": "^5.8.
|
|
14
|
+
"@alexkroman1/aai": "^5.8.1",
|
|
15
|
+
"@alexkroman1/aai-ui": "^5.8.1",
|
|
16
16
|
"react": "^19.2.8",
|
|
17
17
|
"react-dom": "^19.2.8",
|
|
18
18
|
"tailwindcss": "^4.0.0",
|
|
19
19
|
"zod": "^4.4.3"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
|
-
"@alexkroman1/aai-cli": "^5.8.
|
|
22
|
+
"@alexkroman1/aai-cli": "^5.8.1",
|
|
23
23
|
"@tailwindcss/vite": "^4.3.3",
|
|
24
24
|
"@types/node": "^26.1.1",
|
|
25
25
|
"@types/react": "^19.2.17",
|
|
@@ -3,7 +3,7 @@ import { n as log, o as CliError, t as fmtUrl, u as ok } from "./_ui-8kOEB-JH.mj
|
|
|
3
3
|
import { s as updateProjectConfig } from "./_config-Y5V-5Krn.mjs";
|
|
4
4
|
import { t as resolveServerEnv } from "./_server-common-CnaP_Urf.mjs";
|
|
5
5
|
import { i as resolveDeployTarget } from "./_agent-2nVugrN3.mjs";
|
|
6
|
-
import { layerScaffold } from "./_templates-
|
|
6
|
+
import { layerScaffold } from "./_templates-BfyRyE7z.mjs";
|
|
7
7
|
import { n as apiRequest } from "./_api-client-B-upMGkc.mjs";
|
|
8
8
|
import path from "node:path";
|
|
9
9
|
import { mkdir, readFile, readdir, stat, writeFile } from "node:fs/promises";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alexkroman1/aai-cli",
|
|
3
|
-
"version": "5.8.
|
|
3
|
+
"version": "5.8.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"aai": "dist/cli.mjs"
|
|
@@ -37,8 +37,8 @@
|
|
|
37
37
|
"p-timeout": "^7.0.1",
|
|
38
38
|
"vite": "^8.1.5",
|
|
39
39
|
"zod": "^4.4.3",
|
|
40
|
-
"@alexkroman1/aai": "5.8.
|
|
41
|
-
"@alexkroman1/aai
|
|
40
|
+
"@alexkroman1/aai-ui": "5.8.1",
|
|
41
|
+
"@alexkroman1/aai": "5.8.1"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"playwright": "^1.61.1",
|