assistant-ui 0.0.111 → 0.0.113
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/codemods/v0-12/assistant-api-to-aui.d.ts.map +1 -1
- package/dist/codemods/v0-12/assistant-api-to-aui.js +87 -62
- package/dist/codemods/v0-12/assistant-api-to-aui.js.map +1 -1
- package/dist/codemods/v0-12/primitive-if-to-aui-if.d.ts.map +1 -1
- package/dist/codemods/v0-12/primitive-if-to-aui-if.js +31 -45
- package/dist/codemods/v0-12/primitive-if-to-aui-if.js.map +1 -1
- package/dist/commands/add.d.ts +1 -1
- package/dist/commands/add.d.ts.map +1 -1
- package/dist/commands/add.js +4 -2
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/create.d.ts.map +1 -1
- package/dist/commands/create.js +33 -10
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/info.d.ts.map +1 -1
- package/dist/commands/info.js +2 -1
- package/dist/commands/info.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +4 -2
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/mcp.d.ts.map +1 -1
- package/dist/commands/mcp.js +25 -28
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/update.js +6 -7
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/upgrade.d.ts.map +1 -1
- package/dist/commands/upgrade.js +5 -2
- package/dist/commands/upgrade.js.map +1 -1
- package/dist/index.js +2 -6
- package/dist/index.js.map +1 -1
- package/dist/lib/agent-skill.d.ts +1 -1
- package/dist/lib/agent-skill.d.ts.map +1 -1
- package/dist/lib/agent-skill.js.map +1 -1
- package/dist/lib/create-project.d.ts +2 -3
- package/dist/lib/create-project.d.ts.map +1 -1
- package/dist/lib/create-project.js +17 -42
- package/dist/lib/create-project.js.map +1 -1
- package/dist/lib/handle-cli-error.d.ts +5 -0
- package/dist/lib/handle-cli-error.d.ts.map +1 -0
- package/dist/lib/handle-cli-error.js +17 -0
- package/dist/lib/handle-cli-error.js.map +1 -0
- package/dist/lib/install-ai-sdk-lib.js +8 -1
- package/dist/lib/install-ai-sdk-lib.js.map +1 -1
- package/dist/lib/install-edge-lib.js +4 -8
- package/dist/lib/install-edge-lib.js.map +1 -1
- package/dist/lib/run-spawn.d.ts +16 -2
- package/dist/lib/run-spawn.d.ts.map +1 -1
- package/dist/lib/run-spawn.js +87 -9
- package/dist/lib/run-spawn.js.map +1 -1
- package/dist/lib/transform.d.ts +1 -1
- package/dist/lib/transform.d.ts.map +1 -1
- package/dist/lib/transform.js +12 -25
- package/dist/lib/transform.js.map +1 -1
- package/dist/lib/upgrade.js +20 -16
- package/dist/lib/upgrade.js.map +1 -1
- package/dist/lib/utils/file-scanner.d.ts +9 -1
- package/dist/lib/utils/file-scanner.d.ts.map +1 -1
- package/dist/lib/utils/file-scanner.js +22 -20
- package/dist/lib/utils/file-scanner.js.map +1 -1
- package/dist/lib/utils/package-installer.js +1 -1
- package/dist/lib/utils/package-manager.d.ts +3 -1
- package/dist/lib/utils/package-manager.d.ts.map +1 -1
- package/dist/lib/utils/package-manager.js +22 -10
- package/dist/lib/utils/package-manager.js.map +1 -1
- package/package.json +6 -6
- package/plugin/skills/assistant-ui/SKILL.md +3 -3
- package/src/codemods/v0-12/__tests__/assistant-api-to-aui.test.ts +370 -0
- package/src/codemods/v0-12/__tests__/primitive-if-to-aui-if.test.ts +100 -0
- package/src/codemods/v0-12/assistant-api-to-aui.ts +227 -134
- package/src/codemods/v0-12/primitive-if-to-aui-if.ts +44 -72
- package/src/commands/add.ts +5 -5
- package/src/commands/create.ts +41 -7
- package/src/commands/info.ts +1 -0
- package/src/commands/init.ts +4 -6
- package/src/commands/mcp.ts +20 -29
- package/src/commands/update.ts +6 -8
- package/src/commands/upgrade.ts +5 -2
- package/src/index.ts +2 -7
- package/src/lib/agent-skill.ts +2 -1
- package/src/lib/create-project.ts +24 -58
- package/src/lib/handle-cli-error.test.ts +67 -0
- package/src/lib/handle-cli-error.ts +17 -0
- package/src/lib/install-ai-sdk-lib.ts +13 -1
- package/src/lib/install-edge-lib.ts +7 -8
- package/src/lib/run-spawn.test.ts +148 -0
- package/src/lib/run-spawn.ts +121 -11
- package/src/lib/transform.test.ts +62 -0
- package/src/lib/transform.ts +21 -37
- package/src/lib/upgrade.ts +23 -19
- package/src/lib/utils/file-scanner.ts +26 -20
- package/src/lib/utils/package-manager.ts +29 -12
package/dist/lib/run-spawn.js
CHANGED
|
@@ -2,25 +2,103 @@ import { spawn } from "cross-spawn";
|
|
|
2
2
|
//#region src/lib/run-spawn.ts
|
|
3
3
|
var SpawnExitError = class extends Error {
|
|
4
4
|
code;
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
stderr;
|
|
6
|
+
constructor(code, stderr = "") {
|
|
7
|
+
super(stderr ? `Process exited with code ${code}\n${stderr}` : `Process exited with code ${code}`);
|
|
7
8
|
this.code = code;
|
|
9
|
+
this.stderr = stderr;
|
|
8
10
|
}
|
|
9
11
|
};
|
|
10
|
-
|
|
12
|
+
var SpawnSignalError = class extends Error {
|
|
13
|
+
signal;
|
|
14
|
+
forwarded;
|
|
15
|
+
constructor(signal, forwarded) {
|
|
16
|
+
super(`Process terminated by ${signal}`);
|
|
17
|
+
this.signal = signal;
|
|
18
|
+
this.forwarded = forwarded;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
let activeSpawns = 0;
|
|
22
|
+
const hasActiveSpawn = () => activeSpawns > 0;
|
|
23
|
+
function spawnProcess(command, args, cwd, captureOutput) {
|
|
11
24
|
return new Promise((resolve, reject) => {
|
|
12
25
|
const child = spawn(command, args, {
|
|
13
|
-
stdio:
|
|
26
|
+
stdio: captureOutput ? [
|
|
27
|
+
"ignore",
|
|
28
|
+
"pipe",
|
|
29
|
+
"pipe"
|
|
30
|
+
] : "inherit",
|
|
14
31
|
cwd
|
|
15
32
|
});
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
33
|
+
let forwardedSignal = null;
|
|
34
|
+
let settled = false;
|
|
35
|
+
let stdout = "";
|
|
36
|
+
let stderr = "";
|
|
37
|
+
if (captureOutput) {
|
|
38
|
+
child.stdout?.setEncoding("utf8");
|
|
39
|
+
child.stdout?.on("data", (chunk) => {
|
|
40
|
+
stdout += chunk;
|
|
41
|
+
});
|
|
42
|
+
child.stderr?.setEncoding("utf8");
|
|
43
|
+
child.stderr?.on("data", (chunk) => {
|
|
44
|
+
stderr += chunk;
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
const cleanup = () => {
|
|
48
|
+
activeSpawns -= 1;
|
|
49
|
+
process.off("SIGINT", onSigint);
|
|
50
|
+
process.off("SIGTERM", onSigterm);
|
|
51
|
+
};
|
|
52
|
+
const rejectWithSignal = (signal) => {
|
|
53
|
+
settled = true;
|
|
54
|
+
cleanup();
|
|
55
|
+
reject(new SpawnSignalError(signal, forwardedSignal !== null));
|
|
56
|
+
};
|
|
57
|
+
const forwardSignal = (signal) => {
|
|
58
|
+
if (forwardedSignal !== null) {
|
|
59
|
+
child.kill("SIGKILL");
|
|
60
|
+
rejectWithSignal(forwardedSignal);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
forwardedSignal = signal;
|
|
64
|
+
child.kill(signal);
|
|
65
|
+
};
|
|
66
|
+
const onSigint = () => forwardSignal("SIGINT");
|
|
67
|
+
const onSigterm = () => forwardSignal("SIGTERM");
|
|
68
|
+
activeSpawns += 1;
|
|
69
|
+
process.on("SIGINT", onSigint);
|
|
70
|
+
process.on("SIGTERM", onSigterm);
|
|
71
|
+
child.on("error", (error) => {
|
|
72
|
+
if (settled) return;
|
|
73
|
+
settled = true;
|
|
74
|
+
cleanup();
|
|
75
|
+
if (forwardedSignal !== null) reject(new SpawnSignalError(forwardedSignal, true));
|
|
76
|
+
else reject(error);
|
|
77
|
+
});
|
|
78
|
+
child.on("close", (code, signal) => {
|
|
79
|
+
if (settled) return;
|
|
80
|
+
settled = true;
|
|
81
|
+
cleanup();
|
|
82
|
+
if (forwardedSignal !== null) reject(new SpawnSignalError(forwardedSignal, true));
|
|
83
|
+
else resolve({
|
|
84
|
+
code,
|
|
85
|
+
signal: signal ?? null,
|
|
86
|
+
stdout,
|
|
87
|
+
stderr
|
|
88
|
+
});
|
|
20
89
|
});
|
|
21
90
|
});
|
|
22
91
|
}
|
|
92
|
+
function runSpawn(command, args, cwd) {
|
|
93
|
+
return spawnProcess(command, args, cwd, false).then(({ code, signal }) => {
|
|
94
|
+
if (signal != null) throw new SpawnSignalError(signal, false);
|
|
95
|
+
if (code !== 0) throw new SpawnExitError(code || 1);
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
function runSpawnCapture(command, args, cwd) {
|
|
99
|
+
return spawnProcess(command, args, cwd, true);
|
|
100
|
+
}
|
|
23
101
|
//#endregion
|
|
24
|
-
export { SpawnExitError, runSpawn };
|
|
102
|
+
export { SpawnExitError, SpawnSignalError, hasActiveSpawn, runSpawn, runSpawnCapture };
|
|
25
103
|
|
|
26
104
|
//# sourceMappingURL=run-spawn.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-spawn.js","names":[],"sources":["../../src/lib/run-spawn.ts"],"sourcesContent":["import { spawn } from \"cross-spawn\";\n\nexport class SpawnExitError extends Error {\n code: number;\n\n constructor(code: number) {\n super(`Process exited with code ${code}`);\n this.code = code;\n }\n}\n\nexport
|
|
1
|
+
{"version":3,"file":"run-spawn.js","names":[],"sources":["../../src/lib/run-spawn.ts"],"sourcesContent":["import { spawn } from \"cross-spawn\";\n\nexport class SpawnExitError extends Error {\n code: number;\n stderr: string;\n\n constructor(code: number, stderr = \"\") {\n super(\n stderr\n ? `Process exited with code ${code}\\n${stderr}`\n : `Process exited with code ${code}`,\n );\n this.code = code;\n this.stderr = stderr;\n }\n}\n\nexport class SpawnSignalError extends Error {\n signal: NodeJS.Signals;\n forwarded: boolean;\n\n constructor(signal: NodeJS.Signals, forwarded: boolean) {\n super(`Process terminated by ${signal}`);\n this.signal = signal;\n this.forwarded = forwarded;\n }\n}\n\nexport interface SpawnResult {\n code: number | null;\n signal: NodeJS.Signals | null;\n stdout: string;\n stderr: string;\n}\n\nlet activeSpawns = 0;\n\n// A spawn that is forwarding a signal owns termination for that window, so\n// callers with their own cleanup listeners defer to it instead of racing it.\nexport const hasActiveSpawn = (): boolean => activeSpawns > 0;\n\nfunction spawnProcess(\n command: string,\n args: string[],\n cwd: string | undefined,\n captureOutput: boolean,\n): Promise<SpawnResult> {\n return new Promise((resolve, reject) => {\n const child = spawn(command, args, {\n stdio: captureOutput ? [\"ignore\", \"pipe\", \"pipe\"] : \"inherit\",\n cwd,\n });\n let forwardedSignal: NodeJS.Signals | null = null;\n let settled = false;\n let stdout = \"\";\n let stderr = \"\";\n\n if (captureOutput) {\n child.stdout?.setEncoding(\"utf8\");\n child.stdout?.on(\"data\", (chunk: string) => {\n stdout += chunk;\n });\n child.stderr?.setEncoding(\"utf8\");\n child.stderr?.on(\"data\", (chunk: string) => {\n stderr += chunk;\n });\n }\n\n const cleanup = () => {\n activeSpawns -= 1;\n process.off(\"SIGINT\", onSigint);\n process.off(\"SIGTERM\", onSigterm);\n };\n\n const rejectWithSignal = (signal: NodeJS.Signals) => {\n settled = true;\n cleanup();\n reject(new SpawnSignalError(signal, forwardedSignal !== null));\n };\n\n const forwardSignal = (signal: NodeJS.Signals) => {\n if (forwardedSignal !== null) {\n child.kill(\"SIGKILL\");\n rejectWithSignal(forwardedSignal);\n return;\n }\n\n forwardedSignal = signal;\n child.kill(signal);\n };\n const onSigint = () => forwardSignal(\"SIGINT\");\n const onSigterm = () => forwardSignal(\"SIGTERM\");\n\n activeSpawns += 1;\n process.on(\"SIGINT\", onSigint);\n process.on(\"SIGTERM\", onSigterm);\n\n child.on(\"error\", (error) => {\n if (settled) return;\n settled = true;\n cleanup();\n if (forwardedSignal !== null) {\n reject(new SpawnSignalError(forwardedSignal, true));\n } else {\n reject(error);\n }\n });\n child.on(\"close\", (code, signal) => {\n if (settled) return;\n settled = true;\n cleanup();\n if (forwardedSignal !== null) {\n reject(new SpawnSignalError(forwardedSignal, true));\n } else {\n resolve({ code, signal: signal ?? null, stdout, stderr });\n }\n });\n });\n}\n\nexport function runSpawn(\n command: string,\n args: string[],\n cwd?: string,\n): Promise<void> {\n return spawnProcess(command, args, cwd, false).then(({ code, signal }) => {\n if (signal != null) {\n throw new SpawnSignalError(signal, false);\n }\n if (code !== 0) {\n throw new SpawnExitError(code || 1);\n }\n });\n}\n\nexport function runSpawnCapture(\n command: string,\n args: string[],\n cwd?: string,\n): Promise<SpawnResult> {\n return spawnProcess(command, args, cwd, true);\n}\n"],"mappings":";;AAEA,IAAa,iBAAb,cAAoC,MAAM;CACxC;CACA;CAEA,YAAY,MAAc,SAAS,IAAI;EACrC,MACE,SACI,4BAA4B,KAAK,IAAI,WACrC,4BAA4B,MAClC;EACA,KAAK,OAAO;EACZ,KAAK,SAAS;CAChB;AACF;AAEA,IAAa,mBAAb,cAAsC,MAAM;CAC1C;CACA;CAEA,YAAY,QAAwB,WAAoB;EACtD,MAAM,yBAAyB,QAAQ;EACvC,KAAK,SAAS;EACd,KAAK,YAAY;CACnB;AACF;AASA,IAAI,eAAe;AAInB,MAAa,uBAAgC,eAAe;AAE5D,SAAS,aACP,SACA,MACA,KACA,eACsB;CACtB,OAAO,IAAI,SAAS,SAAS,WAAW;EACtC,MAAM,QAAQ,MAAM,SAAS,MAAM;GACjC,OAAO,gBAAgB;IAAC;IAAU;IAAQ;GAAM,IAAI;GACpD;EACF,CAAC;EACD,IAAI,kBAAyC;EAC7C,IAAI,UAAU;EACd,IAAI,SAAS;EACb,IAAI,SAAS;EAEb,IAAI,eAAe;GACjB,MAAM,QAAQ,YAAY,MAAM;GAChC,MAAM,QAAQ,GAAG,SAAS,UAAkB;IAC1C,UAAU;GACZ,CAAC;GACD,MAAM,QAAQ,YAAY,MAAM;GAChC,MAAM,QAAQ,GAAG,SAAS,UAAkB;IAC1C,UAAU;GACZ,CAAC;EACH;EAEA,MAAM,gBAAgB;GACpB,gBAAgB;GAChB,QAAQ,IAAI,UAAU,QAAQ;GAC9B,QAAQ,IAAI,WAAW,SAAS;EAClC;EAEA,MAAM,oBAAoB,WAA2B;GACnD,UAAU;GACV,QAAQ;GACR,OAAO,IAAI,iBAAiB,QAAQ,oBAAoB,IAAI,CAAC;EAC/D;EAEA,MAAM,iBAAiB,WAA2B;GAChD,IAAI,oBAAoB,MAAM;IAC5B,MAAM,KAAK,SAAS;IACpB,iBAAiB,eAAe;IAChC;GACF;GAEA,kBAAkB;GAClB,MAAM,KAAK,MAAM;EACnB;EACA,MAAM,iBAAiB,cAAc,QAAQ;EAC7C,MAAM,kBAAkB,cAAc,SAAS;EAE/C,gBAAgB;EAChB,QAAQ,GAAG,UAAU,QAAQ;EAC7B,QAAQ,GAAG,WAAW,SAAS;EAE/B,MAAM,GAAG,UAAU,UAAU;GAC3B,IAAI,SAAS;GACb,UAAU;GACV,QAAQ;GACR,IAAI,oBAAoB,MACtB,OAAO,IAAI,iBAAiB,iBAAiB,IAAI,CAAC;QAElD,OAAO,KAAK;EAEhB,CAAC;EACD,MAAM,GAAG,UAAU,MAAM,WAAW;GAClC,IAAI,SAAS;GACb,UAAU;GACV,QAAQ;GACR,IAAI,oBAAoB,MACtB,OAAO,IAAI,iBAAiB,iBAAiB,IAAI,CAAC;QAElD,QAAQ;IAAE;IAAM,QAAQ,UAAU;IAAM;IAAQ;GAAO,CAAC;EAE5D,CAAC;CACH,CAAC;AACH;AAEA,SAAgB,SACd,SACA,MACA,KACe;CACf,OAAO,aAAa,SAAS,MAAM,KAAK,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,aAAa;EACxE,IAAI,UAAU,MACZ,MAAM,IAAI,iBAAiB,QAAQ,KAAK;EAE1C,IAAI,SAAS,GACX,MAAM,IAAI,eAAe,QAAQ,CAAC;CAEtC,CAAC;AACH;AAEA,SAAgB,gBACd,SACA,MACA,KACsB;CACtB,OAAO,aAAa,SAAS,MAAM,KAAK,IAAI;AAC9C"}
|
package/dist/lib/transform.d.ts
CHANGED
|
@@ -18,7 +18,7 @@ declare function transform(codemod: string, source: string, transformOptions: Tr
|
|
|
18
18
|
logStatus: boolean;
|
|
19
19
|
onProgress?: (processedFiles: number) => void;
|
|
20
20
|
relevantFiles?: string[];
|
|
21
|
-
}): TransformErrors
|
|
21
|
+
}): Promise<TransformErrors>;
|
|
22
22
|
//#endregion
|
|
23
23
|
export { TransformErrors, countFilesToProcess, getRelevantFiles, transform };
|
|
24
24
|
//# sourceMappingURL=transform.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transform.d.ts","names":[],"sources":["../../src/lib/transform.ts"],"mappings":";;;;;;iBAkBgB,iBAAiB;;;;iBA6BjB,oBAAoB;KAsCxB;EACV;EACA;EACA;;
|
|
1
|
+
{"version":3,"file":"transform.d.ts","names":[],"sources":["../../src/lib/transform.ts"],"mappings":";;;;;;iBAkBgB,iBAAiB;;;;iBA6BjB,oBAAoB;KAsCxB;EACV;EACA;EACA;;iBAoBoB,UACpB,iBACA,gBACA,kBAAkB,kBAClB;EACE;EACA,cAAc;EACd;IAED,QAAQ"}
|
package/dist/lib/transform.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { SpawnExitError, SpawnSignalError, runSpawnCapture } from "./run-spawn.js";
|
|
1
2
|
import * as fs$1 from "node:fs";
|
|
2
3
|
import path from "node:path";
|
|
3
4
|
import { sync } from "glob";
|
|
4
|
-
import { execFileSync, spawnSync } from "node:child_process";
|
|
5
5
|
import debug from "debug";
|
|
6
6
|
import { fileURLToPath } from "node:url";
|
|
7
7
|
//#region src/lib/transform.ts
|
|
@@ -71,7 +71,7 @@ function parseErrors(transform, output) {
|
|
|
71
71
|
}
|
|
72
72
|
return errors;
|
|
73
73
|
}
|
|
74
|
-
function transform(codemod, source, transformOptions, options = { logStatus: true }) {
|
|
74
|
+
async function transform(codemod, source, transformOptions, options = { logStatus: true }) {
|
|
75
75
|
if (options.logStatus) log(`Applying codemod '${codemod}': ${source}`);
|
|
76
76
|
const codemodPath = path.resolve(__dirname, `../codemods/${codemod}.js`);
|
|
77
77
|
const targetFiles = options.relevantFiles || getRelevantFiles(source);
|
|
@@ -81,32 +81,19 @@ function transform(codemod, source, transformOptions, options = { logStatus: tru
|
|
|
81
81
|
}
|
|
82
82
|
log(`Found ${targetFiles.length} relevant files for codemod '${codemod}'`);
|
|
83
83
|
const command = buildCommand(codemodPath, targetFiles, transformOptions);
|
|
84
|
+
const result = await runSpawnCapture(command[0], command.slice(1));
|
|
85
|
+
if (result.signal !== null) throw new SpawnSignalError(result.signal, false);
|
|
86
|
+
if (!options.onProgress && result.code !== 0) throw new SpawnExitError(result.code || 1, result.stderr);
|
|
87
|
+
const { stdout } = result;
|
|
84
88
|
if (options.onProgress) {
|
|
85
|
-
const stdout = spawnSync(command[0], command.slice(1), {
|
|
86
|
-
encoding: "utf8",
|
|
87
|
-
stdio: [
|
|
88
|
-
"ignore",
|
|
89
|
-
"pipe",
|
|
90
|
-
"pipe"
|
|
91
|
-
]
|
|
92
|
-
}).stdout || "";
|
|
93
89
|
const processedFiles = (stdout.match(/Processing file/g) || []).length;
|
|
94
|
-
|
|
95
|
-
const errors = parseErrors(codemod, stdout);
|
|
96
|
-
if (options.logStatus && errors.length > 0) errors.forEach(({ transform, filename, summary }) => {
|
|
97
|
-
error(`Error applying codemod [codemod=${transform}, path=${filename}, summary=${summary}]`);
|
|
98
|
-
});
|
|
99
|
-
return errors;
|
|
100
|
-
} else {
|
|
101
|
-
const errors = parseErrors(codemod, execFileSync(command[0], command.slice(1), {
|
|
102
|
-
encoding: "utf8",
|
|
103
|
-
stdio: "pipe"
|
|
104
|
-
}));
|
|
105
|
-
if (options.logStatus && errors.length > 0) errors.forEach(({ transform, filename, summary }) => {
|
|
106
|
-
error(`Error applying codemod [codemod=${transform}, path=${filename}, summary=${summary}]`);
|
|
107
|
-
});
|
|
108
|
-
return errors;
|
|
90
|
+
options.onProgress(processedFiles);
|
|
109
91
|
}
|
|
92
|
+
const errors = parseErrors(codemod, stdout);
|
|
93
|
+
if (options.logStatus && errors.length > 0) errors.forEach(({ transform, filename, summary }) => {
|
|
94
|
+
error(`Error applying codemod [codemod=${transform}, path=${filename}, summary=${summary}]`);
|
|
95
|
+
});
|
|
96
|
+
return errors;
|
|
110
97
|
}
|
|
111
98
|
//#endregion
|
|
112
99
|
export { countFilesToProcess, getRelevantFiles, transform };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transform.js","names":["globSync","fs"],"sources":["../../src/lib/transform.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"transform.js","names":["globSync","fs"],"sources":["../../src/lib/transform.ts"],"sourcesContent":["import debug from \"debug\";\nimport path from \"node:path\";\nimport type { TransformOptions } from \"./transform-options\";\nimport { fileURLToPath } from \"node:url\";\nimport * as fs from \"node:fs\";\nimport { sync as globSync } from \"glob\";\nimport { runSpawnCapture, SpawnExitError, SpawnSignalError } from \"./run-spawn\";\n\nconst log = debug(\"codemod:transform\");\nconst error = debug(\"codemod:transform:error\");\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\n/**\n * Gets the list of files that need to be processed in the codebase\n * Only includes files that contain \"assistant-ui\" to optimize performance\n */\nexport function getRelevantFiles(cwd: string): string[] {\n const pattern = \"**/*.{js,jsx,ts,tsx}\";\n const files = globSync(pattern, {\n cwd,\n ignore: [\n \"**/node_modules/**\",\n \"**/dist/**\",\n \"**/build/**\",\n \"**/*.min.js\",\n \"**/*.bundle.js\",\n ],\n });\n\n // Filter files to only include those containing \"assistant-ui\"\n const relevantFiles = files.filter((file) => {\n try {\n const content = fs.readFileSync(path.join(cwd, file), \"utf8\");\n return content.includes(\"assistant-ui\");\n } catch {\n return false;\n }\n });\n\n return relevantFiles.map((file) => path.join(cwd, file));\n}\n\n/**\n * Counts the number of files that need to be processed\n */\nexport function countFilesToProcess(cwd: string): number {\n return getRelevantFiles(cwd).length;\n}\n\nfunction buildCommand(\n codemodPath: string,\n targetFiles: string[],\n options: TransformOptions,\n): string[] {\n const command = [\n \"npx\",\n \"jscodeshift\",\n \"-t\",\n codemodPath,\n ...targetFiles,\n \"--parser\",\n \"tsx\",\n ];\n\n if (options.dry) {\n command.push(\"--dry\");\n }\n\n if (options.print) {\n command.push(\"--print\");\n }\n\n if (options.verbose) {\n command.push(\"--verbose\");\n }\n\n if (options.jscodeshift) {\n command.push(options.jscodeshift);\n }\n\n return command;\n}\n\nexport type TransformErrors = {\n transform: string;\n filename: string;\n summary: string;\n}[];\n\nfunction parseErrors(transform: string, output: string): TransformErrors {\n const errors: TransformErrors = [];\n const errorRegex = /ERR (.+) Transformation error/g;\n const syntaxErrorRegex = /SyntaxError: .+/g;\n\n for (const match of output.matchAll(errorRegex)) {\n const filename = match[1]!;\n const syntaxErrorMatch = syntaxErrorRegex.exec(output);\n if (syntaxErrorMatch) {\n const summary = syntaxErrorMatch[0];\n errors.push({ transform, filename, summary });\n }\n }\n\n return errors;\n}\n\nexport async function transform(\n codemod: string,\n source: string,\n transformOptions: TransformOptions,\n options: {\n logStatus: boolean;\n onProgress?: (processedFiles: number) => void;\n relevantFiles?: string[];\n } = { logStatus: true },\n): Promise<TransformErrors> {\n if (options.logStatus) {\n log(`Applying codemod '${codemod}': ${source}`);\n }\n const codemodPath = path.resolve(__dirname, `../codemods/${codemod}.js`);\n\n // Use pre-computed relevant files if provided, otherwise get them\n const targetFiles = options.relevantFiles || getRelevantFiles(source);\n\n if (targetFiles.length === 0) {\n log(`No relevant files found for codemod '${codemod}'`);\n return [];\n }\n\n log(`Found ${targetFiles.length} relevant files for codemod '${codemod}'`);\n\n const command = buildCommand(codemodPath, targetFiles, transformOptions);\n\n const result = await runSpawnCapture(command[0]!, command.slice(1));\n if (result.signal !== null) {\n throw new SpawnSignalError(result.signal, false);\n }\n if (!options.onProgress && result.code !== 0) {\n throw new SpawnExitError(result.code || 1, result.stderr);\n }\n\n const { stdout } = result;\n\n if (options.onProgress) {\n const processedFiles = (stdout.match(/Processing file/g) || []).length;\n options.onProgress(processedFiles);\n }\n\n const errors = parseErrors(codemod, stdout);\n if (options.logStatus && errors.length > 0) {\n errors.forEach(({ transform, filename, summary }) => {\n error(\n `Error applying codemod [codemod=${transform}, path=${filename}, summary=${summary}]`,\n );\n });\n }\n return errors;\n}\n"],"mappings":";;;;;;;AAQA,MAAM,MAAM,MAAM,mBAAmB;AACrC,MAAM,QAAQ,MAAM,yBAAyB;AAE7C,MAAM,aAAa,cAAc,YAAY,GAAG;AAChD,MAAM,YAAY,KAAK,QAAQ,UAAU;;;;;AAMzC,SAAgB,iBAAiB,KAAuB;CAuBtD,OArBcA,KAAS,wBAAS;EAC9B;EACA,QAAQ;GACN;GACA;GACA;GACA;GACA;EACF;CACF,CAG0B,CAAC,CAAC,QAAQ,SAAS;EAC3C,IAAI;GAEF,OADgBC,KAAG,aAAa,KAAK,KAAK,KAAK,IAAI,GAAG,MACzC,CAAC,CAAC,SAAS,cAAc;EACxC,QAAQ;GACN,OAAO;EACT;CACF,CAEmB,CAAC,CAAC,KAAK,SAAS,KAAK,KAAK,KAAK,IAAI,CAAC;AACzD;;;;AAKA,SAAgB,oBAAoB,KAAqB;CACvD,OAAO,iBAAiB,GAAG,CAAC,CAAC;AAC/B;AAEA,SAAS,aACP,aACA,aACA,SACU;CACV,MAAM,UAAU;EACd;EACA;EACA;EACA;EACA,GAAG;EACH;EACA;CACF;CAEA,IAAI,QAAQ,KACV,QAAQ,KAAK,OAAO;CAGtB,IAAI,QAAQ,OACV,QAAQ,KAAK,SAAS;CAGxB,IAAI,QAAQ,SACV,QAAQ,KAAK,WAAW;CAG1B,IAAI,QAAQ,aACV,QAAQ,KAAK,QAAQ,WAAW;CAGlC,OAAO;AACT;AAQA,SAAS,YAAY,WAAmB,QAAiC;CACvE,MAAM,SAA0B,CAAC;CACjC,MAAM,aAAa;CACnB,MAAM,mBAAmB;CAEzB,KAAK,MAAM,SAAS,OAAO,SAAS,UAAU,GAAG;EAC/C,MAAM,WAAW,MAAM;EACvB,MAAM,mBAAmB,iBAAiB,KAAK,MAAM;EACrD,IAAI,kBAAkB;GACpB,MAAM,UAAU,iBAAiB;GACjC,OAAO,KAAK;IAAE;IAAW;IAAU;GAAQ,CAAC;EAC9C;CACF;CAEA,OAAO;AACT;AAEA,eAAsB,UACpB,SACA,QACA,kBACA,UAII,EAAE,WAAW,KAAK,GACI;CAC1B,IAAI,QAAQ,WACV,IAAI,qBAAqB,QAAQ,KAAK,QAAQ;CAEhD,MAAM,cAAc,KAAK,QAAQ,WAAW,eAAe,QAAQ,IAAI;CAGvE,MAAM,cAAc,QAAQ,iBAAiB,iBAAiB,MAAM;CAEpE,IAAI,YAAY,WAAW,GAAG;EAC5B,IAAI,wCAAwC,QAAQ,EAAE;EACtD,OAAO,CAAC;CACV;CAEA,IAAI,SAAS,YAAY,OAAO,+BAA+B,QAAQ,EAAE;CAEzE,MAAM,UAAU,aAAa,aAAa,aAAa,gBAAgB;CAEvE,MAAM,SAAS,MAAM,gBAAgB,QAAQ,IAAK,QAAQ,MAAM,CAAC,CAAC;CAClE,IAAI,OAAO,WAAW,MACpB,MAAM,IAAI,iBAAiB,OAAO,QAAQ,KAAK;CAEjD,IAAI,CAAC,QAAQ,cAAc,OAAO,SAAS,GACzC,MAAM,IAAI,eAAe,OAAO,QAAQ,GAAG,OAAO,MAAM;CAG1D,MAAM,EAAE,WAAW;CAEnB,IAAI,QAAQ,YAAY;EACtB,MAAM,kBAAkB,OAAO,MAAM,kBAAkB,KAAK,CAAC,EAAA,CAAG;EAChE,QAAQ,WAAW,cAAc;CACnC;CAEA,MAAM,SAAS,YAAY,SAAS,MAAM;CAC1C,IAAI,QAAQ,aAAa,OAAO,SAAS,GACvC,OAAO,SAAS,EAAE,WAAW,UAAU,cAAc;EACnD,MACE,mCAAmC,UAAU,SAAS,SAAS,YAAY,QAAQ,EACrF;CACF,CAAC;CAEH,OAAO;AACT"}
|
package/dist/lib/upgrade.js
CHANGED
|
@@ -32,26 +32,30 @@ async function upgrade(options) {
|
|
|
32
32
|
let completedWork = 0;
|
|
33
33
|
const bar = new SingleBar({
|
|
34
34
|
format: "Progress |{bar}| {percentage}% | ETA: {eta}s || {status}",
|
|
35
|
-
hideCursor: true
|
|
35
|
+
hideCursor: true,
|
|
36
|
+
gracefulExit: true
|
|
36
37
|
}, Presets.shades_classic);
|
|
37
38
|
bar.start(totalWork, 0, { status: "Starting..." });
|
|
38
39
|
const allErrors = [];
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
40
|
+
try {
|
|
41
|
+
for (const codemod of bundle) {
|
|
42
|
+
bar.update(completedWork, { status: `Running ${codemod}...` });
|
|
43
|
+
const errors = await transform(codemod, cwd, options, {
|
|
44
|
+
logStatus: false,
|
|
45
|
+
onProgress: (processedFiles) => {
|
|
46
|
+
completedWork = bundle.indexOf(codemod) * fileCount + processedFiles;
|
|
47
|
+
bar.update(Math.min(completedWork, totalWork), { status: `Running ${codemod} (${processedFiles}/${fileCount} files)` });
|
|
48
|
+
},
|
|
49
|
+
relevantFiles
|
|
50
|
+
});
|
|
51
|
+
allErrors.push(...errors);
|
|
52
|
+
completedWork = (bundle.indexOf(codemod) + 1) * fileCount;
|
|
53
|
+
bar.update(completedWork, { status: `Completed ${codemod}` });
|
|
54
|
+
}
|
|
55
|
+
bar.update(totalWork, { status: "Checking dependencies..." });
|
|
56
|
+
} finally {
|
|
57
|
+
bar.stop();
|
|
52
58
|
}
|
|
53
|
-
bar.update(totalWork, { status: "Checking dependencies..." });
|
|
54
|
-
bar.stop();
|
|
55
59
|
if (allErrors.length > 0) {
|
|
56
60
|
log("Some codemods did not apply successfully to all files. Details:");
|
|
57
61
|
allErrors.forEach(({ transform, filename, summary }) => {
|
package/dist/lib/upgrade.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upgrade.js","names":[],"sources":["../../src/lib/upgrade.ts"],"sourcesContent":["import debug from \"debug\";\nimport { transform, type TransformErrors, getRelevantFiles } from \"./transform\";\nimport type { TransformOptions } from \"./transform-options\";\nimport { SingleBar, Presets } from \"cli-progress\";\nimport installEdgeLib from \"./install-edge-lib\";\nimport installAiSdkLib from \"./install-ai-sdk-lib\";\nimport { logger } from \"./utils/logger\";\n\nconst bundle = [\n \"v0-9/edge-package-split\",\n \"v0-11/content-part-to-message-part\",\n \"v0-12/assistant-api-to-aui\",\n \"v0-12/event-names-to-camelcase\",\n \"v0-12/primitive-if-to-aui-if\",\n \"v0-15/aui-accessor-calls-to-properties\",\n];\n\nconst log = debug(\"codemod:upgrade\");\nconst error = debug(\"codemod:upgrade:error\");\n\n/**\n * Runs the upgrade cycle:\n * - Runs each codemod in the bundle.\n * - Displays progress using cli-progress.\n * - After codemods run, checks if any file now imports from the new packages and prompts for install.\n */\nexport async function upgrade(options: TransformOptions) {\n const cwd = process.cwd();\n log(\"Starting upgrade...\");\n\n // Find relevant files once to avoid duplicate work\n logger.info(\"Analyzing codebase...\");\n const relevantFiles = getRelevantFiles(cwd);\n const fileCount = relevantFiles.length;\n logger.info(`Found ${fileCount} files to process.`);\n\n // Calculate total work units (files × codemods)\n const totalWork = fileCount * bundle.length;\n let completedWork = 0;\n\n const bar = new SingleBar(\n {\n format: \"Progress |{bar}| {percentage}% | ETA: {eta}s || {status}\",\n hideCursor: true,\n },\n Presets.shades_classic,\n );\n\n bar.start(totalWork, 0, { status: \"Starting...\" });\n const allErrors: TransformErrors = [];\n\n for (const codemod of bundle) {\n
|
|
1
|
+
{"version":3,"file":"upgrade.js","names":[],"sources":["../../src/lib/upgrade.ts"],"sourcesContent":["import debug from \"debug\";\nimport { transform, type TransformErrors, getRelevantFiles } from \"./transform\";\nimport type { TransformOptions } from \"./transform-options\";\nimport { SingleBar, Presets } from \"cli-progress\";\nimport installEdgeLib from \"./install-edge-lib\";\nimport installAiSdkLib from \"./install-ai-sdk-lib\";\nimport { logger } from \"./utils/logger\";\n\nconst bundle = [\n \"v0-9/edge-package-split\",\n \"v0-11/content-part-to-message-part\",\n \"v0-12/assistant-api-to-aui\",\n \"v0-12/event-names-to-camelcase\",\n \"v0-12/primitive-if-to-aui-if\",\n \"v0-15/aui-accessor-calls-to-properties\",\n];\n\nconst log = debug(\"codemod:upgrade\");\nconst error = debug(\"codemod:upgrade:error\");\n\n/**\n * Runs the upgrade cycle:\n * - Runs each codemod in the bundle.\n * - Displays progress using cli-progress.\n * - After codemods run, checks if any file now imports from the new packages and prompts for install.\n */\nexport async function upgrade(options: TransformOptions) {\n const cwd = process.cwd();\n log(\"Starting upgrade...\");\n\n // Find relevant files once to avoid duplicate work\n logger.info(\"Analyzing codebase...\");\n const relevantFiles = getRelevantFiles(cwd);\n const fileCount = relevantFiles.length;\n logger.info(`Found ${fileCount} files to process.`);\n\n // Calculate total work units (files × codemods)\n const totalWork = fileCount * bundle.length;\n let completedWork = 0;\n\n const bar = new SingleBar(\n {\n format: \"Progress |{bar}| {percentage}% | ETA: {eta}s || {status}\",\n hideCursor: true,\n gracefulExit: true,\n },\n Presets.shades_classic,\n );\n\n bar.start(totalWork, 0, { status: \"Starting...\" });\n const allErrors: TransformErrors = [];\n\n try {\n for (const codemod of bundle) {\n bar.update(completedWork, { status: `Running ${codemod}...` });\n\n // Use a custom progress callback to update the progress bar\n const errors = await transform(codemod, cwd, options, {\n logStatus: false,\n onProgress: (processedFiles: number) => {\n completedWork = bundle.indexOf(codemod) * fileCount + processedFiles;\n bar.update(Math.min(completedWork, totalWork), {\n status: `Running ${codemod} (${processedFiles}/${fileCount} files)`,\n });\n },\n relevantFiles, // Pass the pre-computed relevant files\n });\n\n allErrors.push(...errors);\n completedWork = (bundle.indexOf(codemod) + 1) * fileCount;\n bar.update(completedWork, { status: `Completed ${codemod}` });\n }\n\n bar.update(totalWork, { status: \"Checking dependencies...\" });\n } finally {\n bar.stop();\n }\n\n if (allErrors.length > 0) {\n log(\"Some codemods did not apply successfully to all files. Details:\");\n allErrors.forEach(({ transform, filename, summary }) => {\n error(`codemod=${transform}, path=${filename}, summary=${summary}`);\n });\n }\n\n // After codemods run, check if files import from the new packages and prompt for install.\n logger.info(\"Checking for package dependencies...\");\n await installEdgeLib();\n await installAiSdkLib();\n\n log(\"Upgrade complete.\");\n logger.success(\"Upgrade complete!\");\n}\n"],"mappings":";;;;;;;AAQA,MAAM,SAAS;CACb;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,MAAM,MAAM,MAAM,iBAAiB;AACnC,MAAM,QAAQ,MAAM,uBAAuB;;;;;;;AAQ3C,eAAsB,QAAQ,SAA2B;CACvD,MAAM,MAAM,QAAQ,IAAI;CACxB,IAAI,qBAAqB;CAGzB,OAAO,KAAK,uBAAuB;CACnC,MAAM,gBAAgB,iBAAiB,GAAG;CAC1C,MAAM,YAAY,cAAc;CAChC,OAAO,KAAK,SAAS,UAAU,mBAAmB;CAGlD,MAAM,YAAY,YAAY,OAAO;CACrC,IAAI,gBAAgB;CAEpB,MAAM,MAAM,IAAI,UACd;EACE,QAAQ;EACR,YAAY;EACZ,cAAc;CAChB,GACA,QAAQ,cACV;CAEA,IAAI,MAAM,WAAW,GAAG,EAAE,QAAQ,cAAc,CAAC;CACjD,MAAM,YAA6B,CAAC;CAEpC,IAAI;EACF,KAAK,MAAM,WAAW,QAAQ;GAC5B,IAAI,OAAO,eAAe,EAAE,QAAQ,WAAW,QAAQ,KAAK,CAAC;GAG7D,MAAM,SAAS,MAAM,UAAU,SAAS,KAAK,SAAS;IACpD,WAAW;IACX,aAAa,mBAA2B;KACtC,gBAAgB,OAAO,QAAQ,OAAO,IAAI,YAAY;KACtD,IAAI,OAAO,KAAK,IAAI,eAAe,SAAS,GAAG,EAC7C,QAAQ,WAAW,QAAQ,IAAI,eAAe,GAAG,UAAU,SAC7D,CAAC;IACH;IACA;GACF,CAAC;GAED,UAAU,KAAK,GAAG,MAAM;GACxB,iBAAiB,OAAO,QAAQ,OAAO,IAAI,KAAK;GAChD,IAAI,OAAO,eAAe,EAAE,QAAQ,aAAa,UAAU,CAAC;EAC9D;EAEA,IAAI,OAAO,WAAW,EAAE,QAAQ,2BAA2B,CAAC;CAC9D,UAAU;EACR,IAAI,KAAK;CACX;CAEA,IAAI,UAAU,SAAS,GAAG;EACxB,IAAI,iEAAiE;EACrE,UAAU,SAAS,EAAE,WAAW,UAAU,cAAc;GACtD,MAAM,WAAW,UAAU,SAAS,SAAS,YAAY,SAAS;EACpE,CAAC;CACH;CAGA,OAAO,KAAK,sCAAsC;CAClD,MAAM,eAAe;CACrB,MAAM,gBAAgB;CAEtB,IAAI,mBAAmB;CACvB,OAAO,QAAQ,mBAAmB;AACpC"}
|
|
@@ -4,8 +4,16 @@ interface ScanOptions {
|
|
|
4
4
|
pattern?: string;
|
|
5
5
|
ignore?: string[];
|
|
6
6
|
}
|
|
7
|
+
declare function readProjectFiles(pattern: string, options: {
|
|
8
|
+
cwd: string;
|
|
9
|
+
ignore?: string[];
|
|
10
|
+
}): Generator<{
|
|
11
|
+
file: string;
|
|
12
|
+
fullPath: string;
|
|
13
|
+
content: string;
|
|
14
|
+
}>;
|
|
7
15
|
declare function scanForImport(importPattern: string | string[], options?: ScanOptions): boolean;
|
|
8
16
|
declare function getFilesContaining(searchString: string, options?: ScanOptions): string[];
|
|
9
17
|
//#endregion
|
|
10
|
-
export { ScanOptions, getFilesContaining, scanForImport };
|
|
18
|
+
export { ScanOptions, getFilesContaining, readProjectFiles, scanForImport };
|
|
11
19
|
//# sourceMappingURL=file-scanner.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-scanner.d.ts","names":[],"sources":["../../../src/lib/utils/file-scanner.ts"],"mappings":";UAIiB;EACf;EACA;EACA;;
|
|
1
|
+
{"version":3,"file":"file-scanner.d.ts","names":[],"sources":["../../../src/lib/utils/file-scanner.ts"],"mappings":";UAIiB;EACf;EACA;EACA;;iBAGe,iBACf,iBACA;EAAW;EAAa;IACvB;EAAY;EAAc;EAAkB;;iBAc/B,cACd,kCACA,UAAS;iBAuBK,mBACd,sBACA,UAAS"}
|
|
@@ -2,6 +2,21 @@ import * as fs$1 from "node:fs";
|
|
|
2
2
|
import * as path$1 from "node:path";
|
|
3
3
|
import { sync } from "glob";
|
|
4
4
|
//#region src/lib/utils/file-scanner.ts
|
|
5
|
+
function* readProjectFiles(pattern, options) {
|
|
6
|
+
const files = sync(pattern, options);
|
|
7
|
+
for (const file of files) {
|
|
8
|
+
const fullPath = path$1.join(options.cwd, file);
|
|
9
|
+
try {
|
|
10
|
+
yield {
|
|
11
|
+
file,
|
|
12
|
+
fullPath,
|
|
13
|
+
content: fs$1.readFileSync(fullPath, "utf8")
|
|
14
|
+
};
|
|
15
|
+
} catch {
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
5
20
|
function scanForImport(importPattern, options = {}) {
|
|
6
21
|
const cwd = options.cwd || process.cwd();
|
|
7
22
|
const pattern = options.pattern || "**/*.{js,jsx,ts,tsx}";
|
|
@@ -10,18 +25,11 @@ function scanForImport(importPattern, options = {}) {
|
|
|
10
25
|
"**/dist/**",
|
|
11
26
|
"**/build/**"
|
|
12
27
|
];
|
|
13
|
-
const
|
|
28
|
+
const patterns = Array.isArray(importPattern) ? importPattern : [importPattern];
|
|
29
|
+
for (const { content } of readProjectFiles(pattern, {
|
|
14
30
|
cwd,
|
|
15
31
|
ignore
|
|
16
|
-
});
|
|
17
|
-
const patterns = Array.isArray(importPattern) ? importPattern : [importPattern];
|
|
18
|
-
for (const file of files) {
|
|
19
|
-
const fullPath = path$1.join(cwd, file);
|
|
20
|
-
try {
|
|
21
|
-
const content = fs$1.readFileSync(fullPath, "utf8");
|
|
22
|
-
if (patterns.some((p) => content.includes(p))) return true;
|
|
23
|
-
} catch {}
|
|
24
|
-
}
|
|
32
|
+
})) if (patterns.some((p) => content.includes(p))) return true;
|
|
25
33
|
return false;
|
|
26
34
|
}
|
|
27
35
|
function getFilesContaining(searchString, options = {}) {
|
|
@@ -32,20 +40,14 @@ function getFilesContaining(searchString, options = {}) {
|
|
|
32
40
|
"**/dist/**",
|
|
33
41
|
"**/build/**"
|
|
34
42
|
];
|
|
35
|
-
const
|
|
43
|
+
const result = [];
|
|
44
|
+
for (const { fullPath, content } of readProjectFiles(pattern, {
|
|
36
45
|
cwd,
|
|
37
46
|
ignore
|
|
38
|
-
});
|
|
39
|
-
const result = [];
|
|
40
|
-
for (const file of files) {
|
|
41
|
-
const fullPath = path$1.join(cwd, file);
|
|
42
|
-
try {
|
|
43
|
-
if (fs$1.readFileSync(fullPath, "utf8").includes(searchString)) result.push(fullPath);
|
|
44
|
-
} catch {}
|
|
45
|
-
}
|
|
47
|
+
})) if (content.includes(searchString)) result.push(fullPath);
|
|
46
48
|
return result;
|
|
47
49
|
}
|
|
48
50
|
//#endregion
|
|
49
|
-
export { getFilesContaining, scanForImport };
|
|
51
|
+
export { getFilesContaining, readProjectFiles, scanForImport };
|
|
50
52
|
|
|
51
53
|
//# sourceMappingURL=file-scanner.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-scanner.js","names":["globSync","path","fs"],"sources":["../../../src/lib/utils/file-scanner.ts"],"sourcesContent":["import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { sync as globSync } from \"glob\";\n\nexport interface ScanOptions {\n cwd?: string;\n pattern?: string;\n ignore?: string[];\n}\n\nexport function scanForImport(\n importPattern: string | string[],\n options: ScanOptions = {},\n): boolean {\n const cwd = options.cwd || process.cwd();\n const pattern = options.pattern || \"**/*.{js,jsx,ts,tsx}\";\n const ignore = options.ignore || [\n \"**/node_modules/**\",\n \"**/dist/**\",\n \"**/build/**\",\n ];\n\n const
|
|
1
|
+
{"version":3,"file":"file-scanner.js","names":["globSync","path","fs"],"sources":["../../../src/lib/utils/file-scanner.ts"],"sourcesContent":["import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { sync as globSync } from \"glob\";\n\nexport interface ScanOptions {\n cwd?: string;\n pattern?: string;\n ignore?: string[];\n}\n\nexport function* readProjectFiles(\n pattern: string,\n options: { cwd: string; ignore?: string[] },\n): Generator<{ file: string; fullPath: string; content: string }> {\n const files = globSync(pattern, options);\n\n for (const file of files) {\n const fullPath = path.join(options.cwd, file);\n try {\n const content = fs.readFileSync(fullPath, \"utf8\");\n yield { file, fullPath, content };\n } catch {\n continue;\n }\n }\n}\n\nexport function scanForImport(\n importPattern: string | string[],\n options: ScanOptions = {},\n): boolean {\n const cwd = options.cwd || process.cwd();\n const pattern = options.pattern || \"**/*.{js,jsx,ts,tsx}\";\n const ignore = options.ignore || [\n \"**/node_modules/**\",\n \"**/dist/**\",\n \"**/build/**\",\n ];\n\n const patterns = Array.isArray(importPattern)\n ? importPattern\n : [importPattern];\n\n for (const { content } of readProjectFiles(pattern, { cwd, ignore })) {\n if (patterns.some((p) => content.includes(p))) {\n return true;\n }\n }\n\n return false;\n}\n\nexport function getFilesContaining(\n searchString: string,\n options: ScanOptions = {},\n): string[] {\n const cwd = options.cwd || process.cwd();\n const pattern = options.pattern || \"**/*.{js,jsx,ts,tsx}\";\n const ignore = options.ignore || [\n \"**/node_modules/**\",\n \"**/dist/**\",\n \"**/build/**\",\n ];\n\n const result: string[] = [];\n\n for (const { fullPath, content } of readProjectFiles(pattern, {\n cwd,\n ignore,\n })) {\n if (content.includes(searchString)) {\n result.push(fullPath);\n }\n }\n\n return result;\n}\n"],"mappings":";;;;AAUA,UAAiB,iBACf,SACA,SACgE;CAChE,MAAM,QAAQA,KAAS,SAAS,OAAO;CAEvC,KAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,WAAWC,OAAK,KAAK,QAAQ,KAAK,IAAI;EAC5C,IAAI;GAEF,MAAM;IAAE;IAAM;IAAU,SADRC,KAAG,aAAa,UAAU,MACZ;GAAE;EAClC,QAAQ;GACN;EACF;CACF;AACF;AAEA,SAAgB,cACd,eACA,UAAuB,CAAC,GACf;CACT,MAAM,MAAM,QAAQ,OAAO,QAAQ,IAAI;CACvC,MAAM,UAAU,QAAQ,WAAW;CACnC,MAAM,SAAS,QAAQ,UAAU;EAC/B;EACA;EACA;CACF;CAEA,MAAM,WAAW,MAAM,QAAQ,aAAa,IACxC,gBACA,CAAC,aAAa;CAElB,KAAK,MAAM,EAAE,aAAa,iBAAiB,SAAS;EAAE;EAAK;CAAO,CAAC,GACjE,IAAI,SAAS,MAAM,MAAM,QAAQ,SAAS,CAAC,CAAC,GAC1C,OAAO;CAIX,OAAO;AACT;AAEA,SAAgB,mBACd,cACA,UAAuB,CAAC,GACd;CACV,MAAM,MAAM,QAAQ,OAAO,QAAQ,IAAI;CACvC,MAAM,UAAU,QAAQ,WAAW;CACnC,MAAM,SAAS,QAAQ,UAAU;EAC/B;EACA;EACA;CACF;CAEA,MAAM,SAAmB,CAAC;CAE1B,KAAK,MAAM,EAAE,UAAU,aAAa,iBAAiB,SAAS;EAC5D;EACA;CACF,CAAC,GACC,IAAI,QAAQ,SAAS,YAAY,GAC/B,OAAO,KAAK,QAAQ;CAIxB,OAAO;AACT"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { logger } from "./logger.js";
|
|
2
|
-
import { scanForImport } from "./file-scanner.js";
|
|
3
2
|
import { askQuestion, installPackage, isPackageInstalled } from "./package-manager.js";
|
|
3
|
+
import { scanForImport } from "./file-scanner.js";
|
|
4
4
|
//#region src/lib/utils/package-installer.ts
|
|
5
5
|
async function installPackageIfNeeded(config) {
|
|
6
6
|
if (!scanForImport(config.importPatterns)) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
//#region src/lib/utils/package-manager.d.ts
|
|
2
|
+
type PackageManagerName = "npm" | "pnpm" | "yarn" | "bun";
|
|
2
3
|
declare function askQuestion(query: string): Promise<string>;
|
|
3
4
|
declare function isPackageInstalled(pkg: string, cwd?: string): boolean;
|
|
4
5
|
interface InstallCommand {
|
|
@@ -6,7 +7,8 @@ interface InstallCommand {
|
|
|
6
7
|
args: string[];
|
|
7
8
|
}
|
|
8
9
|
declare function getInstallCommand(packageName: string | string[], cwd?: string): Promise<InstallCommand>;
|
|
10
|
+
declare function resolvePackageManagerForCwd(cwd: string, packageManager?: PackageManagerName): Promise<PackageManagerName>;
|
|
9
11
|
declare function installPackage(packageName: string, cwd?: string): Promise<boolean>;
|
|
10
12
|
//#endregion
|
|
11
|
-
export { InstallCommand, askQuestion, getInstallCommand, installPackage, isPackageInstalled };
|
|
13
|
+
export { InstallCommand, PackageManagerName, askQuestion, getInstallCommand, installPackage, isPackageInstalled, resolvePackageManagerForCwd };
|
|
12
14
|
//# sourceMappingURL=package-manager.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"package-manager.d.ts","names":[],"sources":["../../../src/lib/utils/package-manager.ts"],"mappings":";
|
|
1
|
+
{"version":3,"file":"package-manager.d.ts","names":[],"sources":["../../../src/lib/utils/package-manager.ts"],"mappings":";KAOY;iBAEI,YAAY,gBAAgB;iBAa5B,mBACd,aACA;UAmBe;EACf;EACA;;iBAGoB,kBACpB,gCACA,eACC,QAAQ;iBAyBW,4BACpB,aACA,iBAAiB,qBAChB,QAAQ;iBAWW,eACpB,qBACA,eACC"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import { SpawnSignalError, runSpawn } from "../run-spawn.js";
|
|
1
2
|
import { logger } from "./logger.js";
|
|
2
3
|
import * as fs$1 from "node:fs";
|
|
3
4
|
import * as path$1 from "node:path";
|
|
4
5
|
import { detect } from "detect-package-manager";
|
|
5
|
-
import { spawnSync } from "node:child_process";
|
|
6
6
|
import * as readline from "node:readline";
|
|
7
7
|
//#region src/lib/utils/package-manager.ts
|
|
8
8
|
function askQuestion(query) {
|
|
@@ -52,24 +52,36 @@ async function getInstallCommand(packageName, cwd) {
|
|
|
52
52
|
};
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
|
+
function detectFromUserAgent() {
|
|
56
|
+
const ua = process.env.npm_config_user_agent;
|
|
57
|
+
if (!ua) return void 0;
|
|
58
|
+
if (ua.startsWith("bun/")) return "bun";
|
|
59
|
+
if (ua.startsWith("pnpm/")) return "pnpm";
|
|
60
|
+
if (ua.startsWith("yarn/")) return "yarn";
|
|
61
|
+
if (ua.startsWith("npm/")) return "npm";
|
|
62
|
+
}
|
|
63
|
+
async function resolvePackageManagerForCwd(cwd, packageManager) {
|
|
64
|
+
if (packageManager) return packageManager;
|
|
65
|
+
const fromAgent = detectFromUserAgent();
|
|
66
|
+
if (fromAgent) return fromAgent;
|
|
67
|
+
try {
|
|
68
|
+
return await detect({ cwd });
|
|
69
|
+
} catch {
|
|
70
|
+
return "npm";
|
|
71
|
+
}
|
|
72
|
+
}
|
|
55
73
|
async function installPackage(packageName, cwd) {
|
|
56
74
|
try {
|
|
57
75
|
const { command, args } = await getInstallCommand(packageName, cwd);
|
|
58
|
-
|
|
59
|
-
stdio: "inherit",
|
|
60
|
-
cwd
|
|
61
|
-
});
|
|
62
|
-
if (result.error || result.status !== 0) {
|
|
63
|
-
logger.error(`Installation failed${result.error ? `: ${String(result.error)}` : "."}`);
|
|
64
|
-
return false;
|
|
65
|
-
}
|
|
76
|
+
await runSpawn(command, args, cwd);
|
|
66
77
|
return true;
|
|
67
78
|
} catch (e) {
|
|
79
|
+
if (e instanceof SpawnSignalError) throw e;
|
|
68
80
|
logger.error(`Installation failed: ${String(e)}`);
|
|
69
81
|
return false;
|
|
70
82
|
}
|
|
71
83
|
}
|
|
72
84
|
//#endregion
|
|
73
|
-
export { askQuestion, getInstallCommand, installPackage, isPackageInstalled };
|
|
85
|
+
export { askQuestion, getInstallCommand, installPackage, isPackageInstalled, resolvePackageManagerForCwd };
|
|
74
86
|
|
|
75
87
|
//# sourceMappingURL=package-manager.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"package-manager.js","names":["path","fs"],"sources":["../../../src/lib/utils/package-manager.ts"],"sourcesContent":["import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport {
|
|
1
|
+
{"version":3,"file":"package-manager.js","names":["path","fs"],"sources":["../../../src/lib/utils/package-manager.ts"],"sourcesContent":["import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { detect } from \"detect-package-manager\";\nimport * as readline from \"node:readline\";\nimport { logger } from \"./logger\";\nimport { runSpawn, SpawnSignalError } from \"../run-spawn\";\n\nexport type PackageManagerName = \"npm\" | \"pnpm\" | \"yarn\" | \"bun\";\n\nexport function askQuestion(query: string): Promise<string> {\n return new Promise((resolve) => {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n rl.question(query, (answer) => {\n rl.close();\n resolve(answer);\n });\n });\n}\n\nexport function isPackageInstalled(\n pkg: string,\n cwd: string = process.cwd(),\n): boolean {\n try {\n const pkgJsonPath = path.join(cwd, \"package.json\");\n if (fs.existsSync(pkgJsonPath)) {\n const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, \"utf8\"));\n const deps = pkgJson.dependencies || {};\n const devDeps = pkgJson.devDependencies || {};\n if (deps[pkg] || devDeps[pkg]) {\n return true;\n }\n }\n } catch {\n // Fall back to node_modules check below.\n }\n const modulePath = path.join(cwd, \"node_modules\", ...pkg.split(\"/\"));\n return fs.existsSync(modulePath);\n}\n\nexport interface InstallCommand {\n command: string;\n args: string[];\n}\n\nexport async function getInstallCommand(\n packageName: string | string[],\n cwd?: string,\n): Promise<InstallCommand> {\n const pm = await detect({ cwd });\n const packages = Array.isArray(packageName) ? packageName : [packageName];\n switch (pm) {\n case \"yarn\":\n return { command: \"yarn\", args: [\"add\", ...packages] };\n case \"pnpm\":\n return { command: \"pnpm\", args: [\"add\", ...packages] };\n case \"bun\":\n return { command: \"bun\", args: [\"add\", ...packages] };\n default:\n return { command: \"npm\", args: [\"install\", ...packages] };\n }\n}\n\nfunction detectFromUserAgent(): PackageManagerName | undefined {\n const ua = process.env.npm_config_user_agent;\n if (!ua) return undefined;\n if (ua.startsWith(\"bun/\")) return \"bun\";\n if (ua.startsWith(\"pnpm/\")) return \"pnpm\";\n if (ua.startsWith(\"yarn/\")) return \"yarn\";\n if (ua.startsWith(\"npm/\")) return \"npm\";\n return undefined;\n}\n\nexport async function resolvePackageManagerForCwd(\n cwd: string,\n packageManager?: PackageManagerName,\n): Promise<PackageManagerName> {\n if (packageManager) return packageManager;\n const fromAgent = detectFromUserAgent();\n if (fromAgent) return fromAgent;\n try {\n return await detect({ cwd });\n } catch {\n return \"npm\";\n }\n}\n\nexport async function installPackage(\n packageName: string,\n cwd?: string,\n): Promise<boolean> {\n try {\n const { command, args } = await getInstallCommand(packageName, cwd);\n await runSpawn(command, args, cwd);\n return true;\n } catch (e) {\n if (e instanceof SpawnSignalError) throw e;\n logger.error(`Installation failed: ${String(e)}`);\n return false;\n }\n}\n"],"mappings":";;;;;;;AASA,SAAgB,YAAY,OAAgC;CAC1D,OAAO,IAAI,SAAS,YAAY;EAC9B,MAAM,KAAK,SAAS,gBAAgB;GAClC,OAAO,QAAQ;GACf,QAAQ,QAAQ;EAClB,CAAC;EACD,GAAG,SAAS,QAAQ,WAAW;GAC7B,GAAG,MAAM;GACT,QAAQ,MAAM;EAChB,CAAC;CACH,CAAC;AACH;AAEA,SAAgB,mBACd,KACA,MAAc,QAAQ,IAAI,GACjB;CACT,IAAI;EACF,MAAM,cAAcA,OAAK,KAAK,KAAK,cAAc;EACjD,IAAIC,KAAG,WAAW,WAAW,GAAG;GAC9B,MAAM,UAAU,KAAK,MAAMA,KAAG,aAAa,aAAa,MAAM,CAAC;GAC/D,MAAM,OAAO,QAAQ,gBAAgB,CAAC;GACtC,MAAM,UAAU,QAAQ,mBAAmB,CAAC;GAC5C,IAAI,KAAK,QAAQ,QAAQ,MACvB,OAAO;EAEX;CACF,QAAQ,CAER;CACA,MAAM,aAAaD,OAAK,KAAK,KAAK,gBAAgB,GAAG,IAAI,MAAM,GAAG,CAAC;CACnE,OAAOC,KAAG,WAAW,UAAU;AACjC;AAOA,eAAsB,kBACpB,aACA,KACyB;CACzB,MAAM,KAAK,MAAM,OAAO,EAAE,IAAI,CAAC;CAC/B,MAAM,WAAW,MAAM,QAAQ,WAAW,IAAI,cAAc,CAAC,WAAW;CACxE,QAAQ,IAAR;EACE,KAAK,QACH,OAAO;GAAE,SAAS;GAAQ,MAAM,CAAC,OAAO,GAAG,QAAQ;EAAE;EACvD,KAAK,QACH,OAAO;GAAE,SAAS;GAAQ,MAAM,CAAC,OAAO,GAAG,QAAQ;EAAE;EACvD,KAAK,OACH,OAAO;GAAE,SAAS;GAAO,MAAM,CAAC,OAAO,GAAG,QAAQ;EAAE;EACtD,SACE,OAAO;GAAE,SAAS;GAAO,MAAM,CAAC,WAAW,GAAG,QAAQ;EAAE;CAC5D;AACF;AAEA,SAAS,sBAAsD;CAC7D,MAAM,KAAK,QAAQ,IAAI;CACvB,IAAI,CAAC,IAAI,OAAO,KAAA;CAChB,IAAI,GAAG,WAAW,MAAM,GAAG,OAAO;CAClC,IAAI,GAAG,WAAW,OAAO,GAAG,OAAO;CACnC,IAAI,GAAG,WAAW,OAAO,GAAG,OAAO;CACnC,IAAI,GAAG,WAAW,MAAM,GAAG,OAAO;AAEpC;AAEA,eAAsB,4BACpB,KACA,gBAC6B;CAC7B,IAAI,gBAAgB,OAAO;CAC3B,MAAM,YAAY,oBAAoB;CACtC,IAAI,WAAW,OAAO;CACtB,IAAI;EACF,OAAO,MAAM,OAAO,EAAE,IAAI,CAAC;CAC7B,QAAQ;EACN,OAAO;CACT;AACF;AAEA,eAAsB,eACpB,aACA,KACkB;CAClB,IAAI;EACF,MAAM,EAAE,SAAS,SAAS,MAAM,kBAAkB,aAAa,GAAG;EAClE,MAAM,SAAS,SAAS,MAAM,GAAG;EACjC,OAAO;CACT,SAAS,GAAG;EACV,IAAI,aAAa,kBAAkB,MAAM;EACzC,OAAO,MAAM,wBAAwB,OAAO,CAAC,GAAG;EAChD,OAAO;CACT;AACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "assistant-ui",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.113",
|
|
4
4
|
"description": "CLI for assistant-ui",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
],
|
|
27
27
|
"sideEffects": false,
|
|
28
28
|
"dependencies": {
|
|
29
|
+
"@assistant-ui/agent-launcher": "0.1.13",
|
|
29
30
|
"@clack/prompts": "^1.7.0",
|
|
30
31
|
"chalk": "^6.0.0",
|
|
31
32
|
"cli-progress": "^3.12.0",
|
|
@@ -37,19 +38,18 @@
|
|
|
37
38
|
"glob": "^13.0.6",
|
|
38
39
|
"jscodeshift": "^17.4.0",
|
|
39
40
|
"jsonc-parser": "^3.3.1",
|
|
40
|
-
"semver": "^7.8.5"
|
|
41
|
-
"@assistant-ui/agent-launcher": "0.1.11"
|
|
41
|
+
"semver": "^7.8.5"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
|
+
"@assistant-ui/x-buildutils": "0.0.24",
|
|
44
45
|
"@types/cli-progress": "^3.11.6",
|
|
45
46
|
"@types/cross-spawn": "^6.0.6",
|
|
46
47
|
"@types/debug": "^4.1.13",
|
|
47
48
|
"@types/jscodeshift": "^17.3.0",
|
|
48
49
|
"@types/node": "^26.2.0",
|
|
49
50
|
"@types/semver": "^7.8.0",
|
|
50
|
-
"@vitest/coverage-v8": "^4.1.
|
|
51
|
-
"vitest": "^4.1.
|
|
52
|
-
"@assistant-ui/x-buildutils": "0.0.23"
|
|
51
|
+
"@vitest/coverage-v8": "^4.1.11",
|
|
52
|
+
"vitest": "^4.1.11"
|
|
53
53
|
},
|
|
54
54
|
"publishConfig": {
|
|
55
55
|
"access": "public",
|
|
@@ -67,7 +67,7 @@ assistant-ui requires a runtime. The most common setup uses AI SDK:
|
|
|
67
67
|
|
|
68
68
|
Install the integration package:
|
|
69
69
|
```bash
|
|
70
|
-
npm install @assistant-ui/
|
|
70
|
+
npm install @assistant-ui/ai-sdk
|
|
71
71
|
```
|
|
72
72
|
|
|
73
73
|
Create a chat API route (Next.js App Router):
|
|
@@ -98,7 +98,7 @@ Create the assistant component:
|
|
|
98
98
|
"use client";
|
|
99
99
|
|
|
100
100
|
import { AssistantRuntimeProvider } from "@assistant-ui/react";
|
|
101
|
-
import { useChatRuntime } from "@assistant-ui/
|
|
101
|
+
import { useChatRuntime } from "@assistant-ui/ai-sdk";
|
|
102
102
|
import { Thread } from "@/components/assistant-ui/thread";
|
|
103
103
|
|
|
104
104
|
export const Assistant = () => {
|
|
@@ -188,7 +188,7 @@ Do not use `makeAssistantToolUI`, `useAssistantToolUI`, `makeAssistantTool`, or
|
|
|
188
188
|
| Package | Purpose |
|
|
189
189
|
|---------|---------|
|
|
190
190
|
| `@assistant-ui/react` | Core React components and primitives |
|
|
191
|
-
| `@assistant-ui/
|
|
191
|
+
| `@assistant-ui/ai-sdk` | Vercel AI SDK integration |
|
|
192
192
|
| `@assistant-ui/react-markdown` | Markdown rendering |
|
|
193
193
|
| `@assistant-ui/react-syntax-highlighter` | Code highlighting |
|
|
194
194
|
| `@assistant-ui/ui` | Pre-built shadcn/ui component set |
|