assistant-ui 0.0.92 → 0.0.93

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 (117) 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 +454 -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/dist/index.d.ts.map +0 -1
  117. package/dist/lib/transform-options.js.map +0 -1
@@ -1,545 +1,472 @@
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 rendering",
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-parent-id-grouping",
189
+ label: "Parent ID Grouping",
190
+ description: "Message grouping strategy",
191
+ category: "example",
192
+ path: "examples/with-parent-id-grouping",
193
+ hasLocalComponents: false
194
+ },
195
+ {
196
+ name: "with-react-hook-form",
197
+ label: "React Hook Form",
198
+ description: "Form integration",
199
+ category: "example",
200
+ path: "examples/with-react-hook-form",
201
+ hasLocalComponents: false
202
+ },
203
+ {
204
+ name: "with-react-ink",
205
+ label: "React Ink",
206
+ description: "Terminal UI chat",
207
+ category: "example",
208
+ path: "examples/with-react-ink",
209
+ hasLocalComponents: true
210
+ },
211
+ {
212
+ name: "with-react-router",
213
+ label: "React Router",
214
+ description: "React Router v7 + Vite",
215
+ category: "example",
216
+ path: "examples/with-react-router",
217
+ hasLocalComponents: false
218
+ },
219
+ {
220
+ name: "with-tanstack",
221
+ label: "TanStack",
222
+ description: "TanStack/React Router + Vite",
223
+ category: "example",
224
+ path: "examples/with-tanstack",
225
+ hasLocalComponents: false
226
+ }
228
227
  ];
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
228
  const templateNames = PROJECT_METADATA.filter((m) => m.category === "template").map((m) => m.name);
238
229
  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;
230
+ async function resolveProject(params) {
231
+ const { template, example, stdinIsTTY = process.stdin.isTTY, select = p.select, isCancel = p.isCancel } = params;
232
+ if (template !== void 0) {
233
+ const meta = PROJECT_METADATA.find((m) => m.name === template && m.category === "template");
234
+ if (!meta) {
235
+ logger.error(`Unknown template: ${template}`);
236
+ logger.info(`Available templates: ${templateNames.join(", ")}`);
237
+ process.exit(1);
238
+ }
239
+ return meta;
240
+ }
241
+ if (example !== void 0) {
242
+ const meta = PROJECT_METADATA.find((m) => m.name === example && m.category === "example");
243
+ if (!meta) {
244
+ logger.error(`Unknown example: ${example}`);
245
+ logger.info(`Available examples: ${exampleNames.join(", ")}`);
246
+ process.exit(1);
247
+ }
248
+ return meta;
249
+ }
250
+ if (!stdinIsTTY) return PROJECT_METADATA.find((m) => m.name === "default");
251
+ const selected = await select({
252
+ message: "Select a project to scaffold:",
253
+ options: [
254
+ {
255
+ value: "_separator",
256
+ label: "────── Starter Templates ──────",
257
+ disabled: true
258
+ },
259
+ ...PROJECT_METADATA.filter((m) => m.category === "template").map((m) => ({
260
+ value: m.name,
261
+ label: m.label,
262
+ ...m.description ? { hint: m.description } : {}
263
+ })),
264
+ {
265
+ value: "_separator",
266
+ label: "────── Feature Examples ──────",
267
+ disabled: true
268
+ },
269
+ ...PROJECT_METADATA.filter((m) => m.category === "example").map((m) => ({
270
+ value: m.name,
271
+ label: m.label,
272
+ ...m.description ? { hint: m.description } : {}
273
+ }))
274
+ ]
275
+ });
276
+ if (isCancel(selected)) return null;
277
+ const meta = PROJECT_METADATA.find((m) => m.name === selected);
278
+ if (!meta) {
279
+ logger.error(`Unknown selection: ${String(selected)}`);
280
+ process.exit(1);
281
+ }
282
+ return meta;
296
283
  }
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;
284
+ function resolveCreateProjectDirectory(params) {
285
+ const { projectDirectory, stdinIsTTY = process.stdin.isTTY } = params;
286
+ if (projectDirectory) return projectDirectory;
287
+ if (!stdinIsTTY) return "my-aui-app";
304
288
  }
