assistant-ui 0.0.92 → 0.0.94

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.
Files changed (118) hide show
  1. package/dist/codemods/utils/createTransformer.d.ts +17 -13
  2. package/dist/codemods/utils/createTransformer.d.ts.map +1 -1
  3. package/dist/codemods/utils/createTransformer.js +18 -15
  4. package/dist/codemods/utils/createTransformer.js.map +1 -1
  5. package/dist/codemods/v0-11/content-part-to-message-part.d.ts +3 -1
  6. package/dist/codemods/v0-11/content-part-to-message-part.d.ts.map +1 -1
  7. package/dist/codemods/v0-11/content-part-to-message-part.js +98 -135
  8. package/dist/codemods/v0-11/content-part-to-message-part.js.map +1 -1
  9. package/dist/codemods/v0-12/assistant-api-to-aui.d.ts +3 -1
  10. package/dist/codemods/v0-12/assistant-api-to-aui.d.ts.map +1 -1
  11. package/dist/codemods/v0-12/assistant-api-to-aui.js +126 -213
  12. package/dist/codemods/v0-12/assistant-api-to-aui.js.map +1 -1
  13. package/dist/codemods/v0-12/event-names-to-camelcase.d.ts +3 -1
  14. package/dist/codemods/v0-12/event-names-to-camelcase.d.ts.map +1 -1
  15. package/dist/codemods/v0-12/event-names-to-camelcase.js +33 -38
  16. package/dist/codemods/v0-12/event-names-to-camelcase.js.map +1 -1
  17. package/dist/codemods/v0-12/primitive-if-to-aui-if.d.ts +3 -1
  18. package/dist/codemods/v0-12/primitive-if-to-aui-if.d.ts.map +1 -1
  19. package/dist/codemods/v0-12/primitive-if-to-aui-if.js +212 -297
  20. package/dist/codemods/v0-12/primitive-if-to-aui-if.js.map +1 -1
  21. package/dist/codemods/v0-8/ui-package-split.d.ts +3 -1
  22. package/dist/codemods/v0-8/ui-package-split.d.ts.map +1 -1
  23. package/dist/codemods/v0-8/ui-package-split.js +121 -164
  24. package/dist/codemods/v0-8/ui-package-split.js.map +1 -1
  25. package/dist/codemods/v0-9/edge-package-split.d.ts +3 -1
  26. package/dist/codemods/v0-9/edge-package-split.d.ts.map +1 -1
  27. package/dist/codemods/v0-9/edge-package-split.js +96 -140
  28. package/dist/codemods/v0-9/edge-package-split.js.map +1 -1
  29. package/dist/commands/add.d.ts +16 -12
  30. package/dist/commands/add.d.ts.map +1 -1
  31. package/dist/commands/add.js +53 -64
  32. package/dist/commands/add.js.map +1 -1
  33. package/dist/commands/agent.d.ts +5 -1
  34. package/dist/commands/agent.d.ts.map +1 -1
  35. package/dist/commands/agent.js +16 -25
  36. package/dist/commands/agent.js.map +1 -1
  37. package/dist/commands/create.d.ts +34 -30
  38. package/dist/commands/create.d.ts.map +1 -1
  39. package/dist/commands/create.js +446 -527
  40. package/dist/commands/create.js.map +1 -1
  41. package/dist/commands/info.d.ts +5 -1
  42. package/dist/commands/info.d.ts.map +1 -1
  43. package/dist/commands/info.js +233 -314
  44. package/dist/commands/info.js.map +1 -1
  45. package/dist/commands/init.d.ts +12 -9
  46. package/dist/commands/init.d.ts.map +1 -1
  47. package/dist/commands/init.js +98 -107
  48. package/dist/commands/init.js.map +1 -1
  49. package/dist/commands/mcp.d.ts +5 -1
  50. package/dist/commands/mcp.d.ts.map +1 -1
  51. package/dist/commands/mcp.js +175 -214
  52. package/dist/commands/mcp.js.map +1 -1
  53. package/dist/commands/update.d.ts +5 -1
  54. package/dist/commands/update.d.ts.map +1 -1
  55. package/dist/commands/update.js +46 -55
  56. package/dist/commands/update.js.map +1 -1
  57. package/dist/commands/upgrade.d.ts +11 -7
  58. package/dist/commands/upgrade.d.ts.map +1 -1
  59. package/dist/commands/upgrade.js +26 -38
  60. package/dist/commands/upgrade.js.map +1 -1
  61. package/dist/index.d.ts +1 -3
  62. package/dist/index.js +15 -14
  63. package/dist/index.js.map +1 -1
  64. package/dist/lib/create-project.d.ts +24 -21
  65. package/dist/lib/create-project.d.ts.map +1 -1
  66. package/dist/lib/create-project.js +227 -297
  67. package/dist/lib/create-project.js.map +1 -1
  68. package/dist/lib/install-ai-sdk-lib.d.ts +4 -1
  69. package/dist/lib/install-ai-sdk-lib.d.ts.map +1 -1
  70. package/dist/lib/install-ai-sdk-lib.js +12 -8
  71. package/dist/lib/install-ai-sdk-lib.js.map +1 -1
  72. package/dist/lib/install-edge-lib.d.ts +4 -1
  73. package/dist/lib/install-edge-lib.d.ts.map +1 -1
  74. package/dist/lib/install-edge-lib.js +16 -12
  75. package/dist/lib/install-edge-lib.js.map +1 -1
  76. package/dist/lib/install-ui-lib.d.ts +4 -1
  77. package/dist/lib/install-ui-lib.d.ts.map +1 -1
  78. package/dist/lib/install-ui-lib.js +12 -8
  79. package/dist/lib/install-ui-lib.js.map +1 -1
  80. package/dist/lib/run-spawn.d.ts +7 -4
  81. package/dist/lib/run-spawn.d.ts.map +1 -1
  82. package/dist/lib/run-spawn.js +23 -23
  83. package/dist/lib/run-spawn.js.map +1 -1
  84. package/dist/lib/transform-options.d.ts +8 -5
  85. package/dist/lib/transform-options.d.ts.map +1 -1
  86. package/dist/lib/transform-options.js +0 -2
  87. package/dist/lib/transform.d.ts +15 -11
  88. package/dist/lib/transform.d.ts.map +1 -1
  89. package/dist/lib/transform.js +97 -114
  90. package/dist/lib/transform.js.map +1 -1
  91. package/dist/lib/upgrade.d.ts +6 -2
  92. package/dist/lib/upgrade.d.ts.map +1 -1
  93. package/dist/lib/upgrade.js +62 -64
  94. package/dist/lib/upgrade.js.map +1 -1
  95. package/dist/lib/utils/config.d.ts +21 -18
  96. package/dist/lib/utils/config.d.ts.map +1 -1
  97. package/dist/lib/utils/config.js +24 -28
  98. package/dist/lib/utils/config.js.map +1 -1
  99. package/dist/lib/utils/file-scanner.d.ts +9 -6
  100. package/dist/lib/utils/file-scanner.d.ts.map +1 -1
  101. package/dist/lib/utils/file-scanner.js +44 -51
  102. package/dist/lib/utils/file-scanner.js.map +1 -1
  103. package/dist/lib/utils/logger.d.ts +10 -7
  104. package/dist/lib/utils/logger.d.ts.map +1 -1
  105. package/dist/lib/utils/logger.js +23 -19
  106. package/dist/lib/utils/logger.js.map +1 -1
  107. package/dist/lib/utils/package-installer.d.ts +10 -7
  108. package/dist/lib/utils/package-installer.d.ts.map +1 -1
  109. package/dist/lib/utils/package-installer.js +18 -19
  110. package/dist/lib/utils/package-installer.js.map +1 -1
  111. package/dist/lib/utils/package-manager.d.ts +10 -7
  112. package/dist/lib/utils/package-manager.d.ts.map +1 -1
  113. package/dist/lib/utils/package-manager.js +68 -59
  114. package/dist/lib/utils/package-manager.js.map +1 -1
  115. package/package.json +7 -7
  116. package/src/commands/create.ts +1 -9
  117. package/dist/index.d.ts.map +0 -1
  118. package/dist/lib/transform-options.js.map +0 -1
