create-assistant-ui 0.0.42 → 0.0.44
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/index.js +2 -163
- package/dist/index.js.map +1 -1
- package/dist/run.d.ts +2 -0
- package/dist/run.d.ts.map +1 -0
- package/dist/run.js +59 -0
- package/dist/run.js.map +1 -0
- package/package.json +3 -5
- package/src/index.ts +2 -209
- package/src/run.ts +72 -0
package/dist/index.js
CHANGED
|
@@ -1,167 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import chalk from "chalk";
|
|
4
|
-
import { spawn } from "cross-spawn";
|
|
5
|
-
import path from "node:path";
|
|
6
|
-
import * as p from "@clack/prompts";
|
|
7
|
-
// Keep in sync with packages/cli/src/commands/create.ts
|
|
8
|
-
const templates = {
|
|
9
|
-
default: {
|
|
10
|
-
url: "https://github.com/assistant-ui/assistant-ui-starter",
|
|
11
|
-
label: "Default",
|
|
12
|
-
hint: "Default template with Vercel AI SDK",
|
|
13
|
-
},
|
|
14
|
-
minimal: {
|
|
15
|
-
url: "https://github.com/assistant-ui/assistant-ui-starter-minimal",
|
|
16
|
-
label: "Minimal",
|
|
17
|
-
hint: "Bare-bones starting point",
|
|
18
|
-
},
|
|
19
|
-
cloud: {
|
|
20
|
-
url: "https://github.com/assistant-ui/assistant-cloud-starter",
|
|
21
|
-
label: "Cloud",
|
|
22
|
-
hint: "Cloud-backed persistence starter",
|
|
23
|
-
},
|
|
24
|
-
"cloud-clerk": {
|
|
25
|
-
url: "https://github.com/assistant-ui/assistant-ui-starter-cloud-clerk",
|
|
26
|
-
label: "Cloud + Clerk",
|
|
27
|
-
hint: "Cloud-backed starter with Clerk auth",
|
|
28
|
-
},
|
|
29
|
-
langgraph: {
|
|
30
|
-
url: "https://github.com/assistant-ui/assistant-ui-starter-langgraph",
|
|
31
|
-
label: "LangGraph",
|
|
32
|
-
hint: "LangGraph starter template",
|
|
33
|
-
},
|
|
34
|
-
mcp: {
|
|
35
|
-
url: "https://github.com/assistant-ui/assistant-ui-starter-mcp",
|
|
36
|
-
label: "MCP",
|
|
37
|
-
hint: "MCP starter template",
|
|
38
|
-
},
|
|
39
|
-
};
|
|
40
|
-
const templateNames = Object.keys(templates);
|
|
41
|
-
class SpawnExitError extends Error {
|
|
42
|
-
code;
|
|
43
|
-
constructor(code) {
|
|
44
|
-
super(`Process exited with code ${code}`);
|
|
45
|
-
this.code = code;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
async function runSpawn(command, args, cwd) {
|
|
49
|
-
return new Promise((resolve, reject) => {
|
|
50
|
-
const child = spawn(command, args, {
|
|
51
|
-
stdio: "inherit",
|
|
52
|
-
cwd,
|
|
53
|
-
});
|
|
54
|
-
child.on("error", (error) => reject(error));
|
|
55
|
-
child.on("close", (code) => {
|
|
56
|
-
if (code !== 0) {
|
|
57
|
-
reject(new SpawnExitError(code || 1));
|
|
58
|
-
}
|
|
59
|
-
else {
|
|
60
|
-
resolve();
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
function buildCreateNextAppArgs(commandArgs, templateUrl) {
|
|
66
|
-
const filteredArgs = commandArgs.filter((arg, index, arr) => {
|
|
67
|
-
const previousArg = arr[index - 1];
|
|
68
|
-
return !(arg === "-t" ||
|
|
69
|
-
arg === "--template" ||
|
|
70
|
-
arg.startsWith("--template=") ||
|
|
71
|
-
previousArg === "-t" ||
|
|
72
|
-
previousArg === "--template" ||
|
|
73
|
-
arg === "-p" ||
|
|
74
|
-
arg === "--preset" ||
|
|
75
|
-
arg.startsWith("--preset=") ||
|
|
76
|
-
previousArg === "-p" ||
|
|
77
|
-
previousArg === "--preset");
|
|
78
|
-
});
|
|
79
|
-
return ["create-next-app@latest", ...filteredArgs, "-e", templateUrl];
|
|
80
|
-
}
|
|
81
|
-
const create = new Command()
|
|
82
|
-
.name("create-assistant-ui")
|
|
83
|
-
.description("create a new assistant-ui project")
|
|
84
|
-
.argument("[project-directory]")
|
|
85
|
-
.usage(`${chalk.green("[project-directory]")} [options]`)
|
|
86
|
-
.option("-t, --template <template>", `
|
|
87
|
-
The template to use (${templateNames.join(", ")})
|
|
88
|
-
`)
|
|
89
|
-
.option("--use-npm", `
|
|
90
|
-
|
|
91
|
-
Explicitly tell the CLI to bootstrap the application using npm
|
|
92
|
-
`)
|
|
93
|
-
.option("--use-pnpm", `
|
|
94
|
-
|
|
95
|
-
Explicitly tell the CLI to bootstrap the application using pnpm
|
|
96
|
-
`)
|
|
97
|
-
.option("--use-yarn", `
|
|
98
|
-
|
|
99
|
-
Explicitly tell the CLI to bootstrap the application using Yarn
|
|
100
|
-
`)
|
|
101
|
-
.option("--use-bun", `
|
|
102
|
-
|
|
103
|
-
Explicitly tell the CLI to bootstrap the application using Bun
|
|
104
|
-
`)
|
|
105
|
-
.option("--skip-install", `
|
|
106
|
-
|
|
107
|
-
Explicitly tell the CLI to skip installing packages
|
|
108
|
-
`)
|
|
109
|
-
.option("-p, --preset <url>", `
|
|
110
|
-
|
|
111
|
-
Preset URL from playground (e.g., https://www.assistant-ui.com/playground/init?preset=chatgpt)
|
|
112
|
-
`)
|
|
113
|
-
.action(async (projectDirectory, opts) => {
|
|
114
|
-
if (opts.preset && !projectDirectory) {
|
|
115
|
-
console.error("Project directory is required when using --preset.");
|
|
116
|
-
process.exit(1);
|
|
117
|
-
}
|
|
118
|
-
let templateName;
|
|
119
|
-
if (opts.template) {
|
|
120
|
-
templateName = opts.template;
|
|
121
|
-
}
|
|
122
|
-
else if (process.stdin.isTTY) {
|
|
123
|
-
const selected = await p.select({
|
|
124
|
-
message: "Select a template:",
|
|
125
|
-
options: templateNames.map((name) => ({
|
|
126
|
-
value: name,
|
|
127
|
-
label: templates[name].label,
|
|
128
|
-
hint: templates[name].hint,
|
|
129
|
-
})),
|
|
130
|
-
});
|
|
131
|
-
if (p.isCancel(selected)) {
|
|
132
|
-
p.cancel("Project creation cancelled.");
|
|
133
|
-
process.exit(0);
|
|
134
|
-
}
|
|
135
|
-
templateName = selected;
|
|
136
|
-
}
|
|
137
|
-
else {
|
|
138
|
-
templateName = "default";
|
|
139
|
-
}
|
|
140
|
-
const templateUrl = templates[templateName]?.url;
|
|
141
|
-
if (!templateUrl) {
|
|
142
|
-
console.error(`Unknown template: ${opts.template}\nAvailable templates: ${templateNames.join(", ")}`);
|
|
143
|
-
process.exit(1);
|
|
144
|
-
}
|
|
145
|
-
try {
|
|
146
|
-
await runSpawn("npx", buildCreateNextAppArgs(process.argv.slice(2), templateUrl));
|
|
147
|
-
if (opts.preset) {
|
|
148
|
-
await runSpawn("npx", ["shadcn@latest", "add", "--yes", opts.preset], path.resolve(process.cwd(), projectDirectory));
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
catch (error) {
|
|
152
|
-
if (error instanceof SpawnExitError) {
|
|
153
|
-
console.error(`create-next-app process exited with code ${error.code}`);
|
|
154
|
-
process.exit(error.code);
|
|
155
|
-
}
|
|
156
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
157
|
-
console.error(`Error: ${message}`);
|
|
158
|
-
process.exit(1);
|
|
159
|
-
}
|
|
160
|
-
});
|
|
2
|
+
import { main } from "./run.js";
|
|
161
3
|
process.on("SIGINT", () => process.exit(0));
|
|
162
4
|
process.on("SIGTERM", () => process.exit(0));
|
|
163
|
-
|
|
164
|
-
create.parse();
|
|
165
|
-
}
|
|
166
|
-
main();
|
|
5
|
+
void main();
|
|
167
6
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,iBAAc;AAE7B,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAC5C,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAE7C,KAAK,IAAI,EAAE,CAAC"}
|
package/dist/run.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"AAoDA,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAmB1C"}
|
package/dist/run.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { spawn } from "cross-spawn";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import { createRequire } from "node:module";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
const require = createRequire(import.meta.url);
|
|
6
|
+
class SpawnExitError extends Error {
|
|
7
|
+
code;
|
|
8
|
+
constructor(code) {
|
|
9
|
+
super(`Process exited with code ${code}`);
|
|
10
|
+
this.code = code;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
function runSpawn(command, args) {
|
|
14
|
+
return new Promise((resolve, reject) => {
|
|
15
|
+
const child = spawn(command, args, {
|
|
16
|
+
stdio: "inherit",
|
|
17
|
+
});
|
|
18
|
+
child.on("error", (error) => reject(error));
|
|
19
|
+
child.on("close", (code) => {
|
|
20
|
+
if (code !== 0) {
|
|
21
|
+
reject(new SpawnExitError(code || 1));
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
resolve();
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
async function resolveAssistantUiBinPath() {
|
|
30
|
+
const packageJsonPath = require.resolve("assistant-ui/package.json");
|
|
31
|
+
const packageJsonRaw = await readFile(packageJsonPath, "utf8");
|
|
32
|
+
const packageJson = JSON.parse(packageJsonRaw);
|
|
33
|
+
const bin = typeof packageJson.bin === "string"
|
|
34
|
+
? packageJson.bin
|
|
35
|
+
: packageJson.bin?.["assistant-ui"];
|
|
36
|
+
if (!bin) {
|
|
37
|
+
throw new Error("assistant-ui package does not expose a binary.");
|
|
38
|
+
}
|
|
39
|
+
return path.resolve(path.dirname(packageJsonPath), bin);
|
|
40
|
+
}
|
|
41
|
+
export async function main() {
|
|
42
|
+
try {
|
|
43
|
+
const assistantUiBinPath = await resolveAssistantUiBinPath();
|
|
44
|
+
const args = process.argv.slice(2);
|
|
45
|
+
if (args[0] !== "create") {
|
|
46
|
+
args.unshift("create");
|
|
47
|
+
}
|
|
48
|
+
await runSpawn(process.execPath, [assistantUiBinPath, ...args]);
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
if (error instanceof SpawnExitError) {
|
|
52
|
+
process.exit(error.code);
|
|
53
|
+
}
|
|
54
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
55
|
+
console.error(`Error: ${message}`);
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=run.js.map
|
package/dist/run.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAE/C,MAAM,cAAe,SAAQ,KAAK;IAChC,IAAI,CAAS;IAEb,YAAY,IAAY;QACtB,KAAK,CAAC,4BAA4B,IAAI,EAAE,CAAC,CAAC;QAC1C,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAED,SAAS,QAAQ,CAAC,OAAe,EAAE,IAAc;IAC/C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE;YACjC,KAAK,EAAE,SAAS;SACjB,CAAC,CAAC;QAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAC5C,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YACzB,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;gBACf,MAAM,CAAC,IAAI,cAAc,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;YACxC,CAAC;iBAAM,CAAC;gBACN,OAAO,EAAE,CAAC;YACZ,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,yBAAyB;IACtC,MAAM,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,2BAA2B,CAAC,CAAC;IACrE,MAAM,cAAc,GAAG,MAAM,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;IAC/D,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAE5C,CAAC;IAEF,MAAM,GAAG,GACP,OAAO,WAAW,CAAC,GAAG,KAAK,QAAQ;QACjC,CAAC,CAAC,WAAW,CAAC,GAAG;QACjB,CAAC,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,cAAc,CAAC,CAAC;IAExC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;IACpE,CAAC;IAED,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,GAAG,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,IAAI;IACxB,IAAI,CAAC;QACH,MAAM,kBAAkB,GAAG,MAAM,yBAAyB,EAAE,CAAC;QAE7D,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACnC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE,CAAC;YACzB,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACzB,CAAC;QAED,MAAM,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,kBAAkB,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC;IAClE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,cAAc,EAAE,CAAC;YACpC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;QAED,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,OAAO,CAAC,KAAK,CAAC,UAAU,OAAO,EAAE,CAAC,CAAC;QACnC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-assistant-ui",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.44",
|
|
4
4
|
"description": "Create assistant-ui apps with one command",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -25,10 +25,8 @@
|
|
|
25
25
|
],
|
|
26
26
|
"sideEffects": false,
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"commander": "^14.0.3",
|
|
31
|
-
"cross-spawn": "^7.0.6"
|
|
28
|
+
"cross-spawn": "^7.0.6",
|
|
29
|
+
"assistant-ui": "0.0.81"
|
|
32
30
|
},
|
|
33
31
|
"devDependencies": {
|
|
34
32
|
"@types/cross-spawn": "^6.0.6",
|
package/src/index.ts
CHANGED
|
@@ -1,214 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import chalk from "chalk";
|
|
4
|
-
import { spawn } from "cross-spawn";
|
|
5
|
-
import path from "node:path";
|
|
6
|
-
import * as p from "@clack/prompts";
|
|
7
|
-
|
|
8
|
-
// Keep in sync with packages/cli/src/commands/create.ts
|
|
9
|
-
const templates = {
|
|
10
|
-
default: {
|
|
11
|
-
url: "https://github.com/assistant-ui/assistant-ui-starter",
|
|
12
|
-
label: "Default",
|
|
13
|
-
hint: "Default template with Vercel AI SDK",
|
|
14
|
-
},
|
|
15
|
-
minimal: {
|
|
16
|
-
url: "https://github.com/assistant-ui/assistant-ui-starter-minimal",
|
|
17
|
-
label: "Minimal",
|
|
18
|
-
hint: "Bare-bones starting point",
|
|
19
|
-
},
|
|
20
|
-
cloud: {
|
|
21
|
-
url: "https://github.com/assistant-ui/assistant-cloud-starter",
|
|
22
|
-
label: "Cloud",
|
|
23
|
-
hint: "Cloud-backed persistence starter",
|
|
24
|
-
},
|
|
25
|
-
"cloud-clerk": {
|
|
26
|
-
url: "https://github.com/assistant-ui/assistant-ui-starter-cloud-clerk",
|
|
27
|
-
label: "Cloud + Clerk",
|
|
28
|
-
hint: "Cloud-backed starter with Clerk auth",
|
|
29
|
-
},
|
|
30
|
-
langgraph: {
|
|
31
|
-
url: "https://github.com/assistant-ui/assistant-ui-starter-langgraph",
|
|
32
|
-
label: "LangGraph",
|
|
33
|
-
hint: "LangGraph starter template",
|
|
34
|
-
},
|
|
35
|
-
mcp: {
|
|
36
|
-
url: "https://github.com/assistant-ui/assistant-ui-starter-mcp",
|
|
37
|
-
label: "MCP",
|
|
38
|
-
hint: "MCP starter template",
|
|
39
|
-
},
|
|
40
|
-
} as const;
|
|
41
|
-
|
|
42
|
-
type TemplateName = keyof typeof templates;
|
|
43
|
-
const templateNames = Object.keys(templates) as TemplateName[];
|
|
44
|
-
|
|
45
|
-
class SpawnExitError extends Error {
|
|
46
|
-
code: number;
|
|
47
|
-
|
|
48
|
-
constructor(code: number) {
|
|
49
|
-
super(`Process exited with code ${code}`);
|
|
50
|
-
this.code = code;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
async function runSpawn(command: string, args: string[], cwd?: string) {
|
|
55
|
-
return new Promise<void>((resolve, reject) => {
|
|
56
|
-
const child = spawn(command, args, {
|
|
57
|
-
stdio: "inherit",
|
|
58
|
-
cwd,
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
child.on("error", (error) => reject(error));
|
|
62
|
-
child.on("close", (code) => {
|
|
63
|
-
if (code !== 0) {
|
|
64
|
-
reject(new SpawnExitError(code || 1));
|
|
65
|
-
} else {
|
|
66
|
-
resolve();
|
|
67
|
-
}
|
|
68
|
-
});
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
function buildCreateNextAppArgs(
|
|
73
|
-
commandArgs: string[],
|
|
74
|
-
templateUrl: string,
|
|
75
|
-
): string[] {
|
|
76
|
-
const filteredArgs = commandArgs.filter((arg, index, arr) => {
|
|
77
|
-
const previousArg = arr[index - 1];
|
|
78
|
-
return !(
|
|
79
|
-
arg === "-t" ||
|
|
80
|
-
arg === "--template" ||
|
|
81
|
-
arg.startsWith("--template=") ||
|
|
82
|
-
previousArg === "-t" ||
|
|
83
|
-
previousArg === "--template" ||
|
|
84
|
-
arg === "-p" ||
|
|
85
|
-
arg === "--preset" ||
|
|
86
|
-
arg.startsWith("--preset=") ||
|
|
87
|
-
previousArg === "-p" ||
|
|
88
|
-
previousArg === "--preset"
|
|
89
|
-
);
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
return ["create-next-app@latest", ...filteredArgs, "-e", templateUrl];
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const create = new Command()
|
|
96
|
-
.name("create-assistant-ui")
|
|
97
|
-
.description("create a new assistant-ui project")
|
|
98
|
-
.argument("[project-directory]")
|
|
99
|
-
.usage(`${chalk.green("[project-directory]")} [options]`)
|
|
100
|
-
.option(
|
|
101
|
-
"-t, --template <template>",
|
|
102
|
-
`
|
|
103
|
-
The template to use (${templateNames.join(", ")})
|
|
104
|
-
`,
|
|
105
|
-
)
|
|
106
|
-
.option(
|
|
107
|
-
"--use-npm",
|
|
108
|
-
`
|
|
109
|
-
|
|
110
|
-
Explicitly tell the CLI to bootstrap the application using npm
|
|
111
|
-
`,
|
|
112
|
-
)
|
|
113
|
-
.option(
|
|
114
|
-
"--use-pnpm",
|
|
115
|
-
`
|
|
116
|
-
|
|
117
|
-
Explicitly tell the CLI to bootstrap the application using pnpm
|
|
118
|
-
`,
|
|
119
|
-
)
|
|
120
|
-
.option(
|
|
121
|
-
"--use-yarn",
|
|
122
|
-
`
|
|
123
|
-
|
|
124
|
-
Explicitly tell the CLI to bootstrap the application using Yarn
|
|
125
|
-
`,
|
|
126
|
-
)
|
|
127
|
-
.option(
|
|
128
|
-
"--use-bun",
|
|
129
|
-
`
|
|
130
|
-
|
|
131
|
-
Explicitly tell the CLI to bootstrap the application using Bun
|
|
132
|
-
`,
|
|
133
|
-
)
|
|
134
|
-
.option(
|
|
135
|
-
"--skip-install",
|
|
136
|
-
`
|
|
137
|
-
|
|
138
|
-
Explicitly tell the CLI to skip installing packages
|
|
139
|
-
`,
|
|
140
|
-
)
|
|
141
|
-
.option(
|
|
142
|
-
"-p, --preset <url>",
|
|
143
|
-
`
|
|
144
|
-
|
|
145
|
-
Preset URL from playground (e.g., https://www.assistant-ui.com/playground/init?preset=chatgpt)
|
|
146
|
-
`,
|
|
147
|
-
)
|
|
148
|
-
.action(async (projectDirectory, opts) => {
|
|
149
|
-
if (opts.preset && !projectDirectory) {
|
|
150
|
-
console.error("Project directory is required when using --preset.");
|
|
151
|
-
process.exit(1);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
let templateName: TemplateName;
|
|
155
|
-
if (opts.template) {
|
|
156
|
-
templateName = opts.template as TemplateName;
|
|
157
|
-
} else if (process.stdin.isTTY) {
|
|
158
|
-
const selected = await p.select({
|
|
159
|
-
message: "Select a template:",
|
|
160
|
-
options: templateNames.map((name) => ({
|
|
161
|
-
value: name,
|
|
162
|
-
label: templates[name].label,
|
|
163
|
-
hint: templates[name].hint,
|
|
164
|
-
})),
|
|
165
|
-
});
|
|
166
|
-
if (p.isCancel(selected)) {
|
|
167
|
-
p.cancel("Project creation cancelled.");
|
|
168
|
-
process.exit(0);
|
|
169
|
-
}
|
|
170
|
-
templateName = selected as TemplateName;
|
|
171
|
-
} else {
|
|
172
|
-
templateName = "default";
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
const templateUrl = templates[templateName]?.url;
|
|
176
|
-
if (!templateUrl) {
|
|
177
|
-
console.error(
|
|
178
|
-
`Unknown template: ${opts.template}\nAvailable templates: ${templateNames.join(", ")}`,
|
|
179
|
-
);
|
|
180
|
-
process.exit(1);
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
try {
|
|
184
|
-
await runSpawn(
|
|
185
|
-
"npx",
|
|
186
|
-
buildCreateNextAppArgs(process.argv.slice(2), templateUrl),
|
|
187
|
-
);
|
|
188
|
-
|
|
189
|
-
if (opts.preset) {
|
|
190
|
-
await runSpawn(
|
|
191
|
-
"npx",
|
|
192
|
-
["shadcn@latest", "add", "--yes", opts.preset],
|
|
193
|
-
path.resolve(process.cwd(), projectDirectory),
|
|
194
|
-
);
|
|
195
|
-
}
|
|
196
|
-
} catch (error) {
|
|
197
|
-
if (error instanceof SpawnExitError) {
|
|
198
|
-
console.error(`create-next-app process exited with code ${error.code}`);
|
|
199
|
-
process.exit(error.code);
|
|
200
|
-
}
|
|
201
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
202
|
-
console.error(`Error: ${message}`);
|
|
203
|
-
process.exit(1);
|
|
204
|
-
}
|
|
205
|
-
});
|
|
2
|
+
import { main } from "./run";
|
|
206
3
|
|
|
207
4
|
process.on("SIGINT", () => process.exit(0));
|
|
208
5
|
process.on("SIGTERM", () => process.exit(0));
|
|
209
6
|
|
|
210
|
-
|
|
211
|
-
create.parse();
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
main();
|
|
7
|
+
void main();
|
package/src/run.ts
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { spawn } from "cross-spawn";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import { createRequire } from "node:module";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
|
|
6
|
+
const require = createRequire(import.meta.url);
|
|
7
|
+
|
|
8
|
+
class SpawnExitError extends Error {
|
|
9
|
+
code: number;
|
|
10
|
+
|
|
11
|
+
constructor(code: number) {
|
|
12
|
+
super(`Process exited with code ${code}`);
|
|
13
|
+
this.code = code;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function runSpawn(command: string, args: string[]): Promise<void> {
|
|
18
|
+
return new Promise((resolve, reject) => {
|
|
19
|
+
const child = spawn(command, args, {
|
|
20
|
+
stdio: "inherit",
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
child.on("error", (error) => reject(error));
|
|
24
|
+
child.on("close", (code) => {
|
|
25
|
+
if (code !== 0) {
|
|
26
|
+
reject(new SpawnExitError(code || 1));
|
|
27
|
+
} else {
|
|
28
|
+
resolve();
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async function resolveAssistantUiBinPath(): Promise<string> {
|
|
35
|
+
const packageJsonPath = require.resolve("assistant-ui/package.json");
|
|
36
|
+
const packageJsonRaw = await readFile(packageJsonPath, "utf8");
|
|
37
|
+
const packageJson = JSON.parse(packageJsonRaw) as {
|
|
38
|
+
bin?: string | Record<string, string>;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const bin =
|
|
42
|
+
typeof packageJson.bin === "string"
|
|
43
|
+
? packageJson.bin
|
|
44
|
+
: packageJson.bin?.["assistant-ui"];
|
|
45
|
+
|
|
46
|
+
if (!bin) {
|
|
47
|
+
throw new Error("assistant-ui package does not expose a binary.");
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return path.resolve(path.dirname(packageJsonPath), bin);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export async function main(): Promise<void> {
|
|
54
|
+
try {
|
|
55
|
+
const assistantUiBinPath = await resolveAssistantUiBinPath();
|
|
56
|
+
|
|
57
|
+
const args = process.argv.slice(2);
|
|
58
|
+
if (args[0] !== "create") {
|
|
59
|
+
args.unshift("create");
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
await runSpawn(process.execPath, [assistantUiBinPath, ...args]);
|
|
63
|
+
} catch (error) {
|
|
64
|
+
if (error instanceof SpawnExitError) {
|
|
65
|
+
process.exit(error.code);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
69
|
+
console.error(`Error: ${message}`);
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
}
|