create-assistant-ui 0.0.41 → 0.0.42
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 +122 -28
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
- package/src/index.ts +143 -37
package/dist/index.js
CHANGED
|
@@ -2,21 +2,89 @@
|
|
|
2
2
|
import { Command } from "commander";
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
import { spawn } from "cross-spawn";
|
|
5
|
-
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import * as p from "@clack/prompts";
|
|
7
|
+
// Keep in sync with packages/cli/src/commands/create.ts
|
|
6
8
|
const templates = {
|
|
7
|
-
default:
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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
|
+
},
|
|
12
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
|
+
}
|
|
13
81
|
const create = new Command()
|
|
14
82
|
.name("create-assistant-ui")
|
|
15
83
|
.description("create a new assistant-ui project")
|
|
16
84
|
.argument("[project-directory]")
|
|
17
85
|
.usage(`${chalk.green("[project-directory]")} [options]`)
|
|
18
86
|
.option("-t, --template <template>", `
|
|
19
|
-
The template to use (${
|
|
87
|
+
The template to use (${templateNames.join(", ")})
|
|
20
88
|
`)
|
|
21
89
|
.option("--use-npm", `
|
|
22
90
|
|
|
@@ -38,31 +106,57 @@ const create = new Command()
|
|
|
38
106
|
|
|
39
107
|
Explicitly tell the CLI to skip installing packages
|
|
40
108
|
`)
|
|
41
|
-
.
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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.");
|
|
45
116
|
process.exit(1);
|
|
46
117
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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(", ")}`);
|
|
58
143
|
process.exit(1);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
process.
|
|
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));
|
|
64
149
|
}
|
|
65
|
-
}
|
|
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
|
+
}
|
|
66
160
|
});
|
|
67
161
|
process.on("SIGINT", () => process.exit(0));
|
|
68
162
|
process.on("SIGTERM", () => process.exit(0));
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEpC,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-assistant-ui",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.42",
|
|
4
4
|
"description": "Create assistant-ui apps with one command",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
],
|
|
26
26
|
"sideEffects": false,
|
|
27
27
|
"dependencies": {
|
|
28
|
+
"@clack/prompts": "^1.0.0",
|
|
28
29
|
"chalk": "^5.6.2",
|
|
29
30
|
"commander": "^14.0.3",
|
|
30
31
|
"cross-spawn": "^7.0.6"
|
package/src/index.ts
CHANGED
|
@@ -2,15 +2,95 @@
|
|
|
2
2
|
import { Command } from "commander";
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
import { spawn } from "cross-spawn";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import * as p from "@clack/prompts";
|
|
5
7
|
|
|
6
|
-
// Keep in sync with packages/cli/src/
|
|
8
|
+
// Keep in sync with packages/cli/src/commands/create.ts
|
|
7
9
|
const templates = {
|
|
8
|
-
default:
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
+
}
|
|
14
94
|
|
|
15
95
|
const create = new Command()
|
|
16
96
|
.name("create-assistant-ui")
|
|
@@ -20,7 +100,7 @@ const create = new Command()
|
|
|
20
100
|
.option(
|
|
21
101
|
"-t, --template <template>",
|
|
22
102
|
`
|
|
23
|
-
The template to use (${
|
|
103
|
+
The template to use (${templateNames.join(", ")})
|
|
24
104
|
`,
|
|
25
105
|
)
|
|
26
106
|
.option(
|
|
@@ -58,44 +138,70 @@ const create = new Command()
|
|
|
58
138
|
Explicitly tell the CLI to skip installing packages
|
|
59
139
|
`,
|
|
60
140
|
)
|
|
61
|
-
.
|
|
62
|
-
|
|
63
|
-
|
|
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;
|
|
64
176
|
if (!templateUrl) {
|
|
65
177
|
console.error(
|
|
66
|
-
`Unknown template: ${opts.template}\nAvailable templates: ${
|
|
178
|
+
`Unknown template: ${opts.template}\nAvailable templates: ${templateNames.join(", ")}`,
|
|
67
179
|
);
|
|
68
180
|
process.exit(1);
|
|
69
181
|
}
|
|
70
182
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
arr[index - 1] === "-t" ||
|
|
76
|
-
arr[index - 1] === "--template"
|
|
183
|
+
try {
|
|
184
|
+
await runSpawn(
|
|
185
|
+
"npx",
|
|
186
|
+
buildCreateNextAppArgs(process.argv.slice(2), templateUrl),
|
|
77
187
|
);
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
const child = spawn(
|
|
81
|
-
"npx",
|
|
82
|
-
[`create-next-app@latest`, ...filteredArgs, "-e", templateUrl],
|
|
83
|
-
{
|
|
84
|
-
stdio: "inherit",
|
|
85
|
-
},
|
|
86
|
-
);
|
|
87
188
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
if (code !== 0) {
|
|
95
|
-
console.error(`create-next-app process exited with code ${code}`);
|
|
96
|
-
process.exit(code || 1);
|
|
189
|
+
if (opts.preset) {
|
|
190
|
+
await runSpawn(
|
|
191
|
+
"npx",
|
|
192
|
+
["shadcn@latest", "add", "--yes", opts.preset],
|
|
193
|
+
path.resolve(process.cwd(), projectDirectory),
|
|
194
|
+
);
|
|
97
195
|
}
|
|
98
|
-
})
|
|
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
|
+
}
|
|
99
205
|
});
|
|
100
206
|
|
|
101
207
|
process.on("SIGINT", () => process.exit(0));
|