@@ -1,545 +1,464 @@
1
+ import { logger } from "../lib/utils/logger.js";
2
+ import { SpawnExitError, runSpawn } from "../lib/run-spawn.js";
3
+ import { dlxCommand, downloadProject, resolveLatestReleaseRef, resolvePackageManager, resolvePackageManagerForCwd, scaffoldProject, transformProject } from "../lib/create-project.js";
1
4
  import { Command, Option } from "commander";
2
5
  import chalk from "chalk";
3
6
  import fs from "node:fs";
4
7
  import path from "node:path";
5
8
  import * as p from "@clack/prompts";
6
- import { logger } from "../lib/utils/logger.js";
7
- import { dlxCommand, downloadProject, resolveLatestReleaseRef, resolvePackageManager, resolvePackageManagerForCwd, scaffoldProject, transformProject, } from "../lib/create-project.js";
8
- import { runSpawn, SpawnExitError } from "../lib/run-spawn.js";
9
- export const PROJECT_METADATA = [
10
- // Templates
11
- {
12
- name: "default",
13
- label: "Default",
14
- description: "Default template with Vercel AI SDK",
15
- category: "template",
16
- path: "templates/default",
17
- hasLocalComponents: false,
18
- },
19
- {
20
- name: "minimal",
21
- label: "Minimal",
22
- description: "Bare-bones starting point",
23
- category: "template",
24
- path: "templates/minimal",
25
- hasLocalComponents: true,
26
- },
27
- {
28
- name: "cloud",
29
- label: "Cloud",
30
- description: "Cloud-backed persistence starter",
31
- category: "template",
32
- path: "templates/cloud",
33
- hasLocalComponents: false,
34
- },
35
- {
36
- name: "cloud-clerk",
37
- label: "Cloud + Clerk",
38
- description: "Cloud-backed starter with Clerk auth",
39
- category: "template",
40
- path: "templates/cloud-clerk",
41
- hasLocalComponents: false,
42
- },
43
- {
44
- name: "langgraph",
45
- label: "LangGraph",
46
- description: "LangGraph starter template",
47
- category: "template",
48
- path: "templates/langgraph",
49
- hasLocalComponents: false,
50
- },
51
- {
52
- name: "mcp",
53
- label: "MCP",
54
- description: "MCP tools + MCP Apps renderer starter",
55
- category: "template",
56
- path: "templates/mcp",
57
- hasLocalComponents: false,
58
- },
59
- // Examples
60
- {
61
- name: "with-ag-ui",
62
- label: "AG-UI",
63
- description: "AG-UI protocol integration",
64
- category: "example",
65
- path: "examples/with-ag-ui",
66
- hasLocalComponents: false,
67
- },
68
- {
69
- name: "with-google-adk",
70
- label: "Google ADK",
71
- description: "Google ADK agent integration",
72
- category: "example",
73
- path: "examples/with-google-adk",
74
- hasLocalComponents: false,
75
- },
76
- {
77
- name: "with-ai-sdk-v6",
78
- label: "AI SDK v6",
79
- description: "Vercel AI SDK v6",
80
- category: "example",
81
- path: "examples/with-ai-sdk-v6",
82
- hasLocalComponents: false,
83
- },
84
- {
85
- name: "with-artifacts",
86
- label: "Artifacts",
87
- description: "Artifact rendering",
88
- category: "example",
89
- path: "examples/with-artifacts",
90
- hasLocalComponents: false,
91
- },
92
- {
93
- name: "with-assistant-transport",
94
- label: "Assistant Transport",
95
- description: "Assistant transport protocol",
96
- category: "example",
97
- path: "examples/with-assistant-transport",
98
- hasLocalComponents: false,
99
- },
100
- {
101
- name: "with-chain-of-thought",
102
- label: "Chain of Thought",
103
- description: "Chain-of-thought rendering",
104
- category: "example",
105
- path: "examples/with-chain-of-thought",
106
- hasLocalComponents: false,
107
- },
108
- {
109
- name: "with-cloud",
110
- label: "Cloud Example",
111
- description: "Cloud integration example",
112
- category: "example",
113
- path: "examples/with-cloud",
114
- hasLocalComponents: false,
115
- },
116
- {
117
- name: "with-custom-thread-list",
118
- label: "Custom Thread List",
119
- description: "Custom thread list UI",
120
- category: "example",
121
- path: "examples/with-custom-thread-list",
122
- hasLocalComponents: false,
123
- },
124
- {
125
- name: "with-elevenlabs-conversational",
126
- label: "ElevenLabs Conversational",
127
- description: "Realtime voice with ElevenLabs",
128
- category: "example",
129
- path: "examples/with-elevenlabs-conversational",
130
- hasLocalComponents: true,
131
- },
132
- {
133
- name: "with-elevenlabs-scribe",
134
- label: "ElevenLabs Scribe",
135
- description: "Audio/speech integration",
136
- category: "example",
137
- path: "examples/with-elevenlabs-scribe",
138
- hasLocalComponents: false,
139
- },
140
- {
141
- name: "with-livekit",
142
- label: "LiveKit Voice",
143
- description: "Realtime voice with LiveKit",
144
- category: "example",
145
- path: "examples/with-livekit",
146
- hasLocalComponents: true,
147
- },
148
- {
149
- name: "with-expo",
150
- label: "Expo",
151
- description: "Expo / React Native",
152
- category: "example",
153
- path: "examples/with-expo",
154
- hasLocalComponents: true,
155
- },
156
- {
157
- name: "with-interactables",
158
- label: "Interactables",
159
- description: "AI-driven interactive UI components",
160
- category: "example",
161
- path: "examples/with-interactables",
162
- hasLocalComponents: true,
163
- },
164
- {
165
- name: "with-external-store",
166
- label: "External Store",
167
- description: "Custom message store",
168
- category: "example",
169
- path: "examples/with-external-store",
170
- hasLocalComponents: false,
171
- },
172
- {
173
- name: "with-ffmpeg",
174
- label: "FFmpeg",
175
- description: "File processing",
176
- category: "example",
177
- path: "examples/with-ffmpeg",
178
- hasLocalComponents: false,
179
- },
180
- {
181
- name: "with-langgraph",
182
- label: "LangGraph Example",
183
- description: "LangGraph integration",
184
- category: "example",
185
- path: "examples/with-langgraph",
186
- hasLocalComponents: false,
187
- },
188
- {
189
- name: "with-parent-id-grouping",
190
- label: "Parent ID Grouping",
191
- description: "Message grouping strategy",
192
- category: "example",
193
- path: "examples/with-parent-id-grouping",
194
- hasLocalComponents: false,
195
- },
196
- {
197
- name: "with-react-hook-form",
198
- label: "React Hook Form",
199
- description: "Form integration",
200
- category: "example",
201
- path: "examples/with-react-hook-form",
202
- hasLocalComponents: false,
203
- },
204
- {
205
- name: "with-react-ink",
206
- label: "React Ink",
207
- description: "Terminal UI chat",
208
- category: "example",
209
- path: "examples/with-react-ink",
210
- hasLocalComponents: true,
211
- },
212
- {
213
- name: "with-react-router",
214
- label: "React Router",
215
- description: "React Router v7 + Vite",
216
- category: "example",
217
- path: "examples/with-react-router",
218
- hasLocalComponents: false,
219
- },
220
- {
221
- name: "with-tanstack",
222
- label: "TanStack",
223
- description: "TanStack/React Router + Vite",
224
- category: "example",
225
- path: "examples/with-tanstack",
226
- hasLocalComponents: false,
227
- },
9
+ //#region src/commands/create.ts
10
+ const PROJECT_METADATA = [
11
+ {
12
+ name: "default",
13
+ label: "Default",
14
+ description: "Default template with Vercel AI SDK",
15
+ category: "template",
16
+ path: "templates/default",
17
+ hasLocalComponents: false
18
+ },
19
+ {
20
+ name: "minimal",
21
+ label: "Minimal",
22
+ description: "Bare-bones starting point",
23
+ category: "template",
24
+ path: "templates/minimal",
25
+ hasLocalComponents: true
26
+ },
27
+ {
28
+ name: "cloud",
29
+ label: "Cloud",
30
+ description: "Cloud-backed persistence starter",
31
+ category: "template",
32
+ path: "templates/cloud",
33
+ hasLocalComponents: false
34
+ },
35
+ {
36
+ name: "cloud-clerk",
37
+ label: "Cloud + Clerk",
38
+ description: "Cloud-backed starter with Clerk auth",
39
+ category: "template",
40
+ path: "templates/cloud-clerk",
41
+ hasLocalComponents: false
42
+ },
43
+ {
44
+ name: "langgraph",
45
+ label: "LangGraph",
46
+ description: "LangGraph starter template",
47
+ category: "template",
48
+ path: "templates/langgraph",
49
+ hasLocalComponents: false
50
+ },
51
+ {
52
+ name: "mcp",
53
+ label: "MCP",
54
+ description: "MCP tools + MCP Apps renderer starter",
55
+ category: "template",
56
+ path: "templates/mcp",
57
+ hasLocalComponents: false
58
+ },
59
+ {
60
+ name: "with-ag-ui",
61
+ label: "AG-UI",
62
+ description: "AG-UI protocol integration",
63
+ category: "example",
64
+ path: "examples/with-ag-ui",
65
+ hasLocalComponents: false
66
+ },
67
+ {
68
+ name: "with-google-adk",
69
+ label: "Google ADK",
70
+ description: "Google ADK agent integration",
71
+ category: "example",
72
+ path: "examples/with-google-adk",
73
+ hasLocalComponents: false
74
+ },
75
+ {
76
+ name: "with-ai-sdk-v6",
77
+ label: "AI SDK v6",
78
+ description: "Vercel AI SDK v6",
79
+ category: "example",
80
+ path: "examples/with-ai-sdk-v6",
81
+ hasLocalComponents: false
82
+ },
83
+ {
84
+ name: "with-artifacts",
85
+ label: "Artifacts",
86
+ description: "Artifact rendering",
87
+ category: "example",
88
+ path: "examples/with-artifacts",
89
+ hasLocalComponents: false
90
+ },
91
+ {
92
+ name: "with-assistant-transport",
93
+ label: "Assistant Transport",
94
+ description: "Assistant transport protocol",
95
+ category: "example",
96
+ path: "examples/with-assistant-transport",
97
+ hasLocalComponents: false
98
+ },
99
+ {
100
+ name: "with-chain-of-thought",
101
+ label: "Chain of Thought",
102
+ description: "Chain-of-thought, tool calls, and source citations",
103
+ category: "example",
104
+ path: "examples/with-chain-of-thought",
105
+ hasLocalComponents: false
106
+ },
107
+ {
108
+ name: "with-cloud",
109
+ label: "Cloud Example",
110
+ description: "Cloud integration example",
111
+ category: "example",
112
+ path: "examples/with-cloud",
113
+ hasLocalComponents: false
114
+ },
115
+ {
116
+ name: "with-custom-thread-list",
117
+ label: "Custom Thread List",
118
+ description: "Custom thread list UI",
119
+ category: "example",
120
+ path: "examples/with-custom-thread-list",
121
+ hasLocalComponents: false
122
+ },
123
+ {
124
+ name: "with-elevenlabs-conversational",
125
+ label: "ElevenLabs Conversational",
126
+ description: "Realtime voice with ElevenLabs",
127
+ category: "example",
128
+ path: "examples/with-elevenlabs-conversational",
129
+ hasLocalComponents: true
130
+ },
131
+ {
132
+ name: "with-elevenlabs-scribe",
133
+ label: "ElevenLabs Scribe",
134
+ description: "Audio/speech integration",
135
+ category: "example",
136
+ path: "examples/with-elevenlabs-scribe",
137
+ hasLocalComponents: false
138
+ },
139
+ {
140
+ name: "with-livekit",
141
+ label: "LiveKit Voice",
142
+ description: "Realtime voice with LiveKit",
143
+ category: "example",
144
+ path: "examples/with-livekit",
145
+ hasLocalComponents: true
146
+ },
147
+ {
148
+ name: "with-expo",
149
+ label: "Expo",
150
+ description: "Expo / React Native",
151
+ category: "example",
152
+ path: "examples/with-expo",
153
+ hasLocalComponents: true
154
+ },
155
+ {
156
+ name: "with-interactables",
157
+ label: "Interactables",
158
+ description: "AI-driven interactive UI components",
159
+ category: "example",
160
+ path: "examples/with-interactables",
161
+ hasLocalComponents: true
162
+ },
163
+ {
164
+ name: "with-external-store",
165
+ label: "External Store",
166
+ description: "Custom message store",
167
+ category: "example",
168
+ path: "examples/with-external-store",
169
+ hasLocalComponents: false
170
+ },
171
+ {
172
+ name: "with-ffmpeg",
173
+ label: "FFmpeg",
174
+ description: "File processing",
175
+ category: "example",
176
+ path: "examples/with-ffmpeg",
177
+ hasLocalComponents: false
178
+ },
179
+ {
180
+ name: "with-langgraph",
181
+ label: "LangGraph Example",
182
+ description: "LangGraph integration",
183
+ category: "example",
184
+ path: "examples/with-langgraph",
185
+ hasLocalComponents: false
186
+ },
187
+ {
188
+ name: "with-react-hook-form",
189
+ label: "React Hook Form",
190
+ description: "Form integration",
191
+ category: "example",
192
+ path: "examples/with-react-hook-form",
193
+ hasLocalComponents: false
194
+ },
195
+ {
196
+ name: "with-react-ink",
197
+ label: "React Ink",
198
+ description: "Terminal UI chat",
199
+ category: "example",
200
+ path: "examples/with-react-ink",
201
+ hasLocalComponents: true
202
+ },
203
+ {
204
+ name: "with-react-router",
205
+ label: "React Router",
206
+ description: "React Router v7 + Vite",
207
+ category: "example",
208
+ path: "examples/with-react-router",
209
+ hasLocalComponents: false
210
+ },
211
+ {
212
+ name: "with-tanstack",
213
+ label: "TanStack",
214
+ description: "TanStack/React Router + Vite",
215
+ category: "example",
216
+ path: "examples/with-tanstack",
217
+ hasLocalComponents: false
218
+ }
228
219
  ];
229
- // Examples that exist in the monorepo but are intentionally excluded from the CLI:
230
- //
231
- // - waterfall: Still in development, not ready for production.
232
- // - with-cloud-standalone: For cloud without assistant-ui — not for the
233
- // assistant-ui CLI.
234
- // - with-store: In development, not ready for public use of the tap store.
235
- // - with-tap-runtime: In development, not ready for public use of the tap
236
- // store.
237
220
  const templateNames = PROJECT_METADATA.filter((m) => m.category === "template").map((m) => m.name);
238
221
  const exampleNames = PROJECT_METADATA.filter((m) => m.category === "example").map((m) => m.name);
239
- export async function resolveProject(params) {
240
- const { template, example, stdinIsTTY = process.stdin.isTTY, select = p.select, isCancel = p.isCancel, } = params;
241
- if (template !== undefined) {
242
- const meta = PROJECT_METADATA.find((m) => m.name === template && m.category === "template");
243
- if (!meta) {
244
- logger.error(`Unknown template: ${template}`);
245
- logger.info(`Available templates: ${templateNames.join(", ")}`);
246
- process.exit(1);
247
- }
248
- return meta;
249
- }
250
- if (example !== undefined) {
251
- const meta = PROJECT_METADATA.find((m) => m.name === example && m.category === "example");
252
- if (!meta) {
253
- logger.error(`Unknown example: ${example}`);
254
- logger.info(`Available examples: ${exampleNames.join(", ")}`);
255
- process.exit(1);
256
- }
257
- return meta;
258
- }
259
- if (!stdinIsTTY) {
260
- return PROJECT_METADATA.find((m) => m.name === "default");
261
- }
262
- const selected = await select({
263
- message: "Select a project to scaffold:",
264
- options: [
265
- {
266
- value: "_separator",
267
- label: "────── Starter Templates ──────",
268
- disabled: true,
269
- },
270
- ...PROJECT_METADATA.filter((m) => m.category === "template").map((m) => ({
271
- value: m.name,
272
- label: m.label,
273
- ...(m.description ? { hint: m.description } : {}),
274
- })),
275
- {
276
- value: "_separator",
277
- label: "────── Feature Examples ──────",
278
- disabled: true,
279
- },
280
- ...PROJECT_METADATA.filter((m) => m.category === "example").map((m) => ({
281
- value: m.name,
282
- label: m.label,
283
- ...(m.description ? { hint: m.description } : {}),
284
- })),
285
- ],
286
- });
287
- if (isCancel(selected)) {
288
- return null;
289
- }
290
- const meta = PROJECT_METADATA.find((m) => m.name === selected);
291
- if (!meta) {
292
- logger.error(`Unknown selection: ${String(selected)}`);
293
- process.exit(1);
294
- }
295
- return meta;
222
+ async function resolveProject(params) {
223
+ const { template, example, stdinIsTTY = process.stdin.isTTY, select = p.select, isCancel = p.isCancel } = params;
224
+ if (template !== void 0) {
225
+ const meta = PROJECT_METADATA.find((m) => m.name === template && m.category === "template");
226
+ if (!meta) {
227
+ logger.error(`Unknown template: ${template}`);
228
+ logger.info(`Available templates: ${templateNames.join(", ")}`);
229
+ process.exit(1);
230
+ }
231
+ return meta;
232
+ }
233
+ if (example !== void 0) {
234
+ const meta = PROJECT_METADATA.find((m) => m.name === example && m.category === "example");
235
+ if (!meta) {
236
+ logger.error(`Unknown example: ${example}`);
237
+ logger.info(`Available examples: ${exampleNames.join(", ")}`);
238
+ process.exit(1);
239
+ }
240
+ return meta;
241
+ }
242
+ if (!stdinIsTTY) return PROJECT_METADATA.find((m) => m.name === "default");
243
+ const selected = await select({
244
+ message: "Select a project to scaffold:",
245
+ options: [
246
+ {
247
+ value: "_separator",
248
+ label: "────── Starter Templates ──────",
249
+ disabled: true
250
+ },
251
+ ...PROJECT_METADATA.filter((m) => m.category === "template").map((m) => ({
252
+ value: m.name,
253
+ label: m.label,
254
+ ...m.description ? { hint: m.description } : {}
255
+ })),
256
+ {
257
+ value: "_separator",
258
+ label: "────── Feature Examples ──────",
259
+ disabled: true
260
+ },
261
+ ...PROJECT_METADATA.filter((m) => m.category === "example").map((m) => ({
262
+ value: m.name,
263
+ label: m.label,
264
+ ...m.description ? { hint: m.description } : {}
265
+ }))
266
+ ]
267
+ });
268
+ if (isCancel(selected)) return null;
269
+ const meta = PROJECT_METADATA.find((m) => m.name === selected);
270
+ if (!meta) {
271
+ logger.error(`Unknown selection: ${String(selected)}`);
272
+ process.exit(1);
273
+ }
274
+ return meta;
296
275
  }
297
- export function resolveCreateProjectDirectory(params) {
298
- const { projectDirectory, stdinIsTTY = process.stdin.isTTY } = params;
299
- if (projectDirectory)
300
- return projectDirectory;
301
- if (!stdinIsTTY)
302
- return "my-aui-app";
303
- return undefined;
276
+ function resolveCreateProjectDirectory(params) {
277
+ const { projectDirectory, stdinIsTTY = process.stdin.isTTY } = params;
278
+ if (projectDirectory) return projectDirectory;
279
+ if (!stdinIsTTY) return "my-aui-app";
304
280
  }
305
281
  const PLAYGROUND_PRESET_BASE_URL = "https://www.assistant-ui.com/playground/init";
306
- export function resolvePresetUrl(preset) {
307
- if (preset.startsWith("http://") || preset.startsWith("https://")) {
308
- return preset;
309
- }
310
- return `${PLAYGROUND_PRESET_BASE_URL}?preset=${encodeURIComponent(preset)}`;
282
+ function resolvePresetUrl(preset) {
283
+ if (preset.startsWith("http://") || preset.startsWith("https://")) return preset;
284
+ return `${PLAYGROUND_PRESET_BASE_URL}?preset=${encodeURIComponent(preset)}`;
311
285
  }
312
286
  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
287
  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;
288
+ if (opts.example !== void 0) return "--example";
289
+ if (opts.native) return "--native";
290
+ if (opts.ink) return "--ink";
321
291
  }
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
- };
292
+ function resolveScaffoldSelector(opts) {
293
+ const hasPreset = opts.preset !== void 0;
294
+ const presetConflict = getPresetConflict(opts);
295
+ const selectors = [
296
+ opts.template !== void 0 ? "--template" : void 0,
297
+ opts.example !== void 0 ? "--example" : void 0,
298
+ opts.native ? "--native" : void 0,
299
+ opts.ink ? "--ink" : void 0
300
+ ].filter((selector) => selector !== void 0);
301
+ if (selectors.length > 1) throw new Error(`Only one scaffold selector can be provided (${selectors.join(", ")}). ${scaffoldSelectorHelp}`);
302
+ if (hasPreset && presetConflict) throw new Error(`Cannot use --preset with ${presetConflict}. ${scaffoldSelectorHelp}`);
303
+ if (opts.native) return { example: "with-expo" };
304
+ if (opts.ink) return { example: "with-react-ink" };
305
+ if (opts.preset !== void 0 && opts.template === void 0) return {
306
+ template: "default",
307
+ preset: opts.preset
308
+ };
309
+ return {
310
+ ...opts.template !== void 0 && { template: opts.template },
311
+ ...opts.example !== void 0 && { example: opts.example },
312
+ ...hasPreset && { preset: opts.preset }
313
+ };
349
314
  }
350
- export const create = new Command()
351
- .name("create")
352
- .description("create a new project")
353
- .argument("[project-directory]")
354
- .usage(`${chalk.green("[project-directory]")} [options]`)
355
- .option("-t, --template <template>", `template to use (${templateNames.join(", ")})`)
356
- .option("-e, --example <example>", `create from an example (${exampleNames.join(", ")})`)
357
- .option("-p, --preset <name-or-url>", "preset name or URL (e.g., chatgpt or https://www.assistant-ui.com/playground/init?preset=chatgpt)")
358
- .option("--use-npm", "explicitly use npm")
359
- .option("--use-pnpm", "explicitly use pnpm")
360
- .option("--use-yarn", "explicitly use yarn")
361
- .option("--use-bun", "explicitly use bun")
362
- .option("--native", "create an Expo / React Native project")
363
- .option("--ink", "create a React Ink terminal project")
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())
366
- .action(async (projectDirectory, opts) => {
367
- let scaffoldSelector;
368
- try {
369
- scaffoldSelector = resolveScaffoldSelector(opts);
370
- }
371
- catch (error) {
372
- const message = error instanceof Error ? error.message : String(error);
373
- logger.error(message);
374
- process.exit(1);
375
- }
376
- const localSourceRoot = opts.debugSourceRoot
377
- ? path.resolve(opts.debugSourceRoot)
378
- : undefined;
379
- // Start release ref resolution early (runs during user prompts)
380
- const refPromise = localSourceRoot
381
- ? Promise.resolve(undefined)
382
- : resolveLatestReleaseRef();
383
- // 1. Resolve project directory
384
- let resolvedProjectDirectory = resolveCreateProjectDirectory({
385
- projectDirectory,
386
- });
387
- if (!resolvedProjectDirectory) {
388
- const result = await p.text({
389
- message: "Project name:",
390
- placeholder: "my-aui-app",
391
- defaultValue: "my-aui-app",
392
- validate: (value) => {
393
- const name = (value ?? "").trim();
394
- if (!name)
395
- return "Project name cannot be empty";
396
- if (name === "." || name === "..")
397
- return "Project name cannot be . or ..";
398
- if (name.includes("/") || name.includes("\\"))
399
- return "Project name cannot contain path separators";
400
- return undefined;
401
- },
402
- });
403
- if (p.isCancel(result)) {
404
- p.cancel("Project creation cancelled.");
405
- process.exit(0);
406
- }
407
- resolvedProjectDirectory = result;
408
- }
409
- // Check directory
410
- const absoluteProjectDir = path.resolve(resolvedProjectDirectory);
411
- try {
412
- const files = fs.readdirSync(absoluteProjectDir);
413
- if (files.length > 0) {
414
- logger.error(`Directory ${resolvedProjectDirectory} already exists and is not empty`);
415
- process.exit(1);
416
- }
417
- }
418
- catch (err) {
419
- const code = err instanceof Error ? err.code : undefined;
420
- if (code === "ENOENT") {
421
- // Directory doesn't exist — good, proceed
422
- }
423
- else if (code === "ENOTDIR") {
424
- logger.error(`${resolvedProjectDirectory} already exists and is not a directory`);
425
- process.exit(1);
426
- }
427
- else {
428
- const message = err instanceof Error ? err.message : String(err);
429
- logger.error(`Cannot access ${resolvedProjectDirectory}: ${message}`);
430
- process.exit(1);
431
- }
432
- }
433
- // 2. Resolve scaffold target
434
- const project = await resolveProject(scaffoldSelector);
435
- if (!project) {
436
- p.cancel("Project creation cancelled.");
437
- process.exit(0);
438
- }
439
- logger.info(`Creating project from ${project.category}: ${project.label}`);
440
- logger.break();
441
- const pm = await resolvePackageManagerForCwd(path.dirname(absoluteProjectDir), resolvePackageManager(opts));
442
- // Clean up partial project directory on unexpected exit (e.g. Ctrl+C)
443
- const cleanupOnExit = () => {
444
- fs.rmSync(absoluteProjectDir, { recursive: true, force: true });
445
- };
446
- process.once("exit", cleanupOnExit);
447
- try {
448
- // 3. Resolve latest release ref (started before prompts)
449
- if (!localSourceRoot) {
450
- logger.step("Resolving latest release...");
451
- }
452
- const ref = await refPromise;
453
- if (!localSourceRoot && !ref) {
454
- logger.warn("Could not resolve latest release, downloading from HEAD");
455
- }
456
- // 4. Scaffold project
457
- logger.step(localSourceRoot
458
- ? `Copying project from local source: ${localSourceRoot}`
459
- : "Downloading project...");
460
- try {
461
- const source = localSourceRoot
462
- ? { kind: "local", rootDir: localSourceRoot }
463
- : {
464
- kind: "github",
465
- ref,
466
- };
467
- await scaffoldProject(project.path, absoluteProjectDir, source);
468
- // If the template didn't exist at the release tag, retry from HEAD
469
- if (!localSourceRoot &&
470
- ref &&
471
- !fs.existsSync(path.join(absoluteProjectDir, "package.json"))) {
472
- fs.rmSync(absoluteProjectDir, { recursive: true, force: true });
473
- logger.warn("Template not found at release tag, downloading from HEAD");
474
- await downloadProject(project.path, absoluteProjectDir);
475
- }
476
- // 5. Run transform pipeline
477
- await transformProject(absoluteProjectDir, {
478
- hasLocalComponents: project.hasLocalComponents,
479
- skipInstall: opts.skipInstall,
480
- packageManager: pm,
481
- });
482
- }
483
- catch (err) {
484
- // Clean up partially created project directory
485
- fs.rmSync(absoluteProjectDir, { recursive: true, force: true });
486
- throw err;
487
- }
488
- // 6. Apply preset if provided
489
- if (scaffoldSelector.preset) {
490
- const presetUrl = resolvePresetUrl(scaffoldSelector.preset);
491
- logger.info("Applying preset configuration...");
492
- logger.break();
493
- const [dlxCmd, dlxArgs] = dlxCommand(pm);
494
- try {
495
- await runSpawn(dlxCmd, [
496
- ...dlxArgs,
497
- "shadcn@latest",
498
- "add",
499
- "--yes",
500
- "--overwrite",
501
- presetUrl,
502
- ], absoluteProjectDir);
503
- }
504
- catch {
505
- logger.warn(`Preset application failed. You can retry manually with:\n ${dlxCmd} ${[...dlxArgs, "shadcn@latest", "add", presetUrl].join(" ")}`);
506
- }
507
- }
508
- process.removeListener("exit", cleanupOnExit);
509
- logger.break();
510
- logger.success("Project created successfully!");
511
- logger.break();
512
- const runCmd = pm === "npm" ? "npm run" : pm;
513
- let devScript = "dev";
514
- let envFile = ".env.local";
515
- try {
516
- const scaffoldedPkg = JSON.parse(fs.readFileSync(path.join(absoluteProjectDir, "package.json"), "utf-8"));
517
- devScript = scaffoldedPkg.scripts?.dev
518
- ? "dev"
519
- : scaffoldedPkg.scripts?.start
520
- ? "start"
521
- : "dev";
522
- envFile = scaffoldedPkg.dependencies?.next ? ".env.local" : ".env";
523
- }
524
- catch {
525
- // Fall back to defaults if package.json cannot be read
526
- }
527
- logger.info("Next steps:");
528
- logger.info(` cd ${resolvedProjectDirectory}`);
529
- if (opts.skipInstall) {
530
- logger.info(` ${pm} install`);
531
- }
532
- logger.info(` # Set up your environment variables in ${envFile}`);
533
- logger.info(` ${runCmd} ${devScript}`);
534
- }
535
- catch (error) {
536
- if (error instanceof SpawnExitError) {
537
- logger.error(`Project creation failed with code ${error.code}`);
538
- process.exit(error.code);
539
- }
540
- const message = error instanceof Error ? error.message : String(error);
541
- logger.error(`Failed to create project: ${message}`);
542
- process.exit(1);
543
- }
315
+ const create = new Command().name("create").description("create a new project").argument("[project-directory]").usage(`${chalk.green("[project-directory]")} [options]`).option("-t, --template <template>", `template to use (${templateNames.join(", ")})`).option("-e, --example <example>", `create from an example (${exampleNames.join(", ")})`).option("-p, --preset <name-or-url>", "preset name or URL (e.g., chatgpt or https://www.assistant-ui.com/playground/init?preset=chatgpt)").option("--use-npm", "explicitly use npm").option("--use-pnpm", "explicitly use pnpm").option("--use-yarn", "explicitly use yarn").option("--use-bun", "explicitly use bun").option("--native", "create an Expo / React Native project").option("--ink", "create a React Ink terminal project").option("--skip-install", "skip installing packages").addOption(new Option("--debug-source-root <path>", "copy templates/examples from a local assistant-ui repo root").hideHelp()).action(async (projectDirectory, opts) => {
316
+ let scaffoldSelector;
317
+ try {
318
+ scaffoldSelector = resolveScaffoldSelector(opts);
319
+ } catch (error) {
320
+ const message = error instanceof Error ? error.message : String(error);
321
+ logger.error(message);
322
+ process.exit(1);
323
+ }
324
+ const localSourceRoot = opts.debugSourceRoot ? path.resolve(opts.debugSourceRoot) : void 0;
325
+ const refPromise = localSourceRoot ? Promise.resolve(void 0) : resolveLatestReleaseRef();
326
+ let resolvedProjectDirectory = resolveCreateProjectDirectory({ projectDirectory });
327
+ if (!resolvedProjectDirectory) {
328
+ const result = await p.text({
329
+ message: "Project name:",
330
+ placeholder: "my-aui-app",
331
+ defaultValue: "my-aui-app",
332
+ validate: (value) => {
333
+ const name = (value ?? "").trim();
334
+ if (!name) return "Project name cannot be empty";
335
+ if (name === "." || name === "..") return "Project name cannot be . or ..";
336
+ if (name.includes("/") || name.includes("\\")) return "Project name cannot contain path separators";
337
+ }
338
+ });
339
+ if (p.isCancel(result)) {
340
+ p.cancel("Project creation cancelled.");
341
+ process.exit(0);
342
+ }
343
+ resolvedProjectDirectory = result;
344
+ }
345
+ const absoluteProjectDir = path.resolve(resolvedProjectDirectory);
346
+ try {
347
+ if (fs.readdirSync(absoluteProjectDir).length > 0) {
348
+ logger.error(`Directory ${resolvedProjectDirectory} already exists and is not empty`);
349
+ process.exit(1);
350
+ }
351
+ } catch (err) {
352
+ const code = err instanceof Error ? err.code : void 0;
353
+ if (code === "ENOENT") {} else if (code === "ENOTDIR") {
354
+ logger.error(`${resolvedProjectDirectory} already exists and is not a directory`);
355
+ process.exit(1);
356
+ } else {
357
+ const message = err instanceof Error ? err.message : String(err);
358
+ logger.error(`Cannot access ${resolvedProjectDirectory}: ${message}`);
359
+ process.exit(1);
360
+ }
361
+ }
362
+ const project = await resolveProject(scaffoldSelector);
363
+ if (!project) {
364
+ p.cancel("Project creation cancelled.");
365
+ process.exit(0);
366
+ }
367
+ logger.info(`Creating project from ${project.category}: ${project.label}`);
368
+ logger.break();
369
+ const pm = await resolvePackageManagerForCwd(path.dirname(absoluteProjectDir), resolvePackageManager(opts));
370
+ const cleanupOnExit = () => {
371
+ fs.rmSync(absoluteProjectDir, {
372
+ recursive: true,
373
+ force: true
374
+ });
375
+ };
376
+ process.once("exit", cleanupOnExit);
377
+ try {
378
+ if (!localSourceRoot) logger.step("Resolving latest release...");
379
+ const ref = await refPromise;
380
+ if (!localSourceRoot && !ref) logger.warn("Could not resolve latest release, downloading from HEAD");
381
+ logger.step(localSourceRoot ? `Copying project from local source: ${localSourceRoot}` : "Downloading project...");
382
+ try {
383
+ const source = localSourceRoot ? {
384
+ kind: "local",
385
+ rootDir: localSourceRoot
386
+ } : {
387
+ kind: "github",
388
+ ref
389
+ };
390
+ await scaffoldProject(project.path, absoluteProjectDir, source);
391
+ if (!localSourceRoot && ref && !fs.existsSync(path.join(absoluteProjectDir, "package.json"))) {
392
+ fs.rmSync(absoluteProjectDir, {
393
+ recursive: true,
394
+ force: true
395
+ });
396
+ logger.warn("Template not found at release tag, downloading from HEAD");
397
+ await downloadProject(project.path, absoluteProjectDir);
398
+ }
399
+ await transformProject(absoluteProjectDir, {
400
+ hasLocalComponents: project.hasLocalComponents,
401
+ skipInstall: opts.skipInstall,
402
+ packageManager: pm
403
+ });
404
+ } catch (err) {
405
+ fs.rmSync(absoluteProjectDir, {
406
+ recursive: true,
407
+ force: true
408
+ });
409
+ throw err;
410
+ }
411
+ if (scaffoldSelector.preset) {
412
+ const presetUrl = resolvePresetUrl(scaffoldSelector.preset);
413
+ logger.info("Applying preset configuration...");
414
+ logger.break();
415
+ const [dlxCmd, dlxArgs] = dlxCommand(pm);
416
+ try {
417
+ await runSpawn(dlxCmd, [
418
+ ...dlxArgs,
419
+ "shadcn@latest",
420
+ "add",
421
+ "--yes",
422
+ "--overwrite",
423
+ presetUrl
424
+ ], absoluteProjectDir);
425
+ } catch {
426
+ logger.warn(`Preset application failed. You can retry manually with:\n ${dlxCmd} ${[
427
+ ...dlxArgs,
428
+ "shadcn@latest",
429
+ "add",
430
+ presetUrl
431
+ ].join(" ")}`);
432
+ }
433
+ }
434
+ process.removeListener("exit", cleanupOnExit);
435
+ logger.break();
436
+ logger.success("Project created successfully!");
437
+ logger.break();
438
+ const runCmd = pm === "npm" ? "npm run" : pm;
439
+ let devScript = "dev";
440
+ let envFile = ".env.local";
441
+ try {
442
+ const scaffoldedPkg = JSON.parse(fs.readFileSync(path.join(absoluteProjectDir, "package.json"), "utf-8"));
443
+ devScript = scaffoldedPkg.scripts?.dev ? "dev" : scaffoldedPkg.scripts?.start ? "start" : "dev";
444
+ envFile = scaffoldedPkg.dependencies?.next ? ".env.local" : ".env";
445
+ } catch {}
446
+ logger.info("Next steps:");
447
+ logger.info(` cd ${resolvedProjectDirectory}`);
448
+ if (opts.skipInstall) logger.info(` ${pm} install`);
449
+ logger.info(` # Set up your environment variables in ${envFile}`);
450
+ logger.info(` ${runCmd} ${devScript}`);
451
+ } catch (error) {
452
+ if (error instanceof SpawnExitError) {
453
+ logger.error(`Project creation failed with code ${error.code}`);
454
+ process.exit(error.code);
455
+ }
456
+ const message = error instanceof Error ? error.message : String(error);
457
+ logger.error(`Failed to create project: ${message}`);
458
+ process.exit(1);
459
+ }
544
460
  });
461
+ //#endregion
462
+ export { PROJECT_METADATA, create, resolveCreateProjectDirectory, resolvePresetUrl, resolveProject, resolveScaffoldSelector };
463
+
545
464
  //# sourceMappingURL=create.js.map