assistant-ui 0.0.106 → 0.0.108

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 (59) hide show
  1. package/dist/codemods/v0-12/assistant-api-to-aui.js.map +1 -1
  2. package/dist/codemods/v0-15/aui-accessor-calls-to-properties.d.ts +5 -0
  3. package/dist/codemods/v0-15/aui-accessor-calls-to-properties.d.ts.map +1 -0
  4. package/dist/codemods/v0-15/aui-accessor-calls-to-properties.js +58 -0
  5. package/dist/codemods/v0-15/aui-accessor-calls-to-properties.js.map +1 -0
  6. package/dist/codemods/v0-8/ui-package-split.js.map +1 -1
  7. package/dist/commands/add.js +1 -1
  8. package/dist/commands/add.js.map +1 -1
  9. package/dist/commands/create.d.ts.map +1 -1
  10. package/dist/commands/create.js +14 -4
  11. package/dist/commands/create.js.map +1 -1
  12. package/dist/commands/doctor.d.ts.map +1 -1
  13. package/dist/commands/doctor.js +11 -10
  14. package/dist/commands/doctor.js.map +1 -1
  15. package/dist/commands/info.d.ts +1 -1
  16. package/dist/commands/info.d.ts.map +1 -1
  17. package/dist/commands/info.js +13 -14
  18. package/dist/commands/info.js.map +1 -1
  19. package/dist/commands/upgrade.js +2 -2
  20. package/dist/commands/upgrade.js.map +1 -1
  21. package/dist/index.d.ts +1 -1
  22. package/dist/index.js +5 -5
  23. package/dist/index.js.map +1 -1
  24. package/dist/lib/create-project.d.ts +7 -2
  25. package/dist/lib/create-project.d.ts.map +1 -1
  26. package/dist/lib/create-project.js +13 -10
  27. package/dist/lib/create-project.js.map +1 -1
  28. package/dist/lib/run-spawn.d.ts.map +1 -1
  29. package/dist/lib/upgrade.d.ts.map +1 -1
  30. package/dist/lib/upgrade.js +2 -1
  31. package/dist/lib/upgrade.js.map +1 -1
  32. package/dist/lib/utils/logger.d.ts.map +1 -1
  33. package/dist/lib/utils/registry.js +2 -1
  34. package/dist/lib/utils/registry.js.map +1 -1
  35. package/dist/lib/utils/workspace.d.ts +6 -0
  36. package/dist/lib/utils/workspace.d.ts.map +1 -0
  37. package/dist/lib/utils/workspace.js +28 -0
  38. package/dist/lib/utils/workspace.js.map +1 -0
  39. package/dist/run.d.ts +5 -0
  40. package/dist/run.d.ts.map +1 -0
  41. package/dist/run.js +9 -0
  42. package/dist/run.js.map +1 -0
  43. package/package.json +4 -4
  44. package/plugin/skills/assistant-ui/SKILL.md +24 -5
  45. package/src/codemods/v0-15/__tests__/aui-accessor-calls-to-properties.test.ts +109 -0
  46. package/src/codemods/v0-15/aui-accessor-calls-to-properties.ts +83 -0
  47. package/src/commands/add.ts +1 -1
  48. package/src/commands/create.ts +16 -4
  49. package/src/commands/doctor.ts +17 -13
  50. package/src/commands/info.ts +21 -20
  51. package/src/commands/upgrade.ts +2 -2
  52. package/src/index.ts +5 -6
  53. package/src/lib/create-project.ts +25 -14
  54. package/src/lib/upgrade.ts +1 -0
  55. package/src/lib/utils/registry.test.ts +8 -2
  56. package/src/lib/utils/registry.ts +5 -1
  57. package/src/lib/utils/workspace.ts +34 -0
  58. package/src/run.test.ts +27 -0
  59. package/src/run.ts +5 -0
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.js","names":["fs","path"],"sources":["../../src/commands/doctor.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport chalk from \"chalk\";\nimport { compare, valid } from \"semver\";\n\nconst ASSISTANT_UI_PACKAGE_NAMES = new Set([\n \"assistant-stream\",\n \"assistant-cloud\",\n \"assistant-ui\",\n]);\n\nfunction isTrackedPackage(name: string | undefined): boolean {\n if (!name) return false;\n if (name.startsWith(\"@assistant-ui/\")) return true;\n return ASSISTANT_UI_PACKAGE_NAMES.has(name);\n}\n\nexport interface DiscoveredPackage {\n name: string;\n version: string;\n installPath: string;\n}\n\ninterface ProcessedDir {\n set: Set<string>;\n}\n\nfunction readJson(file: string): Record<string, unknown> | null {\n try {\n return JSON.parse(fs.readFileSync(file, \"utf8\"));\n } catch {\n return null;\n }\n}\n\nfunction processPackageDir(\n pkgDir: string,\n results: DiscoveredPackage[],\n visited: ProcessedDir,\n): void {\n const real = (() => {\n try {\n return fs.realpathSync(pkgDir);\n } catch {\n return pkgDir;\n }\n })();\n if (visited.set.has(real)) return;\n visited.set.add(real);\n\n const pkgJson = readJson(path.join(pkgDir, \"package.json\"));\n let isTracked = false;\n if (pkgJson) {\n const name = pkgJson.name as string | undefined;\n const version = pkgJson.version as string | undefined;\n if (name && version && isTrackedPackage(name)) {\n results.push({ name, version, installPath: pkgDir });\n isTracked = true;\n }\n }\n\n // Only descend into nested node_modules of tracked packages. Transitive\n // copies of @assistant-ui/* live inside packages that depend on them,\n // which are themselves tracked. Walking every unrelated package's\n // subtree turns a doctor run on a large repo into thousands of stat\n // calls for no gain.\n if (isTracked) {\n walkNodeModulesAt(pkgDir, results, visited);\n }\n}\n\nfunction walkNodeModulesAt(\n baseDir: string,\n results: DiscoveredPackage[],\n visited: ProcessedDir,\n): void {\n const nm = path.join(baseDir, \"node_modules\");\n if (!fs.existsSync(nm)) return;\n\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(nm, { withFileTypes: true });\n } catch {\n return;\n }\n\n for (const entry of entries) {\n if (entry.name.startsWith(\".\")) continue;\n if (!entry.isDirectory() && !entry.isSymbolicLink()) continue;\n\n if (entry.name.startsWith(\"@\")) {\n const scopeDir = path.join(nm, entry.name);\n let scoped: fs.Dirent[];\n try {\n scoped = fs.readdirSync(scopeDir, { withFileTypes: true });\n } catch {\n continue;\n }\n for (const s of scoped) {\n if (!s.isDirectory() && !s.isSymbolicLink()) continue;\n processPackageDir(path.join(scopeDir, s.name), results, visited);\n }\n } else {\n processPackageDir(path.join(nm, entry.name), results, visited);\n }\n }\n}\n\n// pnpm keeps every real package dir in the `.pnpm` virtual store as\n// `node_modules/.pnpm/<pkg>@<ver>[_<peerhash>]/node_modules/<pkg>` and never\n// nests a package's deps inside its own dir, so the hoisted-layout walk above\n// only ever reaches the project's direct deps. The store dir name encodes the\n// package, so filtering by a tracked prefix keeps this pass O(tracked entries).\nconst TRACKED_PNPM_ENTRY_PREFIXES = [\n \"@assistant-ui+\",\n \"assistant-ui@\",\n \"assistant-stream@\",\n \"assistant-cloud@\",\n];\n\nfunction isTrackedPnpmEntry(dirName: string): boolean {\n return TRACKED_PNPM_ENTRY_PREFIXES.some((p) => dirName.startsWith(p));\n}\n\nfunction processTrackedPackagesIn(\n nm: string,\n results: DiscoveredPackage[],\n visited: ProcessedDir,\n): void {\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(nm, { withFileTypes: true });\n } catch {\n return;\n }\n\n for (const entry of entries) {\n if (entry.name.startsWith(\".\")) continue;\n if (!entry.isDirectory() && !entry.isSymbolicLink()) continue;\n\n if (entry.name.startsWith(\"@\")) {\n const scopeDir = path.join(nm, entry.name);\n let scoped: fs.Dirent[];\n try {\n scoped = fs.readdirSync(scopeDir, { withFileTypes: true });\n } catch {\n continue;\n }\n for (const s of scoped) {\n if (!s.isDirectory() && !s.isSymbolicLink()) continue;\n if (!isTrackedPackage(`${entry.name}/${s.name}`)) continue;\n processPackageDir(path.join(scopeDir, s.name), results, visited);\n }\n } else if (isTrackedPackage(entry.name)) {\n processPackageDir(path.join(nm, entry.name), results, visited);\n }\n }\n}\n\nfunction walkPnpmStore(\n cwd: string,\n results: DiscoveredPackage[],\n visited: ProcessedDir,\n): void {\n const storeDir = path.join(cwd, \"node_modules\", \".pnpm\");\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(storeDir, { withFileTypes: true });\n } catch {\n return;\n }\n\n for (const entry of entries) {\n if (!entry.isDirectory() && !entry.isSymbolicLink()) continue;\n if (!isTrackedPnpmEntry(entry.name)) continue;\n processTrackedPackagesIn(\n path.join(storeDir, entry.name, \"node_modules\"),\n results,\n visited,\n );\n }\n}\n\n// Discover every installation of an assistant-ui-family package reachable\n// from `cwd`. Recurses into nested node_modules so transitive copies\n// (the real source of duplicate-version bugs) are not missed, and scans the\n// pnpm `.pnpm` virtual store, which the hoisted walk cannot reach.\nexport function discoverInstalledPackages(cwd: string): DiscoveredPackage[] {\n const results: DiscoveredPackage[] = [];\n const visited: ProcessedDir = { set: new Set() };\n walkNodeModulesAt(cwd, results, visited);\n walkPnpmStore(cwd, results, visited);\n return results;\n}\n\nexport interface DuplicateGroup {\n name: string;\n installations: DiscoveredPackage[];\n}\n\nexport function findDuplicates(\n packages: DiscoveredPackage[],\n): DuplicateGroup[] {\n const byName = new Map<string, DiscoveredPackage[]>();\n for (const pkg of packages) {\n const list = byName.get(pkg.name) ?? [];\n list.push(pkg);\n byName.set(pkg.name, list);\n }\n\n const duplicates: DuplicateGroup[] = [];\n for (const [name, installations] of byName) {\n const versions = new Set(installations.map((i) => i.version));\n if (versions.size > 1) {\n duplicates.push({ name, installations });\n }\n }\n duplicates.sort((a, b) => a.name.localeCompare(b.name));\n return duplicates;\n}\n\nexport function uniquePackageNames(packages: DiscoveredPackage[]): string[] {\n return Array.from(new Set(packages.map((p) => p.name))).sort();\n}\n\n// Package names use a restricted character set (`[a-z0-9._~-]` plus a\n// leading `@scope/` for scoped packages — see the npm package-name spec)\n// and the npm registry expects the scope's `@` and `/` un-encoded. So a\n// simple validation + concatenation is both correct and avoids the\n// CodeQL \"incomplete string escaping\" foot-gun of `encodeURIComponent`\n// + targeted un-escape.\nconst VALID_NPM_NAME = /^(@[a-z0-9._~-]+\\/)?[a-z0-9._~-]+$/;\n\nasync function fetchLatestVersion(name: string): Promise<string | null> {\n if (!VALID_NPM_NAME.test(name)) return null;\n try {\n const res = await fetch(`https://registry.npmjs.org/${name}/latest`, {\n headers: { Accept: \"application/json\" },\n });\n if (!res.ok) return null;\n const data = (await res.json()) as { version?: string };\n return data.version ?? null;\n } catch {\n return null;\n }\n}\n\nasync function fetchAllLatestVersions(\n names: string[],\n): Promise<Map<string, string | null>> {\n const entries = await Promise.all(\n names.map(async (n) => [n, await fetchLatestVersion(n)] as const),\n );\n return new Map(entries);\n}\n\nexport function compareSemver(a: string, b: string): number {\n const validA = valid(a);\n const validB = valid(b);\n if (!validA || !validB) return a.localeCompare(b);\n return compare(validA, validB);\n}\n\nexport interface OutdatedPackage {\n name: string;\n current: string;\n latest: string;\n}\n\nexport function findOutdated(\n packages: DiscoveredPackage[],\n latest: Map<string, string | null>,\n): OutdatedPackage[] {\n const newestByName = new Map<string, string>();\n for (const pkg of packages) {\n const existing = newestByName.get(pkg.name);\n if (!existing || compareSemver(pkg.version, existing) > 0) {\n newestByName.set(pkg.name, pkg.version);\n }\n }\n\n const result: OutdatedPackage[] = [];\n for (const [name, current] of newestByName) {\n const latestVersion = latest.get(name);\n if (!latestVersion) continue;\n if (compareSemver(current, latestVersion) < 0) {\n result.push({ name, current, latest: latestVersion });\n }\n }\n result.sort((a, b) => a.name.localeCompare(b.name));\n return result;\n}\n\nfunction relativeInstallPath(installPath: string, cwd: string): string {\n const rel = path.relative(cwd, installPath);\n return rel.startsWith(\"..\") ? installPath : rel;\n}\n\nfunction reportDuplicates(\n duplicates: DuplicateGroup[],\n cwd: string,\n lines: string[],\n): void {\n if (duplicates.length === 0) {\n lines.push(chalk.green(\"✓ No duplicate versions detected.\"));\n return;\n }\n\n lines.push(chalk.red.bold(\"✗ Duplicate versions detected:\"));\n for (const dup of duplicates) {\n const versions = Array.from(\n new Set(dup.installations.map((i) => i.version)),\n )\n .sort(compareSemver)\n .join(\", \");\n lines.push(chalk.red(` ${dup.name} → ${versions}`));\n for (const inst of dup.installations) {\n lines.push(\n chalk.dim(\n ` ${inst.version} ${relativeInstallPath(inst.installPath, cwd)}`,\n ),\n );\n }\n }\n lines.push(\"\");\n lines.push(\n chalk.yellow(\n \"Duplicates almost always cause subtle runtime bugs (see https://github.com/assistant-ui/assistant-ui/issues/4101).\",\n ),\n );\n lines.push(\n chalk.yellow(\n \"Fix by aligning all @assistant-ui/* packages to compatible versions — run:\",\n ),\n );\n lines.push(chalk.cyan(\" npx assistant-ui update\"));\n}\n\nfunction reportOutdated(outdated: OutdatedPackage[], lines: string[]): void {\n if (outdated.length === 0) {\n lines.push(chalk.green(\"✓ All assistant-ui packages are up to date.\"));\n return;\n }\n\n lines.push(chalk.yellow.bold(\"! Outdated packages:\"));\n const maxLen = Math.max(...outdated.map((o) => o.name.length));\n for (const o of outdated) {\n lines.push(\n chalk.yellow(\n ` ${o.name.padEnd(maxLen)} ${o.current} → ${o.latest} (latest)`,\n ),\n );\n }\n lines.push(\"\");\n lines.push(chalk.yellow(\"Run the following to upgrade everything:\"));\n lines.push(chalk.cyan(\" npx assistant-ui update\"));\n}\n\nexport const doctor = new Command()\n .name(\"doctor\")\n .description(\n \"Diagnose mismatched or outdated assistant-ui packages (including transitive ones).\",\n )\n .option(\n \"-c, --cwd <cwd>\",\n \"the working directory. defaults to the current directory.\",\n process.cwd(),\n )\n .option(\"--no-network\", \"Skip the npm registry check for latest versions.\")\n .action(async (opts: { cwd: string; network: boolean }) => {\n const cwd = path.resolve(opts.cwd);\n const packageJsonPath = path.join(cwd, \"package.json\");\n\n if (!fs.existsSync(packageJsonPath)) {\n console.error(\n chalk.red(\"No package.json found in the current directory.\"),\n );\n process.exit(1);\n }\n\n console.log(\"\");\n console.log(chalk.bold(\"Running assistant-ui doctor...\"));\n console.log(\"\");\n\n const installed = discoverInstalledPackages(cwd);\n\n if (installed.length === 0) {\n console.log(\n chalk.yellow(\n \"No assistant-ui packages found in node_modules. Did you run `npm install`?\",\n ),\n );\n console.log(\"\");\n return;\n }\n\n const duplicates = findDuplicates(installed);\n\n let latest = new Map<string, string | null>();\n if (opts.network) {\n latest = await fetchAllLatestVersions(uniquePackageNames(installed));\n }\n const outdated = findOutdated(installed, latest);\n\n const lines: string[] = [];\n reportDuplicates(duplicates, cwd, lines);\n lines.push(\"\");\n if (opts.network) {\n reportOutdated(outdated, lines);\n } else {\n lines.push(chalk.dim(\"Skipped npm registry check (--no-network).\"));\n }\n\n for (const line of lines) console.log(line);\n console.log(\"\");\n\n if (duplicates.length > 0) {\n process.exitCode = 1;\n }\n });\n"],"mappings":"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"}
1
+ {"version":3,"file":"doctor.js","names":["fs","path"],"sources":["../../src/commands/doctor.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport chalk from \"chalk\";\nimport { compare, valid } from \"semver\";\nimport { findWorkspaceRoot, resolveRealPath } from \"../lib/utils/workspace\";\n\nconst ASSISTANT_UI_PACKAGE_NAMES = new Set([\n \"assistant-stream\",\n \"assistant-cloud\",\n \"assistant-ui\",\n]);\n\nfunction isTrackedPackage(name: string | undefined): boolean {\n if (!name) return false;\n if (name.startsWith(\"@assistant-ui/\")) return true;\n return ASSISTANT_UI_PACKAGE_NAMES.has(name);\n}\n\nexport interface DiscoveredPackage {\n name: string;\n version: string;\n installPath: string;\n}\n\ninterface ProcessedDir {\n set: Set<string>;\n}\n\nfunction readJson(file: string): Record<string, unknown> | null {\n try {\n return JSON.parse(fs.readFileSync(file, \"utf8\"));\n } catch {\n return null;\n }\n}\n\nfunction processPackageDir(\n pkgDir: string,\n results: DiscoveredPackage[],\n visited: ProcessedDir,\n): void {\n const real = resolveRealPath(pkgDir);\n if (visited.set.has(real)) return;\n visited.set.add(real);\n\n const pkgJson = readJson(path.join(pkgDir, \"package.json\"));\n let isTracked = false;\n if (pkgJson) {\n const name = pkgJson.name as string | undefined;\n const version = pkgJson.version as string | undefined;\n if (name && version && isTrackedPackage(name)) {\n results.push({ name, version, installPath: pkgDir });\n isTracked = true;\n }\n }\n\n // Only descend into nested node_modules of tracked packages. Transitive\n // copies of @assistant-ui/* live inside packages that depend on them,\n // which are themselves tracked. Walking every unrelated package's\n // subtree turns a doctor run on a large repo into thousands of stat\n // calls for no gain.\n if (isTracked) {\n walkNodeModulesAt(pkgDir, results, visited);\n }\n}\n\nfunction walkNodeModulesAt(\n baseDir: string,\n results: DiscoveredPackage[],\n visited: ProcessedDir,\n): void {\n const nm = path.join(baseDir, \"node_modules\");\n if (!fs.existsSync(nm)) return;\n\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(nm, { withFileTypes: true });\n } catch {\n return;\n }\n\n for (const entry of entries) {\n if (entry.name.startsWith(\".\")) continue;\n if (!entry.isDirectory() && !entry.isSymbolicLink()) continue;\n\n if (entry.name.startsWith(\"@\")) {\n const scopeDir = path.join(nm, entry.name);\n let scoped: fs.Dirent[];\n try {\n scoped = fs.readdirSync(scopeDir, { withFileTypes: true });\n } catch {\n continue;\n }\n for (const s of scoped) {\n if (!s.isDirectory() && !s.isSymbolicLink()) continue;\n processPackageDir(path.join(scopeDir, s.name), results, visited);\n }\n } else {\n processPackageDir(path.join(nm, entry.name), results, visited);\n }\n }\n}\n\n// pnpm keeps every real package dir in the `.pnpm` virtual store as\n// `node_modules/.pnpm/<pkg>@<ver>[_<peerhash>]/node_modules/<pkg>` and never\n// nests a package's deps inside its own dir, so the hoisted-layout walk above\n// only ever reaches the project's direct deps. The store dir name encodes the\n// package, so filtering by a tracked prefix keeps this pass O(tracked entries).\nconst TRACKED_PNPM_ENTRY_PREFIXES = [\n \"@assistant-ui+\",\n \"assistant-ui@\",\n \"assistant-stream@\",\n \"assistant-cloud@\",\n];\n\nfunction isTrackedPnpmEntry(dirName: string): boolean {\n return TRACKED_PNPM_ENTRY_PREFIXES.some((p) => dirName.startsWith(p));\n}\n\nfunction processTrackedPackagesIn(\n nm: string,\n results: DiscoveredPackage[],\n visited: ProcessedDir,\n): void {\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(nm, { withFileTypes: true });\n } catch {\n return;\n }\n\n for (const entry of entries) {\n if (entry.name.startsWith(\".\")) continue;\n if (!entry.isDirectory() && !entry.isSymbolicLink()) continue;\n\n if (entry.name.startsWith(\"@\")) {\n const scopeDir = path.join(nm, entry.name);\n let scoped: fs.Dirent[];\n try {\n scoped = fs.readdirSync(scopeDir, { withFileTypes: true });\n } catch {\n continue;\n }\n for (const s of scoped) {\n if (!s.isDirectory() && !s.isSymbolicLink()) continue;\n if (!isTrackedPackage(`${entry.name}/${s.name}`)) continue;\n processPackageDir(path.join(scopeDir, s.name), results, visited);\n }\n } else if (isTrackedPackage(entry.name)) {\n processPackageDir(path.join(nm, entry.name), results, visited);\n }\n }\n}\n\nfunction walkPnpmStore(\n cwd: string,\n results: DiscoveredPackage[],\n visited: ProcessedDir,\n): void {\n const storeDir = path.join(cwd, \"node_modules\", \".pnpm\");\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(storeDir, { withFileTypes: true });\n } catch {\n return;\n }\n\n for (const entry of entries) {\n if (!entry.isDirectory() && !entry.isSymbolicLink()) continue;\n if (!isTrackedPnpmEntry(entry.name)) continue;\n processTrackedPackagesIn(\n path.join(storeDir, entry.name, \"node_modules\"),\n results,\n visited,\n );\n }\n}\n\n// Discover every installation of an assistant-ui-family package reachable\n// from `cwd`. Node resolves packages through ancestor node_modules directories,\n// so inspect each level to include workspace-hoisted installs. Nested installs\n// and pnpm virtual stores are scanned to catch duplicate transitive copies.\nexport function discoverInstalledPackages(cwd: string): DiscoveredPackage[] {\n const results: DiscoveredPackage[] = [];\n const visited: ProcessedDir = { set: new Set() };\n let dir = resolveRealPath(cwd);\n const scanRoot = findWorkspaceRoot(dir) ?? dir;\n\n while (true) {\n walkNodeModulesAt(dir, results, visited);\n walkPnpmStore(dir, results, visited);\n\n if (dir === scanRoot) break;\n dir = path.dirname(dir);\n }\n\n return results;\n}\n\nexport interface DuplicateGroup {\n name: string;\n installations: DiscoveredPackage[];\n}\n\nexport function findDuplicates(\n packages: DiscoveredPackage[],\n): DuplicateGroup[] {\n const byName = new Map<string, DiscoveredPackage[]>();\n for (const pkg of packages) {\n const list = byName.get(pkg.name) ?? [];\n list.push(pkg);\n byName.set(pkg.name, list);\n }\n\n const duplicates: DuplicateGroup[] = [];\n for (const [name, installations] of byName) {\n const versions = new Set(installations.map((i) => i.version));\n if (versions.size > 1) {\n duplicates.push({ name, installations });\n }\n }\n duplicates.sort((a, b) => a.name.localeCompare(b.name));\n return duplicates;\n}\n\nexport function uniquePackageNames(packages: DiscoveredPackage[]): string[] {\n return Array.from(new Set(packages.map((p) => p.name))).sort();\n}\n\n// Package names use a restricted character set (`[a-z0-9._~-]` plus a\n// leading `@scope/` for scoped packages — see the npm package-name spec)\n// and the npm registry expects the scope's `@` and `/` un-encoded. So a\n// simple validation + concatenation is both correct and avoids the\n// CodeQL \"incomplete string escaping\" foot-gun of `encodeURIComponent`\n// + targeted un-escape.\nconst VALID_NPM_NAME = /^(@[a-z0-9._~-]+\\/)?[a-z0-9._~-]+$/;\n\nasync function fetchLatestVersion(name: string): Promise<string | null> {\n if (!VALID_NPM_NAME.test(name)) return null;\n try {\n const res = await fetch(`https://registry.npmjs.org/${name}/latest`, {\n headers: { Accept: \"application/json\" },\n });\n if (!res.ok) return null;\n const data = (await res.json()) as { version?: string };\n return data.version ?? null;\n } catch {\n return null;\n }\n}\n\nasync function fetchAllLatestVersions(\n names: string[],\n): Promise<Map<string, string | null>> {\n const entries = await Promise.all(\n names.map(async (n) => [n, await fetchLatestVersion(n)] as const),\n );\n return new Map(entries);\n}\n\nexport function compareSemver(a: string, b: string): number {\n const validA = valid(a);\n const validB = valid(b);\n if (!validA || !validB) return a.localeCompare(b);\n return compare(validA, validB);\n}\n\nexport interface OutdatedPackage {\n name: string;\n current: string;\n latest: string;\n}\n\nexport function findOutdated(\n packages: DiscoveredPackage[],\n latest: Map<string, string | null>,\n): OutdatedPackage[] {\n const newestByName = new Map<string, string>();\n for (const pkg of packages) {\n const existing = newestByName.get(pkg.name);\n if (!existing || compareSemver(pkg.version, existing) > 0) {\n newestByName.set(pkg.name, pkg.version);\n }\n }\n\n const result: OutdatedPackage[] = [];\n for (const [name, current] of newestByName) {\n const latestVersion = latest.get(name);\n if (!latestVersion) continue;\n if (compareSemver(current, latestVersion) < 0) {\n result.push({ name, current, latest: latestVersion });\n }\n }\n result.sort((a, b) => a.name.localeCompare(b.name));\n return result;\n}\n\nfunction relativeInstallPath(installPath: string, cwd: string): string {\n const rel = path.relative(cwd, installPath);\n return rel.startsWith(\"..\") ? installPath : rel;\n}\n\nfunction reportDuplicates(\n duplicates: DuplicateGroup[],\n cwd: string,\n lines: string[],\n): void {\n if (duplicates.length === 0) {\n lines.push(chalk.green(\"✓ No duplicate versions detected.\"));\n return;\n }\n\n lines.push(chalk.red.bold(\"✗ Duplicate versions detected:\"));\n for (const dup of duplicates) {\n const versions = Array.from(\n new Set(dup.installations.map((i) => i.version)),\n )\n .sort(compareSemver)\n .join(\", \");\n lines.push(chalk.red(` ${dup.name} → ${versions}`));\n for (const inst of dup.installations) {\n lines.push(\n chalk.dim(\n ` ${inst.version} ${relativeInstallPath(inst.installPath, cwd)}`,\n ),\n );\n }\n }\n lines.push(\"\");\n lines.push(\n chalk.yellow(\n \"Duplicates almost always cause subtle runtime bugs (see https://github.com/assistant-ui/assistant-ui/issues/4101).\",\n ),\n );\n lines.push(\n chalk.yellow(\n \"Fix by aligning all @assistant-ui/* packages to compatible versions — run:\",\n ),\n );\n lines.push(chalk.cyan(\" npx assistant-ui update\"));\n}\n\nfunction reportOutdated(outdated: OutdatedPackage[], lines: string[]): void {\n if (outdated.length === 0) {\n lines.push(chalk.green(\"✓ All assistant-ui packages are up to date.\"));\n return;\n }\n\n lines.push(chalk.yellow.bold(\"! Outdated packages:\"));\n const maxLen = Math.max(...outdated.map((o) => o.name.length));\n for (const o of outdated) {\n lines.push(\n chalk.yellow(\n ` ${o.name.padEnd(maxLen)} ${o.current} → ${o.latest} (latest)`,\n ),\n );\n }\n lines.push(\"\");\n lines.push(chalk.yellow(\"Run the following to upgrade everything:\"));\n lines.push(chalk.cyan(\" npx assistant-ui update\"));\n}\n\nexport const doctor = new Command()\n .name(\"doctor\")\n .description(\n \"Diagnose mismatched or outdated assistant-ui packages (including transitive ones).\",\n )\n .option(\n \"-c, --cwd <cwd>\",\n \"the working directory. defaults to the current directory.\",\n process.cwd(),\n )\n .option(\"--no-network\", \"Skip the npm registry check for latest versions.\")\n .action(async (opts: { cwd: string; network: boolean }) => {\n const cwd = resolveRealPath(opts.cwd);\n const packageJsonPath = path.join(cwd, \"package.json\");\n\n if (!fs.existsSync(packageJsonPath)) {\n console.error(\n chalk.red(\"No package.json found in the current directory.\"),\n );\n process.exit(1);\n }\n\n console.log(\"\");\n console.log(chalk.bold(\"Running assistant-ui doctor...\"));\n console.log(\"\");\n\n const installed = discoverInstalledPackages(cwd);\n\n if (installed.length === 0) {\n console.log(\n chalk.yellow(\n \"No assistant-ui packages found in node_modules. Did you run `npm install`?\",\n ),\n );\n console.log(\"\");\n return;\n }\n\n const duplicates = findDuplicates(installed);\n\n let latest = new Map<string, string | null>();\n if (opts.network) {\n latest = await fetchAllLatestVersions(uniquePackageNames(installed));\n }\n const outdated = findOutdated(installed, latest);\n\n const lines: string[] = [];\n reportDuplicates(duplicates, cwd, lines);\n lines.push(\"\");\n if (opts.network) {\n reportOutdated(outdated, lines);\n } else {\n lines.push(chalk.dim(\"Skipped npm registry check (--no-network).\"));\n }\n\n for (const line of lines) console.log(line);\n console.log(\"\");\n\n if (duplicates.length > 0) {\n process.exitCode = 1;\n }\n });\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
+ import { findWorkspaceRoot } from "../lib/utils/workspace.js";
1
2
  import { Command } from "commander";
2
3
  //#region src/commands/info.d.ts
3
- declare function findWorkspaceRoot(cwd: string): string | null;
4
4
  declare function satisfiesRange(version: string, range: string): boolean;
5
5
  declare const info: Command;
6
6
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"info.d.ts","names":[],"sources":["../../src/commands/info.ts"],"mappings":";;iBA2FgB,kBAAkB;iBAwHlB,eAAe,iBAAiB;cAqMnC,MAAI"}
1
+ {"version":3,"file":"info.d.ts","names":[],"sources":["../../src/commands/info.ts"],"mappings":";;;iBAgNgB,eAAe,iBAAiB;cAyMnC,MAAI"}
@@ -1,3 +1,4 @@
1
+ import { findWorkspaceRoot, resolveRealPath } from "../lib/utils/workspace.js";
1
2
  import { Command } from "commander";
2
3
  import chalk from "chalk";
3
4
  import * as fs$1 from "node:fs";
@@ -66,19 +67,6 @@ function getInstalledVersion(pkg, cwd) {
66
67
  } catch {}
67
68
  return null;
68
69
  }
