assistant-ui 0.0.96 → 0.0.98

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.
@@ -1 +1 @@
1
- {"version":3,"file":"create.d.ts","names":[],"sources":["../../src/commands/create.ts"],"mappings":";;;;UAiBiB,eAAA;EACf,IAAA;EACA,KAAA;EACA,WAAA;EACA,QAAA;EACA,IAAA;EACA,kBAAA;AAAA;AAAA,cAGW,gBAAA,EAAkB,eAAe;AAAA,iBAsOxB,cAAA,CAAe,MAAA;EACnC,QAAA;EACA,OAAA;EACA,UAAA;EACA,MAAA,UAAgB,CAAA,CAAE,MAAA;EAClB,QAAA,UAAkB,CAAA,CAAE,QAAA;AAAA,IAClB,OAAA,CAAQ,eAAA;AAAA,iBA2EI,6BAAA,CAA8B,MAAA;EAC5C,gBAAA;EACA,UAAA;AAAA;AAAA,iBAYc,gBAAA,CAAiB,MAAc;AAAA,UAO9B,uBAAA;EACf,QAAA;EACA,OAAA;EACA,MAAA;EACA,MAAA;EACA,GAAA;AAAA;AAAA,UAGe,wBAAA;EACf,QAAA;EACA,OAAA;EACA,MAAA;AAAA;AAAA,iBAac,uBAAA,CACd,IAAA,EAAM,uBAAA,GACL,wBAAwB;AAAA,cAoCd,MAAA,EAAM,OAmPf"}
1
+ {"version":3,"file":"create.d.ts","names":[],"sources":["../../src/commands/create.ts"],"mappings":";;;;UAqBiB,eAAA;EACf,IAAA;EACA,KAAA;EACA,WAAA;EACA,QAAA;EACA,IAAA;EACA,kBAAA;AAAA;AAAA,cAGW,gBAAA,EAAkB,eAAe;AAAA,iBAsOxB,cAAA,CAAe,MAAA;EACnC,QAAA;EACA,OAAA;EACA,UAAA;EACA,MAAA,UAAgB,CAAA,CAAE,MAAA;EAClB,QAAA,UAAkB,CAAA,CAAE,QAAA;AAAA,IAClB,OAAA,CAAQ,eAAA;AAAA,iBA2EI,6BAAA,CAA8B,MAAA;EAC5C,gBAAA;EACA,UAAA;AAAA;AAAA,iBAYc,gBAAA,CAAiB,MAAc;AAAA,UAO9B,uBAAA;EACf,QAAA;EACA,OAAA;EACA,MAAA;EACA,MAAA;EACA,GAAA;AAAA;AAAA,UAGe,wBAAA;EACf,QAAA;EACA,OAAA;EACA,MAAA;AAAA;AAAA,iBAac,uBAAA,CACd,IAAA,EAAM,uBAAA,GACL,wBAAwB;AAAA,cAoCd,MAAA,EAAM,OAsRf"}
@@ -1,6 +1,7 @@
1
1
  import { logger } from "../lib/utils/logger.js";
2
2
  import { SpawnExitError, runSpawn } from "../lib/run-spawn.js";
3
3
  import { dlxCommand, downloadProject, resolveLatestReleaseRef, resolvePackageManager, resolvePackageManagerForCwd, scaffoldProject, transformProject } from "../lib/create-project.js";
4
+ import { buildSkillsAddCommand, resolveSkillsInstall } from "../lib/agent-skill.js";
4
5
  import { Command, Option } from "commander";
5
6
  import chalk from "chalk";
6
7
  import fs from "node:fs";
@@ -312,7 +313,7 @@ function resolveScaffoldSelector(opts) {
312
313
  ...hasPreset && { preset: opts.preset }
313
314
  };
314
315
  }
