assistant-ui 0.0.91 → 0.0.92
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/README.md +32 -108
- package/dist/commands/add.d.ts +13 -0
- package/dist/commands/add.d.ts.map +1 -1
- package/dist/commands/add.js +48 -32
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/create.d.ts +13 -7
- package/dist/commands/create.d.ts.map +1 -1
- package/dist/commands/create.js +83 -71
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +4 -33
- package/dist/commands/init.js.map +1 -1
- package/dist/lib/create-project.d.ts +15 -1
- package/dist/lib/create-project.d.ts.map +1 -1
- package/dist/lib/create-project.js +93 -61
- package/dist/lib/create-project.js.map +1 -1
- package/dist/lib/run-spawn.d.ts +6 -0
- package/dist/lib/run-spawn.d.ts.map +1 -0
- package/dist/lib/run-spawn.js +26 -0
- package/dist/lib/run-spawn.js.map +1 -0
- package/package.json +2 -2
- package/plugin/skills/assistant-ui/SKILL.md +2 -2
- package/src/commands/add.ts +67 -30
- package/src/commands/create.ts +116 -84
- package/src/commands/init.ts +9 -42
- package/src/lib/create-project.ts +123 -74
- package/src/lib/run-spawn.ts +32 -0
package/README.md
CHANGED
|
@@ -1,141 +1,65 @@
|
|
|
1
1
|
# `assistant-ui` CLI
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/assistant-ui)
|
|
4
|
+
[](https://www.npmjs.com/package/assistant-ui)
|
|
5
|
+
[](https://github.com/assistant-ui/assistant-ui)
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
Command-line tool for adding shadcn-style components to your project, scaffolding a new app, and keeping your assistant-ui packages up to date.
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
## Installation
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
Run via your package manager of choice; nothing to install globally:
|
|
10
12
|
|
|
11
13
|
```bash
|
|
12
|
-
npx assistant-ui@latest
|
|
13
|
-
|
|
14
|
+
npx assistant-ui@latest <command>
|
|
15
|
+
pnpm dlx assistant-ui@latest <command>
|
|
16
|
+
yarn dlx assistant-ui@latest <command>
|
|
17
|
+
bunx assistant-ui@latest <command>
|
|
14
18
|
```
|
|
15
19
|
|
|
16
|
-
|
|
17
|
-
Passing `--preset` to `init` also forwards to `create` for compatibility.
|
|
18
|
-
|
|
19
|
-
## create
|
|
20
|
-
|
|
21
|
-
Use the `create` command to scaffold a new Next.js project with assistant-ui.
|
|
22
|
-
|
|
23
|
-
The `create` command scaffolds a project from assistant-ui starter templates or examples.
|
|
20
|
+
## Common tasks
|
|
24
21
|
|
|
25
22
|
```bash
|
|
23
|
+
# scaffold a new Next.js project
|
|
26
24
|
npx assistant-ui@latest create my-app
|
|
27
|
-
```
|
|
28
25
|
|
|
29
|
-
|
|
26
|
+
# scaffold a minimal project
|
|
27
|
+
npx assistant-ui@latest create my-app --template minimal
|
|
30
28
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
npx assistant-ui@latest create my-app
|
|
34
|
-
|
|
35
|
-
# Minimal starter
|
|
36
|
-
npx assistant-ui@latest create my-app -t minimal
|
|
37
|
-
|
|
38
|
-
# With Assistant Cloud for persistence
|
|
39
|
-
npx assistant-ui@latest create my-app -t cloud
|
|
29
|
+
# scaffold from a feature example
|
|
30
|
+
npx assistant-ui@latest create my-app --example with-ai-sdk-v6
|
|
40
31
|
|
|
41
|
-
#
|
|
42
|
-
npx assistant-ui@latest create my-app
|
|
32
|
+
# scaffold an Expo / React Native project
|
|
33
|
+
npx assistant-ui@latest create my-app --native
|
|
43
34
|
|
|
44
|
-
#
|
|
45
|
-
npx assistant-ui@latest create my-app
|
|
35
|
+
# scaffold a React Ink terminal project
|
|
36
|
+
npx assistant-ui@latest create my-app --ink
|
|
46
37
|
|
|
47
|
-
#
|
|
48
|
-
npx assistant-ui@latest
|
|
49
|
-
|
|
50
|
-
# With playground preset configuration
|
|
51
|
-
npx assistant-ui@latest create my-app --preset "https://www.assistant-ui.com/playground/init?preset=chatgpt"
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
## add
|
|
55
|
-
|
|
56
|
-
Use the `add` command to add components to your project.
|
|
57
|
-
|
|
58
|
-
The `add` command adds a component to your project and installs all required dependencies.
|
|
59
|
-
|
|
60
|
-
```bash
|
|
61
|
-
npx assistant-ui@latest add [component]
|
|
62
|
-
```
|
|
38
|
+
# add assistant-ui to an existing project
|
|
39
|
+
npx assistant-ui@latest init
|
|
63
40
|
|
|
64
|
-
|
|
41
|
+
# initialize non-interactively for CI or agent flows
|
|
42
|
+
npx assistant-ui@latest init --yes
|
|
65
43
|
|
|
66
|
-
|
|
44
|
+
# add a component
|
|
67
45
|
npx assistant-ui@latest add thread
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
You can also add multiple components at once:
|
|
71
46
|
|
|
72
|
-
|
|
73
|
-
npx assistant-ui@latest add thread thread-list assistant-modal
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
## update
|
|
77
|
-
|
|
78
|
-
Use the `update` command to update all assistant-ui packages to their latest versions.
|
|
79
|
-
|
|
80
|
-
```bash
|
|
47
|
+
# update all @assistant-ui/* and assistant-* packages
|
|
81
48
|
npx assistant-ui@latest update
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
## upgrade
|
|
85
|
-
|
|
86
|
-
Use the `upgrade` command to automatically migrate your codebase when upgrading to a new major version.
|
|
87
49
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
```bash
|
|
50
|
+
# run codemods after a major version bump
|
|
91
51
|
npx assistant-ui@latest upgrade
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
## info
|
|
95
|
-
|
|
96
|
-
Use the `info` command to print your environment and package versions for bug reports.
|
|
97
52
|
|
|
98
|
-
|
|
53
|
+
# print env + version info for a bug report
|
|
99
54
|
npx assistant-ui info
|
|
100
55
|
```
|
|
101
56
|
|
|
102
|
-
|
|
103
|
-
- OS, Node.js version, package manager, and framework
|
|
104
|
-
- All installed `@assistant-ui/*` and `assistant-*` package versions
|
|
105
|
-
- Key ecosystem dependency versions (React, Next.js, AI SDK, etc.)
|
|
106
|
-
- Peer dependency warnings if any mismatches are detected
|
|
107
|
-
|
|
108
|
-
**Example output:**
|
|
57
|
+
`init` falls back to `create` when no `package.json` is found, so a single command works for both new and existing projects. Use `init --yes` for CI and agent flows where prompts are not available.
|
|
109
58
|
|
|
110
|
-
|
|
111
|
-
Environment:
|
|
112
|
-
OS: macOS 15.3 (arm64)
|
|
113
|
-
Node.js: v22.14.0
|
|
114
|
-
Package Manager: pnpm 10.32.1
|
|
115
|
-
Framework: Next.js 15.3.1
|
|
116
|
-
|
|
117
|
-
Packages:
|
|
118
|
-
@assistant-ui/react 0.12.15
|
|
119
|
-
@assistant-ui/react-ai-sdk 1.3.12
|
|
120
|
-
@assistant-ui/react-markdown 0.3.8
|
|
121
|
-
assistant-stream 0.2.14
|
|
122
|
-
|
|
123
|
-
Ecosystem:
|
|
124
|
-
react 19.1.0
|
|
125
|
-
react-dom 19.1.0
|
|
126
|
-
next 15.3.1
|
|
127
|
-
ai 6.0.120
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
The output includes a copy-pasteable markdown block that you can paste directly into a bug report.
|
|
59
|
+
## Templates
|
|
131
60
|
|
|
132
|
-
|
|
133
|
-
- `-c, --cwd <cwd>` - the working directory. defaults to the current directory.
|
|
61
|
+
`create` scaffolds from named templates: `default` (AI SDK), `minimal`, `cloud`, `cloud-clerk`, `langgraph`, `mcp`. Pass `-t <name>`, pass `--example <name>` for examples such as `with-ai-sdk-v6`, use `--native` for Expo / React Native, use `--ink` for React Ink, or pass `--preset <url>` to scaffold from an `assistant-ui.com` playground link.
|
|
134
62
|
|
|
135
63
|
## Documentation
|
|
136
64
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
## License
|
|
140
|
-
|
|
141
|
-
Licensed under the [MIT license](https://github.com/assistant-ui/assistant-ui/blob/main/LICENSE).
|
|
65
|
+
Full command reference, flags, and template details at [assistant-ui.com/docs/cli](https://www.assistant-ui.com/docs/cli).
|
package/dist/commands/add.d.ts
CHANGED
|
@@ -1,3 +1,16 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
|
+
import { type PackageManagerName } from "../lib/create-project.js";
|
|
3
|
+
export interface AddComponentsPlan {
|
|
4
|
+
command: string;
|
|
5
|
+
args: string[];
|
|
6
|
+
}
|
|
7
|
+
export declare function createAddComponentsPlan(params: {
|
|
8
|
+
components: string[];
|
|
9
|
+
packageManager: PackageManagerName;
|
|
10
|
+
yes?: boolean;
|
|
11
|
+
overwrite?: boolean;
|
|
12
|
+
cwd?: string;
|
|
13
|
+
path?: string;
|
|
14
|
+
}): AddComponentsPlan;
|
|
2
15
|
export declare const add: Command;
|
|
3
16
|
//# sourceMappingURL=add.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,EAIL,KAAK,kBAAkB,EACxB,iCAA8B;AAK/B,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE;IAC9C,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,cAAc,EAAE,kBAAkB,CAAC;IACnC,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,GAAG,iBAAiB,CAmBpB;AAED,eAAO,MAAM,GAAG,SAqDZ,CAAC"}
|
package/dist/commands/add.js
CHANGED
|
@@ -1,8 +1,30 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
|
-
import { spawn } from "cross-spawn";
|
|
3
2
|
import { logger } from "../lib/utils/logger.js";
|
|
4
3
|
import { hasConfig } from "../lib/utils/config.js";
|
|
4
|
+
import { dlxCommand, resolvePackageManager, resolvePackageManagerForCwd, } from "../lib/create-project.js";
|
|
5
|
+
import { runSpawn, SpawnExitError } from "../lib/run-spawn.js";
|
|
5
6
|
const REGISTRY_BASE_URL = "https://r.assistant-ui.com";
|
|
7
|
+
export function createAddComponentsPlan(params) {
|
|
8
|
+
const componentsToAdd = params.components.map((c) => {
|
|
9
|
+
if (!/^[a-zA-Z0-9-/]+$/.test(c)) {
|
|
10
|
+
throw new Error(`Invalid component name: ${c}`);
|
|
11
|
+
}
|
|
12
|
+
return `${REGISTRY_BASE_URL}/${encodeURIComponent(c)}.json`;
|
|
13
|
+
});
|
|
14
|
+
const [command, dlxArgs] = dlxCommand(params.packageManager);
|
|
15
|
+
const args = [...dlxArgs, "shadcn@latest", "add", ...componentsToAdd];
|
|
16
|
+
// For npm, dlxArgs may already include `--yes` for npx auto-install.
|
|
17
|
+
// This flag is for shadcn's own confirmation prompt.
|
|
18
|
+
if (params.yes)
|
|
19
|
+
args.push("--yes");
|
|
20
|
+
if (params.overwrite)
|
|
21
|
+
args.push("--overwrite");
|
|
22
|
+
if (params.cwd)
|
|
23
|
+
args.push("--cwd", params.cwd);
|
|
24
|
+
if (params.path)
|
|
25
|
+
args.push("--path", params.path);
|
|
26
|
+
return { command, args };
|
|
27
|
+
}
|
|
6
28
|
export const add = new Command()
|
|
7
29
|
.name("add")
|
|
8
30
|
.description("add a component to your project")
|
|
@@ -11,44 +33,38 @@ export const add = new Command()
|
|
|
11
33
|
.option("-o, --overwrite", "overwrite existing files.", false)
|
|
12
34
|
.option("-c, --cwd <cwd>", "the working directory. defaults to the current directory.", process.cwd())
|
|
13
35
|
.option("-p, --path <path>", "the path to add the component to.")
|
|
14
|
-
.
|
|
36
|
+
.option("--use-npm", "explicitly use npm")
|
|
37
|
+
.option("--use-pnpm", "explicitly use pnpm")
|
|
38
|
+
.option("--use-yarn", "explicitly use yarn")
|
|
39
|
+
.option("--use-bun", "explicitly use bun")
|
|
40
|
+
.action(async (components, opts) => {
|
|
15
41
|
// Check if project is initialized
|
|
16
42
|
if (!hasConfig(opts.cwd)) {
|
|
17
43
|
logger.warn("It looks like you haven't initialized your project yet. Run 'assistant-ui init' first.");
|
|
18
44
|
logger.break();
|
|
19
45
|
}
|
|
20
|
-
const componentsToAdd = components.map((c) => {
|
|
21
|
-
if (!/^[a-zA-Z0-9-/]+$/.test(c)) {
|
|
22
|
-
throw new Error(`Invalid component name: ${c}`);
|
|
23
|
-
}
|
|
24
|
-
return `${REGISTRY_BASE_URL}/${encodeURIComponent(c)}.json`;
|
|
25
|
-
});
|
|
26
46
|
logger.step(`Adding ${components.length} component(s)...`);
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
args.push("--path", opts.path);
|
|
36
|
-
const child = spawn("npx", args, {
|
|
37
|
-
stdio: "inherit",
|
|
38
|
-
shell: true,
|
|
39
|
-
});
|
|
40
|
-
child.on("error", (error) => {
|
|
41
|
-
logger.error(`Failed to add components: ${error.message}`);
|
|
42
|
-
process.exit(1);
|
|
47
|
+
const packageManager = await resolvePackageManagerForCwd(opts.cwd, resolvePackageManager(opts));
|
|
48
|
+
const { command, args } = createAddComponentsPlan({
|
|
49
|
+
components,
|
|
50
|
+
packageManager,
|
|
51
|
+
yes: opts.yes,
|
|
52
|
+
overwrite: opts.overwrite,
|
|
53
|
+
cwd: opts.cwd,
|
|
54
|
+
path: opts.path,
|
|
43
55
|
});
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
56
|
+
try {
|
|
57
|
+
await runSpawn(command, args, opts.cwd);
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
if (error instanceof SpawnExitError) {
|
|
61
|
+
logger.error(`Process exited with code ${error.code}`);
|
|
62
|
+
process.exit(error.code);
|
|
51
63
|
}
|
|
52
|
-
|
|
64
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
65
|
+
logger.error(`Failed to add components: ${message}`);
|
|
66
|
+
process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
logger.success("Components added successfully!");
|
|
53
69
|
});
|
|
54
70
|
//# sourceMappingURL=add.js.map
|
package/dist/commands/add.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add.js","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"add.js","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
2
|
import * as p from "@clack/prompts";
|
|
3
|
-
import { type PackageManagerName } from "../lib/create-project.js";
|
|
4
3
|
export interface ProjectMetadata {
|
|
5
4
|
name: string;
|
|
6
5
|
label: string;
|
|
@@ -21,12 +20,19 @@ export declare function resolveCreateProjectDirectory(params: {
|
|
|
21
20
|
projectDirectory?: string;
|
|
22
21
|
stdinIsTTY?: boolean;
|
|
23
22
|
}): string | undefined;
|
|
24
|
-
export declare function resolvePackageManager(opts: {
|
|
25
|
-
useNpm?: boolean;
|
|
26
|
-
usePnpm?: boolean;
|
|
27
|
-
useYarn?: boolean;
|
|
28
|
-
useBun?: boolean;
|
|
29
|
-
}): PackageManagerName | undefined;
|
|
30
23
|
export declare function resolvePresetUrl(preset: string): string;
|
|
24
|
+
export interface ScaffoldSelectorOptions {
|
|
25
|
+
template?: string;
|
|
26
|
+
example?: string;
|
|
27
|
+
preset?: string;
|
|
28
|
+
native?: boolean;
|
|
29
|
+
ink?: boolean;
|
|
30
|
+
}
|
|
31
|
+
export interface ResolvedScaffoldSelector {
|
|
32
|
+
template?: string;
|
|
33
|
+
example?: string;
|
|
34
|
+
preset?: string;
|
|
35
|
+
}
|
|
36
|
+
export declare function resolveScaffoldSelector(opts: ScaffoldSelectorOptions): ResolvedScaffoldSelector;
|
|
31
37
|
export declare const create: Command;
|
|
32
38
|
//# sourceMappingURL=create.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAI5C,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AAapC,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,UAAU,GAAG,SAAS,CAAC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,kBAAkB,EAAE,OAAO,CAAC;CAC7B;AAED,eAAO,MAAM,gBAAgB,EAAE,eAAe,EA2N7C,CAAC;AAmBF,wBAAsB,cAAc,CAAC,MAAM,EAAE;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC;CAC9B,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAyElC;AAED,wBAAgB,6BAA6B,CAAC,MAAM,EAAE;IACpD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,GAAG,MAAM,GAAG,SAAS,CAMrB;AAKD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAKvD;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAYD,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,uBAAuB,GAC5B,wBAAwB,CAkC1B;AAED,eAAO,MAAM,MAAM,SAmPf,CAAC"}
|
package/dist/commands/create.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { Command } from "commander";
|
|
1
|
+
import { Command, Option } from "commander";
|
|
2
2
|
import chalk from "chalk";
|
|
3
|
-
import { spawn } from "cross-spawn";
|
|
4
3
|
import fs from "node:fs";
|
|
5
4
|
import path from "node:path";
|
|
6
5
|
import * as p from "@clack/prompts";
|
|
7
6
|
import { logger } from "../lib/utils/logger.js";
|
|
8
|
-
import { dlxCommand, downloadProject, resolveLatestReleaseRef,
|
|
7
|
+
import { dlxCommand, downloadProject, resolveLatestReleaseRef, resolvePackageManager, resolvePackageManagerForCwd, scaffoldProject, transformProject, } from "../lib/create-project.js";
|
|
8
|
+
import { runSpawn, SpawnExitError } from "../lib/run-spawn.js";
|
|
9
9
|
export const PROJECT_METADATA = [
|
|
10
10
|
// Templates
|
|
11
11
|
{
|
|
@@ -14,7 +14,7 @@ export const PROJECT_METADATA = [
|
|
|
14
14
|
description: "Default template with Vercel AI SDK",
|
|
15
15
|
category: "template",
|
|
16
16
|
path: "templates/default",
|
|
17
|
-
hasLocalComponents:
|
|
17
|
+
hasLocalComponents: false,
|
|
18
18
|
},
|
|
19
19
|
{
|
|
20
20
|
name: "minimal",
|
|
@@ -30,7 +30,7 @@ export const PROJECT_METADATA = [
|
|
|
30
30
|
description: "Cloud-backed persistence starter",
|
|
31
31
|
category: "template",
|
|
32
32
|
path: "templates/cloud",
|
|
33
|
-
hasLocalComponents:
|
|
33
|
+
hasLocalComponents: false,
|
|
34
34
|
},
|
|
35
35
|
{
|
|
36
36
|
name: "cloud-clerk",
|
|
@@ -38,7 +38,7 @@ export const PROJECT_METADATA = [
|
|
|
38
38
|
description: "Cloud-backed starter with Clerk auth",
|
|
39
39
|
category: "template",
|
|
40
40
|
path: "templates/cloud-clerk",
|
|
41
|
-
hasLocalComponents:
|
|
41
|
+
hasLocalComponents: false,
|
|
42
42
|
},
|
|
43
43
|
{
|
|
44
44
|
name: "langgraph",
|
|
@@ -46,15 +46,15 @@ export const PROJECT_METADATA = [
|
|
|
46
46
|
description: "LangGraph starter template",
|
|
47
47
|
category: "template",
|
|
48
48
|
path: "templates/langgraph",
|
|
49
|
-
hasLocalComponents:
|
|
49
|
+
hasLocalComponents: false,
|
|
50
50
|
},
|
|
51
51
|
{
|
|
52
52
|
name: "mcp",
|
|
53
53
|
label: "MCP",
|
|
54
|
-
description: "MCP starter
|
|
54
|
+
description: "MCP tools + MCP Apps renderer starter",
|
|
55
55
|
category: "template",
|
|
56
56
|
path: "templates/mcp",
|
|
57
|
-
hasLocalComponents:
|
|
57
|
+
hasLocalComponents: false,
|
|
58
58
|
},
|
|
59
59
|
// Examples
|
|
60
60
|
{
|
|
@@ -238,7 +238,7 @@ const templateNames = PROJECT_METADATA.filter((m) => m.category === "template").
|
|
|
238
238
|
const exampleNames = PROJECT_METADATA.filter((m) => m.category === "example").map((m) => m.name);
|
|
239
239
|
export async function resolveProject(params) {
|
|
240
240
|
const { template, example, stdinIsTTY = process.stdin.isTTY, select = p.select, isCancel = p.isCancel, } = params;
|
|
241
|
-
if (template) {
|
|
241
|
+
if (template !== undefined) {
|
|
242
242
|
const meta = PROJECT_METADATA.find((m) => m.name === template && m.category === "template");
|
|
243
243
|
if (!meta) {
|
|
244
244
|
logger.error(`Unknown template: ${template}`);
|
|
@@ -247,7 +247,7 @@ export async function resolveProject(params) {
|
|
|
247
247
|
}
|
|
248
248
|
return meta;
|
|
249
249
|
}
|
|
250
|
-
if (example) {
|
|
250
|
+
if (example !== undefined) {
|
|
251
251
|
const meta = PROJECT_METADATA.find((m) => m.name === example && m.category === "example");
|
|
252
252
|
if (!meta) {
|
|
253
253
|
logger.error(`Unknown example: ${example}`);
|
|
@@ -294,30 +294,6 @@ export async function resolveProject(params) {
|
|
|
294
294
|
}
|
|
295
295
|
return meta;
|
|
296
296
|
}
|
|
297
|
-
class SpawnExitError extends Error {
|
|
298
|
-
code;
|
|
299
|
-
constructor(code) {
|
|
300
|
-
super(`Process exited with code ${code}`);
|
|
301
|
-
this.code = code;
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
async function runSpawn(command, args, cwd) {
|
|
305
|
-
return new Promise((resolve, reject) => {
|
|
306
|
-
const child = spawn(command, args, {
|
|
307
|
-
stdio: "inherit",
|
|
308
|
-
cwd,
|
|
309
|
-
});
|
|
310
|
-
child.on("error", (error) => reject(error));
|
|
311
|
-
child.on("close", (code) => {
|
|
312
|
-
if (code !== 0) {
|
|
313
|
-
reject(new SpawnExitError(code || 1));
|
|
314
|
-
}
|
|
315
|
-
else {
|
|
316
|
-
resolve();
|
|
317
|
-
}
|
|
318
|
-
});
|
|
319
|
-
});
|
|
320
|
-
}
|
|
321
297
|
export function resolveCreateProjectDirectory(params) {
|
|
322
298
|
const { projectDirectory, stdinIsTTY = process.stdin.isTTY } = params;
|
|
323
299
|
if (projectDirectory)
|
|
@@ -326,17 +302,6 @@ export function resolveCreateProjectDirectory(params) {
|
|
|
326
302
|
return "my-aui-app";
|
|
327
303
|
return undefined;
|
|
328
304
|
}
|
|
329
|
-
export function resolvePackageManager(opts) {
|
|
330
|
-
if (opts.useNpm)
|
|
331
|
-
return "npm";
|
|
332
|
-
if (opts.usePnpm)
|
|
333
|
-
return "pnpm";
|
|
334
|
-
if (opts.useYarn)
|
|
335
|
-
return "yarn";
|
|
336
|
-
if (opts.useBun)
|
|
337
|
-
return "bun";
|
|
338
|
-
return undefined;
|
|
339
|
-
}
|
|
340
305
|
const PLAYGROUND_PRESET_BASE_URL = "https://www.assistant-ui.com/playground/init";
|
|
341
306
|
export function resolvePresetUrl(preset) {
|
|
342
307
|
if (preset.startsWith("http://") || preset.startsWith("https://")) {
|
|
@@ -344,6 +309,44 @@ export function resolvePresetUrl(preset) {
|
|
|
344
309
|
}
|
|
345
310
|
return `${PLAYGROUND_PRESET_BASE_URL}?preset=${encodeURIComponent(preset)}`;
|
|
346
311
|
}
|
|
312
|
+
const scaffoldSelectorHelp = "Choose one scaffold selector: --template <name>, --example <name>, --native, or --ink. --preset <name-or-url> can be used with --template or by itself.";
|
|
313
|
+
function getPresetConflict(opts) {
|
|
314
|
+
if (opts.example !== undefined)
|
|
315
|
+
return "--example";
|
|
316
|
+
if (opts.native)
|
|
317
|
+
return "--native";
|
|
318
|
+
if (opts.ink)
|
|
319
|
+
return "--ink";
|
|
320
|
+
return undefined;
|
|
321
|
+
}
|
|
322
|
+
export function resolveScaffoldSelector(opts) {
|
|
323
|
+
const hasPreset = opts.preset !== undefined;
|
|
324
|
+
const presetConflict = getPresetConflict(opts);
|
|
325
|
+
const selectors = [
|
|
326
|
+
opts.template !== undefined ? "--template" : undefined,
|
|
327
|
+
opts.example !== undefined ? "--example" : undefined,
|
|
328
|
+
opts.native ? "--native" : undefined,
|
|
329
|
+
opts.ink ? "--ink" : undefined,
|
|
330
|
+
].filter((selector) => selector !== undefined);
|
|
331
|
+
if (selectors.length > 1) {
|
|
332
|
+
throw new Error(`Only one scaffold selector can be provided (${selectors.join(", ")}). ${scaffoldSelectorHelp}`);
|
|
333
|
+
}
|
|
334
|
+
if (hasPreset && presetConflict) {
|
|
335
|
+
throw new Error(`Cannot use --preset with ${presetConflict}. ${scaffoldSelectorHelp}`);
|
|
336
|
+
}
|
|
337
|
+
if (opts.native)
|
|
338
|
+
return { example: "with-expo" };
|
|
339
|
+
if (opts.ink)
|
|
340
|
+
return { example: "with-react-ink" };
|
|
341
|
+
if (opts.preset !== undefined && opts.template === undefined) {
|
|
342
|
+
return { template: "default", preset: opts.preset };
|
|
343
|
+
}
|
|
344
|
+
return {
|
|
345
|
+
...(opts.template !== undefined && { template: opts.template }),
|
|
346
|
+
...(opts.example !== undefined && { example: opts.example }),
|
|
347
|
+
...(hasPreset && { preset: opts.preset }),
|
|
348
|
+
};
|
|
349
|
+
}
|
|
347
350
|
export const create = new Command()
|
|
348
351
|
.name("create")
|
|
349
352
|
.description("create a new project")
|
|
@@ -359,23 +362,24 @@ export const create = new Command()
|
|
|
359
362
|
.option("--native", "create an Expo / React Native project")
|
|
360
363
|
.option("--ink", "create a React Ink terminal project")
|
|
361
364
|
.option("--skip-install", "skip installing packages")
|
|
365
|
+
.addOption(new Option("--debug-source-root <path>", "copy templates/examples from a local assistant-ui repo root").hideHelp())
|
|
362
366
|
.action(async (projectDirectory, opts) => {
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
if (opts.ink) {
|
|
367
|
-
opts.example = "with-react-ink";
|
|
368
|
-
}
|
|
369
|
-
if (opts.example && opts.preset) {
|
|
370
|
-
logger.error("Cannot use --preset with --example.");
|
|
371
|
-
process.exit(1);
|
|
367
|
+
let scaffoldSelector;
|
|
368
|
+
try {
|
|
369
|
+
scaffoldSelector = resolveScaffoldSelector(opts);
|
|
372
370
|
}
|
|
373
|
-
|
|
374
|
-
|
|
371
|
+
catch (error) {
|
|
372
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
373
|
+
logger.error(message);
|
|
375
374
|
process.exit(1);
|
|
376
375
|
}
|
|
376
|
+
const localSourceRoot = opts.debugSourceRoot
|
|
377
|
+
? path.resolve(opts.debugSourceRoot)
|
|
378
|
+
: undefined;
|
|
377
379
|
// Start release ref resolution early (runs during user prompts)
|
|
378
|
-
const refPromise =
|
|
380
|
+
const refPromise = localSourceRoot
|
|
381
|
+
? Promise.resolve(undefined)
|
|
382
|
+
: resolveLatestReleaseRef();
|
|
379
383
|
// 1. Resolve project directory
|
|
380
384
|
let resolvedProjectDirectory = resolveCreateProjectDirectory({
|
|
381
385
|
projectDirectory,
|
|
@@ -427,17 +431,14 @@ export const create = new Command()
|
|
|
427
431
|
}
|
|
428
432
|
}
|
|
429
433
|
// 2. Resolve scaffold target
|
|
430
|
-
const project = await resolveProject(
|
|
431
|
-
template: opts.template,
|
|
432
|
-
example: opts.example,
|
|
433
|
-
});
|
|
434
|
+
const project = await resolveProject(scaffoldSelector);
|
|
434
435
|
if (!project) {
|
|
435
436
|
p.cancel("Project creation cancelled.");
|
|
436
437
|
process.exit(0);
|
|
437
438
|
}
|
|
438
439
|
logger.info(`Creating project from ${project.category}: ${project.label}`);
|
|
439
440
|
logger.break();
|
|
440
|
-
const pm = await
|
|
441
|
+
const pm = await resolvePackageManagerForCwd(path.dirname(absoluteProjectDir), resolvePackageManager(opts));
|
|
441
442
|
// Clean up partial project directory on unexpected exit (e.g. Ctrl+C)
|
|
442
443
|
const cleanupOnExit = () => {
|
|
443
444
|
fs.rmSync(absoluteProjectDir, { recursive: true, force: true });
|
|
@@ -445,17 +446,28 @@ export const create = new Command()
|
|
|
445
446
|
process.once("exit", cleanupOnExit);
|
|
446
447
|
try {
|
|
447
448
|
// 3. Resolve latest release ref (started before prompts)
|
|
448
|
-
|
|
449
|
+
if (!localSourceRoot) {
|
|
450
|
+
logger.step("Resolving latest release...");
|
|
451
|
+
}
|
|
449
452
|
const ref = await refPromise;
|
|
450
|
-
if (!ref) {
|
|
453
|
+
if (!localSourceRoot && !ref) {
|
|
451
454
|
logger.warn("Could not resolve latest release, downloading from HEAD");
|
|
452
455
|
}
|
|
453
|
-
// 4.
|
|
454
|
-
logger.step(
|
|
456
|
+
// 4. Scaffold project
|
|
457
|
+
logger.step(localSourceRoot
|
|
458
|
+
? `Copying project from local source: ${localSourceRoot}`
|
|
459
|
+
: "Downloading project...");
|
|
455
460
|
try {
|
|
456
|
-
|
|
461
|
+
const source = localSourceRoot
|
|
462
|
+
? { kind: "local", rootDir: localSourceRoot }
|
|
463
|
+
: {
|
|
464
|
+
kind: "github",
|
|
465
|
+
ref,
|
|
466
|
+
};
|
|
467
|
+
await scaffoldProject(project.path, absoluteProjectDir, source);
|
|
457
468
|
// If the template didn't exist at the release tag, retry from HEAD
|
|
458
|
-
if (
|
|
469
|
+
if (!localSourceRoot &&
|
|
470
|
+
ref &&
|
|
459
471
|
!fs.existsSync(path.join(absoluteProjectDir, "package.json"))) {
|
|
460
472
|
fs.rmSync(absoluteProjectDir, { recursive: true, force: true });
|
|
461
473
|
logger.warn("Template not found at release tag, downloading from HEAD");
|
|
@@ -474,8 +486,8 @@ export const create = new Command()
|
|
|
474
486
|
throw err;
|
|
475
487
|
}
|
|
476
488
|
// 6. Apply preset if provided
|
|
477
|
-
if (
|
|
478
|
-
const presetUrl = resolvePresetUrl(
|
|
489
|
+
if (scaffoldSelector.preset) {
|
|
490
|
+
const presetUrl = resolvePresetUrl(scaffoldSelector.preset);
|
|
479
491
|
logger.info("Applying preset configuration...");
|
|
480
492
|
logger.break();
|
|
481
493
|
const [dlxCmd, dlxArgs] = dlxCommand(pm);
|