assistant-ui 0.0.120 → 0.0.121

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 (92) hide show
  1. package/README.md +60 -1
  2. package/dist/commands/cloud.d.ts +25 -0
  3. package/dist/commands/cloud.d.ts.map +1 -0
  4. package/dist/commands/cloud.js +194 -0
  5. package/dist/commands/cloud.js.map +1 -0
  6. package/dist/commands/create.d.ts.map +1 -1
  7. package/dist/commands/create.js +8 -0
  8. package/dist/commands/create.js.map +1 -1
  9. package/dist/commands/info.js +1 -1
  10. package/dist/lib/agent-skill.d.ts +2 -2
  11. package/dist/lib/agent-skill.js +1 -1
  12. package/dist/lib/agent-skill.js.map +1 -1
  13. package/dist/lib/cloud-abort.d.ts +2 -0
  14. package/dist/lib/cloud-abort.d.ts.map +1 -0
  15. package/dist/lib/cloud-abort.js +13 -0
  16. package/dist/lib/cloud-abort.js.map +1 -0
  17. package/dist/lib/cloud-auth.d.ts +28 -0
  18. package/dist/lib/cloud-auth.d.ts.map +1 -0
  19. package/dist/lib/cloud-auth.js +169 -0
  20. package/dist/lib/cloud-auth.js.map +1 -0
  21. package/dist/lib/cloud-config.d.ts +21 -0
  22. package/dist/lib/cloud-config.d.ts.map +1 -0
  23. package/dist/lib/cloud-config.js +76 -0
  24. package/dist/lib/cloud-config.js.map +1 -0
  25. package/dist/lib/cloud-provision.d.ts +20 -0
  26. package/dist/lib/cloud-provision.d.ts.map +1 -0
  27. package/dist/lib/cloud-provision.js +55 -0
  28. package/dist/lib/cloud-provision.js.map +1 -0
  29. package/dist/lib/cloud-setup-login.d.ts +9 -0
  30. package/dist/lib/cloud-setup-login.d.ts.map +1 -0
  31. package/dist/lib/cloud-setup-login.js +137 -0
  32. package/dist/lib/cloud-setup-login.js.map +1 -0
  33. package/dist/lib/cloud-url.d.ts +2 -0
  34. package/dist/lib/cloud-url.d.ts.map +1 -0
  35. package/dist/lib/cloud-url.js +14 -0
  36. package/dist/lib/cloud-url.js.map +1 -0
  37. package/dist/lib/transform.js +1 -1
  38. package/dist/program.d.ts.map +1 -1
  39. package/dist/program.js +2 -1
  40. package/dist/program.js.map +1 -1
  41. package/package.json +11 -7
  42. package/src/commands/cloud.test.ts +238 -0
  43. package/src/commands/cloud.ts +455 -0
  44. package/src/commands/create.ts +8 -0
  45. package/src/lib/agent-skill.ts +1 -1
  46. package/src/lib/cloud-abort.ts +12 -0
  47. package/src/lib/cloud-auth.test.ts +500 -0
  48. package/src/lib/cloud-auth.ts +273 -0
  49. package/src/lib/cloud-config.test.ts +82 -0
  50. package/src/lib/cloud-config.ts +138 -0
  51. package/src/lib/cloud-provision.test.ts +132 -0
  52. package/src/lib/cloud-provision.ts +93 -0
  53. package/src/lib/cloud-setup-login.test.ts +361 -0
  54. package/src/lib/cloud-setup-login.ts +240 -0
  55. package/src/lib/cloud-url.ts +19 -0
  56. package/src/program.ts +2 -0
  57. package/templates/cloud-harness/.assistant-ui/template.json +3 -0
  58. package/templates/cloud-harness/.env.example +1 -0
  59. package/templates/cloud-harness/.gitignore +42 -0
  60. package/templates/cloud-harness/README.md +28 -0
  61. package/templates/cloud-harness/app/api/chat/route.ts +13 -0
  62. package/templates/cloud-harness/app/api/credential/route.ts +14 -0
  63. package/templates/cloud-harness/app/assistant.tsx +83 -0
  64. package/templates/cloud-harness/app/favicon.ico +0 -0
  65. package/templates/cloud-harness/app/globals.css +139 -0
  66. package/templates/cloud-harness/app/layout.tsx +37 -0
  67. package/templates/cloud-harness/app/page.tsx +5 -0
  68. package/templates/cloud-harness/components/assistant-ui/elements/attachment.aui.tsx +279 -0
  69. package/templates/cloud-harness/components/assistant-ui/elements/markdown-text.tsx +238 -0
  70. package/templates/cloud-harness/components/assistant-ui/elements/thread.aui.tsx +521 -0
  71. package/templates/cloud-harness/components/assistant-ui/elements/tool-fallback.aui.tsx +1153 -0
  72. package/templates/cloud-harness/components/assistant-ui/elements/tooltip-icon-button.tsx +49 -0
  73. package/templates/cloud-harness/components/ui/avatar.tsx +109 -0
  74. package/templates/cloud-harness/components/ui/button.tsx +58 -0
  75. package/templates/cloud-harness/components/ui/collapsible.tsx +21 -0
  76. package/templates/cloud-harness/components/ui/dialog.tsx +159 -0
  77. package/templates/cloud-harness/components/ui/textarea.tsx +18 -0
  78. package/templates/cloud-harness/components/ui/tooltip.tsx +69 -0
  79. package/templates/cloud-harness/components.json +24 -0
  80. package/templates/cloud-harness/hooks/use-attachment-src.ts +46 -0
  81. package/templates/cloud-harness/hooks/use-copy-to-clipboard.ts +54 -0
  82. package/templates/cloud-harness/lib/utils.ts +1 -0
  83. package/templates/cloud-harness/next.config.ts +6 -0
  84. package/templates/cloud-harness/package.json +51 -0
  85. package/templates/cloud-harness/postcss.config.mjs +5 -0
  86. package/templates/cloud-harness/tsconfig.json +33 -0
  87. package/templates/cloud-harness/vendor/README.md +13 -0
  88. package/templates/cloud-harness/vendor/assistant-ui-react-harness-sdk-0.0.2.tgz +0 -0
  89. package/templates/cloud-harness/vendor/harness-sdk-0.3.1.tgz +0 -0
  90. package/templates/cloud-harness/vendor/provenance.json +38 -0
  91. package/templates/cloud-harness/vendor/statewire-0.19.3.tgz +0 -0
  92. /package/{LICENSE → templates/cloud-harness/vendor/LICENSE} +0 -0
package/README.md CHANGED
@@ -58,7 +58,66 @@ npx assistant-ui info
58
58
 
59
59
  ## Templates
60
60
 