69
- function findWorkspaceRoot(cwd) {
70
- let dir = cwd;
71
- const root = path$1.parse(dir).root;
72
- while (true) {
73
- if (fs$1.existsSync(path$1.join(dir, "pnpm-workspace.yaml"))) return dir;
74
- const pkgPath = path$1.join(dir, "package.json");
75
- if (fs$1.existsSync(pkgPath)) try {
76
- if (JSON.parse(fs$1.readFileSync(pkgPath, "utf8")).workspaces) return dir;
77
- } catch {}
78
- if (dir === root) return null;
79
- dir = path$1.dirname(dir);
80
- }
81
- }
82
70
  function readProjectDeps(projectPkg) {
83
71
  return {
84
72
  ...projectPkg.dependencies ?? {},
@@ -125,6 +113,14 @@ function getOsInfo() {
125
113
  default: return `${platform} ${release} (${arch})`;
126
114
  }
127
115
  }
116
+ function getCliVersion() {
117
+ try {
118
+ const packageJson = JSON.parse(fs$1.readFileSync(new URL("../../package.json", import.meta.url), "utf8"));
119
+ return typeof packageJson.version === "string" ? packageJson.version : "unknown";
120
+ } catch {
121
+ return "unknown";
122
+ }
123
+ }
128
124
  async function getPackageManagerInfo(cwd) {
129
125
  const pm = await detect({ cwd });
130
126
  return {
@@ -181,6 +177,7 @@ async function collectInfo(cwd, projectPkg) {
181
177
  const ecosystem = collectPackages(ECOSYSTEM_PACKAGES, cwd, projectPkg);
182
178
  const warnings = collectWarnings(packages, cwd, projectPkg);
183
179
  return {
180
+ cliVersion: getCliVersion(),
184
181
  os: getOsInfo(),
185
182
  node: process.version,
186
183
  pm,
@@ -203,6 +200,7 @@ function formatSection(label, items) {
203
200
  function renderPlain(data) {
204
201
  const lines = [];
205
202
  lines.push("Environment:");
203
+ lines.push(` assistant-ui CLI: ${data.cliVersion}`);
206
204
  lines.push(` OS: ${data.os}`);
207
205
  lines.push(` Node.js: ${data.node}`);
208
206
  lines.push(` Package Manager: ${data.pm.name} ${data.pm.version}`);
@@ -220,6 +218,7 @@ function renderPlain(data) {
220
218
  function renderColored(data) {
221
219
  const lines = [];
222
220
  lines.push(chalk.bold("Environment:"));
221
+ lines.push(` assistant-ui CLI: ${data.cliVersion}`);
223
222
  lines.push(` OS: ${data.os}`);
224
223
  lines.push(` Node.js: ${data.node}`);
225
224
  lines.push(` Package Manager: ${data.pm.name} ${data.pm.version}`);
@@ -248,7 +247,7 @@ function renderColored(data) {
248
247
  return lines;
249
248
  }
250
249
  const info = new Command().name("info").description("Print environment and package information for bug reports.").option("-c, --cwd <cwd>", "the working directory. defaults to the current directory.", process.cwd()).action(async (opts) => {
251
- const cwd = path$1.resolve(opts.cwd);
250
+ const cwd = resolveRealPath(opts.cwd);
252
251
  const packageJsonPath = path$1.join(cwd, "package.json");
253
252
  if (!fs$1.existsSync(packageJsonPath)) {
254
253
  console.error(chalk.red("No package.json found in the current directory."));
@@ -1 +1 @@
1
- {"version":3,"file":"info.js","names":["path","fs","os"],"sources":["../../src/commands/info.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport { spawnSync } from \"node:child_process\";\nimport chalk from \"chalk\";\nimport { detect } from \"detect-package-manager\";\nimport { satisfies } from \"semver\";\n\nconst ASSISTANT_UI_PACKAGES = [\n // Distribution\n \"@assistant-ui/react\",\n \"@assistant-ui/react-native\",\n \"@assistant-ui/react-ink\",\n // Core (should not be installed directly)\n \"@assistant-ui/core\",\n \"@assistant-ui/store\",\n \"@assistant-ui/tap\",\n // Streaming & Cloud\n \"assistant-stream\",\n \"assistant-cloud\",\n \"@assistant-ui/cloud-ai-sdk\",\n // Adapters\n \"@assistant-ui/eve\",\n \"@assistant-ui/react-ai-sdk\",\n \"@assistant-ui/react-langgraph\",\n \"@assistant-ui/react-ag-ui\",\n \"@assistant-ui/react-a2a\",\n \"@assistant-ui/react-data-stream\",\n \"@assistant-ui/react-google-adk\",\n // UI / Rendering\n \"@assistant-ui/react-markdown\",\n \"@assistant-ui/react-streamdown\",\n \"@assistant-ui/react-lexical\",\n \"@assistant-ui/react-syntax-highlighter\",\n \"@assistant-ui/react-hook-form\",\n // Observability & DevTools\n \"@assistant-ui/react-o11y\",\n \"@assistant-ui/react-devtools\",\n];\n\nconst ECOSYSTEM_PACKAGES = [\n \"react\",\n \"react-dom\",\n \"react-native\",\n \"next\",\n \"vite\",\n \"expo\",\n \"ai\",\n \"zod\",\n \"zustand\",\n \"typescript\",\n];\n\n// Packages that users should NOT install directly — they are internal\n// dependencies pulled in automatically by distribution packages.\nconst SHOULD_NOT_DIRECT_INSTALL = new Set([\n \"@assistant-ui/core\",\n \"@assistant-ui/store\",\n \"@assistant-ui/tap\",\n]);\n\nfunction resolvePackageJson(pkg: string, cwd: string): string | null {\n let dir = cwd;\n const root = path.parse(dir).root;\n while (dir !== root) {\n const candidate = path.join(\n dir,\n \"node_modules\",\n ...pkg.split(\"/\"),\n \"package.json\",\n );\n if (fs.existsSync(candidate)) return candidate;\n dir = path.dirname(dir);\n }\n return null;\n}\n\nfunction getInstalledVersion(pkg: string, cwd: string): string | null {\n try {\n const pkgJsonPath = resolvePackageJson(pkg, cwd);\n if (pkgJsonPath) {\n const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, \"utf8\"));\n return pkgJson.version ?? null;\n }\n } catch {\n // ignore\n }\n return null;\n}\n\nexport function findWorkspaceRoot(cwd: string): string | null {\n let dir = cwd;\n const root = path.parse(dir).root;\n while (true) {\n if (fs.existsSync(path.join(dir, \"pnpm-workspace.yaml\"))) return dir;\n const pkgPath = path.join(dir, \"package.json\");\n if (fs.existsSync(pkgPath)) {\n try {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, \"utf8\"));\n if (pkg.workspaces) return dir;\n } catch {\n // ignore\n }\n }\n if (dir === root) return null;\n dir = path.dirname(dir);\n }\n}\n\nfunction readProjectDeps(\n projectPkg: Record<string, unknown>,\n): Record<string, string> {\n return {\n ...((projectPkg.dependencies ?? {}) as Record<string, string>),\n ...((projectPkg.devDependencies ?? {}) as Record<string, string>),\n };\n}\n\nfunction getAssistantUiPackageNames(\n projectPkg: Record<string, unknown>,\n): string[] {\n const declaredPackages = Object.keys(readProjectDeps(projectPkg))\n .filter((name) => name.startsWith(\"@assistant-ui/\"))\n .sort();\n\n return [...new Set([...ASSISTANT_UI_PACKAGES, ...declaredPackages])];\n}\n\nfunction getSpecifiedRange(\n pkg: string,\n projectPkg: Record<string, unknown>,\n): string | null {\n const deps = (projectPkg.dependencies ?? {}) as Record<string, string>;\n const devDeps = (projectPkg.devDependencies ?? {}) as Record<string, string>;\n return deps[pkg] ?? devDeps[pkg] ?? null;\n}\n\nfunction getPeerDeps(pkg: string, cwd: string): Record<string, string> | null {\n try {\n const pkgJsonPath = resolvePackageJson(pkg, cwd);\n if (pkgJsonPath) {\n const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, \"utf8\"));\n return (pkgJson.peerDependencies as Record<string, string>) ?? null;\n }\n } catch {\n // ignore\n }\n return null;\n}\n\nfunction detectFramework(\n projectPkg: Record<string, unknown>,\n cwd: string,\n): string {\n const deps = readProjectDeps(projectPkg);\n\n if (deps.next) {\n const v = getInstalledVersion(\"next\", cwd);\n return `Next.js ${v ?? deps.next}`;\n }\n if (deps.expo) {\n const v = getInstalledVersion(\"expo\", cwd);\n return `Expo ${v ?? deps.expo}`;\n }\n if (deps.vite) {\n const v = getInstalledVersion(\"vite\", cwd);\n return `Vite ${v ?? deps.vite}`;\n }\n if (deps[\"@remix-run/react\"] || deps.remix) return \"Remix\";\n if (deps.gatsby) return \"Gatsby\";\n if (deps.astro) return \"Astro\";\n return \"Unknown\";\n}\n\nfunction getOsInfo(): string {\n const platform = os.platform();\n const arch = os.arch();\n const release = os.release();\n\n switch (platform) {\n case \"darwin\": {\n const result = spawnSync(\"sw_vers\", [\"-productVersion\"], {\n encoding: \"utf8\",\n });\n const macVer = result.stdout?.trim();\n return macVer\n ? `macOS ${macVer} (${arch})`\n : `macOS ${release} (${arch})`;\n }\n case \"win32\":\n return `Windows ${release} (${arch})`;\n case \"linux\":\n return `Linux ${release} (${arch})`;\n default:\n return `${platform} ${release} (${arch})`;\n }\n}\n\nasync function getPackageManagerInfo(\n cwd: string,\n): Promise<{ name: string; version: string }> {\n const pm = await detect({ cwd });\n const result = spawnSync(pm, [\"--version\"], {\n encoding: \"utf8\",\n cwd,\n });\n const version = result.stdout?.trim() ?? \"unknown\";\n return { name: pm, version };\n}\n\nexport function satisfiesRange(version: string, range: string): boolean {\n const normalizedRange = range.startsWith(\"workspace:\")\n ? range.slice(\"workspace:\".length)\n : range;\n\n return (\n normalizedRange === \"\" ||\n normalizedRange === \"^\" ||\n normalizedRange === \"~\" ||\n normalizedRange === \"any\" ||\n satisfies(version, normalizedRange, { includePrerelease: true })\n );\n}\n\ninterface PackageInfo {\n name: string;\n version: string;\n range: string | null;\n}\n\ninterface InfoData {\n os: string;\n node: string;\n pm: { name: string; version: string };\n framework: string;\n isMonorepo: boolean;\n packages: PackageInfo[];\n ecosystem: PackageInfo[];\n warnings: string[];\n}\n\nfunction collectPackages(\n names: string[],\n cwd: string,\n projectPkg: Record<string, unknown>,\n): PackageInfo[] {\n const result: PackageInfo[] = [];\n const deps = readProjectDeps(projectPkg);\n\n for (const name of names) {\n const version = getInstalledVersion(name, cwd);\n if (version) {\n result.push({\n name,\n version,\n range: getSpecifiedRange(name, projectPkg),\n });\n } else {\n // Fallback: no node_modules, show range from package.json\n const range = deps[name];\n if (range && !range.startsWith(\"workspace:\")) {\n result.push({ name, version: `${range} (not installed)`, range });\n }\n }\n }\n return result;\n}\n\nfunction collectWarnings(\n packages: PackageInfo[],\n cwd: string,\n projectPkg: Record<string, unknown>,\n): string[] {\n const warnings: string[] = [];\n const deps = readProjectDeps(projectPkg);\n\n // Check peer dependency mismatches\n for (const pkg of packages) {\n const peerDeps = getPeerDeps(pkg.name, cwd);\n if (!peerDeps) continue;\n\n for (const [peerName, peerRange] of Object.entries(peerDeps)) {\n const peerVersion = getInstalledVersion(peerName, cwd);\n if (!peerVersion) continue;\n if (!satisfiesRange(peerVersion, peerRange)) {\n warnings.push(\n `${pkg.name} requires ${peerName} ${peerRange}, found ${peerVersion}`,\n );\n }\n }\n }\n\n // Check for direct install of internal packages\n for (const name of SHOULD_NOT_DIRECT_INSTALL) {\n if (deps[name]) {\n warnings.push(\n `${name} should not be installed directly — it is an internal dependency`,\n );\n }\n }\n\n return warnings;\n}\n\nasync function collectInfo(\n cwd: string,\n projectPkg: Record<string, unknown>,\n): Promise<InfoData> {\n const pm = await getPackageManagerInfo(cwd);\n const packages = collectPackages(\n getAssistantUiPackageNames(projectPkg),\n cwd,\n projectPkg,\n );\n const ecosystem = collectPackages(ECOSYSTEM_PACKAGES, cwd, projectPkg);\n const warnings = collectWarnings(packages, cwd, projectPkg);\n\n return {\n os: getOsInfo(),\n node: process.version,\n pm,\n framework: detectFramework(projectPkg, cwd),\n isMonorepo: findWorkspaceRoot(cwd) !== null,\n packages,\n ecosystem,\n warnings,\n };\n}\n\nfunction formatSection(label: string, items: PackageInfo[]): string[] {\n if (items.length === 0) return [];\n const lines: string[] = [];\n lines.push(\"\");\n lines.push(`${label}:`);\n const maxLen = Math.max(...items.map((p) => p.name.length));\n for (const pkg of items) {\n lines.push(` ${pkg.name.padEnd(maxLen)} ${pkg.version}`);\n }\n return lines;\n}\n\nfunction renderPlain(data: InfoData): string[] {\n const lines: string[] = [];\n\n lines.push(\"Environment:\");\n lines.push(` OS: ${data.os}`);\n lines.push(` Node.js: ${data.node}`);\n lines.push(` Package Manager: ${data.pm.name} ${data.pm.version}`);\n lines.push(` Framework: ${data.framework}`);\n if (data.isMonorepo) {\n lines.push(` Monorepo: yes`);\n }\n\n lines.push(...formatSection(\"Packages\", data.packages));\n lines.push(...formatSection(\"Ecosystem\", data.ecosystem));\n\n if (data.warnings.length > 0) {\n lines.push(\"\");\n lines.push(\"Warnings:\");\n for (const w of data.warnings) {\n lines.push(` ! ${w}`);\n }\n }\n\n return lines;\n}\n\nfunction renderColored(data: InfoData): string[] {\n const lines: string[] = [];\n\n lines.push(chalk.bold(\"Environment:\"));\n lines.push(` OS: ${data.os}`);\n lines.push(` Node.js: ${data.node}`);\n lines.push(` Package Manager: ${data.pm.name} ${data.pm.version}`);\n lines.push(` Framework: ${data.framework}`);\n if (data.isMonorepo) {\n lines.push(` Monorepo: yes`);\n }\n\n if (data.packages.length > 0) {\n const section = formatSection(\"Packages\", data.packages);\n section[0] = \"\";\n section[1] = chalk.bold(\"Packages:\");\n lines.push(...section);\n } else {\n lines.push(\"\");\n lines.push(chalk.yellow(\" No assistant-ui packages found.\"));\n }\n\n if (data.ecosystem.length > 0) {\n const section = formatSection(\"Ecosystem\", data.ecosystem);\n section[0] = \"\";\n section[1] = chalk.bold(\"Ecosystem:\");\n lines.push(...section);\n }\n\n if (data.warnings.length > 0) {\n lines.push(\"\");\n lines.push(chalk.yellow.bold(\"Warnings:\"));\n for (const w of data.warnings) {\n lines.push(chalk.yellow(` ! ${w}`));\n }\n }\n\n return lines;\n}\n\nexport const info = new Command()\n .name(\"info\")\n .description(\"Print environment and package information for bug reports.\")\n .option(\n \"-c, --cwd <cwd>\",\n \"the working directory. defaults to the current directory.\",\n process.cwd(),\n )\n .action(async (opts) => {\n const cwd = path.resolve(opts.cwd);\n const packageJsonPath = path.join(cwd, \"package.json\");\n\n if (!fs.existsSync(packageJsonPath)) {\n console.error(\n chalk.red(\"No package.json found in the current directory.\"),\n );\n process.exit(1);\n }\n\n const projectPkg = JSON.parse(fs.readFileSync(packageJsonPath, \"utf8\"));\n const data = await collectInfo(cwd, projectPkg);\n\n // Colored output for terminal\n console.log(\"\");\n for (const line of renderColored(data)) {\n console.log(line);\n }\n console.log(\"\");\n\n // Copyable plain text\n const plain = renderPlain(data);\n const block = [\"```\", ...plain, \"```\"].join(\"\\n\");\n\n console.log(chalk.dim(\"— Copy the text below into your bug report —\"));\n console.log(\"\");\n console.log(block);\n console.log(\"\");\n });\n"],"mappings":";;;;;;;;;AASA,MAAM,wBAAwB;CAE5B;CACA;CACA;CAEA;CACA;CACA;CAEA;CACA;CACA;CAEA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA;CACA;CACA;CACA;CACA;CAEA;CACA;AACF;AAEA,MAAM,qBAAqB;CACzB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAIA,MAAM,4CAA4B,IAAI,IAAI;CACxC;CACA;CACA;AACF,CAAC;AAED,SAAS,mBAAmB,KAAa,KAA4B;CACnE,IAAI,MAAM;CACV,MAAM,OAAOA,OAAK,MAAM,GAAG,CAAC,CAAC;CAC7B,OAAO,QAAQ,MAAM;EACnB,MAAM,YAAYA,OAAK,KACrB,KACA,gBACA,GAAG,IAAI,MAAM,GAAG,GAChB,cACF;EACA,IAAIC,KAAG,WAAW,SAAS,GAAG,OAAO;EACrC,MAAMD,OAAK,QAAQ,GAAG;CACxB;CACA,OAAO;AACT;AAEA,SAAS,oBAAoB,KAAa,KAA4B;CACpE,IAAI;EACF,MAAM,cAAc,mBAAmB,KAAK,GAAG;EAC/C,IAAI,aAEF,OADgB,KAAK,MAAMC,KAAG,aAAa,aAAa,MAAM,CACjD,CAAC,CAAC,WAAW;CAE9B,QAAQ,CAER;CACA,OAAO;AACT;AAEA,SAAgB,kBAAkB,KAA4B;CAC5D,IAAI,MAAM;CACV,MAAM,OAAOD,OAAK,MAAM,GAAG,CAAC,CAAC;CAC7B,OAAO,MAAM;EACX,IAAIC,KAAG,WAAWD,OAAK,KAAK,KAAK,qBAAqB,CAAC,GAAG,OAAO;EACjE,MAAM,UAAUA,OAAK,KAAK,KAAK,cAAc;EAC7C,IAAIC,KAAG,WAAW,OAAO,GACvB,IAAI;GAEF,IADY,KAAK,MAAMA,KAAG,aAAa,SAAS,MAAM,CAChD,CAAC,CAAC,YAAY,OAAO;EAC7B,QAAQ,CAER;EAEF,IAAI,QAAQ,MAAM,OAAO;EACzB,MAAMD,OAAK,QAAQ,GAAG;CACxB;AACF;AAEA,SAAS,gBACP,YACwB;CACxB,OAAO;EACL,GAAK,WAAW,gBAAgB,CAAC;EACjC,GAAK,WAAW,mBAAmB,CAAC;CACtC;AACF;AAEA,SAAS,2BACP,YACU;CACV,MAAM,mBAAmB,OAAO,KAAK,gBAAgB,UAAU,CAAC,CAAC,CAC9D,QAAQ,SAAS,KAAK,WAAW,gBAAgB,CAAC,CAAC,CACnD,KAAK;CAER,OAAO,CAAC,mBAAG,IAAI,IAAI,CAAC,GAAG,uBAAuB,GAAG,gBAAgB,CAAC,CAAC;AACrE;AAEA,SAAS,kBACP,KACA,YACe;CACf,MAAM,OAAQ,WAAW,gBAAgB,CAAC;CAC1C,MAAM,UAAW,WAAW,mBAAmB,CAAC;CAChD,OAAO,KAAK,QAAQ,QAAQ,QAAQ;AACtC;AAEA,SAAS,YAAY,KAAa,KAA4C;CAC5E,IAAI;EACF,MAAM,cAAc,mBAAmB,KAAK,GAAG;EAC/C,IAAI,aAEF,OADgB,KAAK,MAAMC,KAAG,aAAa,aAAa,MAAM,CAChD,CAAC,CAAC,oBAA+C;CAEnE,QAAQ,CAER;CACA,OAAO;AACT;AAEA,SAAS,gBACP,YACA,KACQ;CACR,MAAM,OAAO,gBAAgB,UAAU;CAEvC,IAAI,KAAK,MAEP,OAAO,WADG,oBAAoB,QAAQ,GACpB,KAAK,KAAK;CAE9B,IAAI,KAAK,MAEP,OAAO,QADG,oBAAoB,QAAQ,GACvB,KAAK,KAAK;CAE3B,IAAI,KAAK,MAEP,OAAO,QADG,oBAAoB,QAAQ,GACvB,KAAK,KAAK;CAE3B,IAAI,KAAK,uBAAuB,KAAK,OAAO,OAAO;CACnD,IAAI,KAAK,QAAQ,OAAO;CACxB,IAAI,KAAK,OAAO,OAAO;CACvB,OAAO;AACT;AAEA,SAAS,YAAoB;CAC3B,MAAM,WAAWC,KAAG,SAAS;CAC7B,MAAM,OAAOA,KAAG,KAAK;CACrB,MAAM,UAAUA,KAAG,QAAQ;CAE3B,QAAQ,UAAR;EACE,KAAK,UAAU;GAIb,MAAM,SAHS,UAAU,WAAW,CAAC,iBAAiB,GAAG,EACvD,UAAU,OACZ,CACoB,CAAC,CAAC,QAAQ,KAAK;GACnC,OAAO,SACH,SAAS,OAAO,IAAI,KAAK,KACzB,SAAS,QAAQ,IAAI,KAAK;EAChC;EACA,KAAK,SACH,OAAO,WAAW,QAAQ,IAAI,KAAK;EACrC,KAAK,SACH,OAAO,SAAS,QAAQ,IAAI,KAAK;EACnC,SACE,OAAO,GAAG,SAAS,GAAG,QAAQ,IAAI,KAAK;CAC3C;AACF;AAEA,eAAe,sBACb,KAC4C;CAC5C,MAAM,KAAK,MAAM,OAAO,EAAE,IAAI,CAAC;CAM/B,OAAO;EAAE,MAAM;EAAI,SALJ,UAAU,IAAI,CAAC,WAAW,GAAG;GAC1C,UAAU;GACV;EACF,CACqB,CAAC,CAAC,QAAQ,KAAK,KAAK;CACd;AAC7B;AAEA,SAAgB,eAAe,SAAiB,OAAwB;CACtE,MAAM,kBAAkB,MAAM,WAAW,YAAY,IACjD,MAAM,MAAM,EAAmB,IAC/B;CAEJ,OACE,oBAAoB,MACpB,oBAAoB,OACpB,oBAAoB,OACpB,oBAAoB,SACpB,UAAU,SAAS,iBAAiB,EAAE,mBAAmB,KAAK,CAAC;AAEnE;AAmBA,SAAS,gBACP,OACA,KACA,YACe;CACf,MAAM,SAAwB,CAAC;CAC/B,MAAM,OAAO,gBAAgB,UAAU;CAEvC,KAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,UAAU,oBAAoB,MAAM,GAAG;EAC7C,IAAI,SACF,OAAO,KAAK;GACV;GACA;GACA,OAAO,kBAAkB,MAAM,UAAU;EAC3C,CAAC;OACI;GAEL,MAAM,QAAQ,KAAK;GACnB,IAAI,SAAS,CAAC,MAAM,WAAW,YAAY,GACzC,OAAO,KAAK;IAAE;IAAM,SAAS,GAAG,MAAM;IAAmB;GAAM,CAAC;EAEpE;CACF;CACA,OAAO;AACT;AAEA,SAAS,gBACP,UACA,KACA,YACU;CACV,MAAM,WAAqB,CAAC;CAC5B,MAAM,OAAO,gBAAgB,UAAU;CAGvC,KAAK,MAAM,OAAO,UAAU;EAC1B,MAAM,WAAW,YAAY,IAAI,MAAM,GAAG;EAC1C,IAAI,CAAC,UAAU;EAEf,KAAK,MAAM,CAAC,UAAU,cAAc,OAAO,QAAQ,QAAQ,GAAG;GAC5D,MAAM,cAAc,oBAAoB,UAAU,GAAG;GACrD,IAAI,CAAC,aAAa;GAClB,IAAI,CAAC,eAAe,aAAa,SAAS,GACxC,SAAS,KACP,GAAG,IAAI,KAAK,YAAY,SAAS,GAAG,UAAU,UAAU,aAC1D;EAEJ;CACF;CAGA,KAAK,MAAM,QAAQ,2BACjB,IAAI,KAAK,OACP,SAAS,KACP,GAAG,KAAK,iEACV;CAIJ,OAAO;AACT;AAEA,eAAe,YACb,KACA,YACmB;CACnB,MAAM,KAAK,MAAM,sBAAsB,GAAG;CAC1C,MAAM,WAAW,gBACf,2BAA2B,UAAU,GACrC,KACA,UACF;CACA,MAAM,YAAY,gBAAgB,oBAAoB,KAAK,UAAU;CACrE,MAAM,WAAW,gBAAgB,UAAU,KAAK,UAAU;CAE1D,OAAO;EACL,IAAI,UAAU;EACd,MAAM,QAAQ;EACd;EACA,WAAW,gBAAgB,YAAY,GAAG;EAC1C,YAAY,kBAAkB,GAAG,MAAM;EACvC;EACA;EACA;CACF;AACF;AAEA,SAAS,cAAc,OAAe,OAAgC;CACpE,IAAI,MAAM,WAAW,GAAG,OAAO,CAAC;CAChC,MAAM,QAAkB,CAAC;CACzB,MAAM,KAAK,EAAE;CACb,MAAM,KAAK,GAAG,MAAM,EAAE;CACtB,MAAM,SAAS,KAAK,IAAI,GAAG,MAAM,KAAK,MAAM,EAAE,KAAK,MAAM,CAAC;CAC1D,KAAK,MAAM,OAAO,OAChB,MAAM,KAAK,KAAK,IAAI,KAAK,OAAO,MAAM,EAAE,IAAI,IAAI,SAAS;CAE3D,OAAO;AACT;AAEA,SAAS,YAAY,MAA0B;CAC7C,MAAM,QAAkB,CAAC;CAEzB,MAAM,KAAK,cAAc;CACzB,MAAM,KAAK,uBAAuB,KAAK,IAAI;CAC3C,MAAM,KAAK,uBAAuB,KAAK,MAAM;CAC7C,MAAM,KAAK,uBAAuB,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,SAAS;CACnE,MAAM,KAAK,uBAAuB,KAAK,WAAW;CAClD,IAAI,KAAK,YACP,MAAM,KAAK,yBAAyB;CAGtC,MAAM,KAAK,GAAG,cAAc,YAAY,KAAK,QAAQ,CAAC;CACtD,MAAM,KAAK,GAAG,cAAc,aAAa,KAAK,SAAS,CAAC;CAExD,IAAI,KAAK,SAAS,SAAS,GAAG;EAC5B,MAAM,KAAK,EAAE;EACb,MAAM,KAAK,WAAW;EACtB,KAAK,MAAM,KAAK,KAAK,UACnB,MAAM,KAAK,OAAO,GAAG;CAEzB;CAEA,OAAO;AACT;AAEA,SAAS,cAAc,MAA0B;CAC/C,MAAM,QAAkB,CAAC;CAEzB,MAAM,KAAK,MAAM,KAAK,cAAc,CAAC;CACrC,MAAM,KAAK,uBAAuB,KAAK,IAAI;CAC3C,MAAM,KAAK,uBAAuB,KAAK,MAAM;CAC7C,MAAM,KAAK,uBAAuB,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,SAAS;CACnE,MAAM,KAAK,uBAAuB,KAAK,WAAW;CAClD,IAAI,KAAK,YACP,MAAM,KAAK,yBAAyB;CAGtC,IAAI,KAAK,SAAS,SAAS,GAAG;EAC5B,MAAM,UAAU,cAAc,YAAY,KAAK,QAAQ;EACvD,QAAQ,KAAK;EACb,QAAQ,KAAK,MAAM,KAAK,WAAW;EACnC,MAAM,KAAK,GAAG,OAAO;CACvB,OAAO;EACL,MAAM,KAAK,EAAE;EACb,MAAM,KAAK,MAAM,OAAO,mCAAmC,CAAC;CAC9D;CAEA,IAAI,KAAK,UAAU,SAAS,GAAG;EAC7B,MAAM,UAAU,cAAc,aAAa,KAAK,SAAS;EACzD,QAAQ,KAAK;EACb,QAAQ,KAAK,MAAM,KAAK,YAAY;EACpC,MAAM,KAAK,GAAG,OAAO;CACvB;CAEA,IAAI,KAAK,SAAS,SAAS,GAAG;EAC5B,MAAM,KAAK,EAAE;EACb,MAAM,KAAK,MAAM,OAAO,KAAK,WAAW,CAAC;EACzC,KAAK,MAAM,KAAK,KAAK,UACnB,MAAM,KAAK,MAAM,OAAO,OAAO,GAAG,CAAC;CAEvC;CAEA,OAAO;AACT;AAEA,MAAa,OAAO,IAAI,QAAQ,CAAC,CAC9B,KAAK,MAAM,CAAC,CACZ,YAAY,4DAA4D,CAAC,CACzE,OACC,mBACA,6DACA,QAAQ,IAAI,CACd,CAAC,CACA,OAAO,OAAO,SAAS;CACtB,MAAM,MAAMF,OAAK,QAAQ,KAAK,GAAG;CACjC,MAAM,kBAAkBA,OAAK,KAAK,KAAK,cAAc;CAErD,IAAI,CAACC,KAAG,WAAW,eAAe,GAAG;EACnC,QAAQ,MACN,MAAM,IAAI,iDAAiD,CAC7D;EACA,QAAQ,KAAK,CAAC;CAChB;CAGA,MAAM,OAAO,MAAM,YAAY,KADZ,KAAK,MAAMA,KAAG,aAAa,iBAAiB,MAAM,CACxB,CAAC;CAG9C,QAAQ,IAAI,EAAE;CACd,KAAK,MAAM,QAAQ,cAAc,IAAI,GACnC,QAAQ,IAAI,IAAI;CAElB,QAAQ,IAAI,EAAE;CAId,MAAM,QAAQ;EAAC;EAAO,GADR,YAAY,IACG;EAAG;CAAK,CAAC,CAAC,KAAK,IAAI;CAEhD,QAAQ,IAAI,MAAM,IAAI,8CAA8C,CAAC;CACrE,QAAQ,IAAI,EAAE;CACd,QAAQ,IAAI,KAAK;CACjB,QAAQ,IAAI,EAAE;AAChB,CAAC"}
1
+ {"version":3,"file":"info.js","names":["path","fs","os"],"sources":["../../src/commands/info.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport { spawnSync } from \"node:child_process\";\nimport chalk from \"chalk\";\nimport { detect } from \"detect-package-manager\";\nimport { satisfies } from \"semver\";\nimport { findWorkspaceRoot, resolveRealPath } from \"../lib/utils/workspace\";\n\nexport { findWorkspaceRoot };\n\nconst ASSISTANT_UI_PACKAGES = [\n // Distribution\n \"@assistant-ui/react\",\n \"@assistant-ui/react-native\",\n \"@assistant-ui/react-ink\",\n // Core (should not be installed directly)\n \"@assistant-ui/core\",\n \"@assistant-ui/store\",\n \"@assistant-ui/tap\",\n // Streaming & Cloud\n \"assistant-stream\",\n \"assistant-cloud\",\n \"@assistant-ui/cloud-ai-sdk\",\n // Adapters\n \"@assistant-ui/eve\",\n \"@assistant-ui/react-ai-sdk\",\n \"@assistant-ui/react-langgraph\",\n \"@assistant-ui/react-ag-ui\",\n \"@assistant-ui/react-a2a\",\n \"@assistant-ui/react-data-stream\",\n \"@assistant-ui/react-google-adk\",\n // UI / Rendering\n \"@assistant-ui/react-markdown\",\n \"@assistant-ui/react-streamdown\",\n \"@assistant-ui/react-lexical\",\n \"@assistant-ui/react-syntax-highlighter\",\n \"@assistant-ui/react-hook-form\",\n // Observability & DevTools\n \"@assistant-ui/react-o11y\",\n \"@assistant-ui/react-devtools\",\n];\n\nconst ECOSYSTEM_PACKAGES = [\n \"react\",\n \"react-dom\",\n \"react-native\",\n \"next\",\n \"vite\",\n \"expo\",\n \"ai\",\n \"zod\",\n \"zustand\",\n \"typescript\",\n];\n\n// Packages that users should NOT install directly — they are internal\n// dependencies pulled in automatically by distribution packages.\nconst SHOULD_NOT_DIRECT_INSTALL = new Set([\n \"@assistant-ui/core\",\n \"@assistant-ui/store\",\n \"@assistant-ui/tap\",\n]);\n\nfunction resolvePackageJson(pkg: string, cwd: string): string | null {\n let dir = cwd;\n const root = path.parse(dir).root;\n while (dir !== root) {\n const candidate = path.join(\n dir,\n \"node_modules\",\n ...pkg.split(\"/\"),\n \"package.json\",\n );\n if (fs.existsSync(candidate)) return candidate;\n dir = path.dirname(dir);\n }\n return null;\n}\n\nfunction getInstalledVersion(pkg: string, cwd: string): string | null {\n try {\n const pkgJsonPath = resolvePackageJson(pkg, cwd);\n if (pkgJsonPath) {\n const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, \"utf8\"));\n return pkgJson.version ?? null;\n }\n } catch {\n // ignore\n }\n return null;\n}\n\nfunction readProjectDeps(\n projectPkg: Record<string, unknown>,\n): Record<string, string> {\n return {\n ...((projectPkg.dependencies ?? {}) as Record<string, string>),\n ...((projectPkg.devDependencies ?? {}) as Record<string, string>),\n };\n}\n\nfunction getAssistantUiPackageNames(\n projectPkg: Record<string, unknown>,\n): string[] {\n const declaredPackages = Object.keys(readProjectDeps(projectPkg))\n .filter((name) => name.startsWith(\"@assistant-ui/\"))\n .sort();\n\n return [...new Set([...ASSISTANT_UI_PACKAGES, ...declaredPackages])];\n}\n\nfunction getSpecifiedRange(\n pkg: string,\n projectPkg: Record<string, unknown>,\n): string | null {\n const deps = (projectPkg.dependencies ?? {}) as Record<string, string>;\n const devDeps = (projectPkg.devDependencies ?? {}) as Record<string, string>;\n return deps[pkg] ?? devDeps[pkg] ?? null;\n}\n\nfunction getPeerDeps(pkg: string, cwd: string): Record<string, string> | null {\n try {\n const pkgJsonPath = resolvePackageJson(pkg, cwd);\n if (pkgJsonPath) {\n const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, \"utf8\"));\n return (pkgJson.peerDependencies as Record<string, string>) ?? null;\n }\n } catch {\n // ignore\n }\n return null;\n}\n\nfunction detectFramework(\n projectPkg: Record<string, unknown>,\n cwd: string,\n): string {\n const deps = readProjectDeps(projectPkg);\n\n if (deps.next) {\n const v = getInstalledVersion(\"next\", cwd);\n return `Next.js ${v ?? deps.next}`;\n }\n if (deps.expo) {\n const v = getInstalledVersion(\"expo\", cwd);\n return `Expo ${v ?? deps.expo}`;\n }\n if (deps.vite) {\n const v = getInstalledVersion(\"vite\", cwd);\n return `Vite ${v ?? deps.vite}`;\n }\n if (deps[\"@remix-run/react\"] || deps.remix) return \"Remix\";\n if (deps.gatsby) return \"Gatsby\";\n if (deps.astro) return \"Astro\";\n return \"Unknown\";\n}\n\nfunction getOsInfo(): string {\n const platform = os.platform();\n const arch = os.arch();\n const release = os.release();\n\n switch (platform) {\n case \"darwin\": {\n const result = spawnSync(\"sw_vers\", [\"-productVersion\"], {\n encoding: \"utf8\",\n });\n const macVer = result.stdout?.trim();\n return macVer\n ? `macOS ${macVer} (${arch})`\n : `macOS ${release} (${arch})`;\n }\n case \"win32\":\n return `Windows ${release} (${arch})`;\n case \"linux\":\n return `Linux ${release} (${arch})`;\n default:\n return `${platform} ${release} (${arch})`;\n }\n}\n\nfunction getCliVersion(): string {\n try {\n const packageJson = JSON.parse(\n fs.readFileSync(new URL(\"../../package.json\", import.meta.url), \"utf8\"),\n ) as { version?: unknown };\n return typeof packageJson.version === \"string\"\n ? packageJson.version\n : \"unknown\";\n } catch {\n return \"unknown\";\n }\n}\n\nasync function getPackageManagerInfo(\n cwd: string,\n): Promise<{ name: string; version: string }> {\n const pm = await detect({ cwd });\n const result = spawnSync(pm, [\"--version\"], {\n encoding: \"utf8\",\n cwd,\n });\n const version = result.stdout?.trim() ?? \"unknown\";\n return { name: pm, version };\n}\n\nexport function satisfiesRange(version: string, range: string): boolean {\n const normalizedRange = range.startsWith(\"workspace:\")\n ? range.slice(\"workspace:\".length)\n : range;\n\n return (\n normalizedRange === \"\" ||\n normalizedRange === \"^\" ||\n normalizedRange === \"~\" ||\n normalizedRange === \"any\" ||\n satisfies(version, normalizedRange, { includePrerelease: true })\n );\n}\n\ninterface PackageInfo {\n name: string;\n version: string;\n range: string | null;\n}\n\ninterface InfoData {\n cliVersion: string;\n os: string;\n node: string;\n pm: { name: string; version: string };\n framework: string;\n isMonorepo: boolean;\n packages: PackageInfo[];\n ecosystem: PackageInfo[];\n warnings: string[];\n}\n\nfunction collectPackages(\n names: string[],\n cwd: string,\n projectPkg: Record<string, unknown>,\n): PackageInfo[] {\n const result: PackageInfo[] = [];\n const deps = readProjectDeps(projectPkg);\n\n for (const name of names) {\n const version = getInstalledVersion(name, cwd);\n if (version) {\n result.push({\n name,\n version,\n range: getSpecifiedRange(name, projectPkg),\n });\n } else {\n // Fallback: no node_modules, show range from package.json\n const range = deps[name];\n if (range && !range.startsWith(\"workspace:\")) {\n result.push({ name, version: `${range} (not installed)`, range });\n }\n }\n }\n return result;\n}\n\nfunction collectWarnings(\n packages: PackageInfo[],\n cwd: string,\n projectPkg: Record<string, unknown>,\n): string[] {\n const warnings: string[] = [];\n const deps = readProjectDeps(projectPkg);\n\n // Check peer dependency mismatches\n for (const pkg of packages) {\n const peerDeps = getPeerDeps(pkg.name, cwd);\n if (!peerDeps) continue;\n\n for (const [peerName, peerRange] of Object.entries(peerDeps)) {\n const peerVersion = getInstalledVersion(peerName, cwd);\n if (!peerVersion) continue;\n if (!satisfiesRange(peerVersion, peerRange)) {\n warnings.push(\n `${pkg.name} requires ${peerName} ${peerRange}, found ${peerVersion}`,\n );\n }\n }\n }\n\n // Check for direct install of internal packages\n for (const name of SHOULD_NOT_DIRECT_INSTALL) {\n if (deps[name]) {\n warnings.push(\n `${name} should not be installed directly — it is an internal dependency`,\n );\n }\n }\n\n return warnings;\n}\n\nasync function collectInfo(\n cwd: string,\n projectPkg: Record<string, unknown>,\n): Promise<InfoData> {\n const pm = await getPackageManagerInfo(cwd);\n const packages = collectPackages(\n getAssistantUiPackageNames(projectPkg),\n cwd,\n projectPkg,\n );\n const ecosystem = collectPackages(ECOSYSTEM_PACKAGES, cwd, projectPkg);\n const warnings = collectWarnings(packages, cwd, projectPkg);\n\n return {\n cliVersion: getCliVersion(),\n os: getOsInfo(),\n node: process.version,\n pm,\n framework: detectFramework(projectPkg, cwd),\n isMonorepo: findWorkspaceRoot(cwd) !== null,\n packages,\n ecosystem,\n warnings,\n };\n}\n\nfunction formatSection(label: string, items: PackageInfo[]): string[] {\n if (items.length === 0) return [];\n const lines: string[] = [];\n lines.push(\"\");\n lines.push(`${label}:`);\n const maxLen = Math.max(...items.map((p) => p.name.length));\n for (const pkg of items) {\n lines.push(` ${pkg.name.padEnd(maxLen)} ${pkg.version}`);\n }\n return lines;\n}\n\nfunction renderPlain(data: InfoData): string[] {\n const lines: string[] = [];\n\n lines.push(\"Environment:\");\n lines.push(` assistant-ui CLI: ${data.cliVersion}`);\n lines.push(` OS: ${data.os}`);\n lines.push(` Node.js: ${data.node}`);\n lines.push(` Package Manager: ${data.pm.name} ${data.pm.version}`);\n lines.push(` Framework: ${data.framework}`);\n if (data.isMonorepo) {\n lines.push(` Monorepo: yes`);\n }\n\n lines.push(...formatSection(\"Packages\", data.packages));\n lines.push(...formatSection(\"Ecosystem\", data.ecosystem));\n\n if (data.warnings.length > 0) {\n lines.push(\"\");\n lines.push(\"Warnings:\");\n for (const w of data.warnings) {\n lines.push(` ! ${w}`);\n }\n }\n\n return lines;\n}\n\nfunction renderColored(data: InfoData): string[] {\n const lines: string[] = [];\n\n lines.push(chalk.bold(\"Environment:\"));\n lines.push(` assistant-ui CLI: ${data.cliVersion}`);\n lines.push(` OS: ${data.os}`);\n lines.push(` Node.js: ${data.node}`);\n lines.push(` Package Manager: ${data.pm.name} ${data.pm.version}`);\n lines.push(` Framework: ${data.framework}`);\n if (data.isMonorepo) {\n lines.push(` Monorepo: yes`);\n }\n\n if (data.packages.length > 0) {\n const section = formatSection(\"Packages\", data.packages);\n section[0] = \"\";\n section[1] = chalk.bold(\"Packages:\");\n lines.push(...section);\n } else {\n lines.push(\"\");\n lines.push(chalk.yellow(\" No assistant-ui packages found.\"));\n }\n\n if (data.ecosystem.length > 0) {\n const section = formatSection(\"Ecosystem\", data.ecosystem);\n section[0] = \"\";\n section[1] = chalk.bold(\"Ecosystem:\");\n lines.push(...section);\n }\n\n if (data.warnings.length > 0) {\n lines.push(\"\");\n lines.push(chalk.yellow.bold(\"Warnings:\"));\n for (const w of data.warnings) {\n lines.push(chalk.yellow(` ! ${w}`));\n }\n }\n\n return lines;\n}\n\nexport const info = new Command()\n .name(\"info\")\n .description(\"Print environment and package information for bug reports.\")\n .option(\n \"-c, --cwd <cwd>\",\n \"the working directory. defaults to the current directory.\",\n process.cwd(),\n )\n .action(async (opts) => {\n const cwd = resolveRealPath(opts.cwd);\n const packageJsonPath = path.join(cwd, \"package.json\");\n\n if (!fs.existsSync(packageJsonPath)) {\n console.error(\n chalk.red(\"No package.json found in the current directory.\"),\n );\n process.exit(1);\n }\n\n const projectPkg = JSON.parse(fs.readFileSync(packageJsonPath, \"utf8\"));\n const data = await collectInfo(cwd, projectPkg);\n\n // Colored output for terminal\n console.log(\"\");\n for (const line of renderColored(data)) {\n console.log(line);\n }\n console.log(\"\");\n\n // Copyable plain text\n const plain = renderPlain(data);\n const block = [\"```\", ...plain, \"```\"].join(\"\\n\");\n\n console.log(chalk.dim(\"— Copy the text below into your bug report —\"));\n console.log(\"\");\n console.log(block);\n console.log(\"\");\n });\n"],"mappings":"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"}
@@ -19,9 +19,9 @@ const codemodCommand = addTransformOptions(new Command().name("codemod").descrip
19
19
  process.exit(1);
20
20
  }
21
21
  });
22
- const upgradeCommand = addTransformOptions(new Command().command("upgrade").description("Upgrade ai package dependencies and apply codemods")).action((options) => {
22
+ const upgradeCommand = addTransformOptions(new Command().command("upgrade").description("Upgrade ai package dependencies and apply codemods")).action(async (options) => {
23
23
  try {
24
- upgrade(options);
24
+ await upgrade(options);
25
25
  } catch (err) {
26
26
  const errorMessage = err instanceof Error ? err.message : String(err);
27
27
  const errorStack = err instanceof Error ? err.stack : void 0;
@@ -1 +1 @@
1
- {"version":3,"file":"upgrade.js","names":[],"sources":["../../src/commands/upgrade.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { transform } from \"../lib/transform\";\nimport { upgrade } from \"../lib/upgrade\";\nimport debug from \"debug\";\n\nexport interface TransformOptions {\n dry?: boolean;\n print?: boolean;\n verbose?: boolean;\n jscodeshift?: string;\n}\n\nconst error = debug(\"codemod:error\");\ndebug.enable(\"codemod:*\");\n\nconst addTransformOptions = (command: Command): Command => {\n return command\n .option(\"-d, --dry\", \"Dry run (no changes are made to files)\")\n .option(\"-p, --print\", \"Print transformed files to stdout\")\n .option(\"--verbose\", \"Show more information about the transform process\")\n .option(\n \"-j, --jscodeshift <options>\",\n \"Pass options directly to jscodeshift\",\n );\n};\n\nexport const codemodCommand = addTransformOptions(\n new Command()\n .name(\"codemod\")\n .description(\"CLI tool for running codemods\")\n .argument(\"<codemod>\", \"Codemod to run (e.g., rewrite-framework-imports)\")\n .argument(\"<source>\", \"Path to source files or directory to transform\"),\n).action((codemod, source, options: TransformOptions) => {\n try {\n transform(codemod, source, options);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n const errorStack = err instanceof Error ? err.stack : undefined;\n error(`Error transforming: ${errorMessage}`);\n if (errorStack) {\n error(errorStack);\n }\n process.exit(1);\n }\n});\n\nexport const upgradeCommand = addTransformOptions(\n new Command()\n .command(\"upgrade\")\n .description(\"Upgrade ai package dependencies and apply codemods\"),\n).action((options: TransformOptions) => {\n try {\n upgrade(options);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n const errorStack = err instanceof Error ? err.stack : undefined;\n error(`Error upgrading: ${errorMessage}`);\n if (errorStack) {\n error(errorStack);\n }\n process.exit(1);\n }\n});\n"],"mappings":";;;;;AAYA,MAAM,QAAQ,MAAM,eAAe;AACnC,MAAM,OAAO,WAAW;AAExB,MAAM,uBAAuB,YAA8B;CACzD,OAAO,QACJ,OAAO,aAAa,wCAAwC,CAAC,CAC7D,OAAO,eAAe,mCAAmC,CAAC,CAC1D,OAAO,aAAa,mDAAmD,CAAC,CACxE,OACC,+BACA,sCACF;AACJ;AAEA,MAAa,iBAAiB,oBAC5B,IAAI,QAAQ,CAAC,CACV,KAAK,SAAS,CAAC,CACf,YAAY,+BAA+B,CAAC,CAC5C,SAAS,aAAa,kDAAkD,CAAC,CACzE,SAAS,YAAY,gDAAgD,CAC1E,CAAC,CAAC,QAAQ,SAAS,QAAQ,YAA8B;CACvD,IAAI;EACF,UAAU,SAAS,QAAQ,OAAO;CACpC,SAAS,KAAK;EACZ,MAAM,eAAe,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;EACpE,MAAM,aAAa,eAAe,QAAQ,IAAI,QAAQ,KAAA;EACtD,MAAM,uBAAuB,cAAc;EAC3C,IAAI,YACF,MAAM,UAAU;EAElB,QAAQ,KAAK,CAAC;CAChB;AACF,CAAC;AAED,MAAa,iBAAiB,oBAC5B,IAAI,QAAQ,CAAC,CACV,QAAQ,SAAS,CAAC,CAClB,YAAY,oDAAoD,CACrE,CAAC,CAAC,QAAQ,YAA8B;CACtC,IAAI;EACF,QAAQ,OAAO;CACjB,SAAS,KAAK;EACZ,MAAM,eAAe,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;EACpE,MAAM,aAAa,eAAe,QAAQ,IAAI,QAAQ,KAAA;EACtD,MAAM,oBAAoB,cAAc;EACxC,IAAI,YACF,MAAM,UAAU;EAElB,QAAQ,KAAK,CAAC;CAChB;AACF,CAAC"}
1
+ {"version":3,"file":"upgrade.js","names":[],"sources":["../../src/commands/upgrade.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { transform } from \"../lib/transform\";\nimport { upgrade } from \"../lib/upgrade\";\nimport debug from \"debug\";\n\nexport interface TransformOptions {\n dry?: boolean;\n print?: boolean;\n verbose?: boolean;\n jscodeshift?: string;\n}\n\nconst error = debug(\"codemod:error\");\ndebug.enable(\"codemod:*\");\n\nconst addTransformOptions = (command: Command): Command => {\n return command\n .option(\"-d, --dry\", \"Dry run (no changes are made to files)\")\n .option(\"-p, --print\", \"Print transformed files to stdout\")\n .option(\"--verbose\", \"Show more information about the transform process\")\n .option(\n \"-j, --jscodeshift <options>\",\n \"Pass options directly to jscodeshift\",\n );\n};\n\nexport const codemodCommand = addTransformOptions(\n new Command()\n .name(\"codemod\")\n .description(\"CLI tool for running codemods\")\n .argument(\"<codemod>\", \"Codemod to run (e.g., rewrite-framework-imports)\")\n .argument(\"<source>\", \"Path to source files or directory to transform\"),\n).action((codemod, source, options: TransformOptions) => {\n try {\n transform(codemod, source, options);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n const errorStack = err instanceof Error ? err.stack : undefined;\n error(`Error transforming: ${errorMessage}`);\n if (errorStack) {\n error(errorStack);\n }\n process.exit(1);\n }\n});\n\nexport const upgradeCommand = addTransformOptions(\n new Command()\n .command(\"upgrade\")\n .description(\"Upgrade ai package dependencies and apply codemods\"),\n).action(async (options: TransformOptions) => {\n try {\n await upgrade(options);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n const errorStack = err instanceof Error ? err.stack : undefined;\n error(`Error upgrading: ${errorMessage}`);\n if (errorStack) {\n error(errorStack);\n }\n process.exit(1);\n }\n});\n"],"mappings":";;;;;AAYA,MAAM,QAAQ,MAAM,eAAe;AACnC,MAAM,OAAO,WAAW;AAExB,MAAM,uBAAuB,YAA8B;CACzD,OAAO,QACJ,OAAO,aAAa,wCAAwC,CAAC,CAC7D,OAAO,eAAe,mCAAmC,CAAC,CAC1D,OAAO,aAAa,mDAAmD,CAAC,CACxE,OACC,+BACA,sCACF;AACJ;AAEA,MAAa,iBAAiB,oBAC5B,IAAI,QAAQ,CAAC,CACV,KAAK,SAAS,CAAC,CACf,YAAY,+BAA+B,CAAC,CAC5C,SAAS,aAAa,kDAAkD,CAAC,CACzE,SAAS,YAAY,gDAAgD,CAC1E,CAAC,CAAC,QAAQ,SAAS,QAAQ,YAA8B;CACvD,IAAI;EACF,UAAU,SAAS,QAAQ,OAAO;CACpC,SAAS,KAAK;EACZ,MAAM,eAAe,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;EACpE,MAAM,aAAa,eAAe,QAAQ,IAAI,QAAQ,KAAA;EACtD,MAAM,uBAAuB,cAAc;EAC3C,IAAI,YACF,MAAM,UAAU;EAElB,QAAQ,KAAK,CAAC;CAChB;AACF,CAAC;AAED,MAAa,iBAAiB,oBAC5B,IAAI,QAAQ,CAAC,CACV,QAAQ,SAAS,CAAC,CAClB,YAAY,oDAAoD,CACrE,CAAC,CAAC,OAAO,OAAO,YAA8B;CAC5C,IAAI;EACF,MAAM,QAAQ,OAAO;CACvB,SAAS,KAAK;EACZ,MAAM,eAAe,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;EACpE,MAAM,aAAa,eAAe,QAAQ,IAAI,QAAQ,KAAA;EACtD,MAAM,oBAAoB,cAAc;EACxC,IAAI,YACF,MAAM,UAAU;EAElB,QAAQ,KAAK,CAAC;CAChB;AACF,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1 +1 @@
1
- export { };
1
+ export {}
package/dist/index.js CHANGED
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
- import { buildProgram } from "./program.js";
2
+ import { runCli } from "./run.js";
3
3
  //#region src/index.ts
4
4
  process.on("SIGINT", () => process.exit(0));
5
5
  process.on("SIGTERM", () => process.exit(0));
6
- function main() {
7
- buildProgram().parse();
8
- }
9
- main();
6
+ runCli().catch((error) => {
7
+ console.error(error);
8
+ process.exitCode = 1;
9
+ });
10
10
  //#endregion
11
11
 
12
12
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { buildProgram } from \"./program\";\n\nprocess.on(\"SIGINT\", () => process.exit(0));\nprocess.on(\"SIGTERM\", () => process.exit(0));\n\nfunction main() {\n buildProgram().parse();\n}\n\nmain();\n"],"mappings":";;;AAIA,QAAQ,GAAG,gBAAgB,QAAQ,KAAK,CAAC,CAAC;AAC1C,QAAQ,GAAG,iBAAiB,QAAQ,KAAK,CAAC,CAAC;AAE3C,SAAS,OAAO;CACd,aAAa,CAAC,CAAC,MAAM;AACvB;AAEA,KAAK"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { runCli } from \"./run\";\n\nprocess.on(\"SIGINT\", () => process.exit(0));\nprocess.on(\"SIGTERM\", () => process.exit(0));\n\nvoid runCli().catch((error: unknown) => {\n console.error(error);\n process.exitCode = 1;\n});\n"],"mappings":";;;AAIA,QAAQ,GAAG,gBAAgB,QAAQ,KAAK,CAAC,CAAC;AAC1C,QAAQ,GAAG,iBAAiB,QAAQ,KAAK,CAAC,CAAC;AAEtC,OAAO,CAAC,CAAC,OAAO,UAAmB;CACtC,QAAQ,MAAM,KAAK;CACnB,QAAQ,WAAW;AACrB,CAAC"}
@@ -23,7 +23,12 @@ declare function resolveLatestReleaseRef(): Promise<string | undefined>;
23
23
  declare function downloadProject(repoPath: string, destDir: string, ref?: string): Promise<void>;
24
24
  declare function scaffoldProject(repoPath: string, destDir: string, source: ProjectSource): Promise<void>;
25
25
  declare function resolvePackageManagerForCwd(cwd: string, packageManager?: PackageManagerName): Promise<PackageManagerName>;
26
- declare function transformProject(projectDir: string, opts: TransformOptions): Promise<void>;
26
+ interface TransformResult {
27
+ registryInstallFailure?: {
28
+ retryCommand: string;
29
+ };
30
+ }
31
+ declare function transformProject(projectDir: string, opts: TransformOptions): Promise<TransformResult>;
27
32
  //#endregion
28
- export { PackageManagerName, ProjectSource, TransformOptions, dlxCommand, downloadProject, resolveLatestReleaseRef, resolvePackageManager, resolvePackageManagerForCwd, scaffoldProject, transformProject };
33
+ export { PackageManagerName, ProjectSource, TransformOptions, TransformResult, dlxCommand, downloadProject, resolveLatestReleaseRef, resolvePackageManager, resolvePackageManagerForCwd, scaffoldProject, transformProject };
29
34
  //# sourceMappingURL=create-project.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"create-project.d.ts","names":[],"sources":["../../src/lib/create-project.ts"],"mappings":";KAaY;iBAEI,WAAW,IAAI;UAad;EACf;EACA;EACA,gBAAgB;;KAGN;EAEN;EACA;;EAGA;EACA;;iBAcU,sBAAsB;EACpC;EACA;EACA;EACA;IACE;iBAmBkB,2BAA2B;iBAmB3B,gBACpB,kBACA,iBACA,eACC;iBAuDmB,gBACpB,kBACA,iBACA,QAAQ,gBACP;iBAqCmB,4BACpB,aACA,iBAAiB,qBAChB,QAAQ;iBAWW,iBACpB,oBACA,MAAM,mBACL"}
1
+ {"version":3,"file":"create-project.d.ts","names":[],"sources":["../../src/lib/create-project.ts"],"mappings":";KAaY;iBAEI,WAAW,IAAI;UAad;EACf;EACA;EACA,gBAAgB;;KAGN;EAEN;EACA;;EAGA;EACA;;iBAcU,sBAAsB;EACpC;EACA;EACA;EACA;IACE;iBAmBkB,2BAA2B;iBAmB3B,gBACpB,kBACA,iBACA,eACC;iBAuDmB,gBACpB,kBACA,iBACA,QAAQ,gBACP;iBAqCmB,4BACpB,aACA,iBAAiB,qBAChB,QAAQ;UAWM;EACf;IAA2B;;;iBAGP,iBACpB,oBACA,MAAM,mBACL,QAAQ"}
@@ -113,12 +113,12 @@ async function resolvePackageManagerForCwd(cwd, packageManager) {
113
113
  async function transformProject(projectDir, opts) {
114
114
  logger.step("Transforming package.json...");
115
115
  transformPackageJson(projectDir);
116
+ logger.step("Transforming project files...");
117
+ transformTsConfig(projectDir);
118
+ transformCssFiles(projectDir);
116
119
  let assistantUI;
117
120
  let shadcnUI;
118
121
  if (!opts.hasLocalComponents) {
119
- logger.step("Transforming project files...");
120
- transformTsConfig(projectDir);
121
- transformCssFiles(projectDir);
122
122
  const components = scanRequiredComponents(projectDir);
123
123
  assistantUI = components.assistantUI;
124
124
  shadcnUI = components.shadcnUI;
@@ -133,8 +133,10 @@ async function transformProject(projectDir, opts) {
133
133
  const auiComponents = assistantUI.map((c) => `@assistant-ui/${c}`);
134
134
  const components = [...allShadcn, ...auiComponents];
135
135
  logger.step(`Installing components: ${components.join(", ")}...`);
136
- await installShadcnRegistry(projectDir, components, "components", pm);
136
+ const failure = await installShadcnRegistry(projectDir, components, "components", pm);
137
+ if (failure) return { registryInstallFailure: failure };
137
138
  }
139
+ return {};
138
140
  }
139
141
  function transformPackageJson(projectDir) {
140
142
  const pkgPath = path$1.join(projectDir, "package.json");
@@ -171,7 +173,7 @@ function transformTsConfig(projectDir) {
171
173
  "@assistant-ui/ui/*"
172
174
  ]);
173
175
  for (const [key, targets] of Object.entries(tsconfig.compilerOptions.paths)) {
174
- const targetsWorkspace = Array.isArray(targets) && targets.some((target) => typeof target === "string" && target.includes("packages/ui/"));
176
+ const targetsWorkspace = Array.isArray(targets) && targets.some((target) => typeof target === "string" && (target.includes("packages/ui/") || target.startsWith("../")));
175
177
  if (workspaceKeys.has(key) || targetsWorkspace) delete tsconfig.compilerOptions.paths[key];
176
178
  }
177
179
  if (Object.keys(tsconfig.compilerOptions.paths).length === 0) delete tsconfig.compilerOptions.paths;
@@ -254,19 +256,20 @@ async function installDependencies(projectDir, pm) {
254
256
  }
255
257
  async function installShadcnRegistry(projectDir, components, label, pm) {
256
258
  const [cmd, dlxArgs] = dlxCommand(pm);
257
- const addArgs = [
259
+ const retryArgs = [
258
260
  ...dlxArgs,
259
261
  "shadcn@latest",
260
262
  "add",
261
- ...components,
262
- "--yes"
263
+ ...components
263
264
  ];
265
+ const addArgs = [...retryArgs, "--yes"];
264
266
  try {
265
267
  await runSpawn(cmd, addArgs, projectDir);
268
+ return;
266
269
  } catch (error) {
267
270
  if (error instanceof SpawnExitError) {
268
- logger.warn(`shadcn exited with code ${error.code}. Run the following to retry:\n ${cmd} ${addArgs.slice(0, -1).join(" ")}`);
269
- return;
271
+ logger.warn(`shadcn exited with code ${error.code}.`);
272
+ return { retryCommand: `${cmd} ${retryArgs.join(" ")}` };
270
273
  }
271
274
  const message = error instanceof Error ? error.message : String(error);
272
275
  throw new Error(`Failed to install ${label}: ${message}`);
@@ -1 +1 @@
1
- {"version":3,"file":"create-project.js","names":["path","fs","parseJsonc","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 {\n parse as parseJsonc,\n printParseErrorCode,\n type ParseError,\n} from \"jsonc-parser\";\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\nfunction resolveGitHubAuthToken(): string | undefined {\n const token =\n process.env.GIGET_AUTH ?? process.env.GITHUB_TOKEN ?? process.env.GH_TOKEN;\n const trimmed = token?.trim();\n return trimmed || undefined;\n}\n\nfunction toBearerAuthHeader(token: string): string {\n return token.toLowerCase().startsWith(\"bearer \") ? token : `Bearer ${token}`;\n}\n\nexport async function resolveLatestReleaseRef(): Promise<string | undefined> {\n try {\n const authToken = resolveGitHubAuthToken();\n const res = await fetch(\n \"https://api.github.com/repos/assistant-ui/assistant-ui/releases/latest\",\n authToken\n ? { headers: { Authorization: toBearerAuthHeader(authToken) } }\n : undefined,\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 authToken = resolveGitHubAuthToken();\n const downloadPromise = downloadTemplate(source, {\n dir: destDir,\n force: true,\n silent: true,\n ...(authToken ? { auth: authToken } : {}),\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 (\n !opts.skipInstall &&\n !opts.hasLocalComponents &&\n shadcnUI &&\n assistantUI\n ) {\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 parseTsConfig(content: string): any {\n const errors: ParseError[] = [];\n const tsconfig = parseJsonc(content, errors, { allowTrailingComma: true });\n const error = errors[0];\n if (error) {\n throw new SyntaxError(\n `Invalid tsconfig.json: ${printParseErrorCode(error.error)} at offset ${error.offset}`,\n );\n }\n return tsconfig;\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 = parseTsConfig(content);\n\n // Remove workspace paths\n if (tsconfig.compilerOptions?.paths) {\n const workspaceKeys = new Set([\n \"@/components/assistant-ui/*\",\n \"@/components/icons/*\",\n \"@/components/ui/*\",\n \"@/components/ui/radix/*\",\n \"@/hooks/*\",\n \"@/lib/utils\",\n \"@assistant-ui/ui/*\",\n ]);\n for (const [key, targets] of Object.entries(\n tsconfig.compilerOptions.paths as Record<string, unknown>,\n )) {\n const targetsWorkspace =\n Array.isArray(targets) &&\n targets.some(\n (target) =>\n typeof target === \"string\" && target.includes(\"packages/ui/\"),\n );\n if (workspaceKeys.has(key) || targetsWorkspace) {\n delete tsconfig.compilerOptions.paths[key];\n }\n }\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","parseJsonc","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 {\n parse as parseJsonc,\n printParseErrorCode,\n type ParseError,\n} from \"jsonc-parser\";\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\nfunction resolveGitHubAuthToken(): string | undefined {\n const token =\n process.env.GIGET_AUTH ?? process.env.GITHUB_TOKEN ?? process.env.GH_TOKEN;\n const trimmed = token?.trim();\n return trimmed || undefined;\n}\n\nfunction toBearerAuthHeader(token: string): string {\n return token.toLowerCase().startsWith(\"bearer \") ? token : `Bearer ${token}`;\n}\n\nexport async function resolveLatestReleaseRef(): Promise<string | undefined> {\n try {\n const authToken = resolveGitHubAuthToken();\n const res = await fetch(\n \"https://api.github.com/repos/assistant-ui/assistant-ui/releases/latest\",\n authToken\n ? { headers: { Authorization: toBearerAuthHeader(authToken) } }\n : undefined,\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 authToken = resolveGitHubAuthToken();\n const downloadPromise = downloadTemplate(source, {\n dir: destDir,\n force: true,\n silent: true,\n ...(authToken ? { auth: authToken } : {}),\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 interface TransformResult {\n registryInstallFailure?: { retryCommand: string };\n}\n\nexport async function transformProject(\n projectDir: string,\n opts: TransformOptions,\n): Promise<TransformResult> {\n logger.step(\"Transforming package.json...\");\n transformPackageJson(projectDir);\n\n logger.step(\"Transforming project files...\");\n transformTsConfig(projectDir);\n transformCssFiles(projectDir);\n\n let assistantUI: string[] | undefined;\n let shadcnUI: string[] | undefined;\n\n if (!opts.hasLocalComponents) {\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 (\n !opts.skipInstall &&\n !opts.hasLocalComponents &&\n shadcnUI &&\n assistantUI\n ) {\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 const failure = await installShadcnRegistry(\n projectDir,\n components,\n \"components\",\n pm,\n );\n if (failure) return { registryInstallFailure: failure };\n }\n return {};\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 parseTsConfig(content: string): any {\n const errors: ParseError[] = [];\n const tsconfig = parseJsonc(content, errors, { allowTrailingComma: true });\n const error = errors[0];\n if (error) {\n throw new SyntaxError(\n `Invalid tsconfig.json: ${printParseErrorCode(error.error)} at offset ${error.offset}`,\n );\n }\n return tsconfig;\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 = parseTsConfig(content);\n\n // Remove workspace paths\n if (tsconfig.compilerOptions?.paths) {\n const workspaceKeys = new Set([\n \"@/components/assistant-ui/*\",\n \"@/components/icons/*\",\n \"@/components/ui/*\",\n \"@/components/ui/radix/*\",\n \"@/hooks/*\",\n \"@/lib/utils\",\n \"@assistant-ui/ui/*\",\n ]);\n for (const [key, targets] of Object.entries(\n tsconfig.compilerOptions.paths as Record<string, unknown>,\n )) {\n const targetsWorkspace =\n Array.isArray(targets) &&\n targets.some(\n (target) =>\n typeof target === \"string\" &&\n (target.includes(\"packages/ui/\") || target.startsWith(\"../\")),\n );\n if (workspaceKeys.has(key) || targetsWorkspace) {\n delete tsconfig.compilerOptions.paths[key];\n }\n }\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<{ retryCommand: string } | undefined> {\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 retryArgs = [...dlxArgs, \"shadcn@latest\", \"add\", ...components];\n const addArgs = [...retryArgs, \"--yes\"];\n\n try {\n await runSpawn(cmd, addArgs, projectDir);\n return undefined;\n } catch (error) {\n if (error instanceof SpawnExitError) {\n logger.warn(`shadcn exited with code ${error.code}.`);\n return { retryCommand: `${cmd} ${retryArgs.join(\" \")}` };\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 +1 @@
1
- {"version":3,"file":"run-spawn.d.ts","names":[],"sources":["../../src/lib/run-spawn.ts"],"mappings":";cAEa,uBAAuB;EAClC;cAEY;;iBAME,SACd,iBACA,gBACA,eACC"}
1
+ {"version":3,"file":"run-spawn.d.ts","names":[],"sources":["../../src/lib/run-spawn.ts"],"mappings":";cAEa,uBAAuB;EAClC;EAEY,YAAA;;iBAME,SACd,iBACA,gBACA,eACC"}
@@ -1 +1 @@
1
- {"version":3,"file":"upgrade.d.ts","names":[],"sources":["../../src/lib/upgrade.ts"],"mappings":";;;;;;;;iBA2BsB,QAAQ,SAAS,mBAAgB"}
1
+ {"version":3,"file":"upgrade.d.ts","names":[],"sources":["../../src/lib/upgrade.ts"],"mappings":";;;;;;;;iBA4BsB,QAAQ,SAAS,mBAAgB"}
@@ -12,7 +12,8 @@ const bundle = [
12
12
  "v0-11/content-part-to-message-part",
13
13
  "v0-12/assistant-api-to-aui",
14
14
  "v0-12/event-names-to-camelcase",
15
- "v0-12/primitive-if-to-aui-if"
15
+ "v0-12/primitive-if-to-aui-if",
16
+ "v0-15/aui-accessor-calls-to-properties"
16
17
  ];
17
18
  const log = debug("codemod:upgrade");
18
19
  const error = debug("codemod:upgrade:error");
@@ -1 +1 @@
1
- {"version":3,"file":"upgrade.js","names":[],"sources":["../../src/lib/upgrade.ts"],"sourcesContent":["import debug from \"debug\";\nimport { transform, type TransformErrors, getRelevantFiles } from \"./transform\";\nimport type { TransformOptions } from \"./transform-options\";\nimport { SingleBar, Presets } from \"cli-progress\";\nimport installReactUILib from \"./install-ui-lib\";\nimport installEdgeLib from \"./install-edge-lib\";\nimport installAiSdkLib from \"./install-ai-sdk-lib\";\nimport { logger } from \"./utils/logger\";\n\nconst bundle = [\n \"v0-8/ui-package-split\",\n \"v0-9/edge-package-split\",\n \"v0-11/content-part-to-message-part\",\n \"v0-12/assistant-api-to-aui\",\n \"v0-12/event-names-to-camelcase\",\n \"v0-12/primitive-if-to-aui-if\",\n];\n\nconst log = debug(\"codemod:upgrade\");\nconst error = debug(\"codemod:upgrade:error\");\n\n/**\n * Runs the upgrade cycle:\n * - Runs each codemod in the bundle.\n * - Displays progress using cli-progress.\n * - After codemods run, checks if any file now imports from the new packages and prompts for install.\n */\nexport async function upgrade(options: TransformOptions) {\n const cwd = process.cwd();\n log(\"Starting upgrade...\");\n\n // Find relevant files once to avoid duplicate work\n logger.info(\"Analyzing codebase...\");\n const relevantFiles = getRelevantFiles(cwd);\n const fileCount = relevantFiles.length;\n logger.info(`Found ${fileCount} files to process.`);\n\n // Calculate total work units (files × codemods)\n const totalWork = fileCount * bundle.length;\n let completedWork = 0;\n\n const bar = new SingleBar(\n {\n format: \"Progress |{bar}| {percentage}% | ETA: {eta}s || {status}\",\n hideCursor: true,\n },\n Presets.shades_classic,\n );\n\n bar.start(totalWork, 0, { status: \"Starting...\" });\n const allErrors: TransformErrors = [];\n\n for (const codemod of bundle) {\n bar.update(completedWork, { status: `Running ${codemod}...` });\n\n // Use a custom progress callback to update the progress bar\n const errors = transform(codemod, cwd, options, {\n logStatus: false,\n onProgress: (processedFiles: number) => {\n completedWork = bundle.indexOf(codemod) * fileCount + processedFiles;\n bar.update(Math.min(completedWork, totalWork), {\n status: `Running ${codemod} (${processedFiles}/${fileCount} files)`,\n });\n },\n relevantFiles, // Pass the pre-computed relevant files\n });\n\n allErrors.push(...errors);\n completedWork = (bundle.indexOf(codemod) + 1) * fileCount;\n bar.update(completedWork, { status: `Completed ${codemod}` });\n }\n\n bar.update(totalWork, { status: \"Checking dependencies...\" });\n bar.stop();\n\n if (allErrors.length > 0) {\n log(\"Some codemods did not apply successfully to all files. Details:\");\n allErrors.forEach(({ transform, filename, summary }) => {\n error(`codemod=${transform}, path=${filename}, summary=${summary}`);\n });\n }\n\n // After codemods run, check if files import from the new packages and prompt for install.\n logger.info(\"Checking for package dependencies...\");\n await installReactUILib();\n await installEdgeLib();\n await installAiSdkLib();\n\n log(\"Upgrade complete.\");\n logger.success(\"Upgrade complete!\");\n}\n"],"mappings":";;;;;;;;AASA,MAAM,SAAS;CACb;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,MAAM,MAAM,MAAM,iBAAiB;AACnC,MAAM,QAAQ,MAAM,uBAAuB;;;;;;;AAQ3C,eAAsB,QAAQ,SAA2B;CACvD,MAAM,MAAM,QAAQ,IAAI;CACxB,IAAI,qBAAqB;CAGzB,OAAO,KAAK,uBAAuB;CACnC,MAAM,gBAAgB,iBAAiB,GAAG;CAC1C,MAAM,YAAY,cAAc;CAChC,OAAO,KAAK,SAAS,UAAU,mBAAmB;CAGlD,MAAM,YAAY,YAAY,OAAO;CACrC,IAAI,gBAAgB;CAEpB,MAAM,MAAM,IAAI,UACd;EACE,QAAQ;EACR,YAAY;CACd,GACA,QAAQ,cACV;CAEA,IAAI,MAAM,WAAW,GAAG,EAAE,QAAQ,cAAc,CAAC;CACjD,MAAM,YAA6B,CAAC;CAEpC,KAAK,MAAM,WAAW,QAAQ;EAC5B,IAAI,OAAO,eAAe,EAAE,QAAQ,WAAW,QAAQ,KAAK,CAAC;EAG7D,MAAM,SAAS,UAAU,SAAS,KAAK,SAAS;GAC9C,WAAW;GACX,aAAa,mBAA2B;IACtC,gBAAgB,OAAO,QAAQ,OAAO,IAAI,YAAY;IACtD,IAAI,OAAO,KAAK,IAAI,eAAe,SAAS,GAAG,EAC7C,QAAQ,WAAW,QAAQ,IAAI,eAAe,GAAG,UAAU,SAC7D,CAAC;GACH;GACA;EACF,CAAC;EAED,UAAU,KAAK,GAAG,MAAM;EACxB,iBAAiB,OAAO,QAAQ,OAAO,IAAI,KAAK;EAChD,IAAI,OAAO,eAAe,EAAE,QAAQ,aAAa,UAAU,CAAC;CAC9D;CAEA,IAAI,OAAO,WAAW,EAAE,QAAQ,2BAA2B,CAAC;CAC5D,IAAI,KAAK;CAET,IAAI,UAAU,SAAS,GAAG;EACxB,IAAI,iEAAiE;EACrE,UAAU,SAAS,EAAE,WAAW,UAAU,cAAc;GACtD,MAAM,WAAW,UAAU,SAAS,SAAS,YAAY,SAAS;EACpE,CAAC;CACH;CAGA,OAAO,KAAK,sCAAsC;CAClD,MAAM,kBAAkB;CACxB,MAAM,eAAe;CACrB,MAAM,gBAAgB;CAEtB,IAAI,mBAAmB;CACvB,OAAO,QAAQ,mBAAmB;AACpC"}
1
+ {"version":3,"file":"upgrade.js","names":[],"sources":["../../src/lib/upgrade.ts"],"sourcesContent":["import debug from \"debug\";\nimport { transform, type TransformErrors, getRelevantFiles } from \"./transform\";\nimport type { TransformOptions } from \"./transform-options\";\nimport { SingleBar, Presets } from \"cli-progress\";\nimport installReactUILib from \"./install-ui-lib\";\nimport installEdgeLib from \"./install-edge-lib\";\nimport installAiSdkLib from \"./install-ai-sdk-lib\";\nimport { logger } from \"./utils/logger\";\n\nconst bundle = [\n \"v0-8/ui-package-split\",\n \"v0-9/edge-package-split\",\n \"v0-11/content-part-to-message-part\",\n \"v0-12/assistant-api-to-aui\",\n \"v0-12/event-names-to-camelcase\",\n \"v0-12/primitive-if-to-aui-if\",\n \"v0-15/aui-accessor-calls-to-properties\",\n];\n\nconst log = debug(\"codemod:upgrade\");\nconst error = debug(\"codemod:upgrade:error\");\n\n/**\n * Runs the upgrade cycle:\n * - Runs each codemod in the bundle.\n * - Displays progress using cli-progress.\n * - After codemods run, checks if any file now imports from the new packages and prompts for install.\n */\nexport async function upgrade(options: TransformOptions) {\n const cwd = process.cwd();\n log(\"Starting upgrade...\");\n\n // Find relevant files once to avoid duplicate work\n logger.info(\"Analyzing codebase...\");\n const relevantFiles = getRelevantFiles(cwd);\n const fileCount = relevantFiles.length;\n logger.info(`Found ${fileCount} files to process.`);\n\n // Calculate total work units (files × codemods)\n const totalWork = fileCount * bundle.length;\n let completedWork = 0;\n\n const bar = new SingleBar(\n {\n format: \"Progress |{bar}| {percentage}% | ETA: {eta}s || {status}\",\n hideCursor: true,\n },\n Presets.shades_classic,\n );\n\n bar.start(totalWork, 0, { status: \"Starting...\" });\n const allErrors: TransformErrors = [];\n\n for (const codemod of bundle) {\n bar.update(completedWork, { status: `Running ${codemod}...` });\n\n // Use a custom progress callback to update the progress bar\n const errors = transform(codemod, cwd, options, {\n logStatus: false,\n onProgress: (processedFiles: number) => {\n completedWork = bundle.indexOf(codemod) * fileCount + processedFiles;\n bar.update(Math.min(completedWork, totalWork), {\n status: `Running ${codemod} (${processedFiles}/${fileCount} files)`,\n });\n },\n relevantFiles, // Pass the pre-computed relevant files\n });\n\n allErrors.push(...errors);\n completedWork = (bundle.indexOf(codemod) + 1) * fileCount;\n bar.update(completedWork, { status: `Completed ${codemod}` });\n }\n\n bar.update(totalWork, { status: \"Checking dependencies...\" });\n bar.stop();\n\n if (allErrors.length > 0) {\n log(\"Some codemods did not apply successfully to all files. Details:\");\n allErrors.forEach(({ transform, filename, summary }) => {\n error(`codemod=${transform}, path=${filename}, summary=${summary}`);\n });\n }\n\n // After codemods run, check if files import from the new packages and prompt for install.\n logger.info(\"Checking for package dependencies...\");\n await installReactUILib();\n await installEdgeLib();\n await installAiSdkLib();\n\n log(\"Upgrade complete.\");\n logger.success(\"Upgrade complete!\");\n}\n"],"mappings":";;;;;;;;AASA,MAAM,SAAS;CACb;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,MAAM,MAAM,MAAM,iBAAiB;AACnC,MAAM,QAAQ,MAAM,uBAAuB;;;;;;;AAQ3C,eAAsB,QAAQ,SAA2B;CACvD,MAAM,MAAM,QAAQ,IAAI;CACxB,IAAI,qBAAqB;CAGzB,OAAO,KAAK,uBAAuB;CACnC,MAAM,gBAAgB,iBAAiB,GAAG;CAC1C,MAAM,YAAY,cAAc;CAChC,OAAO,KAAK,SAAS,UAAU,mBAAmB;CAGlD,MAAM,YAAY,YAAY,OAAO;CACrC,IAAI,gBAAgB;CAEpB,MAAM,MAAM,IAAI,UACd;EACE,QAAQ;EACR,YAAY;CACd,GACA,QAAQ,cACV;CAEA,IAAI,MAAM,WAAW,GAAG,EAAE,QAAQ,cAAc,CAAC;CACjD,MAAM,YAA6B,CAAC;CAEpC,KAAK,MAAM,WAAW,QAAQ;EAC5B,IAAI,OAAO,eAAe,EAAE,QAAQ,WAAW,QAAQ,KAAK,CAAC;EAG7D,MAAM,SAAS,UAAU,SAAS,KAAK,SAAS;GAC9C,WAAW;GACX,aAAa,mBAA2B;IACtC,gBAAgB,OAAO,QAAQ,OAAO,IAAI,YAAY;IACtD,IAAI,OAAO,KAAK,IAAI,eAAe,SAAS,GAAG,EAC7C,QAAQ,WAAW,QAAQ,IAAI,eAAe,GAAG,UAAU,SAC7D,CAAC;GACH;GACA;EACF,CAAC;EAED,UAAU,KAAK,GAAG,MAAM;EACxB,iBAAiB,OAAO,QAAQ,OAAO,IAAI,KAAK;EAChD,IAAI,OAAO,eAAe,EAAE,QAAQ,aAAa,UAAU,CAAC;CAC9D;CAEA,IAAI,OAAO,WAAW,EAAE,QAAQ,2BAA2B,CAAC;CAC5D,IAAI,KAAK;CAET,IAAI,UAAU,SAAS,GAAG;EACxB,IAAI,iEAAiE;EACrE,UAAU,SAAS,EAAE,WAAW,UAAU,cAAc;GACtD,MAAM,WAAW,UAAU,SAAS,SAAS,YAAY,SAAS;EACpE,CAAC;CACH;CAGA,OAAO,KAAK,sCAAsC;CAClD,MAAM,kBAAkB;CACxB,MAAM,eAAe;CACrB,MAAM,gBAAgB;CAEtB,IAAI,mBAAmB;CACvB,OAAO,QAAQ,mBAAmB;AACpC"}
@@ -1 +1 @@
1
- {"version":3,"file":"logger.d.ts","names":[],"sources":["../../../src/lib/utils/logger.ts"],"mappings":";cAEa"}
1
+ {"version":3,"file":"logger.d.ts","names":[],"sources":["../../../src/lib/utils/logger.ts"],"mappings":";cAEa;EACK,OAAA;EAGG,UAAA;EAGF,QAAA;EAGD,OAAA;EAGA,OAAA"}
@@ -16,7 +16,8 @@ function resolveQuickStartRegistryUrl(style) {
16
16
  return `${REGISTRY_BASE_URL}/chat/b/ai-sdk-quick-start/json`;
17
17
  }
18
18
  function resolveRegistryItemUrl(component, style) {
19
- return `${style?.startsWith("base-") ? `${REGISTRY_BASE_URL}/styles/${encodeURIComponent(style)}` : REGISTRY_BASE_URL}/${encodeURIComponent(component)}.json`;
19
+ if (style === void 0) return `${REGISTRY_BASE_URL}/base/${encodeURIComponent(component)}.json`;
20
+ return `${style.startsWith("base-") ? `${REGISTRY_BASE_URL}/styles/${encodeURIComponent(style)}` : REGISTRY_BASE_URL}/${encodeURIComponent(component)}.json`;
20
21
  }
21
22
  //#endregion
22
23
  export { getComponentsJsonStyle, resolveQuickStartRegistryUrl, resolveRegistryItemUrl };