305
289
  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)}`;
290
+ function resolvePresetUrl(preset) {
291
+ if (preset.startsWith("http://") || preset.startsWith("https://")) return preset;
292
+ return `${PLAYGROUND_PRESET_BASE_URL}?preset=${encodeURIComponent(preset)}`;
311
293
  }
312
294
  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
295
  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;
296
+ if (opts.example !== void 0) return "--example";
297
+ if (opts.native) return "--native";
298
+ if (opts.ink) return "--ink";
321
299
  }
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
- };
300
+ function resolveScaffoldSelector(opts) {
301
+ const hasPreset = opts.preset !== void 0;
302
+ const presetConflict = getPresetConflict(opts);
303
+ const selectors = [
304
+ opts.template !== void 0 ? "--template" : void 0,
305
+ opts.example !== void 0 ? "--example" : void 0,
306
+ opts.native ? "--native" : void 0,
307
+ opts.ink ? "--ink" : void 0
308
+ ].filter((selector) => selector !== void 0);
309
+ if (selectors.length > 1) throw new Error(`Only one scaffold selector can be provided (${selectors.join(", ")}). ${scaffoldSelectorHelp}`);
310
+ if (hasPreset && presetConflict) throw new Error(`Cannot use --preset with ${presetConflict}. ${scaffoldSelectorHelp}`);
311
+ if (opts.native) return { example: "with-expo" };
312
+ if (opts.ink) return { example: "with-react-ink" };
313
+ if (opts.preset !== void 0 && opts.template === void 0) return {
314
+ template: "default",
315
+ preset: opts.preset
316
+ };
317
+ return {
318
+ ...opts.template !== void 0 && { template: opts.template },
319
+ ...opts.example !== void 0 && { example: opts.example },
320
+ ...hasPreset && { preset: opts.preset }
321
+ };
349
322
  }
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
- }
323
+ 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) => {
324
+ let scaffoldSelector;
325
+ try {
326
+ scaffoldSelector = resolveScaffoldSelector(opts);
327
+ } catch (error) {
328
+ const message = error instanceof Error ? error.message : String(error);
329
+ logger.error(message);
330
+ process.exit(1);
331
+ }
332
+ const localSourceRoot = opts.debugSourceRoot ? path.resolve(opts.debugSourceRoot) : void 0;
333
+ const refPromise = localSourceRoot ? Promise.resolve(void 0) : resolveLatestReleaseRef();
334
+ let resolvedProjectDirectory = resolveCreateProjectDirectory({ projectDirectory });
335
+ if (!resolvedProjectDirectory) {
336
+ const result = await p.text({
337
+ message: "Project name:",
338
+ placeholder: "my-aui-app",
339
+ defaultValue: "my-aui-app",
340
+ validate: (value) => {
341
+ const name = (value ?? "").trim();
342
+ if (!name) return "Project name cannot be empty";
343
+ if (name === "." || name === "..") return "Project name cannot be . or ..";
344
+ if (name.includes("/") || name.includes("\\")) return "Project name cannot contain path separators";
345
+ }
346
+ });
347
+ if (p.isCancel(result)) {
348
+ p.cancel("Project creation cancelled.");
349
+ process.exit(0);
350
+ }
351
+ resolvedProjectDirectory = result;
352
+ }
353
+ const absoluteProjectDir = path.resolve(resolvedProjectDirectory);
354
+ try {
355
+ if (fs.readdirSync(absoluteProjectDir).length > 0) {
356
+ logger.error(`Directory ${resolvedProjectDirectory} already exists and is not empty`);
357
+ process.exit(1);
358
+ }
359
+ } catch (err) {
360
+ const code = err instanceof Error ? err.code : void 0;
361
+ if (code === "ENOENT") {} else if (code === "ENOTDIR") {
362
+ logger.error(`${resolvedProjectDirectory} already exists and is not a directory`);
363
+ process.exit(1);
364
+ } else {
365
+ const message = err instanceof Error ? err.message : String(err);
366
+ logger.error(`Cannot access ${resolvedProjectDirectory}: ${message}`);
367
+ process.exit(1);
368
+ }
369
+ }
370
+ const project = await resolveProject(scaffoldSelector);
371
+ if (!project) {
372
+ p.cancel("Project creation cancelled.");
373
+ process.exit(0);
374
+ }
375
+ logger.info(`Creating project from ${project.category}: ${project.label}`);
376
+ logger.break();
377
+ const pm = await resolvePackageManagerForCwd(path.dirname(absoluteProjectDir), resolvePackageManager(opts));
378
+ const cleanupOnExit = () => {
379
+ fs.rmSync(absoluteProjectDir, {
380
+ recursive: true,
381
+ force: true
382
+ });
383
+ };
384
+ process.once("exit", cleanupOnExit);
385
+ try {
386
+ if (!localSourceRoot) logger.step("Resolving latest release...");
387
+ const ref = await refPromise;
388
+ if (!localSourceRoot && !ref) logger.warn("Could not resolve latest release, downloading from HEAD");
389
+ logger.step(localSourceRoot ? `Copying project from local source: ${localSourceRoot}` : "Downloading project...");
390
+ try {
391
+ const source = localSourceRoot ? {
392
+ kind: "local",
393
+ rootDir: localSourceRoot
394
+ } : {
395
+ kind: "github",
396
+ ref
397
+ };
398
+ await scaffoldProject(project.path, absoluteProjectDir, source);
399
+ if (!localSourceRoot && ref && !fs.existsSync(path.join(absoluteProjectDir, "package.json"))) {
400
+ fs.rmSync(absoluteProjectDir, {
401
+ recursive: true,
402
+ force: true
403
+ });
404
+ logger.warn("Template not found at release tag, downloading from HEAD");
405
+ await downloadProject(project.path, absoluteProjectDir);
406
+ }
407
+ await transformProject(absoluteProjectDir, {
408
+ hasLocalComponents: project.hasLocalComponents,
409
+ skipInstall: opts.skipInstall,
410
+ packageManager: pm
411
+ });
412
+ } catch (err) {
413
+ fs.rmSync(absoluteProjectDir, {
414
+ recursive: true,
415
+ force: true
416
+ });
417
+ throw err;
418
+ }
419
+ if (scaffoldSelector.preset) {
420
+ const presetUrl = resolvePresetUrl(scaffoldSelector.preset);
421
+ logger.info("Applying preset configuration...");
422
+ logger.break();
423
+ const [dlxCmd, dlxArgs] = dlxCommand(pm);
424
+ try {
425
+ await runSpawn(dlxCmd, [
426
+ ...dlxArgs,
427
+ "shadcn@latest",
428
+ "add",
429
+ "--yes",
430
+ "--overwrite",
431
+ presetUrl
432
+ ], absoluteProjectDir);
433
+ } catch {
434
+ logger.warn(`Preset application failed. You can retry manually with:\n ${dlxCmd} ${[
435
+ ...dlxArgs,
436
+ "shadcn@latest",
437
+ "add",
438
+ presetUrl
439
+ ].join(" ")}`);
440
+ }
441
+ }
442
+ process.removeListener("exit", cleanupOnExit);
443
+ logger.break();
444
+ logger.success("Project created successfully!");
445
+ logger.break();
446
+ const runCmd = pm === "npm" ? "npm run" : pm;
447
+ let devScript = "dev";
448
+ let envFile = ".env.local";
449
+ try {
450
+ const scaffoldedPkg = JSON.parse(fs.readFileSync(path.join(absoluteProjectDir, "package.json"), "utf-8"));
451
+ devScript = scaffoldedPkg.scripts?.dev ? "dev" : scaffoldedPkg.scripts?.start ? "start" : "dev";
452
+ envFile = scaffoldedPkg.dependencies?.next ? ".env.local" : ".env";
453
+ } catch {}
454
+ logger.info("Next steps:");
455
+ logger.info(` cd ${resolvedProjectDirectory}`);
456
+ if (opts.skipInstall) logger.info(` ${pm} install`);
457
+ logger.info(` # Set up your environment variables in ${envFile}`);
458
+ logger.info(` ${runCmd} ${devScript}`);
459
+ } catch (error) {
460
+ if (error instanceof SpawnExitError) {
461
+ logger.error(`Project creation failed with code ${error.code}`);
462
+ process.exit(error.code);
463
+ }
464
+ const message = error instanceof Error ? error.message : String(error);
465
+ logger.error(`Failed to create project: ${message}`);
466
+ process.exit(1);
467
+ }
544
468
  });
469
+ //#endregion
470
+ export { PROJECT_METADATA, create, resolveCreateProjectDirectory, resolvePresetUrl, resolveProject, resolveScaffoldSelector };
471
+
545
472
  //# sourceMappingURL=create.js.map