61
- `create` scaffolds from named templates: `default` (AI SDK), `minimal`, `cloud`, `cloud-clerk`, `langchain`, `mcp`, `eve`. Pass `-t <name>`, pass `--example <name>` for examples such as `with-ai-sdk-v7`, use `--native` for Expo / React Native, use `--ink` for React Ink, or pass `--preset <url>` to scaffold from an `assistant-ui.com` playground link.
61
+ `create` scaffolds from named templates: `default` (AI SDK), `minimal`, `cloud`, `cloud-clerk`, `cloud-harness`, `langchain`, `mcp`, `eve`. Pass `-t <name>`, pass `--example <name>` for examples such as `with-ai-sdk-v7`, use `--native` for Expo / React Native, use `--ink` for React Ink, or pass `--preset <url>` to scaffold from an `assistant-ui.com` playground link.
62
+
63
+ ## Shared cloud chat
64
+
65
+ ```bash
66
+ npx assistant-ui@latest cloud setup multiplayer-chat
67
+ cd multiplayer-chat
68
+ npm run dev
69
+ ```
70
+
71
+ Setup signs you in through your browser, selects or creates your organization
72
+ and project, provisions a hosted harness, and installs the shared chat starter.
73
+ Add your `OPENAI_API_KEY` to the generated `.env.local` before starting the app.
74
+ Open `http://localhost:3000/#main` in two browsers. Both clients share the
75
+ conversation and see replies as they stream. **Share this chat** copies the
76
+ current conversation's URL.
77
+
78
+ Select resources explicitly for a script or agent:
79
+
80
+ ```bash
81
+ npx assistant-ui@latest cloud setup multiplayer-chat --org team --new-project hackathon-chat --backend-url http://localhost:3000/api/chat --yes
82
+ ```
83
+
84
+ Use `--project <id-or-slug>` for an existing project. A hackathon access code
85
+ can be supplied with `--access-code <code>` or `ASSISTANT_UI_ACCESS_CODE`.
86
+ `--use-npm`, `--use-pnpm`, `--use-yarn`, and `--use-bun` select the installer;
87
+ `--skip-install` leaves dependency installation to you. For a hosted app,
88
+ pass its HTTPS chat endpoint as `--backend-url` during initial setup. If you
89
+ deploy a chat first configured locally, update its backend allowlist in the
90
+ Cloud dashboard and its `backendUrl` in `.assistant-ui/cloud.json`, then rerun
91
+ setup with the same HTTPS `--backend-url`. Existing conversations keep their
92
+ original backend; open the deployed app with a fresh thread fragment such as
93
+ `#deployed-chat`, then use **Share this chat**.
94
+
95
+ The project API key stays in `.env.local`, with owner-only permissions and a
96
+ Git ignore entry. `.assistant-ui/cloud.json` stores the selected project and
97
+ harness IDs. Browser clients receive short-lived credentials from the app's
98
+ server and share the `hackathon` user. Add your application authentication to
99
+ `/api/credential` when the chat needs individual users or private access.
100
+
101
+ Run `npx assistant-ui@latest cloud setup .` from an existing cloud-harness starter to resume
102
+ setup. Existing environment values are preserved; conflicting cloud settings
103
+ produce an error. `npx assistant-ui@latest cloud login` signs in separately and
104
+ `npx assistant-ui@latest cloud logout` revokes the saved CLI login.
105
+
106
+ When an agent is installing from an active setup wizard, pass its setup-agent
107
+ URL with `--setup-url <url>` to `cloud login` or `cloud setup`. The wizard shows
108
+ the device approval code and sends you to Accounts for explicit consent, then
109
+ returns to the same setup. The CLI polls Accounts directly and saves credentials
110
+ locally with owner-only permissions; tokens never pass through the wizard or
111
+ its generic secret inputs. Cancelling the sign-in question or setup cancels
112
+ pending login. Returning from Accounts alone does not complete login.
113
+
114
+ Before the npm patch is released, use the
115
+ [verified wizard sign-in prerelease](https://www.assistant-ui.com/downloads/assistant-ui-wizard-login-ea9aae48e.tgz)
116
+ with your active setup-agent connection URL:
117
+
118
+ ```bash
119
+ npx --yes --package=https://www.assistant-ui.com/downloads/assistant-ui-wizard-login-ea9aae48e.tgz assistant-ui cloud login --setup-url "<active-setup-agent-url>"
120
+ ```
62
121
 
63
122
  ## Documentation
64
123
 
@@ -0,0 +1,25 @@
1
+ import { Command } from "commander";
2
+ type SetupOptions = {
3
+ org?: string;
4
+ newOrg?: string;
5
+ project?: string;
6
+ newProject?: string;
7
+ name?: string;
8
+ harnessName?: string;
9
+ backendUrl: string;
10
+ apiUrl: string;
11
+ accessCode?: string;
12
+ setupUrl?: string;
13
+ open?: boolean;
14
+ yes?: boolean;
15
+ skipInstall?: boolean;
16
+ useNpm?: boolean;
17
+ usePnpm?: boolean;
18
+ useYarn?: boolean;
19
+ useBun?: boolean;
20
+ debugSourceRoot?: string;
21
+ };
22
+ export declare const setupCloud: (directory: string, options: SetupOptions) => Promise<void>;
23
+ export declare const cloud: Command;
24
+ export {};
25
+ //# sourceMappingURL=cloud.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloud.d.ts","sourceRoot":"","sources":["../../src/commands/cloud.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAuC5C,KAAK,YAAY,GAAG;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAkLF,eAAO,MAAM,UAAU,GACrB,WAAW,MAAM,EACjB,SAAS,YAAY,KACpB,OAAO,CAAC,IAAI,CAmId,CAAC;AAEF,eAAO,MAAM,KAAK,SAkFf,CAAC"}
@@ -0,0 +1,194 @@
1
+ import { logger } from "../lib/utils/logger.js";
2
+ import { validateCloudUrl } from "../lib/cloud-url.js";
3
+ import { cloudAccessToken, cloudAuthConfig, loginToCloud, logoutFromCloud } from "../lib/cloud-auth.js";
4
+ import { mergeCloudEnvironment, readCloudProjectConfig, readOptionalFile, writeCloudProjectConfig } from "../lib/cloud-config.js";
5
+ import { provisionCloudHarness, resolveProvisionRequest } from "../lib/cloud-provision.js";
6
+ import { create } from "./create.js";
7
+ import { Command, Option } from "commander";
8
+ import path from "node:path";
9
+ import * as p from "@clack/prompts";
10
+ import { createProject, fetchOrganizations, fetchProjects } from "aui-auth/accounts";
11
+ import { access, readFile } from "node:fs/promises";
12
+ import { fileURLToPath } from "node:url";
13
+ //#region src/commands/cloud.ts
14
+ var SetupCancelled = class extends Error {};
15
+ const answer = (value) => {
16
+ if (p.isCancel(value)) throw new SetupCancelled();
17
+ return value;
18
+ };
19
+ const selectResource = async (resources, selected, kind, yes) => {
20
+ if (selected) {
21
+ const resource = resources.find(({ id, slug }) => selected === id || selected === slug);
22
+ if (!resource) throw new Error(`${kind} "${selected}" was not found in your account.`);
23
+ return resource;
24
+ }
25
+ if (resources.length === 0) return null;
26
+ if (resources.length === 1) return resources[0];
27
+ if (yes) throw new Error(`Choose a ${kind.toLowerCase()} with --${kind.toLowerCase()} when using --yes.`);
28
+ const id = answer(await p.select({
29
+ message: `Choose a ${kind.toLowerCase()}`,
30
+ options: resources.map((resource) => ({
31
+ value: resource.id,
32
+ label: `${resource.name} (${resource.slug})`
33
+ }))
34
+ }));
35
+ return resources.find((resource) => resource.id === id);
36
+ };
37
+ const projectSlug = (value) => value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
38
+ const organizationForSetup = async (issuer, token, options) => {
39
+ const organizations = await fetchOrganizations({ issuer }, token);
40
+ if (!options.newOrg) {
41
+ const existing = await selectResource(organizations, options.org, "Org", !!options.yes);
42
+ if (existing) return existing;
43
+ }
44
+ const slug = options.newOrg ?? (options.yes ? void 0 : answer(await p.text({
45
+ message: "Choose a slug for your new organization",
46
+ validate: (value) => /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(value ?? "") ? void 0 : "Use lowercase letters, numbers, and hyphens."
47
+ })));
48
+ if (!slug) throw new Error("No organizations found. Pass --new-org <slug> to create one.");
49
+ const existing = organizations.find((organization) => organization.slug === slug);
50
+ if (existing) return existing;
51
+ const response = await fetch(`${issuer}/api/oidc/organizations`, {
52
+ method: "POST",
53
+ headers: {
54
+ Authorization: `Bearer ${token}`,
55
+ "Content-Type": "application/json"
56
+ },
57
+ body: JSON.stringify({
58
+ name: options.name ?? slug,
59
+ slug
60
+ }),
61
+ signal: AbortSignal.timeout(3e4),
62
+ redirect: "error"
63
+ });
64
+ if (!response.ok) throw new Error(`Could not create organization (${response.status}).`);
65
+ return await response.json();
66
+ };
67
+ const projectForSetup = async (issuer, token, organization, directory, options) => {
68
+ const projects = await fetchProjects({ issuer }, token, { id: organization.id });
69
+ if (!options.newProject) {
70
+ const existing = await selectResource(projects, options.project, "Project", !!options.yes);
71
+ if (existing) return existing;
72
+ }
73
+ const slug = options.newProject ?? projectSlug(path.basename(directory));
74
+ if (!slug) throw new Error("Choose a project slug with --new-project <slug>.");
75
+ const created = await createProject({ issuer }, token, { id: organization.id }, {
76
+ name: options.name ?? path.basename(directory),
77
+ slug
78
+ });
79
+ if ("reason" in created) {
80
+ const existing = projects.find((project) => project.slug === slug);
81
+ if (existing) return existing;
82
+ throw new Error(`Project slug "${slug}" already exists. Select it with --project or choose another slug.`);
83
+ }
84
+ return created;
85
+ };
86
+ const scaffoldCloudProject = async (directory, options) => {
87
+ try {
88
+ await access(path.join(directory, "package.json"));
89
+ if (JSON.parse(await readFile(path.join(directory, ".assistant-ui", "template.json"), "utf8")).template !== "cloud-harness") throw new Error("This directory is not a cloud-harness app. Use a new directory.");
90
+ return;
91
+ } catch (error) {
92
+ if (error.code !== "ENOENT") throw error;
93
+ if (await readOptionalFile(path.join(directory, "package.json"))) throw new Error("This directory already contains an app. Use a new directory for the multiplayer scaffold.");
94
+ }
95
+ const packageRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../..");
96
+ const args = [
97
+ directory,
98
+ "--template",
99
+ "cloud-harness",
100
+ "--no-skills",
101
+ "--debug-source-root",
102
+ options.debugSourceRoot ?? packageRoot
103
+ ];
104
+ if (options.skipInstall) args.push("--skip-install");
105
+ for (const flag of [
106
+ "useNpm",
107
+ "usePnpm",
108
+ "useYarn",
109
+ "useBun"
110
+ ]) if (options[flag]) args.push(`--use-${flag.slice(3).toLowerCase()}`);
111
+ await create.parseAsync(args, { from: "user" });
112
+ };
113
+ const setupCloud = async (directory, options) => {
114
+ if (options.org && options.newOrg) throw new Error("Choose --org or --new-org.");
115
+ if (options.project && options.newProject) throw new Error("Choose --project or --new-project.");
116
+ validateCloudUrl(options.apiUrl);
117
+ const backend = new URL(options.backendUrl);
118
+ if (backend.username || backend.password || backend.search || backend.hash) throw new Error("Backend URLs must not include credentials, queries, or fragments.");
119
+ if (options.newOrg !== void 0 && !/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(options.newOrg)) throw new Error("Organization slugs must use lowercase letters, numbers, and hyphens.");
120
+ if (backend.protocol !== "https:" && !(backend.protocol === "http:" && [
121
+ "localhost",
122
+ "127.0.0.1",
123
+ "[::1]"
124
+ ].includes(backend.hostname))) throw new Error("Use an HTTPS backend URL or an HTTP localhost URL for development.");
125
+ const target = path.resolve(directory);
126
+ const previous = await readCloudProjectConfig(target);
127
+ if (previous) {
128
+ if (previous.backendUrl !== backend.href) throw new Error("This harness is configured for another backend URL. Update its backend allowlist in the Cloud dashboard and the backendUrl in .assistant-ui/cloud.json before rerunning setup, or use a new directory.");
129
+ if (options.project && options.project !== previous.projectId && options.project !== previous.projectSlug || options.newProject && options.newProject !== previous.projectSlug || options.org && options.org !== previous.organizationId && options.org !== previous.organizationSlug || options.newOrg && options.newOrg !== previous.organizationSlug) throw new Error("This directory is already configured for another organization or project. Use a new directory.");
130
+ const environment = await readOptionalFile(path.join(target, ".env.local"));
131
+ if (!/^\s*(?:export\s+)?ASSISTANT_API_KEY\s*=\s*.+/m.test(environment)) throw new Error("This project is configured but its .env.local API key is missing. Restore it before running setup again.");
132
+ if (mergeCloudEnvironment(environment, {
133
+ NEXT_PUBLIC_ASSISTANT_BASE_URL: previous.apiOrigin,
134
+ NEXT_PUBLIC_ASSISTANT_HARNESS_URL: previous.harnessOrigin,
135
+ NEXT_PUBLIC_ASSISTANT_WORKSPACE_ID: previous.workspaceId
136
+ }) !== environment) throw new Error("Cloud settings are missing from .env.local. Restore them before running setup again.");
137
+ logger.success(`Already configured: ${previous.projectSlug} / ${previous.harnessId}`);
138
+ return;
139
+ }
140
+ const auth = cloudAuthConfig();
141
+ const token = await cloudAccessToken(auth, {
142
+ noOpen: options.open === false,
143
+ ...options.setupUrl && { setupUrl: options.setupUrl },
144
+ print: logger.info
145
+ });
146
+ const organization = await organizationForSetup(auth.issuer, token, options);
147
+ const project = await projectForSetup(auth.issuer, token, organization, target, options);
148
+ await scaffoldCloudProject(target, options);
149
+ const accessCode = options.accessCode ?? process.env.ASSISTANT_UI_ACCESS_CODE ?? (options.yes ? void 0 : answer(await p.password({ message: "Hackathon access code (leave empty if your plan includes harnesses)" })));
150
+ const request = await resolveProvisionRequest(target, {
151
+ org_id: organization.id,
152
+ project_id: project.id,
153
+ harness_name: options.harnessName ?? `${project.name} chat`,
154
+ backend_urls: backend.protocol === "http:" ? [] : [backend.href],
155
+ allow_localhost: backend.protocol === "http:"
156
+ }, accessCode);
157
+ const result = await provisionCloudHarness(options.apiUrl, token, request);
158
+ await writeCloudProjectConfig(target, {
159
+ organizationId: organization.id,
160
+ organizationSlug: organization.slug,
161
+ projectId: result.project_id,
162
+ projectSlug: project.slug,
163
+ harnessId: result.harness_id,
164
+ harnessOrigin: result.harness_origin,
165
+ apiOrigin: result.api_origin,
166
+ workspaceId: result.workspace_id,
167
+ backendUrl: backend.href
168
+ }, result.api_key);
169
+ logger.success(`Multiplayer chat configured for ${project.name}.`);
170
+ logger.info(`Project: ${target}`);
171
+ logger.info("Add OPENAI_API_KEY to .env.local, then start the app with your package manager's dev command.");
172
+ logger.info(backend.protocol === "http:" ? `Open ${backend.origin}/#main in two browser windows to try shared chat. Deploy or expose the app to share it with teammates.` : "Open your deployed app and use \"Share this chat\" to invite teammates to the same conversation.");
173
+ };
174
+ const cloud = new Command().name("cloud").description("sign in and set up a multiplayer Assistant Cloud chat").addCommand(new Command("login").description("sign in to Assistant Cloud using your browser").option("--no-open", "print the device sign-in URL without opening a browser").option("--setup-url <url>", "show device sign-in in an active setup wizard").action(async (options) => {
175
+ await loginToCloud(cloudAuthConfig(), {
176
+ noOpen: options.open === false,
177
+ ...options.setupUrl && { setupUrl: options.setupUrl },
178
+ print: logger.info
179
+ });
180
+ })).addCommand(new Command("logout").description("revoke your CLI login and remove saved credentials").action(async () => {
181
+ await logoutFromCloud(cloudAuthConfig());
182
+ logger.success("Signed out.");
183
+ })).addCommand(new Command("setup").description("create a shared AI chat and provision its cloud harness").argument("[directory]", "new project directory", "multiplayer-chat").option("--org <id-or-slug>", "use an existing organization").option("--new-org <slug>", "create an organization").option("--project <id-or-slug>", "use an existing project").option("--new-project <slug>", "create a project").option("--name <name>", "display name for a new project or organization").option("--harness-name <name>", "name for the multiplayer harness").option("--backend-url <url>", "absolute URL of the app's chat route", "http://localhost:3000/api/chat").option("--api-url <url>", "Assistant Cloud management URL", process.env.ASSISTANT_UI_CLOUD_URL ?? "https://cloud.assistant-ui.com").option("--access-code <code>", "redeem your hackathon harness access code").option("--no-open", "print the device sign-in URL without opening a browser").option("--setup-url <url>", "show device sign-in in an active setup wizard").option("--yes", "skip prompts; select resources with flags").option("--skip-install", "skip installing scaffold dependencies").option("--use-npm", "install with npm").option("--use-pnpm", "install with pnpm").option("--use-yarn", "install with yarn").option("--use-bun", "install with bun").addOption(new Option("--debug-source-root <path>", "local assistant-ui source root").hideHelp()).action(async (directory, options) => {
184
+ try {
185
+ await setupCloud(directory, options);
186
+ } catch (error) {
187
+ if (!(error instanceof SetupCancelled)) throw error;
188
+ p.cancel("Cloud setup cancelled. Rerun the same command to resume.");
189
+ }
190
+ }));
191
+ //#endregion
192
+ export { cloud, setupCloud };
193
+
194
+ //# sourceMappingURL=cloud.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloud.js","names":[],"sources":["../../src/commands/cloud.ts"],"sourcesContent":["import { Command, Option } from \"commander\";\nimport * as p from \"@clack/prompts\";\nimport {\n createProject,\n fetchOrganizations,\n fetchProjects,\n type AccountsOrganization,\n type AccountsProject,\n} from \"aui-auth/accounts\";\nimport { access, readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport {\n cloudAccessToken,\n cloudAuthConfig,\n loginToCloud,\n logoutFromCloud,\n validateCloudUrl,\n} from \"../lib/cloud-auth\";\nimport {\n readCloudProjectConfig,\n mergeCloudEnvironment,\n readOptionalFile,\n writeCloudProjectConfig,\n} from \"../lib/cloud-config\";\nimport {\n provisionCloudHarness,\n resolveProvisionRequest,\n} from \"../lib/cloud-provision\";\nimport { logger } from \"../lib/utils/logger\";\nimport { create } from \"./create\";\n\nclass SetupCancelled extends Error {}\n\nconst answer = <T>(value: T | symbol): Exclude<T, symbol> => {\n if (p.isCancel(value)) throw new SetupCancelled();\n return value as Exclude<T, symbol>;\n};\n\ntype SetupOptions = {\n org?: string;\n newOrg?: string;\n project?: string;\n newProject?: string;\n name?: string;\n harnessName?: string;\n backendUrl: string;\n apiUrl: string;\n accessCode?: string;\n setupUrl?: string;\n open?: boolean;\n yes?: boolean;\n skipInstall?: boolean;\n useNpm?: boolean;\n usePnpm?: boolean;\n useYarn?: boolean;\n useBun?: boolean;\n debugSourceRoot?: string;\n};\n\nconst selectResource = async <\n T extends { id: string; slug: string; name: string },\n>(\n resources: T[],\n selected: string | undefined,\n kind: string,\n yes: boolean,\n): Promise<T | null> => {\n if (selected) {\n const resource = resources.find(\n ({ id, slug }) => selected === id || selected === slug,\n );\n if (!resource)\n throw new Error(`${kind} \"${selected}\" was not found in your account.`);\n return resource;\n }\n if (resources.length === 0) return null;\n if (resources.length === 1) return resources[0]!;\n if (yes)\n throw new Error(\n `Choose a ${kind.toLowerCase()} with --${kind.toLowerCase()} when using --yes.`,\n );\n const id = answer(\n await p.select({\n message: `Choose a ${kind.toLowerCase()}`,\n options: resources.map((resource) => ({\n value: resource.id,\n label: `${resource.name} (${resource.slug})`,\n })),\n }),\n );\n return resources.find((resource) => resource.id === id)!;\n};\n\nconst projectSlug = (value: string): string =>\n value\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-|-$/g, \"\");\n\nconst organizationForSetup = async (\n issuer: string,\n token: string,\n options: SetupOptions,\n): Promise<AccountsOrganization> => {\n const organizations = await fetchOrganizations({ issuer }, token);\n if (!options.newOrg) {\n const existing = await selectResource(\n organizations,\n options.org,\n \"Org\",\n !!options.yes,\n );\n if (existing) return existing;\n }\n const slug =\n options.newOrg ??\n (options.yes\n ? undefined\n : answer(\n await p.text({\n message: \"Choose a slug for your new organization\",\n validate: (value) =>\n /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(value ?? \"\")\n ? undefined\n : \"Use lowercase letters, numbers, and hyphens.\",\n }),\n ));\n if (!slug)\n throw new Error(\n \"No organizations found. Pass --new-org <slug> to create one.\",\n );\n const existing = organizations.find(\n (organization) => organization.slug === slug,\n );\n if (existing) return existing;\n const response = await fetch(`${issuer}/api/oidc/organizations`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({ name: options.name ?? slug, slug }),\n signal: AbortSignal.timeout(30_000),\n redirect: \"error\",\n });\n if (!response.ok)\n throw new Error(`Could not create organization (${response.status}).`);\n return (await response.json()) as AccountsOrganization;\n};\n\nconst projectForSetup = async (\n issuer: string,\n token: string,\n organization: AccountsOrganization,\n directory: string,\n options: SetupOptions,\n): Promise<AccountsProject> => {\n const projects = await fetchProjects({ issuer }, token, {\n id: organization.id,\n });\n if (!options.newProject) {\n const existing = await selectResource(\n projects,\n options.project,\n \"Project\",\n !!options.yes,\n );\n if (existing) return existing;\n }\n const slug = options.newProject ?? projectSlug(path.basename(directory));\n if (!slug)\n throw new Error(\"Choose a project slug with --new-project <slug>.\");\n const created = await createProject(\n { issuer },\n token,\n { id: organization.id },\n {\n name: options.name ?? path.basename(directory),\n slug,\n },\n );\n if (\"reason\" in created) {\n const existing = projects.find((project) => project.slug === slug);\n if (existing) return existing;\n throw new Error(\n `Project slug \"${slug}\" already exists. Select it with --project or choose another slug.`,\n );\n }\n return created;\n};\n\nconst scaffoldCloudProject = async (\n directory: string,\n options: SetupOptions,\n): Promise<void> => {\n try {\n await access(path.join(directory, \"package.json\"));\n const marker = JSON.parse(\n await readFile(\n path.join(directory, \".assistant-ui\", \"template.json\"),\n \"utf8\",\n ),\n ) as { template?: string };\n if (marker.template !== \"cloud-harness\")\n throw new Error(\n \"This directory is not a cloud-harness app. Use a new directory.\",\n );\n return;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") throw error;\n if (await readOptionalFile(path.join(directory, \"package.json\"))) {\n throw new Error(\n \"This directory already contains an app. Use a new directory for the multiplayer scaffold.\",\n );\n }\n }\n const packageRoot = path.resolve(\n path.dirname(fileURLToPath(import.meta.url)),\n \"../..\",\n );\n const args = [\n directory,\n \"--template\",\n \"cloud-harness\",\n \"--no-skills\",\n \"--debug-source-root\",\n options.debugSourceRoot ?? packageRoot,\n ];\n if (options.skipInstall) args.push(\"--skip-install\");\n for (const flag of [\"useNpm\", \"usePnpm\", \"useYarn\", \"useBun\"] as const) {\n if (options[flag]) args.push(`--use-${flag.slice(3).toLowerCase()}`);\n }\n await create.parseAsync(args, { from: \"user\" });\n};\n\nexport const setupCloud = async (\n directory: string,\n options: SetupOptions,\n): Promise<void> => {\n if (options.org && options.newOrg)\n throw new Error(\"Choose --org or --new-org.\");\n if (options.project && options.newProject)\n throw new Error(\"Choose --project or --new-project.\");\n validateCloudUrl(options.apiUrl);\n const backend = new URL(options.backendUrl);\n if (backend.username || backend.password || backend.search || backend.hash)\n throw new Error(\n \"Backend URLs must not include credentials, queries, or fragments.\",\n );\n if (\n options.newOrg !== undefined &&\n !/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(options.newOrg)\n )\n throw new Error(\n \"Organization slugs must use lowercase letters, numbers, and hyphens.\",\n );\n if (\n backend.protocol !== \"https:\" &&\n !(\n backend.protocol === \"http:\" &&\n [\"localhost\", \"127.0.0.1\", \"[::1]\"].includes(backend.hostname)\n )\n ) {\n throw new Error(\n \"Use an HTTPS backend URL or an HTTP localhost URL for development.\",\n );\n }\n const target = path.resolve(directory);\n const previous = await readCloudProjectConfig(target);\n if (previous) {\n if (previous.backendUrl !== backend.href)\n throw new Error(\n \"This harness is configured for another backend URL. Update its backend allowlist in the Cloud dashboard and the backendUrl in .assistant-ui/cloud.json before rerunning setup, or use a new directory.\",\n );\n if (\n (options.project &&\n options.project !== previous.projectId &&\n options.project !== previous.projectSlug) ||\n (options.newProject && options.newProject !== previous.projectSlug) ||\n (options.org &&\n options.org !== previous.organizationId &&\n options.org !== previous.organizationSlug) ||\n (options.newOrg && options.newOrg !== previous.organizationSlug)\n )\n throw new Error(\n \"This directory is already configured for another organization or project. Use a new directory.\",\n );\n const environment = await readOptionalFile(path.join(target, \".env.local\"));\n if (!/^\\s*(?:export\\s+)?ASSISTANT_API_KEY\\s*=\\s*.+/m.test(environment))\n throw new Error(\n \"This project is configured but its .env.local API key is missing. Restore it before running setup again.\",\n );\n const expected = mergeCloudEnvironment(environment, {\n NEXT_PUBLIC_ASSISTANT_BASE_URL: previous.apiOrigin,\n NEXT_PUBLIC_ASSISTANT_HARNESS_URL: previous.harnessOrigin,\n NEXT_PUBLIC_ASSISTANT_WORKSPACE_ID: previous.workspaceId,\n });\n if (expected !== environment)\n throw new Error(\n \"Cloud settings are missing from .env.local. Restore them before running setup again.\",\n );\n logger.success(\n `Already configured: ${previous.projectSlug} / ${previous.harnessId}`,\n );\n return;\n }\n const auth = cloudAuthConfig();\n const token = await cloudAccessToken(auth, {\n noOpen: options.open === false,\n ...(options.setupUrl && { setupUrl: options.setupUrl }),\n print: logger.info,\n });\n const organization = await organizationForSetup(auth.issuer, token, options);\n const project = await projectForSetup(\n auth.issuer,\n token,\n organization,\n target,\n options,\n );\n await scaffoldCloudProject(target, options);\n const accessCode =\n options.accessCode ??\n process.env.ASSISTANT_UI_ACCESS_CODE ??\n (options.yes\n ? undefined\n : answer(\n await p.password({\n message:\n \"Hackathon access code (leave empty if your plan includes harnesses)\",\n }),\n ));\n const request = await resolveProvisionRequest(\n target,\n {\n org_id: organization.id,\n project_id: project.id,\n harness_name: options.harnessName ?? `${project.name} chat`,\n backend_urls: backend.protocol === \"http:\" ? [] : [backend.href],\n allow_localhost: backend.protocol === \"http:\",\n },\n accessCode,\n );\n const result = await provisionCloudHarness(options.apiUrl, token, request);\n await writeCloudProjectConfig(\n target,\n {\n organizationId: organization.id,\n organizationSlug: organization.slug,\n projectId: result.project_id,\n projectSlug: project.slug,\n harnessId: result.harness_id,\n harnessOrigin: result.harness_origin,\n apiOrigin: result.api_origin,\n workspaceId: result.workspace_id,\n backendUrl: backend.href,\n },\n result.api_key,\n );\n logger.success(`Multiplayer chat configured for ${project.name}.`);\n logger.info(`Project: ${target}`);\n logger.info(\n \"Add OPENAI_API_KEY to .env.local, then start the app with your package manager's dev command.\",\n );\n logger.info(\n backend.protocol === \"http:\"\n ? `Open ${backend.origin}/#main in two browser windows to try shared chat. Deploy or expose the app to share it with teammates.`\n : 'Open your deployed app and use \"Share this chat\" to invite teammates to the same conversation.',\n );\n};\n\nexport const cloud = new Command()\n .name(\"cloud\")\n .description(\"sign in and set up a multiplayer Assistant Cloud chat\")\n .addCommand(\n new Command(\"login\")\n .description(\"sign in to Assistant Cloud using your browser\")\n .option(\n \"--no-open\",\n \"print the device sign-in URL without opening a browser\",\n )\n .option(\n \"--setup-url <url>\",\n \"show device sign-in in an active setup wizard\",\n )\n .action(async (options: { open?: boolean; setupUrl?: string }) => {\n await loginToCloud(cloudAuthConfig(), {\n noOpen: options.open === false,\n ...(options.setupUrl && { setupUrl: options.setupUrl }),\n print: logger.info,\n });\n }),\n )\n .addCommand(\n new Command(\"logout\")\n .description(\"revoke your CLI login and remove saved credentials\")\n .action(async () => {\n await logoutFromCloud(cloudAuthConfig());\n logger.success(\"Signed out.\");\n }),\n )\n .addCommand(\n new Command(\"setup\")\n .description(\"create a shared AI chat and provision its cloud harness\")\n .argument(\"[directory]\", \"new project directory\", \"multiplayer-chat\")\n .option(\"--org <id-or-slug>\", \"use an existing organization\")\n .option(\"--new-org <slug>\", \"create an organization\")\n .option(\"--project <id-or-slug>\", \"use an existing project\")\n .option(\"--new-project <slug>\", \"create a project\")\n .option(\"--name <name>\", \"display name for a new project or organization\")\n .option(\"--harness-name <name>\", \"name for the multiplayer harness\")\n .option(\n \"--backend-url <url>\",\n \"absolute URL of the app's chat route\",\n \"http://localhost:3000/api/chat\",\n )\n .option(\n \"--api-url <url>\",\n \"Assistant Cloud management URL\",\n process.env.ASSISTANT_UI_CLOUD_URL ?? \"https://cloud.assistant-ui.com\",\n )\n .option(\n \"--access-code <code>\",\n \"redeem your hackathon harness access code\",\n )\n .option(\n \"--no-open\",\n \"print the device sign-in URL without opening a browser\",\n )\n .option(\n \"--setup-url <url>\",\n \"show device sign-in in an active setup wizard\",\n )\n .option(\"--yes\", \"skip prompts; select resources with flags\")\n .option(\"--skip-install\", \"skip installing scaffold dependencies\")\n .option(\"--use-npm\", \"install with npm\")\n .option(\"--use-pnpm\", \"install with pnpm\")\n .option(\"--use-yarn\", \"install with yarn\")\n .option(\"--use-bun\", \"install with bun\")\n .addOption(\n new Option(\n \"--debug-source-root <path>\",\n \"local assistant-ui source root\",\n ).hideHelp(),\n )\n .action(async (directory: string, options: SetupOptions) => {\n try {\n await setupCloud(directory, options);\n } catch (error) {\n if (!(error instanceof SetupCancelled)) throw error;\n p.cancel(\"Cloud setup cancelled. Rerun the same command to resume.\");\n }\n }),\n );\n"],"mappings":"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"}
@@ -1 +1 @@
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;AAwBpC,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,EAmP7C,CAAC;AAiBF,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;AAED,eAAO,MAAM,yBAAyB,eAAe,CAAC;AAEtD,eAAO,MAAM,wBAAwB;;;;uBAIhB,MAAM;CAY1B,CAAC;AAEF,wBAAgB,+BAA+B,CAAC,MAAM,EAAE;IACtD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;CAC5B,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CA8BzC;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,SA+Uf,CAAC"}
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;AAwBpC,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,EA2P7C,CAAC;AAiBF,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;AAED,eAAO,MAAM,yBAAyB,eAAe,CAAC;AAEtD,eAAO,MAAM,wBAAwB;;;;uBAIhB,MAAM;CAY1B,CAAC;AAEF,wBAAgB,+BAA+B,CAAC,MAAM,EAAE;IACtD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;CAC5B,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CA8BzC;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,SA+Uf,CAAC"}
@@ -42,6 +42,14 @@ const PROJECT_METADATA = [
42
42
  path: "templates/cloud-clerk",
43
43
  hasLocalComponents: false
44
44
  },
45
+ {
46
+ name: "cloud-harness",
47
+ label: "Shared cloud chat",
48
+ description: "A hosted harness with a shared conversation across browsers",
49
+ category: "template",
50
+ path: "templates/cloud-harness",
51
+ hasLocalComponents: true
52
+ },
45
53
  {
46
54
  name: "langchain",
47
55
  label: "LangChain",
@@ -1 +1 @@
1
- {"version":3,"file":"create.js","names":[],"sources":["../../src/commands/create.ts"],"sourcesContent":["import { Command, Option } from \"commander\";\nimport chalk from \"chalk\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport * as p from \"@clack/prompts\";\nimport { logger } from \"../lib/utils/logger\";\nimport {\n cleanupPendingProjectDownloads,\n dlxCommand,\n downloadProject,\n resolveLatestReleaseRef,\n resolvePackageManager,\n scaffoldProject,\n transformProject,\n type TransformResult,\n} from \"../lib/create-project\";\nimport {\n hasActiveSpawn,\n runSpawn,\n SpawnExitError,\n SpawnSignalError,\n} from \"../lib/run-spawn\";\nimport { resolvePackageManagerForCwd } from \"../lib/utils/package-manager\";\nimport {\n buildSkillsAddCommand,\n resolveSkillsInstall,\n} from \"../lib/agent-skill\";\n\nexport interface ProjectMetadata {\n name: string;\n label: string;\n description?: string;\n category: \"template\" | \"example\";\n path: string;\n hasLocalComponents: boolean;\n}\n\nexport const PROJECT_METADATA: ProjectMetadata[] = [\n // Templates\n {\n name: \"default\",\n label: \"Default\",\n description: \"Default template with Vercel AI SDK\",\n category: \"template\",\n path: \"templates/default\",\n hasLocalComponents: false,\n },\n {\n name: \"minimal\",\n label: \"Minimal\",\n description: \"Bare-bones starting point\",\n category: \"template\",\n path: \"templates/minimal\",\n hasLocalComponents: true,\n },\n {\n name: \"cloud\",\n label: \"Cloud\",\n description: \"Cloud-backed persistence starter\",\n category: \"template\",\n path: \"templates/cloud\",\n hasLocalComponents: false,\n },\n {\n name: \"cloud-clerk\",\n label: \"Cloud + Clerk\",\n description: \"Cloud-backed starter with Clerk auth\",\n category: \"template\",\n path: \"templates/cloud-clerk\",\n hasLocalComponents: false,\n },\n {\n name: \"langchain\",\n label: \"LangChain\",\n description: \"LangGraph starter with the react-langchain adapter\",\n category: \"template\",\n path: \"templates/langchain\",\n hasLocalComponents: false,\n },\n {\n name: \"mcp\",\n label: \"MCP\",\n description: \"MCP tools + MCP Apps renderer starter\",\n category: \"template\",\n path: \"templates/mcp\",\n hasLocalComponents: false,\n },\n {\n name: \"eve\",\n label: \"Eve\",\n description: \"Eve agent + Next.js starter\",\n category: \"template\",\n path: \"templates/eve\",\n hasLocalComponents: false,\n },\n // Examples\n {\n name: \"with-ag-ui\",\n label: \"AG-UI\",\n description: \"AG-UI protocol integration\",\n category: \"example\",\n path: \"examples/with-ag-ui\",\n hasLocalComponents: false,\n },\n {\n name: \"with-google-adk\",\n label: \"Google ADK\",\n description: \"Google ADK agent integration\",\n category: \"example\",\n path: \"examples/with-google-adk\",\n hasLocalComponents: false,\n },\n {\n name: \"with-ai-sdk-v7\",\n label: \"AI SDK v7\",\n description: \"Vercel AI SDK v7\",\n category: \"example\",\n path: \"examples/with-ai-sdk-v7\",\n hasLocalComponents: false,\n },\n {\n name: \"with-eve\",\n label: \"Eve\",\n description: \"Eve agent integration\",\n category: \"example\",\n path: \"examples/with-eve\",\n hasLocalComponents: false,\n },\n {\n name: \"with-artifacts\",\n label: \"Artifacts\",\n description: \"Artifact rendering\",\n category: \"example\",\n path: \"examples/with-artifacts\",\n hasLocalComponents: false,\n },\n {\n name: \"with-assistant-transport\",\n label: \"Assistant Transport\",\n description: \"Assistant transport protocol\",\n category: \"example\",\n path: \"examples/with-assistant-transport\",\n hasLocalComponents: false,\n },\n {\n name: \"with-chain-of-thought\",\n label: \"Chain of Thought\",\n description: \"Chain-of-thought, tool calls, and source citations\",\n category: \"example\",\n path: \"examples/with-chain-of-thought\",\n hasLocalComponents: false,\n },\n {\n name: \"with-cloud\",\n label: \"Cloud Example\",\n description: \"Cloud integration example\",\n category: \"example\",\n path: \"examples/with-cloud\",\n hasLocalComponents: false,\n },\n {\n name: \"with-custom-thread-list\",\n label: \"Custom Thread List\",\n description: \"Custom thread list UI\",\n category: \"example\",\n path: \"examples/with-custom-thread-list\",\n hasLocalComponents: false,\n },\n {\n name: \"with-elevenlabs-conversational\",\n label: \"ElevenLabs Conversational\",\n description: \"Realtime voice with ElevenLabs\",\n category: \"example\",\n path: \"examples/with-elevenlabs-conversational\",\n hasLocalComponents: false,\n },\n {\n name: \"with-elevenlabs-scribe\",\n label: \"ElevenLabs Scribe\",\n description: \"Audio/speech integration\",\n category: \"example\",\n path: \"examples/with-elevenlabs-scribe\",\n hasLocalComponents: false,\n },\n {\n name: \"with-livekit\",\n label: \"LiveKit Voice\",\n description: \"Realtime voice with LiveKit\",\n category: \"example\",\n path: \"examples/with-livekit\",\n hasLocalComponents: false,\n },\n {\n name: \"with-expo\",\n label: \"Expo\",\n description: \"Expo / React Native\",\n category: \"example\",\n path: \"examples/with-expo\",\n hasLocalComponents: false,\n },\n {\n name: \"with-interactables\",\n label: \"Interactables\",\n description: \"AI-driven interactive UI components\",\n category: \"example\",\n path: \"examples/with-interactables\",\n hasLocalComponents: false,\n },\n {\n name: \"with-external-store\",\n label: \"External Store\",\n description: \"Custom message store\",\n category: \"example\",\n path: \"examples/with-external-store\",\n hasLocalComponents: false,\n },\n {\n name: \"with-ffmpeg\",\n label: \"FFmpeg\",\n description: \"File processing\",\n category: \"example\",\n path: \"examples/with-ffmpeg\",\n hasLocalComponents: false,\n },\n {\n name: \"with-langgraph\",\n label: \"LangGraph Example\",\n description: \"LangGraph integration\",\n category: \"example\",\n path: \"examples/with-langgraph\",\n hasLocalComponents: false,\n },\n {\n name: \"with-react-hook-form\",\n label: \"React Hook Form\",\n description: \"Form integration\",\n category: \"example\",\n path: \"examples/with-react-hook-form\",\n hasLocalComponents: false,\n },\n {\n name: \"with-react-ink\",\n label: \"React Ink\",\n description: \"Terminal UI chat\",\n category: \"example\",\n path: \"examples/with-react-ink\",\n hasLocalComponents: true,\n },\n {\n name: \"with-react-router\",\n label: \"React Router\",\n description: \"React Router v7 + Vite\",\n category: \"example\",\n path: \"examples/with-react-router\",\n hasLocalComponents: false,\n },\n {\n name: \"with-tanstack\",\n label: \"TanStack\",\n description: \"TanStack/React Router + Vite\",\n category: \"example\",\n path: \"examples/with-tanstack\",\n hasLocalComponents: false,\n },\n {\n name: \"with-resumable-stream\",\n label: \"Resumable Stream\",\n description: \"Resumable LLM stream that survives reload mid-response\",\n category: \"example\",\n path: \"examples/with-resumable-stream\",\n hasLocalComponents: false,\n },\n {\n name: \"with-openui\",\n label: \"OpenUI\",\n description: \"OpenUI generative UI integration\",\n category: \"example\",\n path: \"examples/with-openui\",\n hasLocalComponents: false,\n },\n];\n\n// Examples that exist in the monorepo but are intentionally excluded from the CLI:\n//\n// - waterfall: Still in development, not ready for production.\n// - with-store: In development, not ready for public use of the tap store.\n// - with-tap-runtime: In development, not ready for public use of the tap\n// store.\n\nconst templateNames = PROJECT_METADATA.filter(\n (m) => m.category === \"template\",\n).map((m) => m.name);\n\nconst exampleNames = PROJECT_METADATA.filter(\n (m) => m.category === \"example\",\n).map((m) => m.name);\n\nexport async function resolveProject(params: {\n template?: string;\n example?: string;\n stdinIsTTY?: boolean;\n select?: typeof p.select;\n isCancel?: typeof p.isCancel;\n}): Promise<ProjectMetadata | null> {\n const {\n template,\n example,\n stdinIsTTY = process.stdin.isTTY,\n select = p.select,\n isCancel = p.isCancel,\n } = params;\n\n if (template !== undefined) {\n const meta = PROJECT_METADATA.find(\n (m) => m.name === template && m.category === \"template\",\n );\n if (!meta) {\n logger.error(`Unknown template: ${template}`);\n logger.info(`Available templates: ${templateNames.join(\", \")}`);\n process.exit(1);\n }\n return meta;\n }\n\n if (example !== undefined) {\n const meta = PROJECT_METADATA.find(\n (m) => m.name === example && m.category === \"example\",\n );\n if (!meta) {\n logger.error(`Unknown example: ${example}`);\n logger.info(`Available examples: ${exampleNames.join(\", \")}`);\n process.exit(1);\n }\n return meta;\n }\n\n if (!stdinIsTTY) {\n return PROJECT_METADATA.find((m) => m.name === \"default\")!;\n }\n\n const selected = await select({\n message: \"Select a project to scaffold:\",\n options: [\n {\n value: \"_separator\",\n label: \"────── Starter Templates ──────\",\n disabled: true,\n },\n ...PROJECT_METADATA.filter((m) => m.category === \"template\").map((m) => ({\n value: m.name,\n label: m.label,\n ...(m.description ? { hint: m.description } : {}),\n })),\n {\n value: \"_separator\",\n label: \"────── Feature Examples ──────\",\n disabled: true,\n },\n ...PROJECT_METADATA.filter((m) => m.category === \"example\").map((m) => ({\n value: m.name,\n label: m.label,\n ...(m.description ? { hint: m.description } : {}),\n })),\n ],\n });\n\n if (isCancel(selected)) {\n return null;\n }\n\n const meta = PROJECT_METADATA.find((m) => m.name === selected);\n if (!meta) {\n logger.error(`Unknown selection: ${String(selected)}`);\n process.exit(1);\n }\n return meta;\n}\n\nexport function resolveCreateProjectDirectory(params: {\n projectDirectory?: string;\n stdinIsTTY?: boolean;\n}): string | undefined {\n const { projectDirectory, stdinIsTTY = process.stdin.isTTY } = params;\n\n if (projectDirectory) return projectDirectory;\n if (!stdinIsTTY) return DEFAULT_PROJECT_DIRECTORY;\n return undefined;\n}\n\nexport const DEFAULT_PROJECT_DIRECTORY = \"my-aui-app\";\n\nexport const projectNamePromptOptions = {\n message: \"Project name:\",\n placeholder: DEFAULT_PROJECT_DIRECTORY,\n defaultValue: DEFAULT_PROJECT_DIRECTORY,\n validate: (value?: string) => {\n // Enter on an untouched prompt is how clack accepts `defaultValue`, and it\n // validates before finalize substitutes it, so an empty value has to pass\n // here or the default is unreachable.\n if (value === undefined || value === \"\") return undefined;\n const name = value.trim();\n if (!name) return \"Project name cannot be empty\";\n if (name === \".\" || name === \"..\") return \"Project name cannot be . or ..\";\n if (name.includes(\"/\") || name.includes(\"\\\\\"))\n return \"Project name cannot contain path separators\";\n return undefined;\n },\n};\n\nexport function resolveProjectDirectoryGuidance(params: {\n absoluteProjectDir: string;\n cwd?: string;\n platform?: NodeJS.Platform;\n}): { display: string; cdCommand: string } {\n const {\n absoluteProjectDir,\n cwd = process.cwd(),\n platform = process.platform,\n } = params;\n const isWindows = platform === \"win32\";\n const pathApi = isWindows ? path.win32 : path.posix;\n\n const relative = pathApi.relative(cwd, absoluteProjectDir);\n const escapesCwd =\n relative === \"..\" || relative.startsWith(`..${pathApi.sep}`);\n const display =\n relative && !escapesCwd && !pathApi.isAbsolute(relative)\n ? relative\n : absoluteProjectDir;\n\n const target = display.startsWith(\"-\")\n ? `.${pathApi.sep}${display}`\n : display;\n // Neither Windows shell has a literal quoting form the other accepts: cmd\n // reads single quotes as part of the name, and double quotes still expand\n // %VAR% there and $var in PowerShell.\n const quoted = (isWindows ? /^[\\w@.:/\\\\+-]+$/ : /^[\\w@./+-]+$/).test(target)\n ? target\n : isWindows\n ? `\"${target}\"`\n : `'${target.replaceAll(\"'\", \"'\\\\''\")}'`;\n\n return { display, cdCommand: `cd ${quoted}` };\n}\n\nconst PLAYGROUND_PRESET_BASE_URL =\n \"https://www.assistant-ui.com/playground/init\";\n\nexport function resolvePresetUrl(preset: string): string {\n if (preset.startsWith(\"http://\") || preset.startsWith(\"https://\")) {\n return preset;\n }\n return `${PLAYGROUND_PRESET_BASE_URL}?preset=${encodeURIComponent(preset)}`;\n}\n\nexport interface ScaffoldSelectorOptions {\n template?: string;\n example?: string;\n preset?: string;\n native?: boolean;\n ink?: boolean;\n}\n\nexport interface ResolvedScaffoldSelector {\n template?: string;\n example?: string;\n preset?: string;\n}\n\nconst scaffoldSelectorHelp =\n \"Choose one scaffold selector: --template <name>, --example <name>, --native, or --ink. --preset <name-or-url> can be used with --template or by itself.\";\n\nfunction getPresetConflict(opts: ScaffoldSelectorOptions): string | undefined {\n if (opts.example !== undefined) return \"--example\";\n if (opts.native) return \"--native\";\n if (opts.ink) return \"--ink\";\n return undefined;\n}\n\nexport function resolveScaffoldSelector(\n opts: ScaffoldSelectorOptions,\n): ResolvedScaffoldSelector {\n const hasPreset = opts.preset !== undefined;\n const presetConflict = getPresetConflict(opts);\n const selectors = [\n opts.template !== undefined ? \"--template\" : undefined,\n opts.example !== undefined ? \"--example\" : undefined,\n opts.native ? \"--native\" : undefined,\n opts.ink ? \"--ink\" : undefined,\n ].filter((selector): selector is string => selector !== undefined);\n\n if (selectors.length > 1) {\n throw new Error(\n `Only one scaffold selector can be provided (${selectors.join(\", \")}). ${scaffoldSelectorHelp}`,\n );\n }\n\n if (hasPreset && presetConflict) {\n throw new Error(\n `Cannot use --preset with ${presetConflict}. ${scaffoldSelectorHelp}`,\n );\n }\n\n if (opts.native) return { example: \"with-expo\" };\n if (opts.ink) return { example: \"with-react-ink\" };\n\n if (opts.preset !== undefined && opts.template === undefined) {\n return { template: \"default\", preset: opts.preset };\n }\n\n return {\n ...(opts.template !== undefined && { template: opts.template }),\n ...(opts.example !== undefined && { example: opts.example }),\n ...(hasPreset && { preset: opts.preset }),\n };\n}\n\nexport const create = new Command()\n .name(\"create\")\n .description(\"create a new project\")\n .argument(\"[project-directory]\")\n .usage(`${chalk.green(\"[project-directory]\")} [options]`)\n .option(\n \"-t, --template <template>\",\n `template to use (${templateNames.join(\", \")})`,\n )\n .option(\n \"-e, --example <example>\",\n `create from an example (${exampleNames.join(\", \")})`,\n )\n .option(\n \"-p, --preset <name-or-url>\",\n \"preset name or URL (e.g., chatgpt or https://www.assistant-ui.com/playground/init?preset=chatgpt)\",\n )\n .option(\"--use-npm\", \"explicitly use npm\")\n .option(\"--use-pnpm\", \"explicitly use pnpm\")\n .option(\"--use-yarn\", \"explicitly use yarn\")\n .option(\"--use-bun\", \"explicitly use bun\")\n .option(\"--native\", \"create an Expo / React Native project\")\n .option(\"--ink\", \"create a React Ink terminal project\")\n .option(\"--skip-install\", \"skip installing packages\")\n .option(\"--skills\", \"add assistant-ui agent skills for AI coding assistants\")\n .option(\"--no-skills\", \"skip adding assistant-ui agent skills\")\n .addOption(\n new Option(\n \"--cwd <cwd>\",\n \"the working directory. defaults to the current directory.\",\n ).hideHelp(),\n )\n .addOption(\n new Option(\n \"--debug-source-root <path>\",\n \"copy templates/examples from a local assistant-ui repo root\",\n ).hideHelp(),\n )\n .action(async (projectDirectory, opts) => {\n let scaffoldSelector: ResolvedScaffoldSelector;\n try {\n scaffoldSelector = resolveScaffoldSelector(opts);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n logger.error(message);\n process.exit(1);\n }\n\n const localSourceRoot = opts.debugSourceRoot\n ? path.resolve(opts.debugSourceRoot)\n : undefined;\n\n // Start release ref resolution early (runs during user prompts)\n const refPromise = localSourceRoot\n ? Promise.resolve(undefined)\n : resolveLatestReleaseRef();\n\n // 1. Resolve project directory\n let resolvedProjectDirectory = resolveCreateProjectDirectory({\n projectDirectory,\n });\n\n if (!resolvedProjectDirectory) {\n const result = await p.text(projectNamePromptOptions);\n\n if (p.isCancel(result)) {\n p.cancel(\"Project creation cancelled.\");\n process.exit(0);\n }\n\n resolvedProjectDirectory = result;\n }\n\n // Check directory\n const absoluteProjectDir = path.resolve(\n opts.cwd ?? process.cwd(),\n resolvedProjectDirectory,\n );\n const { display: displayProjectDir, cdCommand } =\n resolveProjectDirectoryGuidance({ absoluteProjectDir });\n let projectDirExisted = true;\n try {\n const files = fs.readdirSync(absoluteProjectDir);\n if (files.length > 0) {\n logger.error(\n `Directory ${displayProjectDir} already exists and is not empty`,\n );\n process.exit(1);\n }\n } catch (err: unknown) {\n const code =\n err instanceof Error ? (err as NodeJS.ErrnoException).code : undefined;\n if (code === \"ENOENT\") {\n // Directory doesn't exist — good, proceed\n projectDirExisted = false;\n } else if (code === \"ENOTDIR\") {\n logger.error(\n `${displayProjectDir} already exists and is not a directory`,\n );\n process.exit(1);\n } else {\n const message = err instanceof Error ? err.message : String(err);\n logger.error(`Cannot access ${displayProjectDir}: ${message}`);\n process.exit(1);\n }\n }\n\n // 2. Resolve scaffold target\n const project = await resolveProject(scaffoldSelector);\n if (!project) {\n p.cancel(\"Project creation cancelled.\");\n process.exit(0);\n }\n\n const stdinIsTTY = process.stdin.isTTY;\n let installSkills = resolveSkillsInstall({\n skills: opts.skills,\n stdinIsTTY,\n });\n if (installSkills === undefined) {\n const result = await p.confirm({\n message: \"Add assistant-ui agent skills for AI coding assistants?\",\n initialValue: true,\n });\n\n if (p.isCancel(result)) {\n p.cancel(\"Project creation cancelled.\");\n process.exit(0);\n }\n\n installSkills = result;\n }\n\n logger.info(`Creating project from ${project.category}: ${project.label}`);\n logger.break();\n\n const pm = await resolvePackageManagerForCwd(\n path.dirname(absoluteProjectDir),\n resolvePackageManager(opts),\n );\n\n // Clean up partial project directory on unexpected exit (e.g. Ctrl+C)\n const resetProjectDir = () => {\n if (!projectDirExisted) {\n fs.rmSync(absoluteProjectDir, { recursive: true, force: true });\n return;\n }\n if (!fs.existsSync(absoluteProjectDir)) return;\n for (const entry of fs.readdirSync(absoluteProjectDir)) {\n fs.rmSync(path.join(absoluteProjectDir, entry), {\n recursive: true,\n force: true,\n });\n }\n };\n let cleanupArmed = true;\n const cleanupOnExit = () => {\n if (!cleanupArmed) return;\n cleanupArmed = false;\n resetProjectDir();\n };\n const disarmCleanup = () => {\n cleanupArmed = false;\n process.removeListener(\"exit\", cleanupOnExit);\n process.removeListener(\"SIGINT\", cleanupOnSignal);\n process.removeListener(\"SIGTERM\", cleanupOnSignal);\n };\n // Node emits no \"exit\" when a signal kills the process. An in-flight\n // runSpawn forwards the signal itself, so cleanup runs on the error path\n // once the child is reaped rather than while it is still writing.\n const cleanupOnSignal = (signal: NodeJS.Signals) => {\n if (hasActiveSpawn()) return;\n cleanupPendingProjectDownloads();\n cleanupOnExit();\n disarmCleanup();\n process.kill(process.pid, signal);\n };\n\n process.once(\"exit\", cleanupOnExit);\n process.on(\"SIGINT\", cleanupOnSignal);\n process.on(\"SIGTERM\", cleanupOnSignal);\n\n try {\n // 3. Resolve latest release ref (started before prompts)\n if (!localSourceRoot) {\n logger.step(\"Resolving latest release...\");\n }\n const ref = await refPromise;\n if (!localSourceRoot && !ref) {\n logger.warn(\"Could not resolve latest release, downloading from HEAD\");\n }\n\n // 4. Scaffold project\n logger.step(\n localSourceRoot\n ? `Copying project from local source: ${localSourceRoot}`\n : \"Downloading project...\",\n );\n let transformResult: TransformResult;\n try {\n const source = localSourceRoot\n ? { kind: \"local\" as const, rootDir: localSourceRoot }\n : {\n kind: \"github\" as const,\n ref,\n };\n await scaffoldProject(project.path, absoluteProjectDir, source);\n\n // If the template didn't exist at the release tag, retry from HEAD\n if (\n !localSourceRoot &&\n ref &&\n !fs.existsSync(path.join(absoluteProjectDir, \"package.json\"))\n ) {\n resetProjectDir();\n logger.warn(\n \"Template not found at release tag, downloading from HEAD\",\n );\n await downloadProject(project.path, absoluteProjectDir);\n }\n\n // 5. Run transform pipeline\n transformResult = await transformProject(absoluteProjectDir, {\n hasLocalComponents: project.hasLocalComponents,\n skipInstall: opts.skipInstall,\n packageManager: pm,\n });\n\n if (installSkills) {\n logger.step(\"Adding assistant-ui agent skills...\");\n const [skillsCmd, skillsArgs] = buildSkillsAddCommand(pm, {\n stdinIsTTY,\n });\n try {\n await runSpawn(skillsCmd, skillsArgs, absoluteProjectDir);\n } catch (error) {\n if (error instanceof SpawnSignalError) throw error;\n logger.warn(\n `Could not add assistant-ui agent skills. You can add them later with:\\n ${skillsCmd} ${skillsArgs.join(\" \")}`,\n );\n }\n }\n } catch (err) {\n // Clean up partially created project directory\n cleanupOnExit();\n disarmCleanup();\n throw err;\n }\n\n if (transformResult.registryInstallFailure) {\n disarmCleanup();\n logger.break();\n logger.error(\"Project created with missing components.\");\n logger.info(\"Retry the component install with:\");\n logger.info(` ${cdCommand}`);\n logger.info(` ${transformResult.registryInstallFailure.retryCommand}`);\n process.exit(1);\n }\n\n // 6. Apply preset if provided\n if (scaffoldSelector.preset) {\n const presetUrl = resolvePresetUrl(scaffoldSelector.preset);\n logger.info(\"Applying preset configuration...\");\n logger.break();\n const [dlxCmd, dlxArgs] = dlxCommand(pm);\n try {\n await runSpawn(\n dlxCmd,\n [\n ...dlxArgs,\n \"shadcn@latest\",\n \"add\",\n \"--yes\",\n \"--overwrite\",\n presetUrl,\n ],\n absoluteProjectDir,\n );\n } catch (error) {\n if (error instanceof SpawnSignalError) throw error;\n logger.warn(\n `Preset application failed. You can retry manually with:\\n ${dlxCmd} ${[...dlxArgs, \"shadcn@latest\", \"add\", presetUrl].join(\" \")}`,\n );\n }\n }\n\n disarmCleanup();\n\n logger.break();\n logger.success(\"Project created successfully!\");\n logger.break();\n const runCmd = pm === \"npm\" ? \"npm run\" : pm;\n let devScript = \"dev\";\n let envFile = \".env.local\";\n try {\n const scaffoldedPkg = JSON.parse(\n fs.readFileSync(\n path.join(absoluteProjectDir, \"package.json\"),\n \"utf-8\",\n ),\n );\n devScript = scaffoldedPkg.scripts?.dev\n ? \"dev\"\n : scaffoldedPkg.scripts?.start\n ? \"start\"\n : \"dev\";\n envFile = scaffoldedPkg.dependencies?.next ? \".env.local\" : \".env\";\n } catch {\n // Fall back to defaults if package.json cannot be read\n }\n\n logger.info(\"Next steps:\");\n logger.info(` ${cdCommand}`);\n if (opts.skipInstall) {\n logger.info(` ${pm} install`);\n if (transformResult.registryInstallCommand) {\n logger.info(` ${transformResult.registryInstallCommand}`);\n }\n }\n logger.info(` # Set up your environment variables in ${envFile}`);\n logger.info(` ${runCmd} ${devScript}`);\n } catch (error) {\n if (error instanceof SpawnSignalError) {\n cleanupOnExit();\n disarmCleanup();\n throw error;\n }\n if (error instanceof SpawnExitError) {\n logger.error(`Project creation failed with code ${error.code}`);\n process.exit(error.code);\n }\n const message = error instanceof Error ? error.message : String(error);\n logger.error(`Failed to create project: ${message}`);\n process.exit(1);\n }\n });\n"],"mappings":";;;;;;;;;;;AAqCA,MAAa,mBAAsC;CAEjD;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CAEA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;AACF;AASA,MAAM,gBAAgB,iBAAiB,QACpC,MAAM,EAAE,aAAa,UACxB,CAAC,CAAC,KAAK,MAAM,EAAE,IAAI;AAEnB,MAAM,eAAe,iBAAiB,QACnC,MAAM,EAAE,aAAa,SACxB,CAAC,CAAC,KAAK,MAAM,EAAE,IAAI;AAEnB,eAAsB,eA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"}
1
+ {"version":3,"file":"create.js","names":[],"sources":["../../src/commands/create.ts"],"sourcesContent":["import { Command, Option } from \"commander\";\nimport chalk from \"chalk\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport * as p from \"@clack/prompts\";\nimport { logger } from \"../lib/utils/logger\";\nimport {\n cleanupPendingProjectDownloads,\n dlxCommand,\n downloadProject,\n resolveLatestReleaseRef,\n resolvePackageManager,\n scaffoldProject,\n transformProject,\n type TransformResult,\n} from \"../lib/create-project\";\nimport {\n hasActiveSpawn,\n runSpawn,\n SpawnExitError,\n SpawnSignalError,\n} from \"../lib/run-spawn\";\nimport { resolvePackageManagerForCwd } from \"../lib/utils/package-manager\";\nimport {\n buildSkillsAddCommand,\n resolveSkillsInstall,\n} from \"../lib/agent-skill\";\n\nexport interface ProjectMetadata {\n name: string;\n label: string;\n description?: string;\n category: \"template\" | \"example\";\n path: string;\n hasLocalComponents: boolean;\n}\n\nexport const PROJECT_METADATA: ProjectMetadata[] = [\n // Templates\n {\n name: \"default\",\n label: \"Default\",\n description: \"Default template with Vercel AI SDK\",\n category: \"template\",\n path: \"templates/default\",\n hasLocalComponents: false,\n },\n {\n name: \"minimal\",\n label: \"Minimal\",\n description: \"Bare-bones starting point\",\n category: \"template\",\n path: \"templates/minimal\",\n hasLocalComponents: true,\n },\n {\n name: \"cloud\",\n label: \"Cloud\",\n description: \"Cloud-backed persistence starter\",\n category: \"template\",\n path: \"templates/cloud\",\n hasLocalComponents: false,\n },\n {\n name: \"cloud-clerk\",\n label: \"Cloud + Clerk\",\n description: \"Cloud-backed starter with Clerk auth\",\n category: \"template\",\n path: \"templates/cloud-clerk\",\n hasLocalComponents: false,\n },\n {\n name: \"cloud-harness\",\n label: \"Shared cloud chat\",\n description: \"A hosted harness with a shared conversation across browsers\",\n category: \"template\",\n path: \"templates/cloud-harness\",\n hasLocalComponents: true,\n },\n {\n name: \"langchain\",\n label: \"LangChain\",\n description: \"LangGraph starter with the react-langchain adapter\",\n category: \"template\",\n path: \"templates/langchain\",\n hasLocalComponents: false,\n },\n {\n name: \"mcp\",\n label: \"MCP\",\n description: \"MCP tools + MCP Apps renderer starter\",\n category: \"template\",\n path: \"templates/mcp\",\n hasLocalComponents: false,\n },\n {\n name: \"eve\",\n label: \"Eve\",\n description: \"Eve agent + Next.js starter\",\n category: \"template\",\n path: \"templates/eve\",\n hasLocalComponents: false,\n },\n // Examples\n {\n name: \"with-ag-ui\",\n label: \"AG-UI\",\n description: \"AG-UI protocol integration\",\n category: \"example\",\n path: \"examples/with-ag-ui\",\n hasLocalComponents: false,\n },\n {\n name: \"with-google-adk\",\n label: \"Google ADK\",\n description: \"Google ADK agent integration\",\n category: \"example\",\n path: \"examples/with-google-adk\",\n hasLocalComponents: false,\n },\n {\n name: \"with-ai-sdk-v7\",\n label: \"AI SDK v7\",\n description: \"Vercel AI SDK v7\",\n category: \"example\",\n path: \"examples/with-ai-sdk-v7\",\n hasLocalComponents: false,\n },\n {\n name: \"with-eve\",\n label: \"Eve\",\n description: \"Eve agent integration\",\n category: \"example\",\n path: \"examples/with-eve\",\n hasLocalComponents: false,\n },\n {\n name: \"with-artifacts\",\n label: \"Artifacts\",\n description: \"Artifact rendering\",\n category: \"example\",\n path: \"examples/with-artifacts\",\n hasLocalComponents: false,\n },\n {\n name: \"with-assistant-transport\",\n label: \"Assistant Transport\",\n description: \"Assistant transport protocol\",\n category: \"example\",\n path: \"examples/with-assistant-transport\",\n hasLocalComponents: false,\n },\n {\n name: \"with-chain-of-thought\",\n label: \"Chain of Thought\",\n description: \"Chain-of-thought, tool calls, and source citations\",\n category: \"example\",\n path: \"examples/with-chain-of-thought\",\n hasLocalComponents: false,\n },\n {\n name: \"with-cloud\",\n label: \"Cloud Example\",\n description: \"Cloud integration example\",\n category: \"example\",\n path: \"examples/with-cloud\",\n hasLocalComponents: false,\n },\n {\n name: \"with-custom-thread-list\",\n label: \"Custom Thread List\",\n description: \"Custom thread list UI\",\n category: \"example\",\n path: \"examples/with-custom-thread-list\",\n hasLocalComponents: false,\n },\n {\n name: \"with-elevenlabs-conversational\",\n label: \"ElevenLabs Conversational\",\n description: \"Realtime voice with ElevenLabs\",\n category: \"example\",\n path: \"examples/with-elevenlabs-conversational\",\n hasLocalComponents: false,\n },\n {\n name: \"with-elevenlabs-scribe\",\n label: \"ElevenLabs Scribe\",\n description: \"Audio/speech integration\",\n category: \"example\",\n path: \"examples/with-elevenlabs-scribe\",\n hasLocalComponents: false,\n },\n {\n name: \"with-livekit\",\n label: \"LiveKit Voice\",\n description: \"Realtime voice with LiveKit\",\n category: \"example\",\n path: \"examples/with-livekit\",\n hasLocalComponents: false,\n },\n {\n name: \"with-expo\",\n label: \"Expo\",\n description: \"Expo / React Native\",\n category: \"example\",\n path: \"examples/with-expo\",\n hasLocalComponents: false,\n },\n {\n name: \"with-interactables\",\n label: \"Interactables\",\n description: \"AI-driven interactive UI components\",\n category: \"example\",\n path: \"examples/with-interactables\",\n hasLocalComponents: false,\n },\n {\n name: \"with-external-store\",\n label: \"External Store\",\n description: \"Custom message store\",\n category: \"example\",\n path: \"examples/with-external-store\",\n hasLocalComponents: false,\n },\n {\n name: \"with-ffmpeg\",\n label: \"FFmpeg\",\n description: \"File processing\",\n category: \"example\",\n path: \"examples/with-ffmpeg\",\n hasLocalComponents: false,\n },\n {\n name: \"with-langgraph\",\n label: \"LangGraph Example\",\n description: \"LangGraph integration\",\n category: \"example\",\n path: \"examples/with-langgraph\",\n hasLocalComponents: false,\n },\n {\n name: \"with-react-hook-form\",\n label: \"React Hook Form\",\n description: \"Form integration\",\n category: \"example\",\n path: \"examples/with-react-hook-form\",\n hasLocalComponents: false,\n },\n {\n name: \"with-react-ink\",\n label: \"React Ink\",\n description: \"Terminal UI chat\",\n category: \"example\",\n path: \"examples/with-react-ink\",\n hasLocalComponents: true,\n },\n {\n name: \"with-react-router\",\n label: \"React Router\",\n description: \"React Router v7 + Vite\",\n category: \"example\",\n path: \"examples/with-react-router\",\n hasLocalComponents: false,\n },\n {\n name: \"with-tanstack\",\n label: \"TanStack\",\n description: \"TanStack/React Router + Vite\",\n category: \"example\",\n path: \"examples/with-tanstack\",\n hasLocalComponents: false,\n },\n {\n name: \"with-resumable-stream\",\n label: \"Resumable Stream\",\n description: \"Resumable LLM stream that survives reload mid-response\",\n category: \"example\",\n path: \"examples/with-resumable-stream\",\n hasLocalComponents: false,\n },\n {\n name: \"with-openui\",\n label: \"OpenUI\",\n description: \"OpenUI generative UI integration\",\n category: \"example\",\n path: \"examples/with-openui\",\n hasLocalComponents: false,\n },\n];\n\n// Examples that exist in the monorepo but are intentionally excluded from the CLI:\n//\n// - waterfall: Still in development, not ready for production.\n// - with-store: In development, not ready for public use of the tap store.\n// - with-tap-runtime: In development, not ready for public use of the tap\n// store.\n\nconst templateNames = PROJECT_METADATA.filter(\n (m) => m.category === \"template\",\n).map((m) => m.name);\n\nconst exampleNames = PROJECT_METADATA.filter(\n (m) => m.category === \"example\",\n).map((m) => m.name);\n\nexport async function resolveProject(params: {\n template?: string;\n example?: string;\n stdinIsTTY?: boolean;\n select?: typeof p.select;\n isCancel?: typeof p.isCancel;\n}): Promise<ProjectMetadata | null> {\n const {\n template,\n example,\n stdinIsTTY = process.stdin.isTTY,\n select = p.select,\n isCancel = p.isCancel,\n } = params;\n\n if (template !== undefined) {\n const meta = PROJECT_METADATA.find(\n (m) => m.name === template && m.category === \"template\",\n );\n if (!meta) {\n logger.error(`Unknown template: ${template}`);\n logger.info(`Available templates: ${templateNames.join(\", \")}`);\n process.exit(1);\n }\n return meta;\n }\n\n if (example !== undefined) {\n const meta = PROJECT_METADATA.find(\n (m) => m.name === example && m.category === \"example\",\n );\n if (!meta) {\n logger.error(`Unknown example: ${example}`);\n logger.info(`Available examples: ${exampleNames.join(\", \")}`);\n process.exit(1);\n }\n return meta;\n }\n\n if (!stdinIsTTY) {\n return PROJECT_METADATA.find((m) => m.name === \"default\")!;\n }\n\n const selected = await select({\n message: \"Select a project to scaffold:\",\n options: [\n {\n value: \"_separator\",\n label: \"────── Starter Templates ──────\",\n disabled: true,\n },\n ...PROJECT_METADATA.filter((m) => m.category === \"template\").map((m) => ({\n value: m.name,\n label: m.label,\n ...(m.description ? { hint: m.description } : {}),\n })),\n {\n value: \"_separator\",\n label: \"────── Feature Examples ──────\",\n disabled: true,\n },\n ...PROJECT_METADATA.filter((m) => m.category === \"example\").map((m) => ({\n value: m.name,\n label: m.label,\n ...(m.description ? { hint: m.description } : {}),\n })),\n ],\n });\n\n if (isCancel(selected)) {\n return null;\n }\n\n const meta = PROJECT_METADATA.find((m) => m.name === selected);\n if (!meta) {\n logger.error(`Unknown selection: ${String(selected)}`);\n process.exit(1);\n }\n return meta;\n}\n\nexport function resolveCreateProjectDirectory(params: {\n projectDirectory?: string;\n stdinIsTTY?: boolean;\n}): string | undefined {\n const { projectDirectory, stdinIsTTY = process.stdin.isTTY } = params;\n\n if (projectDirectory) return projectDirectory;\n if (!stdinIsTTY) return DEFAULT_PROJECT_DIRECTORY;\n return undefined;\n}\n\nexport const DEFAULT_PROJECT_DIRECTORY = \"my-aui-app\";\n\nexport const projectNamePromptOptions = {\n message: \"Project name:\",\n placeholder: DEFAULT_PROJECT_DIRECTORY,\n defaultValue: DEFAULT_PROJECT_DIRECTORY,\n validate: (value?: string) => {\n // Enter on an untouched prompt is how clack accepts `defaultValue`, and it\n // validates before finalize substitutes it, so an empty value has to pass\n // here or the default is unreachable.\n if (value === undefined || value === \"\") return undefined;\n const name = value.trim();\n if (!name) return \"Project name cannot be empty\";\n if (name === \".\" || name === \"..\") return \"Project name cannot be . or ..\";\n if (name.includes(\"/\") || name.includes(\"\\\\\"))\n return \"Project name cannot contain path separators\";\n return undefined;\n },\n};\n\nexport function resolveProjectDirectoryGuidance(params: {\n absoluteProjectDir: string;\n cwd?: string;\n platform?: NodeJS.Platform;\n}): { display: string; cdCommand: string } {\n const {\n absoluteProjectDir,\n cwd = process.cwd(),\n platform = process.platform,\n } = params;\n const isWindows = platform === \"win32\";\n const pathApi = isWindows ? path.win32 : path.posix;\n\n const relative = pathApi.relative(cwd, absoluteProjectDir);\n const escapesCwd =\n relative === \"..\" || relative.startsWith(`..${pathApi.sep}`);\n const display =\n relative && !escapesCwd && !pathApi.isAbsolute(relative)\n ? relative\n : absoluteProjectDir;\n\n const target = display.startsWith(\"-\")\n ? `.${pathApi.sep}${display}`\n : display;\n // Neither Windows shell has a literal quoting form the other accepts: cmd\n // reads single quotes as part of the name, and double quotes still expand\n // %VAR% there and $var in PowerShell.\n const quoted = (isWindows ? /^[\\w@.:/\\\\+-]+$/ : /^[\\w@./+-]+$/).test(target)\n ? target\n : isWindows\n ? `\"${target}\"`\n : `'${target.replaceAll(\"'\", \"'\\\\''\")}'`;\n\n return { display, cdCommand: `cd ${quoted}` };\n}\n\nconst PLAYGROUND_PRESET_BASE_URL =\n \"https://www.assistant-ui.com/playground/init\";\n\nexport function resolvePresetUrl(preset: string): string {\n if (preset.startsWith(\"http://\") || preset.startsWith(\"https://\")) {\n return preset;\n }\n return `${PLAYGROUND_PRESET_BASE_URL}?preset=${encodeURIComponent(preset)}`;\n}\n\nexport interface ScaffoldSelectorOptions {\n template?: string;\n example?: string;\n preset?: string;\n native?: boolean;\n ink?: boolean;\n}\n\nexport interface ResolvedScaffoldSelector {\n template?: string;\n example?: string;\n preset?: string;\n}\n\nconst scaffoldSelectorHelp =\n \"Choose one scaffold selector: --template <name>, --example <name>, --native, or --ink. --preset <name-or-url> can be used with --template or by itself.\";\n\nfunction getPresetConflict(opts: ScaffoldSelectorOptions): string | undefined {\n if (opts.example !== undefined) return \"--example\";\n if (opts.native) return \"--native\";\n if (opts.ink) return \"--ink\";\n return undefined;\n}\n\nexport function resolveScaffoldSelector(\n opts: ScaffoldSelectorOptions,\n): ResolvedScaffoldSelector {\n const hasPreset = opts.preset !== undefined;\n const presetConflict = getPresetConflict(opts);\n const selectors = [\n opts.template !== undefined ? \"--template\" : undefined,\n opts.example !== undefined ? \"--example\" : undefined,\n opts.native ? \"--native\" : undefined,\n opts.ink ? \"--ink\" : undefined,\n ].filter((selector): selector is string => selector !== undefined);\n\n if (selectors.length > 1) {\n throw new Error(\n `Only one scaffold selector can be provided (${selectors.join(\", \")}). ${scaffoldSelectorHelp}`,\n );\n }\n\n if (hasPreset && presetConflict) {\n throw new Error(\n `Cannot use --preset with ${presetConflict}. ${scaffoldSelectorHelp}`,\n );\n }\n\n if (opts.native) return { example: \"with-expo\" };\n if (opts.ink) return { example: \"with-react-ink\" };\n\n if (opts.preset !== undefined && opts.template === undefined) {\n return { template: \"default\", preset: opts.preset };\n }\n\n return {\n ...(opts.template !== undefined && { template: opts.template }),\n ...(opts.example !== undefined && { example: opts.example }),\n ...(hasPreset && { preset: opts.preset }),\n };\n}\n\nexport const create = new Command()\n .name(\"create\")\n .description(\"create a new project\")\n .argument(\"[project-directory]\")\n .usage(`${chalk.green(\"[project-directory]\")} [options]`)\n .option(\n \"-t, --template <template>\",\n `template to use (${templateNames.join(\", \")})`,\n )\n .option(\n \"-e, --example <example>\",\n `create from an example (${exampleNames.join(\", \")})`,\n )\n .option(\n \"-p, --preset <name-or-url>\",\n \"preset name or URL (e.g., chatgpt or https://www.assistant-ui.com/playground/init?preset=chatgpt)\",\n )\n .option(\"--use-npm\", \"explicitly use npm\")\n .option(\"--use-pnpm\", \"explicitly use pnpm\")\n .option(\"--use-yarn\", \"explicitly use yarn\")\n .option(\"--use-bun\", \"explicitly use bun\")\n .option(\"--native\", \"create an Expo / React Native project\")\n .option(\"--ink\", \"create a React Ink terminal project\")\n .option(\"--skip-install\", \"skip installing packages\")\n .option(\"--skills\", \"add assistant-ui agent skills for AI coding assistants\")\n .option(\"--no-skills\", \"skip adding assistant-ui agent skills\")\n .addOption(\n new Option(\n \"--cwd <cwd>\",\n \"the working directory. defaults to the current directory.\",\n ).hideHelp(),\n )\n .addOption(\n new Option(\n \"--debug-source-root <path>\",\n \"copy templates/examples from a local assistant-ui repo root\",\n ).hideHelp(),\n )\n .action(async (projectDirectory, opts) => {\n let scaffoldSelector: ResolvedScaffoldSelector;\n try {\n scaffoldSelector = resolveScaffoldSelector(opts);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n logger.error(message);\n process.exit(1);\n }\n\n const localSourceRoot = opts.debugSourceRoot\n ? path.resolve(opts.debugSourceRoot)\n : undefined;\n\n // Start release ref resolution early (runs during user prompts)\n const refPromise = localSourceRoot\n ? Promise.resolve(undefined)\n : resolveLatestReleaseRef();\n\n // 1. Resolve project directory\n let resolvedProjectDirectory = resolveCreateProjectDirectory({\n projectDirectory,\n });\n\n if (!resolvedProjectDirectory) {\n const result = await p.text(projectNamePromptOptions);\n\n if (p.isCancel(result)) {\n p.cancel(\"Project creation cancelled.\");\n process.exit(0);\n }\n\n resolvedProjectDirectory = result;\n }\n\n // Check directory\n const absoluteProjectDir = path.resolve(\n opts.cwd ?? process.cwd(),\n resolvedProjectDirectory,\n );\n const { display: displayProjectDir, cdCommand } =\n resolveProjectDirectoryGuidance({ absoluteProjectDir });\n let projectDirExisted = true;\n try {\n const files = fs.readdirSync(absoluteProjectDir);\n if (files.length > 0) {\n logger.error(\n `Directory ${displayProjectDir} already exists and is not empty`,\n );\n process.exit(1);\n }\n } catch (err: unknown) {\n const code =\n err instanceof Error ? (err as NodeJS.ErrnoException).code : undefined;\n if (code === \"ENOENT\") {\n // Directory doesn't exist — good, proceed\n projectDirExisted = false;\n } else if (code === \"ENOTDIR\") {\n logger.error(\n `${displayProjectDir} already exists and is not a directory`,\n );\n process.exit(1);\n } else {\n const message = err instanceof Error ? err.message : String(err);\n logger.error(`Cannot access ${displayProjectDir}: ${message}`);\n process.exit(1);\n }\n }\n\n // 2. Resolve scaffold target\n const project = await resolveProject(scaffoldSelector);\n if (!project) {\n p.cancel(\"Project creation cancelled.\");\n process.exit(0);\n }\n\n const stdinIsTTY = process.stdin.isTTY;\n let installSkills = resolveSkillsInstall({\n skills: opts.skills,\n stdinIsTTY,\n });\n if (installSkills === undefined) {\n const result = await p.confirm({\n message: \"Add assistant-ui agent skills for AI coding assistants?\",\n initialValue: true,\n });\n\n if (p.isCancel(result)) {\n p.cancel(\"Project creation cancelled.\");\n process.exit(0);\n }\n\n installSkills = result;\n }\n\n logger.info(`Creating project from ${project.category}: ${project.label}`);\n logger.break();\n\n const pm = await resolvePackageManagerForCwd(\n path.dirname(absoluteProjectDir),\n resolvePackageManager(opts),\n );\n\n // Clean up partial project directory on unexpected exit (e.g. Ctrl+C)\n const resetProjectDir = () => {\n if (!projectDirExisted) {\n fs.rmSync(absoluteProjectDir, { recursive: true, force: true });\n return;\n }\n if (!fs.existsSync(absoluteProjectDir)) return;\n for (const entry of fs.readdirSync(absoluteProjectDir)) {\n fs.rmSync(path.join(absoluteProjectDir, entry), {\n recursive: true,\n force: true,\n });\n }\n };\n let cleanupArmed = true;\n const cleanupOnExit = () => {\n if (!cleanupArmed) return;\n cleanupArmed = false;\n resetProjectDir();\n };\n const disarmCleanup = () => {\n cleanupArmed = false;\n process.removeListener(\"exit\", cleanupOnExit);\n process.removeListener(\"SIGINT\", cleanupOnSignal);\n process.removeListener(\"SIGTERM\", cleanupOnSignal);\n };\n // Node emits no \"exit\" when a signal kills the process. An in-flight\n // runSpawn forwards the signal itself, so cleanup runs on the error path\n // once the child is reaped rather than while it is still writing.\n const cleanupOnSignal = (signal: NodeJS.Signals) => {\n if (hasActiveSpawn()) return;\n cleanupPendingProjectDownloads();\n cleanupOnExit();\n disarmCleanup();\n process.kill(process.pid, signal);\n };\n\n process.once(\"exit\", cleanupOnExit);\n process.on(\"SIGINT\", cleanupOnSignal);\n process.on(\"SIGTERM\", cleanupOnSignal);\n\n try {\n // 3. Resolve latest release ref (started before prompts)\n if (!localSourceRoot) {\n logger.step(\"Resolving latest release...\");\n }\n const ref = await refPromise;\n if (!localSourceRoot && !ref) {\n logger.warn(\"Could not resolve latest release, downloading from HEAD\");\n }\n\n // 4. Scaffold project\n logger.step(\n localSourceRoot\n ? `Copying project from local source: ${localSourceRoot}`\n : \"Downloading project...\",\n );\n let transformResult: TransformResult;\n try {\n const source = localSourceRoot\n ? { kind: \"local\" as const, rootDir: localSourceRoot }\n : {\n kind: \"github\" as const,\n ref,\n };\n await scaffoldProject(project.path, absoluteProjectDir, source);\n\n // If the template didn't exist at the release tag, retry from HEAD\n if (\n !localSourceRoot &&\n ref &&\n !fs.existsSync(path.join(absoluteProjectDir, \"package.json\"))\n ) {\n resetProjectDir();\n logger.warn(\n \"Template not found at release tag, downloading from HEAD\",\n );\n await downloadProject(project.path, absoluteProjectDir);\n }\n\n // 5. Run transform pipeline\n transformResult = await transformProject(absoluteProjectDir, {\n hasLocalComponents: project.hasLocalComponents,\n skipInstall: opts.skipInstall,\n packageManager: pm,\n });\n\n if (installSkills) {\n logger.step(\"Adding assistant-ui agent skills...\");\n const [skillsCmd, skillsArgs] = buildSkillsAddCommand(pm, {\n stdinIsTTY,\n });\n try {\n await runSpawn(skillsCmd, skillsArgs, absoluteProjectDir);\n } catch (error) {\n if (error instanceof SpawnSignalError) throw error;\n logger.warn(\n `Could not add assistant-ui agent skills. You can add them later with:\\n ${skillsCmd} ${skillsArgs.join(\" \")}`,\n );\n }\n }\n } catch (err) {\n // Clean up partially created project directory\n cleanupOnExit();\n disarmCleanup();\n throw err;\n }\n\n if (transformResult.registryInstallFailure) {\n disarmCleanup();\n logger.break();\n logger.error(\"Project created with missing components.\");\n logger.info(\"Retry the component install with:\");\n logger.info(` ${cdCommand}`);\n logger.info(` ${transformResult.registryInstallFailure.retryCommand}`);\n process.exit(1);\n }\n\n // 6. Apply preset if provided\n if (scaffoldSelector.preset) {\n const presetUrl = resolvePresetUrl(scaffoldSelector.preset);\n logger.info(\"Applying preset configuration...\");\n logger.break();\n const [dlxCmd, dlxArgs] = dlxCommand(pm);\n try {\n await runSpawn(\n dlxCmd,\n [\n ...dlxArgs,\n \"shadcn@latest\",\n \"add\",\n \"--yes\",\n \"--overwrite\",\n presetUrl,\n ],\n absoluteProjectDir,\n );\n } catch (error) {\n if (error instanceof SpawnSignalError) throw error;\n logger.warn(\n `Preset application failed. You can retry manually with:\\n ${dlxCmd} ${[...dlxArgs, \"shadcn@latest\", \"add\", presetUrl].join(\" \")}`,\n );\n }\n }\n\n disarmCleanup();\n\n logger.break();\n logger.success(\"Project created successfully!\");\n logger.break();\n const runCmd = pm === \"npm\" ? \"npm run\" : pm;\n let devScript = \"dev\";\n let envFile = \".env.local\";\n try {\n const scaffoldedPkg = JSON.parse(\n fs.readFileSync(\n path.join(absoluteProjectDir, \"package.json\"),\n \"utf-8\",\n ),\n );\n devScript = scaffoldedPkg.scripts?.dev\n ? \"dev\"\n : scaffoldedPkg.scripts?.start\n ? \"start\"\n : \"dev\";\n envFile = scaffoldedPkg.dependencies?.next ? \".env.local\" : \".env\";\n } catch {\n // Fall back to defaults if package.json cannot be read\n }\n\n logger.info(\"Next steps:\");\n logger.info(` ${cdCommand}`);\n if (opts.skipInstall) {\n logger.info(` ${pm} install`);\n if (transformResult.registryInstallCommand) {\n logger.info(` ${transformResult.registryInstallCommand}`);\n }\n }\n logger.info(` # Set up your environment variables in ${envFile}`);\n logger.info(` ${runCmd} ${devScript}`);\n } catch (error) {\n if (error instanceof SpawnSignalError) {\n cleanupOnExit();\n disarmCleanup();\n throw error;\n }\n if (error instanceof SpawnExitError) {\n logger.error(`Project creation failed with code ${error.code}`);\n process.exit(error.code);\n }\n const message = error instanceof Error ? error.message : String(error);\n logger.error(`Failed to create project: ${message}`);\n process.exit(1);\n }\n });\n"],"mappings":";;;;;;;;;;;AAqCA,MAAa,mBAAsC;CAEjD;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CAEA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;AACF;AASA,MAAM,gBAAgB,iBAAiB,QACpC,MAAM,EAAE,aAAa,UACxB,CAAC,CAAC,KAAK,MAAM,EAAE,IAAI;AAEnB,MAAM,eAAe,iBAAi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"}
@@ -6,8 +6,8 @@ import * as fs$1 from "node:fs";
6
6
  import * as path$1 from "node:path";
7
7
  import * as os$1 from "node:os";
8
8
  import { detect } from "detect-package-manager";
9
- import { satisfies } from "semver";
10
9
  import { spawnSync } from "node:child_process";
10
+ import { satisfies } from "semver";
11
11
  //#region src/commands/info.ts
12
12
  const ASSISTANT_UI_PACKAGES = [
13
13
  "@assistant-ui/react",
@@ -1,7 +1,7 @@
1
1
  import { type PackageManagerName } from "./utils/package-manager.js";
2
2
  export declare const SKILLS_PACKAGE = "assistant-ui/skills";
3
- export declare const SKILLS_COMMIT = "4007601e2e16762060f02d45ad82f453eed5409a";
4
- export declare const SKILLS_PLUGIN_SOURCE = "gh:assistant-ui/skills/assistant-ui#4007601e2e16762060f02d45ad82f453eed5409a";
3
+ export declare const SKILLS_COMMIT = "139674dc888ee076982b6726e8e6f5d0fe0b5f67";
4
+ export declare const SKILLS_PLUGIN_SOURCE = "gh:assistant-ui/skills/assistant-ui#139674dc888ee076982b6726e8e6f5d0fe0b5f67";
5
5
  export declare function resolveSkillsInstall(params: {
6
6
  skills?: boolean;
7
7
  stdinIsTTY?: boolean;
@@ -5,7 +5,7 @@ import os from "node:os";
5
5
  import { downloadTemplate } from "giget";
6
6
  //#region src/lib/agent-skill.ts
7
7
  const SKILLS_PACKAGE = "assistant-ui/skills";
8
- const SKILLS_COMMIT = "4007601e2e16762060f02d45ad82f453eed5409a";
8
+ const SKILLS_COMMIT = "139674dc888ee076982b6726e8e6f5d0fe0b5f67";
9
9
  const SKILLS_PLUGIN_SOURCE = `gh:${SKILLS_PACKAGE}/assistant-ui#${SKILLS_COMMIT}`;
10
10
  function resolveSkillsInstall(params) {
11
11
  const { skills, stdinIsTTY = process.stdin.isTTY } = params;