315
- const create = new Command().name("create").description("create a new project").argument("[project-directory]").usage(`${chalk.green("[project-directory]")} [options]`).option("-t, --template <template>", `template to use (${templateNames.join(", ")})`).option("-e, --example <example>", `create from an example (${exampleNames.join(", ")})`).option("-p, --preset <name-or-url>", "preset name or URL (e.g., chatgpt or https://www.assistant-ui.com/playground/init?preset=chatgpt)").option("--use-npm", "explicitly use npm").option("--use-pnpm", "explicitly use pnpm").option("--use-yarn", "explicitly use yarn").option("--use-bun", "explicitly use bun").option("--native", "create an Expo / React Native project").option("--ink", "create a React Ink terminal project").option("--skip-install", "skip installing packages").addOption(new Option("--debug-source-root <path>", "copy templates/examples from a local assistant-ui repo root").hideHelp()).action(async (projectDirectory, opts) => {
316
+ const create = new Command().name("create").description("create a new project").argument("[project-directory]").usage(`${chalk.green("[project-directory]")} [options]`).option("-t, --template <template>", `template to use (${templateNames.join(", ")})`).option("-e, --example <example>", `create from an example (${exampleNames.join(", ")})`).option("-p, --preset <name-or-url>", "preset name or URL (e.g., chatgpt or https://www.assistant-ui.com/playground/init?preset=chatgpt)").option("--use-npm", "explicitly use npm").option("--use-pnpm", "explicitly use pnpm").option("--use-yarn", "explicitly use yarn").option("--use-bun", "explicitly use bun").option("--native", "create an Expo / React Native project").option("--ink", "create a React Ink terminal project").option("--skip-install", "skip installing packages").option("--skills", "add assistant-ui agent skills for AI coding assistants").option("--no-skills", "skip adding assistant-ui agent skills").addOption(new Option("--debug-source-root <path>", "copy templates/examples from a local assistant-ui repo root").hideHelp()).action(async (projectDirectory, opts) => {
316
317
  let scaffoldSelector;
317
318
  try {
318
319
  scaffoldSelector = resolveScaffoldSelector(opts);
@@ -364,6 +365,22 @@ const create = new Command().name("create").description("create a new project").
364
365
  p.cancel("Project creation cancelled.");
365
366
  process.exit(0);
366
367
  }
368
+ const stdinIsTTY = process.stdin.isTTY;
369
+ let installSkills = resolveSkillsInstall({
370
+ skills: opts.skills,
371
+ stdinIsTTY
372
+ });
373
+ if (installSkills === void 0) {
374
+ const result = await p.confirm({
375
+ message: "Add assistant-ui agent skills for AI coding assistants?",
376
+ initialValue: true
377
+ });
378
+ if (p.isCancel(result)) {
379
+ p.cancel("Project creation cancelled.");
380
+ process.exit(0);
381
+ }
382
+ installSkills = result;
383
+ }
367
384
  logger.info(`Creating project from ${project.category}: ${project.label}`);
368
385
  logger.break();
369
386
  const pm = await resolvePackageManagerForCwd(path.dirname(absoluteProjectDir), resolvePackageManager(opts));
@@ -401,6 +418,15 @@ const create = new Command().name("create").description("create a new project").
401
418
  skipInstall: opts.skipInstall,
402
419
  packageManager: pm
403
420
  });
421
+ if (installSkills) {
422
+ logger.step("Adding assistant-ui agent skills...");
423
+ const [skillsCmd, skillsArgs] = buildSkillsAddCommand(pm, { stdinIsTTY });
424
+ try {
425
+ await runSpawn(skillsCmd, skillsArgs, absoluteProjectDir);
426
+ } catch {
427
+ logger.warn(`Could not add assistant-ui agent skills. You can add them later with:\n ${skillsCmd} ${skillsArgs.join(" ")}`);
428
+ }
429
+ }
404
430
  } catch (err) {
405
431
  fs.rmSync(absoluteProjectDir, {
406
432
  recursive: true,
@@ -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 dlxCommand,\n downloadProject,\n resolveLatestReleaseRef,\n resolvePackageManager,\n resolvePackageManagerForCwd,\n scaffoldProject,\n transformProject,\n} from \"../lib/create-project\";\nimport { runSpawn, SpawnExitError } from \"../lib/run-spawn\";\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: \"langgraph\",\n label: \"LangGraph\",\n description: \"LangGraph starter template\",\n category: \"template\",\n path: \"templates/langgraph\",\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 // 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-v6\",\n label: \"AI SDK v6\",\n description: \"Vercel AI SDK v6\",\n category: \"example\",\n path: \"examples/with-ai-sdk-v6\",\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: true,\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: true,\n },\n {\n name: \"with-expo\",\n label: \"Expo\",\n description: \"Expo / React Native\",\n category: \"example\",\n path: \"examples/with-expo\",\n hasLocalComponents: true,\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: true,\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\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-cloud-standalone: For cloud without assistant-ui — not for the\n// assistant-ui CLI.\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 \"my-aui-app\";\n return undefined;\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 .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({\n message: \"Project name:\",\n placeholder: \"my-aui-app\",\n defaultValue: \"my-aui-app\",\n validate: (value?: string) => {\n const name = (value ?? \"\").trim();\n if (!name) return \"Project name cannot be empty\";\n if (name === \".\" || name === \"..\")\n 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\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(resolvedProjectDirectory);\n try {\n const files = fs.readdirSync(absoluteProjectDir);\n if (files.length > 0) {\n logger.error(\n `Directory ${resolvedProjectDirectory} 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 } else if (code === \"ENOTDIR\") {\n logger.error(\n `${resolvedProjectDirectory} 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 ${resolvedProjectDirectory}: ${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 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 cleanupOnExit = () => {\n fs.rmSync(absoluteProjectDir, { recursive: true, force: true });\n };\n process.once(\"exit\", cleanupOnExit);\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 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 fs.rmSync(absoluteProjectDir, { recursive: true, force: true });\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 await transformProject(absoluteProjectDir, {\n hasLocalComponents: project.hasLocalComponents,\n skipInstall: opts.skipInstall,\n packageManager: pm,\n });\n } catch (err) {\n // Clean up partially created project directory\n fs.rmSync(absoluteProjectDir, { recursive: true, force: true });\n throw err;\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 {\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 process.removeListener(\"exit\", cleanupOnExit);\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(` cd ${resolvedProjectDirectory}`);\n if (opts.skipInstall) {\n logger.info(` ${pm} install`);\n }\n logger.info(` # Set up your environment variables in ${envFile}`);\n logger.info(` ${runCmd} ${devScript}`);\n } catch (error) {\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":";;;;;;;;;AA0BA,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;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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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 dlxCommand,\n downloadProject,\n resolveLatestReleaseRef,\n resolvePackageManager,\n resolvePackageManagerForCwd,\n scaffoldProject,\n transformProject,\n} from \"../lib/create-project\";\nimport { runSpawn, SpawnExitError } from \"../lib/run-spawn\";\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: \"langgraph\",\n label: \"LangGraph\",\n description: \"LangGraph starter template\",\n category: \"template\",\n path: \"templates/langgraph\",\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 // 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-v6\",\n label: \"AI SDK v6\",\n description: \"Vercel AI SDK v6\",\n category: \"example\",\n path: \"examples/with-ai-sdk-v6\",\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: true,\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: true,\n },\n {\n name: \"with-expo\",\n label: \"Expo\",\n description: \"Expo / React Native\",\n category: \"example\",\n path: \"examples/with-expo\",\n hasLocalComponents: true,\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: true,\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\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-cloud-standalone: For cloud without assistant-ui — not for the\n// assistant-ui CLI.\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 \"my-aui-app\";\n return undefined;\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 \"--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({\n message: \"Project name:\",\n placeholder: \"my-aui-app\",\n defaultValue: \"my-aui-app\",\n validate: (value?: string) => {\n const name = (value ?? \"\").trim();\n if (!name) return \"Project name cannot be empty\";\n if (name === \".\" || name === \"..\")\n 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\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(resolvedProjectDirectory);\n try {\n const files = fs.readdirSync(absoluteProjectDir);\n if (files.length > 0) {\n logger.error(\n `Directory ${resolvedProjectDirectory} 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 } else if (code === \"ENOTDIR\") {\n logger.error(\n `${resolvedProjectDirectory} 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 ${resolvedProjectDirectory}: ${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 cleanupOnExit = () => {\n fs.rmSync(absoluteProjectDir, { recursive: true, force: true });\n };\n process.once(\"exit\", cleanupOnExit);\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 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 fs.rmSync(absoluteProjectDir, { recursive: true, force: true });\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 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 {\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 fs.rmSync(absoluteProjectDir, { recursive: true, force: true });\n throw err;\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 {\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 process.removeListener(\"exit\", cleanupOnExit);\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(` cd ${resolvedProjectDirectory}`);\n if (opts.skipInstall) {\n logger.info(` ${pm} install`);\n }\n logger.info(` # Set up your environment variables in ${envFile}`);\n logger.info(` ${runCmd} ${devScript}`);\n } catch (error) {\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":";;;;;;;;;;AA8BA,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;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;CAC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"}
@@ -0,0 +1,14 @@
1
+ import { PackageManagerName } from "./create-project.js";
2
+
3
+ //#region src/lib/agent-skill.d.ts
4
+ declare const SKILLS_PACKAGE = "assistant-ui/skills";
5
+ declare function resolveSkillsInstall(params: {
6
+ skills?: boolean;
7
+ stdinIsTTY?: boolean;
8
+ }): boolean | undefined;
9
+ declare function buildSkillsAddCommand(pm: PackageManagerName, params?: {
10
+ stdinIsTTY?: boolean;
11
+ }): [string, string[]];
12
+ //#endregion
13
+ export { SKILLS_PACKAGE, buildSkillsAddCommand, resolveSkillsInstall };
14
+ //# sourceMappingURL=agent-skill.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-skill.d.ts","names":[],"sources":["../../src/lib/agent-skill.ts"],"mappings":";;;cAEa,cAAA;AAAA,iBAEG,oBAAA,CAAqB,MAAA;EACnC,MAAA;EACA,UAAA;AAAA;AAAA,iBAQc,qBAAA,CACd,EAAA,EAAI,kBAAkB,EACtB,MAAA;EAAU,UAAA;AAAA"}
@@ -0,0 +1,24 @@
1
+ import { dlxCommand } from "./create-project.js";
2
+ //#region src/lib/agent-skill.ts
3
+ const SKILLS_PACKAGE = "assistant-ui/skills";
4
+ function resolveSkillsInstall(params) {
5
+ const { skills, stdinIsTTY = process.stdin.isTTY } = params;
6
+ if (skills !== void 0) return skills;
7
+ if (!stdinIsTTY) return true;
8
+ }
9
+ function buildSkillsAddCommand(pm, params = {}) {
10
+ const { stdinIsTTY = process.stdin.isTTY } = params;
11
+ const [command, dlxArgs] = dlxCommand(pm);
12
+ const args = [
13
+ ...dlxArgs,
14
+ "skills",
15
+ "add",
16
+ SKILLS_PACKAGE
17
+ ];
18
+ if (!stdinIsTTY) args.push("--yes");
19
+ return [command, args];
20
+ }
21
+ //#endregion
22
+ export { SKILLS_PACKAGE, buildSkillsAddCommand, resolveSkillsInstall };
23
+
24
+ //# sourceMappingURL=agent-skill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-skill.js","names":[],"sources":["../../src/lib/agent-skill.ts"],"sourcesContent":["import { dlxCommand, type PackageManagerName } from \"./create-project\";\n\nexport const SKILLS_PACKAGE = \"assistant-ui/skills\";\n\nexport function resolveSkillsInstall(params: {\n skills?: boolean;\n stdinIsTTY?: boolean;\n}): boolean | undefined {\n const { skills, stdinIsTTY = process.stdin.isTTY } = params;\n if (skills !== undefined) return skills;\n if (!stdinIsTTY) return true;\n return undefined;\n}\n\nexport function buildSkillsAddCommand(\n pm: PackageManagerName,\n params: { stdinIsTTY?: boolean } = {},\n): [string, string[]] {\n const { stdinIsTTY = process.stdin.isTTY } = params;\n const [command, dlxArgs] = dlxCommand(pm);\n const args = [...dlxArgs, \"skills\", \"add\", SKILLS_PACKAGE];\n\n // Without a TTY the skills CLI cannot prompt for agent platforms, so skip its\n // confirmation; with a TTY it owns the platform selection interactively.\n if (!stdinIsTTY) args.push(\"--yes\");\n\n return [command, args];\n}\n"],"mappings":";;AAEA,MAAa,iBAAiB;AAE9B,SAAgB,qBAAqB,QAGb;CACtB,MAAM,EAAE,QAAQ,aAAa,QAAQ,MAAM,UAAU;CACrD,IAAI,WAAW,KAAA,GAAW,OAAO;CACjC,IAAI,CAAC,YAAY,OAAO;AAE1B;AAEA,SAAgB,sBACd,IACA,SAAmC,CAAC,GAChB;CACpB,MAAM,EAAE,aAAa,QAAQ,MAAM,UAAU;CAC7C,MAAM,CAAC,SAAS,WAAW,WAAW,EAAE;CACxC,MAAM,OAAO;EAAC,GAAG;EAAS;EAAU;EAAO;CAAc;CAIzD,IAAI,CAAC,YAAY,KAAK,KAAK,OAAO;CAElC,OAAO,CAAC,SAAS,IAAI;AACvB"}
@@ -120,13 +120,10 @@ async function transformProject(projectDir, opts) {
120
120
  }
121
121
  if (!opts.hasLocalComponents && shadcnUI && assistantUI) {
122
122
  const allShadcn = shadcnUI.includes("utils") ? shadcnUI : [...shadcnUI, "utils"];
123
- logger.step(`Installing shadcn UI components: ${allShadcn.join(", ")}...`);
124
- await installShadcnRegistry(projectDir, allShadcn, "shadcn components", pm);
125
- if (assistantUI.length > 0) {
126
- const auiComponents = assistantUI.map((c) => `@assistant-ui/${c}`);
127
- logger.step(`Installing assistant-ui components: ${assistantUI.join(", ")}...`);
128
- await installShadcnRegistry(projectDir, auiComponents, "components", pm);
129
- }
123
+ const auiComponents = assistantUI.map((c) => `@assistant-ui/${c}`);
124
+ const components = [...allShadcn, ...auiComponents];
125
+ logger.step(`Installing components: ${components.join(", ")}...`);
126
+ await installShadcnRegistry(projectDir, components, "components", pm);
130
127
  }
131
128
  }
132
129
  function transformPackageJson(projectDir) {
@@ -1 +1 @@
1
- {"version":3,"file":"create-project.js","names":["path","fs","globSync"],"sources":["../../src/lib/create-project.ts"],"sourcesContent":["import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { downloadTemplate } from \"giget\";\nimport { sync as globSync } from \"glob\";\nimport { detect } from \"detect-package-manager\";\nimport { logger } from \"./utils/logger\";\nimport { runSpawn, SpawnExitError } from \"./run-spawn\";\n\nexport type PackageManagerName = \"npm\" | \"pnpm\" | \"yarn\" | \"bun\";\n\nexport function dlxCommand(pm: PackageManagerName): [string, string[]] {\n switch (pm) {\n case \"pnpm\":\n return [\"pnpm\", [\"dlx\"]];\n case \"yarn\":\n return [\"yarn\", [\"dlx\"]];\n case \"bun\":\n return [\"bunx\", []];\n case \"npm\":\n return [\"npx\", [\"--yes\"]];\n }\n}\n\nexport interface TransformOptions {\n hasLocalComponents: boolean;\n skipInstall?: boolean;\n packageManager: PackageManagerName;\n}\n\nexport type ProjectSource =\n | {\n kind: \"github\";\n ref: string | undefined;\n }\n | {\n kind: \"local\";\n rootDir: string;\n };\n\nconst LOCAL_PROJECT_ARTIFACT_DIRS: readonly string[] = [\n \"node_modules\",\n \".next\",\n \"dist\",\n \"build\",\n];\n\nconst LOCAL_PROJECT_ARTIFACT_GLOB_IGNORES = LOCAL_PROJECT_ARTIFACT_DIRS.map(\n (dir) => `**/${dir}/**`,\n);\n\nexport function resolvePackageManager(opts: {\n useNpm?: boolean;\n usePnpm?: boolean;\n useYarn?: boolean;\n useBun?: boolean;\n}): PackageManagerName | undefined {\n if (opts.useNpm) return \"npm\";\n if (opts.usePnpm) return \"pnpm\";\n if (opts.useYarn) return \"yarn\";\n if (opts.useBun) return \"bun\";\n return undefined;\n}\n\nexport async function resolveLatestReleaseRef(): Promise<string | undefined> {\n try {\n const res = await fetch(\n \"https://api.github.com/repos/assistant-ui/assistant-ui/releases/latest\",\n );\n if (!res.ok) return undefined;\n const release = (await res.json()) as { tag_name: string };\n return release.tag_name || undefined;\n } catch {\n return undefined;\n }\n}\n\nconst DOWNLOAD_TIMEOUT_MS = 30_000;\n\nexport async function downloadProject(\n repoPath: string,\n destDir: string,\n ref?: string,\n): Promise<void> {\n const source = ref\n ? `gh:assistant-ui/assistant-ui/${repoPath}#${ref}`\n : `gh:assistant-ui/assistant-ui/${repoPath}`;\n\n // Suppress giget's debug output. The `debug` package (used by the upgrade\n // command) sets process.env.DEBUG at module-load time, and giget logs to\n // console.debug whenever that env var is truthy — even for unrelated\n // namespaces. Temporarily unsetting it targets the root cause.\n const origDebug = process.env.DEBUG;\n delete process.env.DEBUG;\n try {\n const downloadPromise = downloadTemplate(source, {\n dir: destDir,\n force: true,\n silent: true,\n });\n\n let timer: ReturnType<typeof setTimeout>;\n const timeoutPromise = new Promise<never>((_, reject) => {\n timer = setTimeout(\n () =>\n reject(\n new Error(\n \"Download timed out. This may be due to GitHub rate limiting or a network issue. Try again in a few minutes.\",\n ),\n ),\n DOWNLOAD_TIMEOUT_MS,\n );\n });\n\n try {\n await Promise.race([downloadPromise, timeoutPromise]);\n } finally {\n clearTimeout(timer!);\n }\n } finally {\n if (origDebug !== undefined) {\n process.env.DEBUG = origDebug;\n }\n }\n}\n\nfunction shouldCopyLocalProjectPath(src: string, projectDir: string): boolean {\n const relative = path.relative(projectDir, src);\n if (!relative) return true;\n\n const segments = relative.split(path.sep);\n return !segments.some((segment) =>\n LOCAL_PROJECT_ARTIFACT_DIRS.includes(segment),\n );\n}\n\nexport async function scaffoldProject(\n repoPath: string,\n destDir: string,\n source: ProjectSource,\n): Promise<void> {\n if (source.kind === \"github\") {\n await downloadProject(repoPath, destDir, source.ref);\n return;\n }\n\n const localProjectDir = path.resolve(source.rootDir, repoPath);\n try {\n fs.cpSync(localProjectDir, destDir, {\n recursive: true,\n force: true,\n filter: (src) => shouldCopyLocalProjectPath(src, localProjectDir),\n });\n } catch (error) {\n const code =\n error instanceof Error\n ? (error as NodeJS.ErrnoException).code\n : undefined;\n if (code === \"ENOENT\") {\n throw new Error(\n `Local project source does not exist: ${localProjectDir}`,\n );\n }\n throw error;\n }\n}\n\nfunction detectFromUserAgent(): PackageManagerName | undefined {\n const ua = process.env.npm_config_user_agent;\n if (!ua) return undefined;\n if (ua.startsWith(\"bun/\")) return \"bun\";\n if (ua.startsWith(\"pnpm/\")) return \"pnpm\";\n if (ua.startsWith(\"yarn/\")) return \"yarn\";\n if (ua.startsWith(\"npm/\")) return \"npm\";\n return undefined;\n}\n\nexport async function resolvePackageManagerForCwd(\n cwd: string,\n packageManager?: PackageManagerName,\n): Promise<PackageManagerName> {\n if (packageManager) return packageManager;\n const fromAgent = detectFromUserAgent();\n if (fromAgent) return fromAgent;\n try {\n return await detect({ cwd });\n } catch {\n return \"npm\";\n }\n}\n\nexport async function transformProject(\n projectDir: string,\n opts: TransformOptions,\n): Promise<void> {\n logger.step(\"Transforming package.json...\");\n transformPackageJson(projectDir);\n\n let assistantUI: string[] | undefined;\n let shadcnUI: string[] | undefined;\n\n if (!opts.hasLocalComponents) {\n logger.step(\"Transforming project files...\");\n\n transformTsConfig(projectDir);\n transformCssFiles(projectDir);\n\n const components = scanRequiredComponents(projectDir);\n assistantUI = components.assistantUI;\n shadcnUI = components.shadcnUI;\n }\n\n const pm = opts.packageManager;\n if (!opts.skipInstall) {\n logger.step(\"Installing dependencies...\");\n await installDependencies(projectDir, pm);\n }\n\n if (!opts.hasLocalComponents && shadcnUI && assistantUI) {\n const allShadcn = shadcnUI.includes(\"utils\")\n ? shadcnUI\n : [...shadcnUI, \"utils\"];\n logger.step(`Installing shadcn UI components: ${allShadcn.join(\", \")}...`);\n await installShadcnRegistry(projectDir, allShadcn, \"shadcn components\", pm);\n\n if (assistantUI.length > 0) {\n const auiComponents = assistantUI.map((c) => `@assistant-ui/${c}`);\n logger.step(\n `Installing assistant-ui components: ${assistantUI.join(\", \")}...`,\n );\n await installShadcnRegistry(projectDir, auiComponents, \"components\", pm);\n }\n }\n}\n\nfunction transformPackageJson(projectDir: string): void {\n const pkgPath = path.join(projectDir, \"package.json\");\n const pkg = JSON.parse(fs.readFileSync(pkgPath, \"utf-8\"));\n\n // Remove @assistant-ui/ui dependency\n if (pkg.dependencies?.[\"@assistant-ui/ui\"]) {\n delete pkg.dependencies[\"@assistant-ui/ui\"];\n }\n\n // Transform workspace dependencies to latest\n for (const depType of [\"dependencies\", \"devDependencies\"] as const) {\n const deps = pkg[depType];\n if (!deps) continue;\n\n for (const [name, version] of Object.entries(deps)) {\n if (String(version).includes(\"workspace:\")) {\n deps[name] = \"latest\";\n }\n }\n }\n\n // Remove devDependencies that are workspace-only\n if (pkg.devDependencies?.[\"@assistant-ui/x-buildutils\"]) {\n delete pkg.devDependencies[\"@assistant-ui/x-buildutils\"];\n }\n\n // Update package name to be unique\n const dirName = path.basename(projectDir);\n pkg.name = dirName;\n\n fs.writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\\n`);\n}\n\nfunction transformTsConfig(projectDir: string): void {\n const tsconfigPath = path.join(projectDir, \"tsconfig.json\");\n\n if (!fs.existsSync(tsconfigPath)) {\n return;\n }\n\n const content = fs.readFileSync(tsconfigPath, \"utf-8\");\n const tsconfig = JSON.parse(content);\n\n // Remove workspace paths\n if (tsconfig.compilerOptions?.paths) {\n delete tsconfig.compilerOptions.paths[\"@/components/assistant-ui/*\"];\n delete tsconfig.compilerOptions.paths[\"@/components/icons/*\"];\n delete tsconfig.compilerOptions.paths[\"@/components/ui/*\"];\n delete tsconfig.compilerOptions.paths[\"@/hooks/*\"];\n delete tsconfig.compilerOptions.paths[\"@/lib/utils\"];\n delete tsconfig.compilerOptions.paths[\"@assistant-ui/ui/*\"];\n\n if (Object.keys(tsconfig.compilerOptions.paths).length === 0) {\n delete tsconfig.compilerOptions.paths;\n }\n }\n\n // If extends uses @assistant-ui/x-buildutils, replace with inline config\n if (tsconfig.extends?.includes(\"@assistant-ui/x-buildutils\")) {\n const isNext = tsconfig.extends.includes(\"ts/next\");\n delete tsconfig.extends;\n\n const inlinedCompilerOptions = {\n target: \"ESNext\",\n lib: [\"dom\", \"dom.iterable\", \"ES2023\"],\n skipLibCheck: true,\n strict: true,\n noEmit: true,\n esModuleInterop: true,\n module: \"ESNext\",\n moduleResolution: \"bundler\",\n resolveJsonModule: true,\n isolatedModules: true,\n jsx: \"react-jsx\",\n ...(isNext ? { plugins: [{ name: \"next\" }] } : {}),\n };\n\n tsconfig.compilerOptions = {\n ...inlinedCompilerOptions,\n ...tsconfig.compilerOptions,\n paths: {\n \"@/*\": [\"./*\"],\n ...(tsconfig.compilerOptions?.paths || {}),\n },\n };\n }\n\n fs.writeFileSync(tsconfigPath, `${JSON.stringify(tsconfig, null, 2)}\\n`);\n}\n\nfunction transformCssFiles(projectDir: string): void {\n const cssFiles = globSync(\"**/*.css\", {\n cwd: projectDir,\n ignore: LOCAL_PROJECT_ARTIFACT_GLOB_IGNORES,\n });\n\n for (const file of cssFiles) {\n const fullPath = path.join(projectDir, file);\n try {\n const content = fs.readFileSync(fullPath, \"utf-8\");\n\n const newContent = content.replace(\n /@source\\s+[\"'][^\"']*packages\\/ui\\/src[^\"']*[\"'];\\s*\\n?/g,\n \"\",\n );\n\n if (newContent !== content) {\n fs.writeFileSync(fullPath, newContent);\n }\n } catch {\n // Ignore files that cannot be read/written\n }\n }\n}\n\ninterface RequiredComponents {\n assistantUI: string[];\n shadcnUI: string[];\n}\n\nfunction stripImportExtension(component: string): string {\n return component.replace(/\\.[cm]?[tj]sx?$/, \"\");\n}\n\nfunction scanRequiredComponents(projectDir: string): RequiredComponents {\n const files = globSync(\"**/*.{ts,tsx}\", {\n cwd: projectDir,\n ignore: LOCAL_PROJECT_ARTIFACT_GLOB_IGNORES,\n });\n\n const assistantUIComponents = new Set<string>();\n const shadcnUIComponents = new Set<string>();\n\n for (const file of files) {\n const fullPath = path.join(projectDir, file);\n try {\n const content = fs.readFileSync(fullPath, \"utf-8\");\n\n const assistantUIRegex =\n /from\\s+[\"']@\\/components\\/assistant-ui\\/([^\"']+)[\"']/g;\n for (const match of content.matchAll(assistantUIRegex)) {\n assistantUIComponents.add(stripImportExtension(match[1]!));\n }\n\n const uiRegex = /from\\s+[\"']@\\/components\\/ui\\/([^\"']+)[\"']/g;\n for (const match of content.matchAll(uiRegex)) {\n shadcnUIComponents.add(stripImportExtension(match[1]!));\n }\n } catch {\n // Ignore files that cannot be read\n }\n }\n\n return {\n assistantUI: Array.from(assistantUIComponents),\n shadcnUI: Array.from(shadcnUIComponents),\n };\n}\n\nasync function installDependencies(\n projectDir: string,\n pm: PackageManagerName,\n): Promise<void> {\n const args = pm === \"yarn\" ? [] : [\"install\"];\n try {\n await runSpawn(pm, args, projectDir);\n } catch (error) {\n if (error instanceof SpawnExitError) {\n throw new Error(`${pm} install exited with code ${error.code}`);\n }\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to install dependencies: ${message}`);\n }\n}\n\nasync function installShadcnRegistry(\n projectDir: string,\n components: string[],\n label: string,\n pm: PackageManagerName,\n): Promise<void> {\n const [cmd, dlxArgs] = dlxCommand(pm);\n // For npm, dlxArgs may already include `--yes` for npx auto-install.\n // The trailing `--yes` is for shadcn's own confirmation prompt.\n const addArgs = [...dlxArgs, \"shadcn@latest\", \"add\", ...components, \"--yes\"];\n\n try {\n await runSpawn(cmd, addArgs, projectDir);\n } catch (error) {\n if (error instanceof SpawnExitError) {\n logger.warn(\n `shadcn exited with code ${error.code}. Run the following to retry:\\n ${cmd} ${addArgs.slice(0, -1).join(\" \")}`,\n );\n return;\n }\n\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to install ${label}: ${message}`);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"create-project.js","names":["path","fs","globSync"],"sources":["../../src/lib/create-project.ts"],"sourcesContent":["import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { downloadTemplate } from \"giget\";\nimport { sync as globSync } from \"glob\";\nimport { detect } from \"detect-package-manager\";\nimport { logger } from \"./utils/logger\";\nimport { runSpawn, SpawnExitError } from \"./run-spawn\";\n\nexport type PackageManagerName = \"npm\" | \"pnpm\" | \"yarn\" | \"bun\";\n\nexport function dlxCommand(pm: PackageManagerName): [string, string[]] {\n switch (pm) {\n case \"pnpm\":\n return [\"pnpm\", [\"dlx\"]];\n case \"yarn\":\n return [\"yarn\", [\"dlx\"]];\n case \"bun\":\n return [\"bunx\", []];\n case \"npm\":\n return [\"npx\", [\"--yes\"]];\n }\n}\n\nexport interface TransformOptions {\n hasLocalComponents: boolean;\n skipInstall?: boolean;\n packageManager: PackageManagerName;\n}\n\nexport type ProjectSource =\n | {\n kind: \"github\";\n ref: string | undefined;\n }\n | {\n kind: \"local\";\n rootDir: string;\n };\n\nconst LOCAL_PROJECT_ARTIFACT_DIRS: readonly string[] = [\n \"node_modules\",\n \".next\",\n \"dist\",\n \"build\",\n];\n\nconst LOCAL_PROJECT_ARTIFACT_GLOB_IGNORES = LOCAL_PROJECT_ARTIFACT_DIRS.map(\n (dir) => `**/${dir}/**`,\n);\n\nexport function resolvePackageManager(opts: {\n useNpm?: boolean;\n usePnpm?: boolean;\n useYarn?: boolean;\n useBun?: boolean;\n}): PackageManagerName | undefined {\n if (opts.useNpm) return \"npm\";\n if (opts.usePnpm) return \"pnpm\";\n if (opts.useYarn) return \"yarn\";\n if (opts.useBun) return \"bun\";\n return undefined;\n}\n\nexport async function resolveLatestReleaseRef(): Promise<string | undefined> {\n try {\n const res = await fetch(\n \"https://api.github.com/repos/assistant-ui/assistant-ui/releases/latest\",\n );\n if (!res.ok) return undefined;\n const release = (await res.json()) as { tag_name: string };\n return release.tag_name || undefined;\n } catch {\n return undefined;\n }\n}\n\nconst DOWNLOAD_TIMEOUT_MS = 30_000;\n\nexport async function downloadProject(\n repoPath: string,\n destDir: string,\n ref?: string,\n): Promise<void> {\n const source = ref\n ? `gh:assistant-ui/assistant-ui/${repoPath}#${ref}`\n : `gh:assistant-ui/assistant-ui/${repoPath}`;\n\n // Suppress giget's debug output. The `debug` package (used by the upgrade\n // command) sets process.env.DEBUG at module-load time, and giget logs to\n // console.debug whenever that env var is truthy — even for unrelated\n // namespaces. Temporarily unsetting it targets the root cause.\n const origDebug = process.env.DEBUG;\n delete process.env.DEBUG;\n try {\n const downloadPromise = downloadTemplate(source, {\n dir: destDir,\n force: true,\n silent: true,\n });\n\n let timer: ReturnType<typeof setTimeout>;\n const timeoutPromise = new Promise<never>((_, reject) => {\n timer = setTimeout(\n () =>\n reject(\n new Error(\n \"Download timed out. This may be due to GitHub rate limiting or a network issue. Try again in a few minutes.\",\n ),\n ),\n DOWNLOAD_TIMEOUT_MS,\n );\n });\n\n try {\n await Promise.race([downloadPromise, timeoutPromise]);\n } finally {\n clearTimeout(timer!);\n }\n } finally {\n if (origDebug !== undefined) {\n process.env.DEBUG = origDebug;\n }\n }\n}\n\nfunction shouldCopyLocalProjectPath(src: string, projectDir: string): boolean {\n const relative = path.relative(projectDir, src);\n if (!relative) return true;\n\n const segments = relative.split(path.sep);\n return !segments.some((segment) =>\n LOCAL_PROJECT_ARTIFACT_DIRS.includes(segment),\n );\n}\n\nexport async function scaffoldProject(\n repoPath: string,\n destDir: string,\n source: ProjectSource,\n): Promise<void> {\n if (source.kind === \"github\") {\n await downloadProject(repoPath, destDir, source.ref);\n return;\n }\n\n const localProjectDir = path.resolve(source.rootDir, repoPath);\n try {\n fs.cpSync(localProjectDir, destDir, {\n recursive: true,\n force: true,\n filter: (src) => shouldCopyLocalProjectPath(src, localProjectDir),\n });\n } catch (error) {\n const code =\n error instanceof Error\n ? (error as NodeJS.ErrnoException).code\n : undefined;\n if (code === \"ENOENT\") {\n throw new Error(\n `Local project source does not exist: ${localProjectDir}`,\n );\n }\n throw error;\n }\n}\n\nfunction detectFromUserAgent(): PackageManagerName | undefined {\n const ua = process.env.npm_config_user_agent;\n if (!ua) return undefined;\n if (ua.startsWith(\"bun/\")) return \"bun\";\n if (ua.startsWith(\"pnpm/\")) return \"pnpm\";\n if (ua.startsWith(\"yarn/\")) return \"yarn\";\n if (ua.startsWith(\"npm/\")) return \"npm\";\n return undefined;\n}\n\nexport async function resolvePackageManagerForCwd(\n cwd: string,\n packageManager?: PackageManagerName,\n): Promise<PackageManagerName> {\n if (packageManager) return packageManager;\n const fromAgent = detectFromUserAgent();\n if (fromAgent) return fromAgent;\n try {\n return await detect({ cwd });\n } catch {\n return \"npm\";\n }\n}\n\nexport async function transformProject(\n projectDir: string,\n opts: TransformOptions,\n): Promise<void> {\n logger.step(\"Transforming package.json...\");\n transformPackageJson(projectDir);\n\n let assistantUI: string[] | undefined;\n let shadcnUI: string[] | undefined;\n\n if (!opts.hasLocalComponents) {\n logger.step(\"Transforming project files...\");\n\n transformTsConfig(projectDir);\n transformCssFiles(projectDir);\n\n const components = scanRequiredComponents(projectDir);\n assistantUI = components.assistantUI;\n shadcnUI = components.shadcnUI;\n }\n\n const pm = opts.packageManager;\n if (!opts.skipInstall) {\n logger.step(\"Installing dependencies...\");\n await installDependencies(projectDir, pm);\n }\n\n if (!opts.hasLocalComponents && shadcnUI && assistantUI) {\n const allShadcn = shadcnUI.includes(\"utils\")\n ? shadcnUI\n : [...shadcnUI, \"utils\"];\n const auiComponents = assistantUI.map((c) => `@assistant-ui/${c}`);\n const components = [...allShadcn, ...auiComponents];\n logger.step(`Installing components: ${components.join(\", \")}...`);\n await installShadcnRegistry(projectDir, components, \"components\", pm);\n }\n}\n\nfunction transformPackageJson(projectDir: string): void {\n const pkgPath = path.join(projectDir, \"package.json\");\n const pkg = JSON.parse(fs.readFileSync(pkgPath, \"utf-8\"));\n\n // Remove @assistant-ui/ui dependency\n if (pkg.dependencies?.[\"@assistant-ui/ui\"]) {\n delete pkg.dependencies[\"@assistant-ui/ui\"];\n }\n\n // Transform workspace dependencies to latest\n for (const depType of [\"dependencies\", \"devDependencies\"] as const) {\n const deps = pkg[depType];\n if (!deps) continue;\n\n for (const [name, version] of Object.entries(deps)) {\n if (String(version).includes(\"workspace:\")) {\n deps[name] = \"latest\";\n }\n }\n }\n\n // Remove devDependencies that are workspace-only\n if (pkg.devDependencies?.[\"@assistant-ui/x-buildutils\"]) {\n delete pkg.devDependencies[\"@assistant-ui/x-buildutils\"];\n }\n\n // Update package name to be unique\n const dirName = path.basename(projectDir);\n pkg.name = dirName;\n\n fs.writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\\n`);\n}\n\nfunction transformTsConfig(projectDir: string): void {\n const tsconfigPath = path.join(projectDir, \"tsconfig.json\");\n\n if (!fs.existsSync(tsconfigPath)) {\n return;\n }\n\n const content = fs.readFileSync(tsconfigPath, \"utf-8\");\n const tsconfig = JSON.parse(content);\n\n // Remove workspace paths\n if (tsconfig.compilerOptions?.paths) {\n delete tsconfig.compilerOptions.paths[\"@/components/assistant-ui/*\"];\n delete tsconfig.compilerOptions.paths[\"@/components/icons/*\"];\n delete tsconfig.compilerOptions.paths[\"@/components/ui/*\"];\n delete tsconfig.compilerOptions.paths[\"@/hooks/*\"];\n delete tsconfig.compilerOptions.paths[\"@/lib/utils\"];\n delete tsconfig.compilerOptions.paths[\"@assistant-ui/ui/*\"];\n\n if (Object.keys(tsconfig.compilerOptions.paths).length === 0) {\n delete tsconfig.compilerOptions.paths;\n }\n }\n\n // If extends uses @assistant-ui/x-buildutils, replace with inline config\n if (tsconfig.extends?.includes(\"@assistant-ui/x-buildutils\")) {\n const isNext = tsconfig.extends.includes(\"ts/next\");\n delete tsconfig.extends;\n\n const inlinedCompilerOptions = {\n target: \"ESNext\",\n lib: [\"dom\", \"dom.iterable\", \"ES2023\"],\n skipLibCheck: true,\n strict: true,\n noEmit: true,\n esModuleInterop: true,\n module: \"ESNext\",\n moduleResolution: \"bundler\",\n resolveJsonModule: true,\n isolatedModules: true,\n jsx: \"react-jsx\",\n ...(isNext ? { plugins: [{ name: \"next\" }] } : {}),\n };\n\n tsconfig.compilerOptions = {\n ...inlinedCompilerOptions,\n ...tsconfig.compilerOptions,\n paths: {\n \"@/*\": [\"./*\"],\n ...(tsconfig.compilerOptions?.paths || {}),\n },\n };\n }\n\n fs.writeFileSync(tsconfigPath, `${JSON.stringify(tsconfig, null, 2)}\\n`);\n}\n\nfunction transformCssFiles(projectDir: string): void {\n const cssFiles = globSync(\"**/*.css\", {\n cwd: projectDir,\n ignore: LOCAL_PROJECT_ARTIFACT_GLOB_IGNORES,\n });\n\n for (const file of cssFiles) {\n const fullPath = path.join(projectDir, file);\n try {\n const content = fs.readFileSync(fullPath, \"utf-8\");\n\n const newContent = content.replace(\n /@source\\s+[\"'][^\"']*packages\\/ui\\/src[^\"']*[\"'];\\s*\\n?/g,\n \"\",\n );\n\n if (newContent !== content) {\n fs.writeFileSync(fullPath, newContent);\n }\n } catch {\n // Ignore files that cannot be read/written\n }\n }\n}\n\ninterface RequiredComponents {\n assistantUI: string[];\n shadcnUI: string[];\n}\n\nfunction stripImportExtension(component: string): string {\n return component.replace(/\\.[cm]?[tj]sx?$/, \"\");\n}\n\nfunction scanRequiredComponents(projectDir: string): RequiredComponents {\n const files = globSync(\"**/*.{ts,tsx}\", {\n cwd: projectDir,\n ignore: LOCAL_PROJECT_ARTIFACT_GLOB_IGNORES,\n });\n\n const assistantUIComponents = new Set<string>();\n const shadcnUIComponents = new Set<string>();\n\n for (const file of files) {\n const fullPath = path.join(projectDir, file);\n try {\n const content = fs.readFileSync(fullPath, \"utf-8\");\n\n const assistantUIRegex =\n /from\\s+[\"']@\\/components\\/assistant-ui\\/([^\"']+)[\"']/g;\n for (const match of content.matchAll(assistantUIRegex)) {\n assistantUIComponents.add(stripImportExtension(match[1]!));\n }\n\n const uiRegex = /from\\s+[\"']@\\/components\\/ui\\/([^\"']+)[\"']/g;\n for (const match of content.matchAll(uiRegex)) {\n shadcnUIComponents.add(stripImportExtension(match[1]!));\n }\n } catch {\n // Ignore files that cannot be read\n }\n }\n\n return {\n assistantUI: Array.from(assistantUIComponents),\n shadcnUI: Array.from(shadcnUIComponents),\n };\n}\n\nasync function installDependencies(\n projectDir: string,\n pm: PackageManagerName,\n): Promise<void> {\n const args = pm === \"yarn\" ? [] : [\"install\"];\n try {\n await runSpawn(pm, args, projectDir);\n } catch (error) {\n if (error instanceof SpawnExitError) {\n throw new Error(`${pm} install exited with code ${error.code}`);\n }\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to install dependencies: ${message}`);\n }\n}\n\nasync function installShadcnRegistry(\n projectDir: string,\n components: string[],\n label: string,\n pm: PackageManagerName,\n): Promise<void> {\n const [cmd, dlxArgs] = dlxCommand(pm);\n // For npm, dlxArgs may already include `--yes` for npx auto-install.\n // The trailing `--yes` is for shadcn's own confirmation prompt.\n const addArgs = [...dlxArgs, \"shadcn@latest\", \"add\", ...components, \"--yes\"];\n\n try {\n await runSpawn(cmd, addArgs, projectDir);\n } catch (error) {\n if (error instanceof SpawnExitError) {\n logger.warn(\n `shadcn exited with code ${error.code}. Run the following to retry:\\n ${cmd} ${addArgs.slice(0, -1).join(\" \")}`,\n );\n return;\n }\n\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to install ${label}: ${message}`);\n }\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "assistant-ui",
3
- "version": "0.0.96",
3
+ "version": "0.0.98",
4
4
  "description": "CLI for assistant-ui",
5
5
  "keywords": [
6
6
  "cli",
@@ -46,7 +46,7 @@
46
46
  "@types/node": "^25.9.1",
47
47
  "@vitest/coverage-v8": "^4.1.7",
48
48
  "vitest": "^4.1.7",
49
- "@assistant-ui/x-buildutils": "0.0.10"
49
+ "@assistant-ui/x-buildutils": "0.0.11"
50
50
  },
51
51
  "publishConfig": {
52
52
  "access": "public",
@@ -14,6 +14,10 @@ import {
14
14
  transformProject,
15
15
  } from "../lib/create-project";
16
16
  import { runSpawn, SpawnExitError } from "../lib/run-spawn";
17
+ import {
18
+ buildSkillsAddCommand,
19
+ resolveSkillsInstall,
20
+ } from "../lib/agent-skill";
17
21
 
18
22
  export interface ProjectMetadata {
19
23
  name: string;
@@ -442,6 +446,8 @@ export const create = new Command()
442
446
  .option("--native", "create an Expo / React Native project")
443
447
  .option("--ink", "create a React Ink terminal project")
444
448
  .option("--skip-install", "skip installing packages")
449
+ .option("--skills", "add assistant-ui agent skills for AI coding assistants")
450
+ .option("--no-skills", "skip adding assistant-ui agent skills")
445
451
  .addOption(
446
452
  new Option(
447
453
  "--debug-source-root <path>",
@@ -530,6 +536,25 @@ export const create = new Command()
530
536
  process.exit(0);
531
537
  }
532
538
 
539
+ const stdinIsTTY = process.stdin.isTTY;
540
+ let installSkills = resolveSkillsInstall({
541
+ skills: opts.skills,
542
+ stdinIsTTY,
543
+ });
544
+ if (installSkills === undefined) {
545
+ const result = await p.confirm({
546
+ message: "Add assistant-ui agent skills for AI coding assistants?",
547
+ initialValue: true,
548
+ });
549
+
550
+ if (p.isCancel(result)) {
551
+ p.cancel("Project creation cancelled.");
552
+ process.exit(0);
553
+ }
554
+
555
+ installSkills = result;
556
+ }
557
+
533
558
  logger.info(`Creating project from ${project.category}: ${project.label}`);
534
559
  logger.break();
535
560
 
@@ -588,6 +613,20 @@ export const create = new Command()
588
613
  skipInstall: opts.skipInstall,
589
614
  packageManager: pm,
590
615
  });
616
+
617
+ if (installSkills) {
618
+ logger.step("Adding assistant-ui agent skills...");
619
+ const [skillsCmd, skillsArgs] = buildSkillsAddCommand(pm, {
620
+ stdinIsTTY,
621
+ });
622
+ try {
623
+ await runSpawn(skillsCmd, skillsArgs, absoluteProjectDir);
624
+ } catch {
625
+ logger.warn(
626
+ `Could not add assistant-ui agent skills. You can add them later with:\n ${skillsCmd} ${skillsArgs.join(" ")}`,
627
+ );
628
+ }
629
+ }
591
630
  } catch (err) {
592
631
  // Clean up partially created project directory
593
632
  fs.rmSync(absoluteProjectDir, { recursive: true, force: true });
@@ -0,0 +1,28 @@
1
+ import { dlxCommand, type PackageManagerName } from "./create-project";
2
+
3
+ export const SKILLS_PACKAGE = "assistant-ui/skills";
4
+
5
+ export function resolveSkillsInstall(params: {
6
+ skills?: boolean;
7
+ stdinIsTTY?: boolean;
8
+ }): boolean | undefined {
9
+ const { skills, stdinIsTTY = process.stdin.isTTY } = params;
10
+ if (skills !== undefined) return skills;
11
+ if (!stdinIsTTY) return true;
12
+ return undefined;
13
+ }
14
+
15
+ export function buildSkillsAddCommand(
16
+ pm: PackageManagerName,
17
+ params: { stdinIsTTY?: boolean } = {},
18
+ ): [string, string[]] {
19
+ const { stdinIsTTY = process.stdin.isTTY } = params;
20
+ const [command, dlxArgs] = dlxCommand(pm);
21
+ const args = [...dlxArgs, "skills", "add", SKILLS_PACKAGE];
22
+
23
+ // Without a TTY the skills CLI cannot prompt for agent platforms, so skip its
24
+ // confirmation; with a TTY it owns the platform selection interactively.
25
+ if (!stdinIsTTY) args.push("--yes");
26
+
27
+ return [command, args];
28
+ }
@@ -219,16 +219,10 @@ export async function transformProject(
219
219
  const allShadcn = shadcnUI.includes("utils")
220
220
  ? shadcnUI
221
221
  : [...shadcnUI, "utils"];
222
- logger.step(`Installing shadcn UI components: ${allShadcn.join(", ")}...`);
223
- await installShadcnRegistry(projectDir, allShadcn, "shadcn components", pm);
224
-
225
- if (assistantUI.length > 0) {
226
- const auiComponents = assistantUI.map((c) => `@assistant-ui/${c}`);
227
- logger.step(
228
- `Installing assistant-ui components: ${assistantUI.join(", ")}...`,
229
- );
230
- await installShadcnRegistry(projectDir, auiComponents, "components", pm);
231
- }
222
+ const auiComponents = assistantUI.map((c) => `@assistant-ui/${c}`);
223
+ const components = [...allShadcn, ...auiComponents];
224
+ logger.step(`Installing components: ${components.join(", ")}...`);
225
+ await installShadcnRegistry(projectDir, components, "components", pm);
232
226
  }
233
227
  }
234
228