assistant-ui 0.0.106 → 0.0.107
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.
- package/dist/codemods/v0-12/assistant-api-to-aui.js.map +1 -1
- package/dist/codemods/v0-8/ui-package-split.js.map +1 -1
- package/dist/commands/add.js +1 -1
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/create.d.ts.map +1 -1
- package/dist/commands/create.js +14 -4
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +11 -10
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/info.d.ts +1 -1
- package/dist/commands/info.d.ts.map +1 -1
- package/dist/commands/info.js +13 -14
- package/dist/commands/info.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/lib/create-project.d.ts +7 -2
- package/dist/lib/create-project.d.ts.map +1 -1
- package/dist/lib/create-project.js +13 -10
- package/dist/lib/create-project.js.map +1 -1
- package/dist/lib/run-spawn.d.ts.map +1 -1
- package/dist/lib/utils/logger.d.ts.map +1 -1
- package/dist/lib/utils/registry.js +2 -1
- package/dist/lib/utils/registry.js.map +1 -1
- package/dist/lib/utils/workspace.d.ts +6 -0
- package/dist/lib/utils/workspace.d.ts.map +1 -0
- package/dist/lib/utils/workspace.js +28 -0
- package/dist/lib/utils/workspace.js.map +1 -0
- package/package.json +4 -4
- package/plugin/skills/assistant-ui/SKILL.md +24 -5
- package/src/commands/add.ts +1 -1
- package/src/commands/create.ts +16 -4
- package/src/commands/doctor.ts +17 -13
- package/src/commands/info.ts +21 -20
- package/src/lib/create-project.ts +25 -14
- package/src/lib/utils/registry.test.ts +8 -2
- package/src/lib/utils/registry.ts +5 -1
- package/src/lib/utils/workspace.ts +34 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assistant-api-to-aui.js","names":[],"sources":["../../../src/codemods/v0-12/assistant-api-to-aui.ts"],"sourcesContent":["import { createTransformer } from \"../utils/createTransformer\";\n\n// Map of old hook names to new hook names\nconst hookRenamingMap: Record<string, string> = {\n useAssistantApi: \"useAui\",\n useAssistantState: \"useAuiState\",\n useAssistantEvent: \"useAuiEvent\",\n};\n\n// Map of old component names to new component names\nconst componentRenamingMap: Record<string, string> = {\n AssistantIf: \"AuiIf\",\n AssistantProvider: \"AuiProvider\",\n};\n\nconst isUseAuiCall = (j: any, node: any): boolean => {\n return (\n node &&\n j.CallExpression.check(node) &&\n j.Identifier.check(node.callee) &&\n (node.callee.name === \"useAui\" || node.callee.name === \"useAssistantApi\")\n );\n};\n\n// Check if a scope node directly contains an 'api' variable declaration\nconst scopeHasDirectApiDeclaration = (j: any, scopeNode: any): boolean => {\n // Get the body of the scope\n let body = null;\n if (\n j.FunctionDeclaration.check(scopeNode) ||\n j.FunctionExpression.check(scopeNode)\n ) {\n body = scopeNode.body?.body;\n } else if (j.ArrowFunctionExpression.check(scopeNode)) {\n // Arrow functions might have block or expression body\n if (j.BlockStatement.check(scopeNode.body)) {\n body = scopeNode.body.body;\n }\n } else if (j.BlockStatement.check(scopeNode)) {\n body = scopeNode.body;\n }\n\n if (!Array.isArray(body)) return false;\n\n // Check only direct statements in this scope's body\n for (const statement of body) {\n if (j.VariableDeclaration.check(statement)) {\n for (const declarator of statement.declarations) {\n if (j.Identifier.check(declarator.id) && declarator.id.name === \"api\") {\n // Don't count it as shadowing if it's from useAui\n if (!isUseAuiCall(j, declarator.init)) {\n return true;\n }\n }\n }\n }\n }\n\n return false;\n};\n\n// Check if a path is inside a scope that shadows the api variable\nconst isInsideShadowingScope = (j: any, identifierPath: any): boolean => {\n let currentPath = identifierPath.parent;\n\n while (currentPath) {\n const node = currentPath.value;\n\n // Check if this is a scope-creating node (function, arrow function, block)\n if (\n j.FunctionDeclaration.check(node) ||\n j.FunctionExpression.check(node) ||\n j.ArrowFunctionExpression.check(node) ||\n j.BlockStatement.check(node)\n ) {\n if (scopeHasDirectApiDeclaration(j, node)) {\n return true;\n }\n }\n\n currentPath = currentPath.parent;\n }\n\n return false;\n};\n\nconst migrateAssistantApiToAui = createTransformer(\n ({ j, root, markAsChanged }) => {\n let hasApiFromUseAui = false;\n\n // 1. Update imports\n root.find(j.ImportDeclaration).forEach((path: any) => {\n const source = path.value.source.value;\n\n // Only process imports from @assistant-ui packages\n if (typeof source === \"string\" && source.startsWith(\"@assistant-ui/\")) {\n path.value.specifiers?.forEach((specifier: any) => {\n if (j.ImportSpecifier.check(specifier)) {\n const oldName = specifier.imported.name as string;\n\n // Rename hooks\n if (hookRenamingMap[oldName]) {\n const newName = hookRenamingMap[oldName];\n specifier.imported.name = newName;\n if (specifier.local && specifier.local.name === oldName) {\n specifier.local.name = newName;\n }\n markAsChanged();\n }\n\n // Rename components\n if (componentRenamingMap[oldName]) {\n const newName = componentRenamingMap[oldName];\n specifier.imported.name = newName;\n if (specifier.local && specifier.local.name === oldName) {\n specifier.local.name = newName;\n }\n markAsChanged();\n }\n }\n });\n }\n });\n\n // 2. Find and rename variable declarations from useAui (or useAssistantApi)\n root.find(j.VariableDeclarator).forEach((path: any) => {\n const init = path.value.init;\n\n // Check if this is a call to useAui or useAssistantApi\n if (isUseAuiCall(j, init)) {\n if (j.Identifier.check(path.value.id)) {\n const oldVarName = path.value.id.name;\n\n // Only rename if it's called 'api'\n if (oldVarName === \"api\") {\n path.value.id.name = \"aui\";\n hasApiFromUseAui = true;\n markAsChanged();\n }\n }\n }\n });\n\n // 3. Rename all references to 'api' if we found it from useAui\n if (hasApiFromUseAui) {\n root.find(j.Identifier).forEach((path: any) => {\n if (path.value.name === \"api\") {\n // Skip if this is part of an import\n if (j.ImportSpecifier.check(path.parent.value)) {\n return;\n }\n\n // Skip if this is a variable declarator id\n if (j.VariableDeclarator.check(path.parent.value)) {\n const declarator = path.parent.value;\n if (declarator.id === path.value) {\n return;\n }\n }\n\n // Skip if this is a property key in an object (e.g., { api: true })\n if (j.Property.check(path.parent.value)) {\n const prop = path.parent.value;\n if (prop.key === path.value && !prop.shorthand && !prop.computed) {\n return;\n }\n }\n\n if (j.ObjectProperty.check(path.parent.value)) {\n const prop = path.parent.value;\n if (prop.key === path.value && !prop.shorthand && !prop.computed) {\n return;\n }\n }\n\n // Skip if this is a property in a member expression (e.g., foo.api)\n if (\n j.MemberExpression.check(path.parent.value) &&\n path.parent.value.property === path.value &&\n !path.parent.value.computed\n ) {\n return;\n }\n\n // Skip if this is a JSX attribute name\n if (j.JSXAttribute.check(path.parent.value)) {\n return;\n }\n\n // Skip if this identifier is inside a scope that shadows the api variable\n if (isInsideShadowingScope(j, path)) {\n return;\n }\n\n // Update the reference\n path.value.name = \"aui\";\n markAsChanged();\n }\n });\n\n // Also handle JSX identifiers\n root.find(j.JSXIdentifier).forEach((path: any) => {\n if (path.value.name === \"api\") {\n if (!isInsideShadowingScope(j, path)) {\n path.value.name = \"aui\";\n markAsChanged();\n }\n }\n });\n }\n\n // 4. Update hook call references (in case they're used as values)\n Object.entries(hookRenamingMap).forEach(([oldName, newName]) => {\n root.find(j.Identifier).forEach((path: any) => {\n if (path.value.name === oldName) {\n // Skip if already handled in imports\n if (j.ImportSpecifier.check(path.parent.value)) {\n return;\n }\n\n // This might be a reference to the hook as a value\n path.value.name = newName;\n markAsChanged();\n }\n });\n });\n\n // 5. Update JSX component names\n Object.entries(componentRenamingMap).forEach(([oldName, newName]) => {\n // Update JSX opening elements\n root.find(j.JSXOpeningElement).forEach((path: any) => {\n if (\n j.JSXIdentifier.check(path.value.name) &&\n path.value.name.name === oldName\n ) {\n path.value.name.name = newName;\n markAsChanged();\n }\n });\n\n // Update JSX closing elements\n root.find(j.JSXClosingElement).forEach((path: any) => {\n if (\n j.JSXIdentifier.check(path.value.name) &&\n path.value.name.name === oldName\n ) {\n path.value.name.name = newName;\n markAsChanged();\n }\n });\n\n // Update regular identifier references (for component references)\n root.find(j.Identifier).forEach((path: any) => {\n if (path.value.name === oldName) {\n // Skip if already handled in imports\n if (j.ImportSpecifier.check(path.parent.value)) {\n return;\n }\n\n // Skip JSX identifiers (already handled above)\n if (j.JSXIdentifier.check(path.value)) {\n return;\n }\n\n // This might be a reference to the component as a value\n path.value.name = newName;\n markAsChanged();\n }\n });\n });\n },\n);\n\nexport default migrateAssistantApiToAui;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"assistant-api-to-aui.js","names":[],"sources":["../../../src/codemods/v0-12/assistant-api-to-aui.ts"],"sourcesContent":["import { createTransformer } from \"../utils/createTransformer\";\n\n// Map of old hook names to new hook names\nconst hookRenamingMap: Record<string, string> = {\n useAssistantApi: \"useAui\",\n useAssistantState: \"useAuiState\",\n useAssistantEvent: \"useAuiEvent\",\n};\n\n// Map of old component names to new component names\nconst componentRenamingMap: Record<string, string> = {\n AssistantIf: \"AuiIf\",\n AssistantProvider: \"AuiProvider\",\n};\n\nconst isUseAuiCall = (j: any, node: any): boolean => {\n return (\n node &&\n j.CallExpression.check(node) &&\n j.Identifier.check(node.callee) &&\n (node.callee.name === \"useAui\" || node.callee.name === \"useAssistantApi\")\n );\n};\n\n// Check if a scope node directly contains an 'api' variable declaration\nconst scopeHasDirectApiDeclaration = (j: any, scopeNode: any): boolean => {\n // Get the body of the scope\n let body = null;\n if (\n j.FunctionDeclaration.check(scopeNode) ||\n j.FunctionExpression.check(scopeNode)\n ) {\n body = scopeNode.body?.body;\n } else if (j.ArrowFunctionExpression.check(scopeNode)) {\n // Arrow functions might have block or expression body\n if (j.BlockStatement.check(scopeNode.body)) {\n body = scopeNode.body.body;\n }\n } else if (j.BlockStatement.check(scopeNode)) {\n body = scopeNode.body;\n }\n\n if (!Array.isArray(body)) return false;\n\n // Check only direct statements in this scope's body\n for (const statement of body) {\n if (j.VariableDeclaration.check(statement)) {\n for (const declarator of statement.declarations) {\n if (j.Identifier.check(declarator.id) && declarator.id.name === \"api\") {\n // Don't count it as shadowing if it's from useAui\n if (!isUseAuiCall(j, declarator.init)) {\n return true;\n }\n }\n }\n }\n }\n\n return false;\n};\n\n// Check if a path is inside a scope that shadows the api variable\nconst isInsideShadowingScope = (j: any, identifierPath: any): boolean => {\n let currentPath = identifierPath.parent;\n\n while (currentPath) {\n const node = currentPath.value;\n\n // Check if this is a scope-creating node (function, arrow function, block)\n if (\n j.FunctionDeclaration.check(node) ||\n j.FunctionExpression.check(node) ||\n j.ArrowFunctionExpression.check(node) ||\n j.BlockStatement.check(node)\n ) {\n if (scopeHasDirectApiDeclaration(j, node)) {\n return true;\n }\n }\n\n currentPath = currentPath.parent;\n }\n\n return false;\n};\n\nconst migrateAssistantApiToAui = createTransformer(\n ({ j, root, markAsChanged }) => {\n let hasApiFromUseAui = false;\n\n // 1. Update imports\n root.find(j.ImportDeclaration).forEach((path: any) => {\n const source = path.value.source.value;\n\n // Only process imports from @assistant-ui packages\n if (typeof source === \"string\" && source.startsWith(\"@assistant-ui/\")) {\n path.value.specifiers?.forEach((specifier: any) => {\n if (j.ImportSpecifier.check(specifier)) {\n const oldName = specifier.imported.name as string;\n\n // Rename hooks\n if (hookRenamingMap[oldName]) {\n const newName = hookRenamingMap[oldName];\n specifier.imported.name = newName;\n if (specifier.local && specifier.local.name === oldName) {\n specifier.local.name = newName;\n }\n markAsChanged();\n }\n\n // Rename components\n if (componentRenamingMap[oldName]) {\n const newName = componentRenamingMap[oldName];\n specifier.imported.name = newName;\n if (specifier.local && specifier.local.name === oldName) {\n specifier.local.name = newName;\n }\n markAsChanged();\n }\n }\n });\n }\n });\n\n // 2. Find and rename variable declarations from useAui (or useAssistantApi)\n root.find(j.VariableDeclarator).forEach((path: any) => {\n const init = path.value.init;\n\n // Check if this is a call to useAui or useAssistantApi\n if (isUseAuiCall(j, init)) {\n if (j.Identifier.check(path.value.id)) {\n const oldVarName = path.value.id.name;\n\n // Only rename if it's called 'api'\n if (oldVarName === \"api\") {\n path.value.id.name = \"aui\";\n hasApiFromUseAui = true;\n markAsChanged();\n }\n }\n }\n });\n\n // 3. Rename all references to 'api' if we found it from useAui\n if (hasApiFromUseAui) {\n root.find(j.Identifier).forEach((path: any) => {\n if (path.value.name === \"api\") {\n // Skip if this is part of an import\n if (j.ImportSpecifier.check(path.parent.value)) {\n return;\n }\n\n // Skip if this is a variable declarator id\n if (j.VariableDeclarator.check(path.parent.value)) {\n const declarator = path.parent.value;\n if (declarator.id === path.value) {\n return;\n }\n }\n\n // Skip if this is a property key in an object (e.g., { api: true })\n if (j.Property.check(path.parent.value)) {\n const prop = path.parent.value;\n if (prop.key === path.value && !prop.shorthand && !prop.computed) {\n return;\n }\n }\n\n if (j.ObjectProperty.check(path.parent.value)) {\n const prop = path.parent.value;\n if (prop.key === path.value && !prop.shorthand && !prop.computed) {\n return;\n }\n }\n\n // Skip if this is a property in a member expression (e.g., foo.api)\n if (\n j.MemberExpression.check(path.parent.value) &&\n path.parent.value.property === path.value &&\n !path.parent.value.computed\n ) {\n return;\n }\n\n // Skip if this is a JSX attribute name\n if (j.JSXAttribute.check(path.parent.value)) {\n return;\n }\n\n // Skip if this identifier is inside a scope that shadows the api variable\n if (isInsideShadowingScope(j, path)) {\n return;\n }\n\n // Update the reference\n path.value.name = \"aui\";\n markAsChanged();\n }\n });\n\n // Also handle JSX identifiers\n root.find(j.JSXIdentifier).forEach((path: any) => {\n if (path.value.name === \"api\") {\n if (!isInsideShadowingScope(j, path)) {\n path.value.name = \"aui\";\n markAsChanged();\n }\n }\n });\n }\n\n // 4. Update hook call references (in case they're used as values)\n Object.entries(hookRenamingMap).forEach(([oldName, newName]) => {\n root.find(j.Identifier).forEach((path: any) => {\n if (path.value.name === oldName) {\n // Skip if already handled in imports\n if (j.ImportSpecifier.check(path.parent.value)) {\n return;\n }\n\n // This might be a reference to the hook as a value\n path.value.name = newName;\n markAsChanged();\n }\n });\n });\n\n // 5. Update JSX component names\n Object.entries(componentRenamingMap).forEach(([oldName, newName]) => {\n // Update JSX opening elements\n root.find(j.JSXOpeningElement).forEach((path: any) => {\n if (\n j.JSXIdentifier.check(path.value.name) &&\n path.value.name.name === oldName\n ) {\n path.value.name.name = newName;\n markAsChanged();\n }\n });\n\n // Update JSX closing elements\n root.find(j.JSXClosingElement).forEach((path: any) => {\n if (\n j.JSXIdentifier.check(path.value.name) &&\n path.value.name.name === oldName\n ) {\n path.value.name.name = newName;\n markAsChanged();\n }\n });\n\n // Update regular identifier references (for component references)\n root.find(j.Identifier).forEach((path: any) => {\n if (path.value.name === oldName) {\n // Skip if already handled in imports\n if (j.ImportSpecifier.check(path.parent.value)) {\n return;\n }\n\n // Skip JSX identifiers (already handled above)\n if (j.JSXIdentifier.check(path.value)) {\n return;\n }\n\n // This might be a reference to the component as a value\n path.value.name = newName;\n markAsChanged();\n }\n });\n });\n },\n);\n\nexport default migrateAssistantApiToAui;\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui-package-split.js","names":[],"sources":["../../../src/codemods/v0-8/ui-package-split.ts"],"sourcesContent":["import { createTransformer } from \"../utils/createTransformer\";\n\nconst reactUIExports: string[] = [\n \"ThreadConfigProvider\",\n \"useThreadConfig\",\n \"ThreadConfig\",\n \"ThreadWelcomeConfig\",\n \"UserMessageConfig\",\n \"AssistantMessageConfig\",\n \"StringsConfig\",\n \"SuggestionConfig\",\n \"ThreadConfigProviderProps\",\n \"AssistantActionBar\",\n \"AssistantMessage\",\n \"AssistantModal\",\n \"BranchPicker\",\n \"Composer\",\n \"MessagePart\",\n \"AttachmentUI\",\n \"EditComposer\",\n \"Thread\",\n \"ThreadList\",\n \"ThreadListItem\",\n \"ThreadWelcome\",\n \"UserMessage\",\n \"makeMarkdownText\",\n \"MakeMarkdownTextProps\",\n \"CodeHeader\",\n];\n\nconst migrateAssistantUI = createTransformer(({ j, root, markAsChanged }) => {\n const sourcesToMigrate: string[] = [\n \"@assistant-ui/react\",\n \"@assistant-ui/react-markdown\",\n ];\n const movedSpecifiers: any[] = [];\n let lastMigratedImportPath: any = null;\n\n root\n .find(j.ImportDeclaration)\n .filter((path: any) => sourcesToMigrate.includes(path.value.source.value))\n .forEach((path: any) => {\n let hadMigratedSpecifiers = false;\n const remainingSpecifiers: any[] = [];\n path.value.specifiers.forEach((specifier: any) => {\n if (\n j.ImportSpecifier.check(specifier) &&\n reactUIExports.includes(specifier.imported.name as string)\n ) {\n movedSpecifiers.push(specifier);\n hadMigratedSpecifiers = true;\n } else {\n remainingSpecifiers.push(specifier);\n }\n });\n if (hadMigratedSpecifiers) {\n lastMigratedImportPath = path;\n }\n if (remainingSpecifiers.length === 0) {\n j(path).remove();\n markAsChanged();\n } else if (remainingSpecifiers.length !== path.value.specifiers.length) {\n path.value.specifiers = remainingSpecifiers;\n markAsChanged();\n }\n });\n\n if (movedSpecifiers.length > 0) {\n const existingReactUIImport = root.find(j.ImportDeclaration, {\n source: { value: \"@assistant-ui/react-ui\" },\n });\n if (existingReactUIImport.size() > 0) {\n existingReactUIImport.forEach((path: any) => {\n movedSpecifiers.forEach((specifier: any) => {\n if (\n !path.value.specifiers.some(\n (s: any) => s.imported.name === specifier.imported.name,\n )\n ) {\n path.value.specifiers.push(specifier);\n }\n });\n });\n } else {\n const newImport = j.importDeclaration(\n movedSpecifiers,\n j.literal(\"@assistant-ui/react-ui\"),\n );\n if (lastMigratedImportPath) {\n j(lastMigratedImportPath).insertAfter(newImport);\n } else {\n const firstImport = root.find(j.ImportDeclaration).at(0);\n if (firstImport.size() > 0) {\n firstImport.insertBefore(newImport);\n } else {\n root.get().node.program.body.unshift(newImport);\n }\n }\n }\n markAsChanged();\n }\n\n const cssReplacements: Record<string, string> = {\n \"@assistant-ui/react/styles/index.css\":\n \"@assistant-ui/react-ui/styles/index.css\",\n \"@assistant-ui/react/styles/modal.css\":\n \"@assistant-ui/react-ui/styles/modal.css\",\n \"@assistant-ui/react-markdown/styles/markdown.css\":\n \"@assistant-ui/react-ui/styles/markdown.css\",\n };\n\n root.find(j.ImportDeclaration).forEach((path: any) => {\n const sourceValue: string = path.value.source.value;\n if (cssReplacements[sourceValue]) {\n path.value.source = j.literal(cssReplacements[sourceValue]);\n markAsChanged();\n }\n });\n\n let removedMarkdownPlugin = false;\n root\n .find(j.CallExpression, { callee: { name: \"require\" } })\n .filter((path: any) => {\n const arg = path.value.arguments[0];\n return (\n arg &&\n (arg.type === \"Literal\" || arg.type === \"StringLiteral\") &&\n arg.value === \"@assistant-ui/react-markdown/tailwindcss\"\n );\n })\n .forEach((path: any) => {\n removedMarkdownPlugin = true;\n const parent = path.parentPath;\n if (parent?.value && parent.value.type === \"VariableDeclarator\") {\n const varDecl = parent.parentPath;\n if (\n varDecl?.value.declarations &&\n varDecl.value.declarations.length === 1\n ) {\n j(varDecl).remove();\n } else {\n varDecl.value.declarations = varDecl.value.declarations.filter(\n (decl: any) => decl !== parent.value,\n );\n }\n markAsChanged();\n } else {\n j(path).remove();\n markAsChanged();\n }\n });\n\n root\n .find(j.CallExpression, { callee: { name: \"require\" } })\n .filter((path: any) => {\n const arg = path.value.arguments[0];\n return (\n arg &&\n (arg.type === \"Literal\" || arg.type === \"StringLiteral\") &&\n arg.value === \"@assistant-ui/react/tailwindcss\"\n );\n })\n .forEach((path: any) => {\n path.value.arguments[0].value = \"@assistant-ui/react-ui/tailwindcss\";\n markAsChanged();\n if (removedMarkdownPlugin) {\n if (\n path.parentPath?.value &&\n path.parentPath.value.type === \"CallExpression\" &&\n path.parentPath.value.arguments.length > 0\n ) {\n const configObj = path.parentPath.value.arguments[0];\n if (configObj && configObj.type === \"ObjectExpression\") {\n const componentsProp = configObj.properties.find((prop: any) => {\n return (\n (prop.key.name === \"components\" ||\n prop.key.value === \"components\") &&\n prop.value.type === \"ArrayExpression\"\n );\n });\n if (componentsProp) {\n const componentsArray = componentsProp.value.elements;\n const hasMarkdown = componentsArray.some(\n (el: any) => el.type === \"Literal\" && el.value === \"markdown\",\n );\n if (!hasMarkdown) {\n componentsArray.push(j.literal(\"markdown\"));\n markAsChanged();\n }\n }\n }\n }\n }\n });\n});\n\nexport default migrateAssistantUI;\n"],"mappings":"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
|
|
1
|
+
{"version":3,"file":"ui-package-split.js","names":[],"sources":["../../../src/codemods/v0-8/ui-package-split.ts"],"sourcesContent":["import { createTransformer } from \"../utils/createTransformer\";\n\nconst reactUIExports: string[] = [\n \"ThreadConfigProvider\",\n \"useThreadConfig\",\n \"ThreadConfig\",\n \"ThreadWelcomeConfig\",\n \"UserMessageConfig\",\n \"AssistantMessageConfig\",\n \"StringsConfig\",\n \"SuggestionConfig\",\n \"ThreadConfigProviderProps\",\n \"AssistantActionBar\",\n \"AssistantMessage\",\n \"AssistantModal\",\n \"BranchPicker\",\n \"Composer\",\n \"MessagePart\",\n \"AttachmentUI\",\n \"EditComposer\",\n \"Thread\",\n \"ThreadList\",\n \"ThreadListItem\",\n \"ThreadWelcome\",\n \"UserMessage\",\n \"makeMarkdownText\",\n \"MakeMarkdownTextProps\",\n \"CodeHeader\",\n];\n\nconst migrateAssistantUI = createTransformer(({ j, root, markAsChanged }) => {\n const sourcesToMigrate: string[] = [\n \"@assistant-ui/react\",\n \"@assistant-ui/react-markdown\",\n ];\n const movedSpecifiers: any[] = [];\n let lastMigratedImportPath: any = null;\n\n root\n .find(j.ImportDeclaration)\n .filter((path: any) => sourcesToMigrate.includes(path.value.source.value))\n .forEach((path: any) => {\n let hadMigratedSpecifiers = false;\n const remainingSpecifiers: any[] = [];\n path.value.specifiers.forEach((specifier: any) => {\n if (\n j.ImportSpecifier.check(specifier) &&\n reactUIExports.includes(specifier.imported.name as string)\n ) {\n movedSpecifiers.push(specifier);\n hadMigratedSpecifiers = true;\n } else {\n remainingSpecifiers.push(specifier);\n }\n });\n if (hadMigratedSpecifiers) {\n lastMigratedImportPath = path;\n }\n if (remainingSpecifiers.length === 0) {\n j(path).remove();\n markAsChanged();\n } else if (remainingSpecifiers.length !== path.value.specifiers.length) {\n path.value.specifiers = remainingSpecifiers;\n markAsChanged();\n }\n });\n\n if (movedSpecifiers.length > 0) {\n const existingReactUIImport = root.find(j.ImportDeclaration, {\n source: { value: \"@assistant-ui/react-ui\" },\n });\n if (existingReactUIImport.size() > 0) {\n existingReactUIImport.forEach((path: any) => {\n movedSpecifiers.forEach((specifier: any) => {\n if (\n !path.value.specifiers.some(\n (s: any) => s.imported.name === specifier.imported.name,\n )\n ) {\n path.value.specifiers.push(specifier);\n }\n });\n });\n } else {\n const newImport = j.importDeclaration(\n movedSpecifiers,\n j.literal(\"@assistant-ui/react-ui\"),\n );\n if (lastMigratedImportPath) {\n j(lastMigratedImportPath).insertAfter(newImport);\n } else {\n const firstImport = root.find(j.ImportDeclaration).at(0);\n if (firstImport.size() > 0) {\n firstImport.insertBefore(newImport);\n } else {\n root.get().node.program.body.unshift(newImport);\n }\n }\n }\n markAsChanged();\n }\n\n const cssReplacements: Record<string, string> = {\n \"@assistant-ui/react/styles/index.css\":\n \"@assistant-ui/react-ui/styles/index.css\",\n \"@assistant-ui/react/styles/modal.css\":\n \"@assistant-ui/react-ui/styles/modal.css\",\n \"@assistant-ui/react-markdown/styles/markdown.css\":\n \"@assistant-ui/react-ui/styles/markdown.css\",\n };\n\n root.find(j.ImportDeclaration).forEach((path: any) => {\n const sourceValue: string = path.value.source.value;\n if (cssReplacements[sourceValue]) {\n path.value.source = j.literal(cssReplacements[sourceValue]);\n markAsChanged();\n }\n });\n\n let removedMarkdownPlugin = false;\n root\n .find(j.CallExpression, { callee: { name: \"require\" } })\n .filter((path: any) => {\n const arg = path.value.arguments[0];\n return (\n arg &&\n (arg.type === \"Literal\" || arg.type === \"StringLiteral\") &&\n arg.value === \"@assistant-ui/react-markdown/tailwindcss\"\n );\n })\n .forEach((path: any) => {\n removedMarkdownPlugin = true;\n const parent = path.parentPath;\n if (parent?.value && parent.value.type === \"VariableDeclarator\") {\n const varDecl = parent.parentPath;\n if (\n varDecl?.value.declarations &&\n varDecl.value.declarations.length === 1\n ) {\n j(varDecl).remove();\n } else {\n varDecl.value.declarations = varDecl.value.declarations.filter(\n (decl: any) => decl !== parent.value,\n );\n }\n markAsChanged();\n } else {\n j(path).remove();\n markAsChanged();\n }\n });\n\n root\n .find(j.CallExpression, { callee: { name: \"require\" } })\n .filter((path: any) => {\n const arg = path.value.arguments[0];\n return (\n arg &&\n (arg.type === \"Literal\" || arg.type === \"StringLiteral\") &&\n arg.value === \"@assistant-ui/react/tailwindcss\"\n );\n })\n .forEach((path: any) => {\n path.value.arguments[0].value = \"@assistant-ui/react-ui/tailwindcss\";\n markAsChanged();\n if (removedMarkdownPlugin) {\n if (\n path.parentPath?.value &&\n path.parentPath.value.type === \"CallExpression\" &&\n path.parentPath.value.arguments.length > 0\n ) {\n const configObj = path.parentPath.value.arguments[0];\n if (configObj && configObj.type === \"ObjectExpression\") {\n const componentsProp = configObj.properties.find((prop: any) => {\n return (\n (prop.key.name === \"components\" ||\n prop.key.value === \"components\") &&\n prop.value.type === \"ArrayExpression\"\n );\n });\n if (componentsProp) {\n const componentsArray = componentsProp.value.elements;\n const hasMarkdown = componentsArray.some(\n (el: any) => el.type === \"Literal\" && el.value === \"markdown\",\n );\n if (!hasMarkdown) {\n componentsArray.push(j.literal(\"markdown\"));\n markAsChanged();\n }\n }\n }\n }\n }\n });\n});\n\nexport default migrateAssistantUI;\n"],"mappings":"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"}
|
package/dist/commands/add.js
CHANGED
|
@@ -28,7 +28,7 @@ function createAddComponentsPlan(params) {
|
|
|
28
28
|
}
|
|
29
29
|
const add = new Command().name("add").description("add a component to your project").argument("<components...>", "the components to add").option("-y, --yes", "skip confirmation prompt.", true).option("-o, --overwrite", "overwrite existing files.", false).option("-c, --cwd <cwd>", "the working directory. defaults to the current directory.", process.cwd()).option("-p, --path <path>", "the path to add the component to.").option("--use-npm", "explicitly use npm").option("--use-pnpm", "explicitly use pnpm").option("--use-yarn", "explicitly use yarn").option("--use-bun", "explicitly use bun").action(async (components, opts) => {
|
|
30
30
|
if (!hasConfig(opts.cwd)) {
|
|
31
|
-
logger.warn("It looks like you haven't initialized your project yet. Run 'assistant-ui init' first.");
|
|
31
|
+
logger.warn("It looks like you haven't initialized your project yet — defaulting to Base UI flavored components. Run 'assistant-ui init' first for a configured setup.");
|
|
32
32
|
logger.break();
|
|
33
33
|
}
|
|
34
34
|
logger.step(`Adding ${components.length} component(s)...`);
|
package/dist/commands/add.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add.js","names":[],"sources":["../../src/commands/add.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { logger } from \"../lib/utils/logger\";\nimport { hasConfig } from \"../lib/utils/config\";\nimport {\n getComponentsJsonStyle,\n resolveRegistryItemUrl,\n} from \"../lib/utils/registry\";\nimport {\n dlxCommand,\n resolvePackageManager,\n resolvePackageManagerForCwd,\n type PackageManagerName,\n} from \"../lib/create-project\";\nimport { runSpawn, SpawnExitError } from \"../lib/run-spawn\";\n\nexport interface AddComponentsPlan {\n command: string;\n args: string[];\n}\n\nexport function createAddComponentsPlan(params: {\n components: string[];\n packageManager: PackageManagerName;\n yes?: boolean;\n overwrite?: boolean;\n cwd?: string;\n path?: string;\n style?: string;\n}): AddComponentsPlan {\n const componentsToAdd = params.components.map((c) => {\n if (!/^[a-zA-Z0-9-/]+$/.test(c)) {\n throw new Error(`Invalid component name: ${c}`);\n }\n return resolveRegistryItemUrl(c, params.style);\n });\n\n const [command, dlxArgs] = dlxCommand(params.packageManager);\n const args = [...dlxArgs, \"shadcn@latest\", \"add\", ...componentsToAdd];\n\n // For npm, dlxArgs may already include `--yes` for npx auto-install.\n // This flag is for shadcn's own confirmation prompt.\n if (params.yes) args.push(\"--yes\");\n if (params.overwrite) args.push(\"--overwrite\");\n if (params.cwd) args.push(\"--cwd\", params.cwd);\n if (params.path) args.push(\"--path\", params.path);\n\n return { command, args };\n}\n\nexport const add = new Command()\n .name(\"add\")\n .description(\"add a component to your project\")\n .argument(\"<components...>\", \"the components to add\")\n .option(\"-y, --yes\", \"skip confirmation prompt.\", true)\n .option(\"-o, --overwrite\", \"overwrite existing files.\", false)\n .option(\n \"-c, --cwd <cwd>\",\n \"the working directory. defaults to the current directory.\",\n process.cwd(),\n )\n .option(\"-p, --path <path>\", \"the path to add the component to.\")\n .option(\"--use-npm\", \"explicitly use npm\")\n .option(\"--use-pnpm\", \"explicitly use pnpm\")\n .option(\"--use-yarn\", \"explicitly use yarn\")\n .option(\"--use-bun\", \"explicitly use bun\")\n .action(async (components: string[], opts) => {\n // Check if project is initialized\n if (!hasConfig(opts.cwd)) {\n logger.warn(\n \"It looks like you haven't initialized your project yet. Run 'assistant-ui init' first.\",\n );\n logger.break();\n }\n\n logger.step(`Adding ${components.length} component(s)...`);\n\n const packageManager = await resolvePackageManagerForCwd(\n opts.cwd,\n resolvePackageManager(opts),\n );\n const style = getComponentsJsonStyle(opts.cwd);\n const { command, args } = createAddComponentsPlan({\n components,\n packageManager,\n yes: opts.yes,\n overwrite: opts.overwrite,\n cwd: opts.cwd,\n path: opts.path,\n ...(style === undefined ? {} : { style }),\n });\n\n try {\n await runSpawn(command, args, opts.cwd);\n } catch (error) {\n if (error instanceof SpawnExitError) {\n logger.error(`Process exited with code ${error.code}`);\n process.exit(error.code);\n }\n const message = error instanceof Error ? error.message : String(error);\n logger.error(`Failed to add components: ${message}`);\n process.exit(1);\n }\n\n logger.success(\"Components added successfully!\");\n });\n"],"mappings":";;;;;;;AAoBA,SAAgB,wBAAwB,QAQlB;CACpB,MAAM,kBAAkB,OAAO,WAAW,KAAK,MAAM;EACnD,IAAI,CAAC,mBAAmB,KAAK,CAAC,GAC5B,MAAM,IAAI,MAAM,2BAA2B,GAAG;EAEhD,OAAO,uBAAuB,GAAG,OAAO,KAAK;CAC/C,CAAC;CAED,MAAM,CAAC,SAAS,WAAW,WAAW,OAAO,cAAc;CAC3D,MAAM,OAAO;EAAC,GAAG;EAAS;EAAiB;EAAO,GAAG;CAAe;CAIpE,IAAI,OAAO,KAAK,KAAK,KAAK,OAAO;CACjC,IAAI,OAAO,WAAW,KAAK,KAAK,aAAa;CAC7C,IAAI,OAAO,KAAK,KAAK,KAAK,SAAS,OAAO,GAAG;CAC7C,IAAI,OAAO,MAAM,KAAK,KAAK,UAAU,OAAO,IAAI;CAEhD,OAAO;EAAE;EAAS;CAAK;AACzB;AAEA,MAAa,MAAM,IAAI,QAAQ,CAAC,CAC7B,KAAK,KAAK,CAAC,CACX,YAAY,iCAAiC,CAAC,CAC9C,SAAS,mBAAmB,uBAAuB,CAAC,CACpD,OAAO,aAAa,6BAA6B,IAAI,CAAC,CACtD,OAAO,mBAAmB,6BAA6B,KAAK,CAAC,CAC7D,OACC,mBACA,6DACA,QAAQ,IAAI,CACd,CAAC,CACA,OAAO,qBAAqB,mCAAmC,CAAC,CAChE,OAAO,aAAa,oBAAoB,CAAC,CACzC,OAAO,cAAc,qBAAqB,CAAC,CAC3C,OAAO,cAAc,qBAAqB,CAAC,CAC3C,OAAO,aAAa,oBAAoB,CAAC,CACzC,OAAO,OAAO,YAAsB,SAAS;CAE5C,IAAI,CAAC,UAAU,KAAK,GAAG,GAAG;EACxB,OAAO,KACL,
|
|
1
|
+
{"version":3,"file":"add.js","names":[],"sources":["../../src/commands/add.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { logger } from \"../lib/utils/logger\";\nimport { hasConfig } from \"../lib/utils/config\";\nimport {\n getComponentsJsonStyle,\n resolveRegistryItemUrl,\n} from \"../lib/utils/registry\";\nimport {\n dlxCommand,\n resolvePackageManager,\n resolvePackageManagerForCwd,\n type PackageManagerName,\n} from \"../lib/create-project\";\nimport { runSpawn, SpawnExitError } from \"../lib/run-spawn\";\n\nexport interface AddComponentsPlan {\n command: string;\n args: string[];\n}\n\nexport function createAddComponentsPlan(params: {\n components: string[];\n packageManager: PackageManagerName;\n yes?: boolean;\n overwrite?: boolean;\n cwd?: string;\n path?: string;\n style?: string;\n}): AddComponentsPlan {\n const componentsToAdd = params.components.map((c) => {\n if (!/^[a-zA-Z0-9-/]+$/.test(c)) {\n throw new Error(`Invalid component name: ${c}`);\n }\n return resolveRegistryItemUrl(c, params.style);\n });\n\n const [command, dlxArgs] = dlxCommand(params.packageManager);\n const args = [...dlxArgs, \"shadcn@latest\", \"add\", ...componentsToAdd];\n\n // For npm, dlxArgs may already include `--yes` for npx auto-install.\n // This flag is for shadcn's own confirmation prompt.\n if (params.yes) args.push(\"--yes\");\n if (params.overwrite) args.push(\"--overwrite\");\n if (params.cwd) args.push(\"--cwd\", params.cwd);\n if (params.path) args.push(\"--path\", params.path);\n\n return { command, args };\n}\n\nexport const add = new Command()\n .name(\"add\")\n .description(\"add a component to your project\")\n .argument(\"<components...>\", \"the components to add\")\n .option(\"-y, --yes\", \"skip confirmation prompt.\", true)\n .option(\"-o, --overwrite\", \"overwrite existing files.\", false)\n .option(\n \"-c, --cwd <cwd>\",\n \"the working directory. defaults to the current directory.\",\n process.cwd(),\n )\n .option(\"-p, --path <path>\", \"the path to add the component to.\")\n .option(\"--use-npm\", \"explicitly use npm\")\n .option(\"--use-pnpm\", \"explicitly use pnpm\")\n .option(\"--use-yarn\", \"explicitly use yarn\")\n .option(\"--use-bun\", \"explicitly use bun\")\n .action(async (components: string[], opts) => {\n // Check if project is initialized\n if (!hasConfig(opts.cwd)) {\n logger.warn(\n \"It looks like you haven't initialized your project yet — defaulting to Base UI flavored components. Run 'assistant-ui init' first for a configured setup.\",\n );\n logger.break();\n }\n\n logger.step(`Adding ${components.length} component(s)...`);\n\n const packageManager = await resolvePackageManagerForCwd(\n opts.cwd,\n resolvePackageManager(opts),\n );\n const style = getComponentsJsonStyle(opts.cwd);\n const { command, args } = createAddComponentsPlan({\n components,\n packageManager,\n yes: opts.yes,\n overwrite: opts.overwrite,\n cwd: opts.cwd,\n path: opts.path,\n ...(style === undefined ? {} : { style }),\n });\n\n try {\n await runSpawn(command, args, opts.cwd);\n } catch (error) {\n if (error instanceof SpawnExitError) {\n logger.error(`Process exited with code ${error.code}`);\n process.exit(error.code);\n }\n const message = error instanceof Error ? error.message : String(error);\n logger.error(`Failed to add components: ${message}`);\n process.exit(1);\n }\n\n logger.success(\"Components added successfully!\");\n });\n"],"mappings":";;;;;;;AAoBA,SAAgB,wBAAwB,QAQlB;CACpB,MAAM,kBAAkB,OAAO,WAAW,KAAK,MAAM;EACnD,IAAI,CAAC,mBAAmB,KAAK,CAAC,GAC5B,MAAM,IAAI,MAAM,2BAA2B,GAAG;EAEhD,OAAO,uBAAuB,GAAG,OAAO,KAAK;CAC/C,CAAC;CAED,MAAM,CAAC,SAAS,WAAW,WAAW,OAAO,cAAc;CAC3D,MAAM,OAAO;EAAC,GAAG;EAAS;EAAiB;EAAO,GAAG;CAAe;CAIpE,IAAI,OAAO,KAAK,KAAK,KAAK,OAAO;CACjC,IAAI,OAAO,WAAW,KAAK,KAAK,aAAa;CAC7C,IAAI,OAAO,KAAK,KAAK,KAAK,SAAS,OAAO,GAAG;CAC7C,IAAI,OAAO,MAAM,KAAK,KAAK,UAAU,OAAO,IAAI;CAEhD,OAAO;EAAE;EAAS;CAAK;AACzB;AAEA,MAAa,MAAM,IAAI,QAAQ,CAAC,CAC7B,KAAK,KAAK,CAAC,CACX,YAAY,iCAAiC,CAAC,CAC9C,SAAS,mBAAmB,uBAAuB,CAAC,CACpD,OAAO,aAAa,6BAA6B,IAAI,CAAC,CACtD,OAAO,mBAAmB,6BAA6B,KAAK,CAAC,CAC7D,OACC,mBACA,6DACA,QAAQ,IAAI,CACd,CAAC,CACA,OAAO,qBAAqB,mCAAmC,CAAC,CAChE,OAAO,aAAa,oBAAoB,CAAC,CACzC,OAAO,cAAc,qBAAqB,CAAC,CAC3C,OAAO,cAAc,qBAAqB,CAAC,CAC3C,OAAO,aAAa,oBAAoB,CAAC,CACzC,OAAO,OAAO,YAAsB,SAAS;CAE5C,IAAI,CAAC,UAAU,KAAK,GAAG,GAAG;EACxB,OAAO,KACL,2JACF;EACA,OAAO,MAAM;CACf;CAEA,OAAO,KAAK,UAAU,WAAW,OAAO,iBAAiB;CAEzD,MAAM,iBAAiB,MAAM,4BAC3B,KAAK,KACL,sBAAsB,IAAI,CAC5B;CACA,MAAM,QAAQ,uBAAuB,KAAK,GAAG;CAC7C,MAAM,EAAE,SAAS,SAAS,wBAAwB;EAChD;EACA;EACA,KAAK,KAAK;EACV,WAAW,KAAK;EAChB,KAAK,KAAK;EACV,MAAM,KAAK;EACX,GAAI,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM;CACzC,CAAC;CAED,IAAI;EACF,MAAM,SAAS,SAAS,MAAM,KAAK,GAAG;CACxC,SAAS,OAAO;EACd,IAAI,iBAAiB,gBAAgB;GACnC,OAAO,MAAM,4BAA4B,MAAM,MAAM;GACrD,QAAQ,KAAK,MAAM,IAAI;EACzB;EACA,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;EACrE,OAAO,MAAM,6BAA6B,SAAS;EACnD,QAAQ,KAAK,CAAC;CAChB;CAEA,OAAO,QAAQ,gCAAgC;AACjD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.d.ts","names":[],"sources":["../../src/commands/create.ts"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"create.d.ts","names":[],"sources":["../../src/commands/create.ts"],"mappings":";;;UAsBiB;EACf;EACA;EACA;EACA;EACA;EACA;;cAGW,kBAAkB;iBA8PT,eAAe;EACnC;EACA;EACA;EACA,gBAAgB,EAAE;EAClB,kBAAkB,EAAE;IAClB,QAAQ;iBA2EI,8BAA8B;EAC5C;EACA;;iBAYc,iBAAiB;UAOhB;EACf;EACA;EACA;EACA;EACA;;UAGe;EACf;EACA;EACA;;iBAac,wBACd,MAAM,0BACL;cAoCU,QAAM"}
|
package/dist/commands/create.js
CHANGED
|
@@ -143,7 +143,7 @@ const PROJECT_METADATA = [
|
|
|
143
143
|
description: "Realtime voice with ElevenLabs",
|
|
144
144
|
category: "example",
|
|
145
145
|
path: "examples/with-elevenlabs-conversational",
|
|
146
|
-
hasLocalComponents:
|
|
146
|
+
hasLocalComponents: false
|
|
147
147
|
},
|
|
148
148
|
{
|
|
149
149
|
name: "with-elevenlabs-scribe",
|
|
@@ -159,7 +159,7 @@ const PROJECT_METADATA = [
|
|
|
159
159
|
description: "Realtime voice with LiveKit",
|
|
160
160
|
category: "example",
|
|
161
161
|
path: "examples/with-livekit",
|
|
162
|
-
hasLocalComponents:
|
|
162
|
+
hasLocalComponents: false
|
|
163
163
|
},
|
|
164
164
|
{
|
|
165
165
|
name: "with-expo",
|
|
@@ -175,7 +175,7 @@ const PROJECT_METADATA = [
|
|
|
175
175
|
description: "AI-driven interactive UI components",
|
|
176
176
|
category: "example",
|
|
177
177
|
path: "examples/with-interactables",
|
|
178
|
-
hasLocalComponents:
|
|
178
|
+
hasLocalComponents: false
|
|
179
179
|
},
|
|
180
180
|
{
|
|
181
181
|
name: "with-external-store",
|
|
@@ -420,6 +420,7 @@ const create = new Command().name("create").description("create a new project").
|
|
|
420
420
|
const ref = await refPromise;
|
|
421
421
|
if (!localSourceRoot && !ref) logger.warn("Could not resolve latest release, downloading from HEAD");
|
|
422
422
|
logger.step(localSourceRoot ? `Copying project from local source: ${localSourceRoot}` : "Downloading project...");
|
|
423
|
+
let transformResult;
|
|
423
424
|
try {
|
|
424
425
|
const source = localSourceRoot ? {
|
|
425
426
|
kind: "local",
|
|
@@ -437,7 +438,7 @@ const create = new Command().name("create").description("create a new project").
|
|
|
437
438
|
logger.warn("Template not found at release tag, downloading from HEAD");
|
|
438
439
|
await downloadProject(project.path, absoluteProjectDir);
|
|
439
440
|
}
|
|
440
|
-
await transformProject(absoluteProjectDir, {
|
|
441
|
+
transformResult = await transformProject(absoluteProjectDir, {
|
|
441
442
|
hasLocalComponents: project.hasLocalComponents,
|
|
442
443
|
skipInstall: opts.skipInstall,
|
|
443
444
|
packageManager: pm
|
|
@@ -458,6 +459,15 @@ const create = new Command().name("create").description("create a new project").
|
|
|
458
459
|
});
|
|
459
460
|
throw err;
|
|
460
461
|
}
|
|
462
|
+
if (transformResult.registryInstallFailure) {
|
|
463
|
+
process.removeListener("exit", cleanupOnExit);
|
|
464
|
+
logger.break();
|
|
465
|
+
logger.error("Project created with missing components.");
|
|
466
|
+
logger.info("Retry the component install with:");
|
|
467
|
+
logger.info(` cd ${resolvedProjectDirectory}`);
|
|
468
|
+
logger.info(` ${transformResult.registryInstallFailure.retryCommand}`);
|
|
469
|
+
process.exit(1);
|
|
470
|
+
}
|
|
461
471
|
if (scaffoldSelector.preset) {
|
|
462
472
|
const presetUrl = resolvePresetUrl(scaffoldSelector.preset);
|
|
463
473
|
logger.info("Applying preset configuration...");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.js","names":[],"sources":["../../src/commands/create.ts"],"sourcesContent":["import { Command, Option } from \"commander\";\nimport chalk from \"chalk\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport * as p from \"@clack/prompts\";\nimport { logger } from \"../lib/utils/logger\";\nimport {\n dlxCommand,\n downloadProject,\n resolveLatestReleaseRef,\n resolvePackageManager,\n resolvePackageManagerForCwd,\n scaffoldProject,\n transformProject,\n} from \"../lib/create-project\";\nimport { runSpawn, SpawnExitError } from \"../lib/run-spawn\";\nimport {\n buildSkillsAddCommand,\n resolveSkillsInstall,\n} from \"../lib/agent-skill\";\n\nexport interface ProjectMetadata {\n name: string;\n label: string;\n description?: string;\n category: \"template\" | \"example\";\n path: string;\n hasLocalComponents: boolean;\n}\n\nexport const PROJECT_METADATA: ProjectMetadata[] = [\n // Templates\n {\n name: \"default\",\n label: \"Default\",\n description: \"Default template with Vercel AI SDK\",\n category: \"template\",\n path: \"templates/default\",\n hasLocalComponents: false,\n },\n {\n name: \"minimal\",\n label: \"Minimal\",\n description: \"Bare-bones starting point\",\n category: \"template\",\n path: \"templates/minimal\",\n hasLocalComponents: true,\n },\n {\n name: \"cloud\",\n label: \"Cloud\",\n description: \"Cloud-backed persistence starter\",\n category: \"template\",\n path: \"templates/cloud\",\n hasLocalComponents: false,\n },\n {\n name: \"cloud-clerk\",\n label: \"Cloud + Clerk\",\n description: \"Cloud-backed starter with Clerk auth\",\n category: \"template\",\n path: \"templates/cloud-clerk\",\n hasLocalComponents: false,\n },\n {\n name: \"langchain\",\n label: \"LangChain\",\n description: \"LangGraph starter with the react-langchain adapter\",\n category: \"template\",\n path: \"templates/langchain\",\n hasLocalComponents: false,\n },\n {\n name: \"mcp\",\n label: \"MCP\",\n description: \"MCP tools + MCP Apps renderer starter\",\n category: \"template\",\n path: \"templates/mcp\",\n hasLocalComponents: false,\n },\n {\n name: \"eve\",\n label: \"Eve\",\n description: \"Eve agent + Next.js starter\",\n category: \"template\",\n path: \"templates/eve\",\n hasLocalComponents: false,\n },\n // Examples\n {\n name: \"with-ag-ui\",\n label: \"AG-UI\",\n description: \"AG-UI protocol integration\",\n category: \"example\",\n path: \"examples/with-ag-ui\",\n hasLocalComponents: false,\n },\n {\n name: \"with-google-adk\",\n label: \"Google ADK\",\n description: \"Google ADK agent integration\",\n category: \"example\",\n path: \"examples/with-google-adk\",\n hasLocalComponents: false,\n },\n {\n name: \"with-ai-sdk-v7\",\n label: \"AI SDK v7\",\n description: \"Vercel AI SDK v7\",\n category: \"example\",\n path: \"examples/with-ai-sdk-v7\",\n hasLocalComponents: false,\n },\n {\n name: \"with-eve\",\n label: \"Eve\",\n description: \"Eve agent integration\",\n category: \"example\",\n path: \"examples/with-eve\",\n hasLocalComponents: false,\n },\n {\n name: \"with-artifacts\",\n label: \"Artifacts\",\n description: \"Artifact rendering\",\n category: \"example\",\n path: \"examples/with-artifacts\",\n hasLocalComponents: false,\n },\n {\n name: \"with-assistant-transport\",\n label: \"Assistant Transport\",\n description: \"Assistant transport protocol\",\n category: \"example\",\n path: \"examples/with-assistant-transport\",\n hasLocalComponents: false,\n },\n {\n name: \"with-chain-of-thought\",\n label: \"Chain of Thought\",\n description: \"Chain-of-thought, tool calls, and source citations\",\n category: \"example\",\n path: \"examples/with-chain-of-thought\",\n hasLocalComponents: false,\n },\n {\n name: \"with-cloud\",\n label: \"Cloud Example\",\n description: \"Cloud integration example\",\n category: \"example\",\n path: \"examples/with-cloud\",\n hasLocalComponents: false,\n },\n {\n name: \"with-custom-thread-list\",\n label: \"Custom Thread List\",\n description: \"Custom thread list UI\",\n category: \"example\",\n path: \"examples/with-custom-thread-list\",\n hasLocalComponents: false,\n },\n {\n name: \"with-elevenlabs-conversational\",\n label: \"ElevenLabs Conversational\",\n description: \"Realtime voice with ElevenLabs\",\n category: \"example\",\n path: \"examples/with-elevenlabs-conversational\",\n hasLocalComponents: true,\n },\n {\n name: \"with-elevenlabs-scribe\",\n label: \"ElevenLabs Scribe\",\n description: \"Audio/speech integration\",\n category: \"example\",\n path: \"examples/with-elevenlabs-scribe\",\n hasLocalComponents: false,\n },\n {\n name: \"with-livekit\",\n label: \"LiveKit Voice\",\n description: \"Realtime voice with LiveKit\",\n category: \"example\",\n path: \"examples/with-livekit\",\n hasLocalComponents: true,\n },\n {\n name: \"with-expo\",\n label: \"Expo\",\n description: \"Expo / React Native\",\n category: \"example\",\n path: \"examples/with-expo\",\n hasLocalComponents: true,\n },\n {\n name: \"with-interactables\",\n label: \"Interactables\",\n description: \"AI-driven interactive UI components\",\n category: \"example\",\n path: \"examples/with-interactables\",\n hasLocalComponents: true,\n },\n {\n name: \"with-external-store\",\n label: \"External Store\",\n description: \"Custom message store\",\n category: \"example\",\n path: \"examples/with-external-store\",\n hasLocalComponents: false,\n },\n {\n name: \"with-ffmpeg\",\n label: \"FFmpeg\",\n description: \"File processing\",\n category: \"example\",\n path: \"examples/with-ffmpeg\",\n hasLocalComponents: false,\n },\n {\n name: \"with-langgraph\",\n label: \"LangGraph Example\",\n description: \"LangGraph integration\",\n category: \"example\",\n path: \"examples/with-langgraph\",\n hasLocalComponents: false,\n },\n {\n name: \"with-react-hook-form\",\n label: \"React Hook Form\",\n description: \"Form integration\",\n category: \"example\",\n path: \"examples/with-react-hook-form\",\n hasLocalComponents: false,\n },\n {\n name: \"with-react-ink\",\n label: \"React Ink\",\n description: \"Terminal UI chat\",\n category: \"example\",\n path: \"examples/with-react-ink\",\n hasLocalComponents: true,\n },\n {\n name: \"with-react-router\",\n label: \"React Router\",\n description: \"React Router v7 + Vite\",\n category: \"example\",\n path: \"examples/with-react-router\",\n hasLocalComponents: false,\n },\n {\n name: \"with-tanstack\",\n label: \"TanStack\",\n description: \"TanStack/React Router + Vite\",\n category: \"example\",\n path: \"examples/with-tanstack\",\n hasLocalComponents: false,\n },\n {\n name: \"with-resumable-stream\",\n label: \"Resumable Stream\",\n description: \"Resumable LLM stream that survives reload mid-response\",\n category: \"example\",\n path: \"examples/with-resumable-stream\",\n hasLocalComponents: false,\n },\n];\n\n// Examples that exist in the monorepo but are intentionally excluded from the CLI:\n//\n// - waterfall: Still in development, not ready for production.\n// - with-cloud-standalone: For cloud without assistant-ui — not for the\n// assistant-ui CLI.\n// - with-store: In development, not ready for public use of the tap store.\n// - with-tap-runtime: In development, not ready for public use of the tap\n// store.\n\nconst templateNames = PROJECT_METADATA.filter(\n (m) => m.category === \"template\",\n).map((m) => m.name);\n\nconst exampleNames = PROJECT_METADATA.filter(\n (m) => m.category === \"example\",\n).map((m) => m.name);\n\nexport async function resolveProject(params: {\n template?: string;\n example?: string;\n stdinIsTTY?: boolean;\n select?: typeof p.select;\n isCancel?: typeof p.isCancel;\n}): Promise<ProjectMetadata | null> {\n const {\n template,\n example,\n stdinIsTTY = process.stdin.isTTY,\n select = p.select,\n isCancel = p.isCancel,\n } = params;\n\n if (template !== undefined) {\n const meta = PROJECT_METADATA.find(\n (m) => m.name === template && m.category === \"template\",\n );\n if (!meta) {\n logger.error(`Unknown template: ${template}`);\n logger.info(`Available templates: ${templateNames.join(\", \")}`);\n process.exit(1);\n }\n return meta;\n }\n\n if (example !== undefined) {\n const meta = PROJECT_METADATA.find(\n (m) => m.name === example && m.category === \"example\",\n );\n if (!meta) {\n logger.error(`Unknown example: ${example}`);\n logger.info(`Available examples: ${exampleNames.join(\", \")}`);\n process.exit(1);\n }\n return meta;\n }\n\n if (!stdinIsTTY) {\n return PROJECT_METADATA.find((m) => m.name === \"default\")!;\n }\n\n const selected = await select({\n message: \"Select a project to scaffold:\",\n options: [\n {\n value: \"_separator\",\n label: \"────── Starter Templates ──────\",\n disabled: true,\n },\n ...PROJECT_METADATA.filter((m) => m.category === \"template\").map((m) => ({\n value: m.name,\n label: m.label,\n ...(m.description ? { hint: m.description } : {}),\n })),\n {\n value: \"_separator\",\n label: \"────── Feature Examples ──────\",\n disabled: true,\n },\n ...PROJECT_METADATA.filter((m) => m.category === \"example\").map((m) => ({\n value: m.name,\n label: m.label,\n ...(m.description ? { hint: m.description } : {}),\n })),\n ],\n });\n\n if (isCancel(selected)) {\n return null;\n }\n\n const meta = PROJECT_METADATA.find((m) => m.name === selected);\n if (!meta) {\n logger.error(`Unknown selection: ${String(selected)}`);\n process.exit(1);\n }\n return meta;\n}\n\nexport function resolveCreateProjectDirectory(params: {\n projectDirectory?: string;\n stdinIsTTY?: boolean;\n}): string | undefined {\n const { projectDirectory, stdinIsTTY = process.stdin.isTTY } = params;\n\n if (projectDirectory) return projectDirectory;\n if (!stdinIsTTY) return \"my-aui-app\";\n return undefined;\n}\n\nconst PLAYGROUND_PRESET_BASE_URL =\n \"https://www.assistant-ui.com/playground/init\";\n\nexport function resolvePresetUrl(preset: string): string {\n if (preset.startsWith(\"http://\") || preset.startsWith(\"https://\")) {\n return preset;\n }\n return `${PLAYGROUND_PRESET_BASE_URL}?preset=${encodeURIComponent(preset)}`;\n}\n\nexport interface ScaffoldSelectorOptions {\n template?: string;\n example?: string;\n preset?: string;\n native?: boolean;\n ink?: boolean;\n}\n\nexport interface ResolvedScaffoldSelector {\n template?: string;\n example?: string;\n preset?: string;\n}\n\nconst scaffoldSelectorHelp =\n \"Choose one scaffold selector: --template <name>, --example <name>, --native, or --ink. --preset <name-or-url> can be used with --template or by itself.\";\n\nfunction getPresetConflict(opts: ScaffoldSelectorOptions): string | undefined {\n if (opts.example !== undefined) return \"--example\";\n if (opts.native) return \"--native\";\n if (opts.ink) return \"--ink\";\n return undefined;\n}\n\nexport function resolveScaffoldSelector(\n opts: ScaffoldSelectorOptions,\n): ResolvedScaffoldSelector {\n const hasPreset = opts.preset !== undefined;\n const presetConflict = getPresetConflict(opts);\n const selectors = [\n opts.template !== undefined ? \"--template\" : undefined,\n opts.example !== undefined ? \"--example\" : undefined,\n opts.native ? \"--native\" : undefined,\n opts.ink ? \"--ink\" : undefined,\n ].filter((selector): selector is string => selector !== undefined);\n\n if (selectors.length > 1) {\n throw new Error(\n `Only one scaffold selector can be provided (${selectors.join(\", \")}). ${scaffoldSelectorHelp}`,\n );\n }\n\n if (hasPreset && presetConflict) {\n throw new Error(\n `Cannot use --preset with ${presetConflict}. ${scaffoldSelectorHelp}`,\n );\n }\n\n if (opts.native) return { example: \"with-expo\" };\n if (opts.ink) return { example: \"with-react-ink\" };\n\n if (opts.preset !== undefined && opts.template === undefined) {\n return { template: \"default\", preset: opts.preset };\n }\n\n return {\n ...(opts.template !== undefined && { template: opts.template }),\n ...(opts.example !== undefined && { example: opts.example }),\n ...(hasPreset && { preset: opts.preset }),\n };\n}\n\nexport const create = new Command()\n .name(\"create\")\n .description(\"create a new project\")\n .argument(\"[project-directory]\")\n .usage(`${chalk.green(\"[project-directory]\")} [options]`)\n .option(\n \"-t, --template <template>\",\n `template to use (${templateNames.join(\", \")})`,\n )\n .option(\n \"-e, --example <example>\",\n `create from an example (${exampleNames.join(\", \")})`,\n )\n .option(\n \"-p, --preset <name-or-url>\",\n \"preset name or URL (e.g., chatgpt or https://www.assistant-ui.com/playground/init?preset=chatgpt)\",\n )\n .option(\"--use-npm\", \"explicitly use npm\")\n .option(\"--use-pnpm\", \"explicitly use pnpm\")\n .option(\"--use-yarn\", \"explicitly use yarn\")\n .option(\"--use-bun\", \"explicitly use bun\")\n .option(\"--native\", \"create an Expo / React Native project\")\n .option(\"--ink\", \"create a React Ink terminal project\")\n .option(\"--skip-install\", \"skip installing packages\")\n .option(\"--skills\", \"add assistant-ui agent skills for AI coding assistants\")\n .option(\"--no-skills\", \"skip adding assistant-ui agent skills\")\n .addOption(\n new Option(\n \"--debug-source-root <path>\",\n \"copy templates/examples from a local assistant-ui repo root\",\n ).hideHelp(),\n )\n .action(async (projectDirectory, opts) => {\n let scaffoldSelector: ResolvedScaffoldSelector;\n try {\n scaffoldSelector = resolveScaffoldSelector(opts);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n logger.error(message);\n process.exit(1);\n }\n\n const localSourceRoot = opts.debugSourceRoot\n ? path.resolve(opts.debugSourceRoot)\n : undefined;\n\n // Start release ref resolution early (runs during user prompts)\n const refPromise = localSourceRoot\n ? Promise.resolve(undefined)\n : resolveLatestReleaseRef();\n\n // 1. Resolve project directory\n let resolvedProjectDirectory = resolveCreateProjectDirectory({\n projectDirectory,\n });\n\n if (!resolvedProjectDirectory) {\n const result = await p.text({\n message: \"Project name:\",\n placeholder: \"my-aui-app\",\n defaultValue: \"my-aui-app\",\n validate: (value?: string) => {\n const name = (value ?? \"\").trim();\n if (!name) return \"Project name cannot be empty\";\n if (name === \".\" || name === \"..\")\n return \"Project name cannot be . or ..\";\n if (name.includes(\"/\") || name.includes(\"\\\\\"))\n return \"Project name cannot contain path separators\";\n return undefined;\n },\n });\n\n if (p.isCancel(result)) {\n p.cancel(\"Project creation cancelled.\");\n process.exit(0);\n }\n\n resolvedProjectDirectory = result;\n }\n\n // Check directory\n const absoluteProjectDir = path.resolve(resolvedProjectDirectory);\n try {\n const files = fs.readdirSync(absoluteProjectDir);\n if (files.length > 0) {\n logger.error(\n `Directory ${resolvedProjectDirectory} already exists and is not empty`,\n );\n process.exit(1);\n }\n } catch (err: unknown) {\n const code =\n err instanceof Error ? (err as NodeJS.ErrnoException).code : undefined;\n if (code === \"ENOENT\") {\n // Directory doesn't exist — good, proceed\n } else if (code === \"ENOTDIR\") {\n logger.error(\n `${resolvedProjectDirectory} already exists and is not a directory`,\n );\n process.exit(1);\n } else {\n const message = err instanceof Error ? err.message : String(err);\n logger.error(`Cannot access ${resolvedProjectDirectory}: ${message}`);\n process.exit(1);\n }\n }\n\n // 2. Resolve scaffold target\n const project = await resolveProject(scaffoldSelector);\n if (!project) {\n p.cancel(\"Project creation cancelled.\");\n process.exit(0);\n }\n\n const stdinIsTTY = process.stdin.isTTY;\n let installSkills = resolveSkillsInstall({\n skills: opts.skills,\n stdinIsTTY,\n });\n if (installSkills === undefined) {\n const result = await p.confirm({\n message: \"Add assistant-ui agent skills for AI coding assistants?\",\n initialValue: true,\n });\n\n if (p.isCancel(result)) {\n p.cancel(\"Project creation cancelled.\");\n process.exit(0);\n }\n\n installSkills = result;\n }\n\n logger.info(`Creating project from ${project.category}: ${project.label}`);\n logger.break();\n\n const pm = await resolvePackageManagerForCwd(\n path.dirname(absoluteProjectDir),\n resolvePackageManager(opts),\n );\n\n // Clean up partial project directory on unexpected exit (e.g. Ctrl+C)\n const cleanupOnExit = () => {\n fs.rmSync(absoluteProjectDir, { recursive: true, force: true });\n };\n process.once(\"exit\", cleanupOnExit);\n\n try {\n // 3. Resolve latest release ref (started before prompts)\n if (!localSourceRoot) {\n logger.step(\"Resolving latest release...\");\n }\n const ref = await refPromise;\n if (!localSourceRoot && !ref) {\n logger.warn(\"Could not resolve latest release, downloading from HEAD\");\n }\n\n // 4. Scaffold project\n logger.step(\n localSourceRoot\n ? `Copying project from local source: ${localSourceRoot}`\n : \"Downloading project...\",\n );\n try {\n const source = localSourceRoot\n ? { kind: \"local\" as const, rootDir: localSourceRoot }\n : {\n kind: \"github\" as const,\n ref,\n };\n await scaffoldProject(project.path, absoluteProjectDir, source);\n\n // If the template didn't exist at the release tag, retry from HEAD\n if (\n !localSourceRoot &&\n ref &&\n !fs.existsSync(path.join(absoluteProjectDir, \"package.json\"))\n ) {\n fs.rmSync(absoluteProjectDir, { recursive: true, force: true });\n logger.warn(\n \"Template not found at release tag, downloading from HEAD\",\n );\n await downloadProject(project.path, absoluteProjectDir);\n }\n\n // 5. Run transform pipeline\n await transformProject(absoluteProjectDir, {\n hasLocalComponents: project.hasLocalComponents,\n skipInstall: opts.skipInstall,\n packageManager: pm,\n });\n\n if (installSkills) {\n logger.step(\"Adding assistant-ui agent skills...\");\n const [skillsCmd, skillsArgs] = buildSkillsAddCommand(pm, {\n stdinIsTTY,\n });\n try {\n await runSpawn(skillsCmd, skillsArgs, absoluteProjectDir);\n } catch {\n logger.warn(\n `Could not add assistant-ui agent skills. You can add them later with:\\n ${skillsCmd} ${skillsArgs.join(\" \")}`,\n );\n }\n }\n } catch (err) {\n // Clean up partially created project directory\n fs.rmSync(absoluteProjectDir, { recursive: true, force: true });\n throw err;\n }\n\n // 6. Apply preset if provided\n if (scaffoldSelector.preset) {\n const presetUrl = resolvePresetUrl(scaffoldSelector.preset);\n logger.info(\"Applying preset configuration...\");\n logger.break();\n const [dlxCmd, dlxArgs] = dlxCommand(pm);\n try {\n await runSpawn(\n dlxCmd,\n [\n ...dlxArgs,\n \"shadcn@latest\",\n \"add\",\n \"--yes\",\n \"--overwrite\",\n presetUrl,\n ],\n absoluteProjectDir,\n );\n } catch {\n logger.warn(\n `Preset application failed. You can retry manually with:\\n ${dlxCmd} ${[...dlxArgs, \"shadcn@latest\", \"add\", presetUrl].join(\" \")}`,\n );\n }\n }\n\n process.removeListener(\"exit\", cleanupOnExit);\n\n logger.break();\n logger.success(\"Project created successfully!\");\n logger.break();\n const runCmd = pm === \"npm\" ? \"npm run\" : pm;\n let devScript = \"dev\";\n let envFile = \".env.local\";\n try {\n const scaffoldedPkg = JSON.parse(\n fs.readFileSync(\n path.join(absoluteProjectDir, \"package.json\"),\n \"utf-8\",\n ),\n );\n devScript = scaffoldedPkg.scripts?.dev\n ? \"dev\"\n : scaffoldedPkg.scripts?.start\n ? \"start\"\n : \"dev\";\n envFile = scaffoldedPkg.dependencies?.next ? \".env.local\" : \".env\";\n } catch {\n // Fall back to defaults if package.json cannot be read\n }\n\n logger.info(\"Next steps:\");\n logger.info(` cd ${resolvedProjectDirectory}`);\n if (opts.skipInstall) {\n logger.info(` ${pm} install`);\n }\n logger.info(` # Set up your environment variables in ${envFile}`);\n logger.info(` ${runCmd} ${devScript}`);\n } catch (error) {\n if (error instanceof SpawnExitError) {\n logger.error(`Project creation failed with code ${error.code}`);\n process.exit(error.code);\n }\n const message = error instanceof Error ? error.message : String(error);\n logger.error(`Failed to create project: ${message}`);\n process.exit(1);\n }\n });\n"],"mappings":";;;;;;;;;;AA8BA,MAAa,mBAAsC;CAEjD;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CAEA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;AACF;AAWA,MAAM,gBAAgB,iBAAiB,QACpC,MAAM,EAAE,aAAa,UACxB,CAAC,CAAC,KAAK,MAAM,EAAE,IAAI;AAEnB,MAAM,eAAe,iBAAiB,QACnC,MAAM,EAAE,aAAa,SACxB,CAAC,CAAC,KAAK,MAAM,EAAE,IAAI;AAEnB,eAAsB,eAAe,QAMD;CAClC,MAAM,EACJ,UACA,SACA,aAAa,QAAQ,MAAM,OAC3B,SAAS,EAAE,QACX,WAAW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"}
|
|
1
|
+
{"version":3,"file":"create.js","names":[],"sources":["../../src/commands/create.ts"],"sourcesContent":["import { Command, Option } from \"commander\";\nimport chalk from \"chalk\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport * as p from \"@clack/prompts\";\nimport { logger } from \"../lib/utils/logger\";\nimport {\n dlxCommand,\n downloadProject,\n resolveLatestReleaseRef,\n resolvePackageManager,\n resolvePackageManagerForCwd,\n scaffoldProject,\n transformProject,\n type TransformResult,\n} from \"../lib/create-project\";\nimport { runSpawn, SpawnExitError } from \"../lib/run-spawn\";\nimport {\n buildSkillsAddCommand,\n resolveSkillsInstall,\n} from \"../lib/agent-skill\";\n\nexport interface ProjectMetadata {\n name: string;\n label: string;\n description?: string;\n category: \"template\" | \"example\";\n path: string;\n hasLocalComponents: boolean;\n}\n\nexport const PROJECT_METADATA: ProjectMetadata[] = [\n // Templates\n {\n name: \"default\",\n label: \"Default\",\n description: \"Default template with Vercel AI SDK\",\n category: \"template\",\n path: \"templates/default\",\n hasLocalComponents: false,\n },\n {\n name: \"minimal\",\n label: \"Minimal\",\n description: \"Bare-bones starting point\",\n category: \"template\",\n path: \"templates/minimal\",\n hasLocalComponents: true,\n },\n {\n name: \"cloud\",\n label: \"Cloud\",\n description: \"Cloud-backed persistence starter\",\n category: \"template\",\n path: \"templates/cloud\",\n hasLocalComponents: false,\n },\n {\n name: \"cloud-clerk\",\n label: \"Cloud + Clerk\",\n description: \"Cloud-backed starter with Clerk auth\",\n category: \"template\",\n path: \"templates/cloud-clerk\",\n hasLocalComponents: false,\n },\n {\n name: \"langchain\",\n label: \"LangChain\",\n description: \"LangGraph starter with the react-langchain adapter\",\n category: \"template\",\n path: \"templates/langchain\",\n hasLocalComponents: false,\n },\n {\n name: \"mcp\",\n label: \"MCP\",\n description: \"MCP tools + MCP Apps renderer starter\",\n category: \"template\",\n path: \"templates/mcp\",\n hasLocalComponents: false,\n },\n {\n name: \"eve\",\n label: \"Eve\",\n description: \"Eve agent + Next.js starter\",\n category: \"template\",\n path: \"templates/eve\",\n hasLocalComponents: false,\n },\n // Examples\n {\n name: \"with-ag-ui\",\n label: \"AG-UI\",\n description: \"AG-UI protocol integration\",\n category: \"example\",\n path: \"examples/with-ag-ui\",\n hasLocalComponents: false,\n },\n {\n name: \"with-google-adk\",\n label: \"Google ADK\",\n description: \"Google ADK agent integration\",\n category: \"example\",\n path: \"examples/with-google-adk\",\n hasLocalComponents: false,\n },\n {\n name: \"with-ai-sdk-v7\",\n label: \"AI SDK v7\",\n description: \"Vercel AI SDK v7\",\n category: \"example\",\n path: \"examples/with-ai-sdk-v7\",\n hasLocalComponents: false,\n },\n {\n name: \"with-eve\",\n label: \"Eve\",\n description: \"Eve agent integration\",\n category: \"example\",\n path: \"examples/with-eve\",\n hasLocalComponents: false,\n },\n {\n name: \"with-artifacts\",\n label: \"Artifacts\",\n description: \"Artifact rendering\",\n category: \"example\",\n path: \"examples/with-artifacts\",\n hasLocalComponents: false,\n },\n {\n name: \"with-assistant-transport\",\n label: \"Assistant Transport\",\n description: \"Assistant transport protocol\",\n category: \"example\",\n path: \"examples/with-assistant-transport\",\n hasLocalComponents: false,\n },\n {\n name: \"with-chain-of-thought\",\n label: \"Chain of Thought\",\n description: \"Chain-of-thought, tool calls, and source citations\",\n category: \"example\",\n path: \"examples/with-chain-of-thought\",\n hasLocalComponents: false,\n },\n {\n name: \"with-cloud\",\n label: \"Cloud Example\",\n description: \"Cloud integration example\",\n category: \"example\",\n path: \"examples/with-cloud\",\n hasLocalComponents: false,\n },\n {\n name: \"with-custom-thread-list\",\n label: \"Custom Thread List\",\n description: \"Custom thread list UI\",\n category: \"example\",\n path: \"examples/with-custom-thread-list\",\n hasLocalComponents: false,\n },\n {\n name: \"with-elevenlabs-conversational\",\n label: \"ElevenLabs Conversational\",\n description: \"Realtime voice with ElevenLabs\",\n category: \"example\",\n path: \"examples/with-elevenlabs-conversational\",\n hasLocalComponents: false,\n },\n {\n name: \"with-elevenlabs-scribe\",\n label: \"ElevenLabs Scribe\",\n description: \"Audio/speech integration\",\n category: \"example\",\n path: \"examples/with-elevenlabs-scribe\",\n hasLocalComponents: false,\n },\n {\n name: \"with-livekit\",\n label: \"LiveKit Voice\",\n description: \"Realtime voice with LiveKit\",\n category: \"example\",\n path: \"examples/with-livekit\",\n hasLocalComponents: false,\n },\n {\n name: \"with-expo\",\n label: \"Expo\",\n description: \"Expo / React Native\",\n category: \"example\",\n path: \"examples/with-expo\",\n hasLocalComponents: true,\n },\n {\n name: \"with-interactables\",\n label: \"Interactables\",\n description: \"AI-driven interactive UI components\",\n category: \"example\",\n path: \"examples/with-interactables\",\n hasLocalComponents: false,\n },\n {\n name: \"with-external-store\",\n label: \"External Store\",\n description: \"Custom message store\",\n category: \"example\",\n path: \"examples/with-external-store\",\n hasLocalComponents: false,\n },\n {\n name: \"with-ffmpeg\",\n label: \"FFmpeg\",\n description: \"File processing\",\n category: \"example\",\n path: \"examples/with-ffmpeg\",\n hasLocalComponents: false,\n },\n {\n name: \"with-langgraph\",\n label: \"LangGraph Example\",\n description: \"LangGraph integration\",\n category: \"example\",\n path: \"examples/with-langgraph\",\n hasLocalComponents: false,\n },\n {\n name: \"with-react-hook-form\",\n label: \"React Hook Form\",\n description: \"Form integration\",\n category: \"example\",\n path: \"examples/with-react-hook-form\",\n hasLocalComponents: false,\n },\n {\n name: \"with-react-ink\",\n label: \"React Ink\",\n description: \"Terminal UI chat\",\n category: \"example\",\n path: \"examples/with-react-ink\",\n hasLocalComponents: true,\n },\n {\n name: \"with-react-router\",\n label: \"React Router\",\n description: \"React Router v7 + Vite\",\n category: \"example\",\n path: \"examples/with-react-router\",\n hasLocalComponents: false,\n },\n {\n name: \"with-tanstack\",\n label: \"TanStack\",\n description: \"TanStack/React Router + Vite\",\n category: \"example\",\n path: \"examples/with-tanstack\",\n hasLocalComponents: false,\n },\n {\n name: \"with-resumable-stream\",\n label: \"Resumable Stream\",\n description: \"Resumable LLM stream that survives reload mid-response\",\n category: \"example\",\n path: \"examples/with-resumable-stream\",\n hasLocalComponents: false,\n },\n];\n\n// Examples that exist in the monorepo but are intentionally excluded from the CLI:\n//\n// - waterfall: Still in development, not ready for production.\n// - with-cloud-standalone: For cloud without assistant-ui — not for the\n// assistant-ui CLI.\n// - with-store: In development, not ready for public use of the tap store.\n// - with-tap-runtime: In development, not ready for public use of the tap\n// store.\n\nconst templateNames = PROJECT_METADATA.filter(\n (m) => m.category === \"template\",\n).map((m) => m.name);\n\nconst exampleNames = PROJECT_METADATA.filter(\n (m) => m.category === \"example\",\n).map((m) => m.name);\n\nexport async function resolveProject(params: {\n template?: string;\n example?: string;\n stdinIsTTY?: boolean;\n select?: typeof p.select;\n isCancel?: typeof p.isCancel;\n}): Promise<ProjectMetadata | null> {\n const {\n template,\n example,\n stdinIsTTY = process.stdin.isTTY,\n select = p.select,\n isCancel = p.isCancel,\n } = params;\n\n if (template !== undefined) {\n const meta = PROJECT_METADATA.find(\n (m) => m.name === template && m.category === \"template\",\n );\n if (!meta) {\n logger.error(`Unknown template: ${template}`);\n logger.info(`Available templates: ${templateNames.join(\", \")}`);\n process.exit(1);\n }\n return meta;\n }\n\n if (example !== undefined) {\n const meta = PROJECT_METADATA.find(\n (m) => m.name === example && m.category === \"example\",\n );\n if (!meta) {\n logger.error(`Unknown example: ${example}`);\n logger.info(`Available examples: ${exampleNames.join(\", \")}`);\n process.exit(1);\n }\n return meta;\n }\n\n if (!stdinIsTTY) {\n return PROJECT_METADATA.find((m) => m.name === \"default\")!;\n }\n\n const selected = await select({\n message: \"Select a project to scaffold:\",\n options: [\n {\n value: \"_separator\",\n label: \"────── Starter Templates ──────\",\n disabled: true,\n },\n ...PROJECT_METADATA.filter((m) => m.category === \"template\").map((m) => ({\n value: m.name,\n label: m.label,\n ...(m.description ? { hint: m.description } : {}),\n })),\n {\n value: \"_separator\",\n label: \"────── Feature Examples ──────\",\n disabled: true,\n },\n ...PROJECT_METADATA.filter((m) => m.category === \"example\").map((m) => ({\n value: m.name,\n label: m.label,\n ...(m.description ? { hint: m.description } : {}),\n })),\n ],\n });\n\n if (isCancel(selected)) {\n return null;\n }\n\n const meta = PROJECT_METADATA.find((m) => m.name === selected);\n if (!meta) {\n logger.error(`Unknown selection: ${String(selected)}`);\n process.exit(1);\n }\n return meta;\n}\n\nexport function resolveCreateProjectDirectory(params: {\n projectDirectory?: string;\n stdinIsTTY?: boolean;\n}): string | undefined {\n const { projectDirectory, stdinIsTTY = process.stdin.isTTY } = params;\n\n if (projectDirectory) return projectDirectory;\n if (!stdinIsTTY) return \"my-aui-app\";\n return undefined;\n}\n\nconst PLAYGROUND_PRESET_BASE_URL =\n \"https://www.assistant-ui.com/playground/init\";\n\nexport function resolvePresetUrl(preset: string): string {\n if (preset.startsWith(\"http://\") || preset.startsWith(\"https://\")) {\n return preset;\n }\n return `${PLAYGROUND_PRESET_BASE_URL}?preset=${encodeURIComponent(preset)}`;\n}\n\nexport interface ScaffoldSelectorOptions {\n template?: string;\n example?: string;\n preset?: string;\n native?: boolean;\n ink?: boolean;\n}\n\nexport interface ResolvedScaffoldSelector {\n template?: string;\n example?: string;\n preset?: string;\n}\n\nconst scaffoldSelectorHelp =\n \"Choose one scaffold selector: --template <name>, --example <name>, --native, or --ink. --preset <name-or-url> can be used with --template or by itself.\";\n\nfunction getPresetConflict(opts: ScaffoldSelectorOptions): string | undefined {\n if (opts.example !== undefined) return \"--example\";\n if (opts.native) return \"--native\";\n if (opts.ink) return \"--ink\";\n return undefined;\n}\n\nexport function resolveScaffoldSelector(\n opts: ScaffoldSelectorOptions,\n): ResolvedScaffoldSelector {\n const hasPreset = opts.preset !== undefined;\n const presetConflict = getPresetConflict(opts);\n const selectors = [\n opts.template !== undefined ? \"--template\" : undefined,\n opts.example !== undefined ? \"--example\" : undefined,\n opts.native ? \"--native\" : undefined,\n opts.ink ? \"--ink\" : undefined,\n ].filter((selector): selector is string => selector !== undefined);\n\n if (selectors.length > 1) {\n throw new Error(\n `Only one scaffold selector can be provided (${selectors.join(\", \")}). ${scaffoldSelectorHelp}`,\n );\n }\n\n if (hasPreset && presetConflict) {\n throw new Error(\n `Cannot use --preset with ${presetConflict}. ${scaffoldSelectorHelp}`,\n );\n }\n\n if (opts.native) return { example: \"with-expo\" };\n if (opts.ink) return { example: \"with-react-ink\" };\n\n if (opts.preset !== undefined && opts.template === undefined) {\n return { template: \"default\", preset: opts.preset };\n }\n\n return {\n ...(opts.template !== undefined && { template: opts.template }),\n ...(opts.example !== undefined && { example: opts.example }),\n ...(hasPreset && { preset: opts.preset }),\n };\n}\n\nexport const create = new Command()\n .name(\"create\")\n .description(\"create a new project\")\n .argument(\"[project-directory]\")\n .usage(`${chalk.green(\"[project-directory]\")} [options]`)\n .option(\n \"-t, --template <template>\",\n `template to use (${templateNames.join(\", \")})`,\n )\n .option(\n \"-e, --example <example>\",\n `create from an example (${exampleNames.join(\", \")})`,\n )\n .option(\n \"-p, --preset <name-or-url>\",\n \"preset name or URL (e.g., chatgpt or https://www.assistant-ui.com/playground/init?preset=chatgpt)\",\n )\n .option(\"--use-npm\", \"explicitly use npm\")\n .option(\"--use-pnpm\", \"explicitly use pnpm\")\n .option(\"--use-yarn\", \"explicitly use yarn\")\n .option(\"--use-bun\", \"explicitly use bun\")\n .option(\"--native\", \"create an Expo / React Native project\")\n .option(\"--ink\", \"create a React Ink terminal project\")\n .option(\"--skip-install\", \"skip installing packages\")\n .option(\"--skills\", \"add assistant-ui agent skills for AI coding assistants\")\n .option(\"--no-skills\", \"skip adding assistant-ui agent skills\")\n .addOption(\n new Option(\n \"--debug-source-root <path>\",\n \"copy templates/examples from a local assistant-ui repo root\",\n ).hideHelp(),\n )\n .action(async (projectDirectory, opts) => {\n let scaffoldSelector: ResolvedScaffoldSelector;\n try {\n scaffoldSelector = resolveScaffoldSelector(opts);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n logger.error(message);\n process.exit(1);\n }\n\n const localSourceRoot = opts.debugSourceRoot\n ? path.resolve(opts.debugSourceRoot)\n : undefined;\n\n // Start release ref resolution early (runs during user prompts)\n const refPromise = localSourceRoot\n ? Promise.resolve(undefined)\n : resolveLatestReleaseRef();\n\n // 1. Resolve project directory\n let resolvedProjectDirectory = resolveCreateProjectDirectory({\n projectDirectory,\n });\n\n if (!resolvedProjectDirectory) {\n const result = await p.text({\n message: \"Project name:\",\n placeholder: \"my-aui-app\",\n defaultValue: \"my-aui-app\",\n validate: (value?: string) => {\n const name = (value ?? \"\").trim();\n if (!name) return \"Project name cannot be empty\";\n if (name === \".\" || name === \"..\")\n return \"Project name cannot be . or ..\";\n if (name.includes(\"/\") || name.includes(\"\\\\\"))\n return \"Project name cannot contain path separators\";\n return undefined;\n },\n });\n\n if (p.isCancel(result)) {\n p.cancel(\"Project creation cancelled.\");\n process.exit(0);\n }\n\n resolvedProjectDirectory = result;\n }\n\n // Check directory\n const absoluteProjectDir = path.resolve(resolvedProjectDirectory);\n try {\n const files = fs.readdirSync(absoluteProjectDir);\n if (files.length > 0) {\n logger.error(\n `Directory ${resolvedProjectDirectory} already exists and is not empty`,\n );\n process.exit(1);\n }\n } catch (err: unknown) {\n const code =\n err instanceof Error ? (err as NodeJS.ErrnoException).code : undefined;\n if (code === \"ENOENT\") {\n // Directory doesn't exist — good, proceed\n } else if (code === \"ENOTDIR\") {\n logger.error(\n `${resolvedProjectDirectory} already exists and is not a directory`,\n );\n process.exit(1);\n } else {\n const message = err instanceof Error ? err.message : String(err);\n logger.error(`Cannot access ${resolvedProjectDirectory}: ${message}`);\n process.exit(1);\n }\n }\n\n // 2. Resolve scaffold target\n const project = await resolveProject(scaffoldSelector);\n if (!project) {\n p.cancel(\"Project creation cancelled.\");\n process.exit(0);\n }\n\n const stdinIsTTY = process.stdin.isTTY;\n let installSkills = resolveSkillsInstall({\n skills: opts.skills,\n stdinIsTTY,\n });\n if (installSkills === undefined) {\n const result = await p.confirm({\n message: \"Add assistant-ui agent skills for AI coding assistants?\",\n initialValue: true,\n });\n\n if (p.isCancel(result)) {\n p.cancel(\"Project creation cancelled.\");\n process.exit(0);\n }\n\n installSkills = result;\n }\n\n logger.info(`Creating project from ${project.category}: ${project.label}`);\n logger.break();\n\n const pm = await resolvePackageManagerForCwd(\n path.dirname(absoluteProjectDir),\n resolvePackageManager(opts),\n );\n\n // Clean up partial project directory on unexpected exit (e.g. Ctrl+C)\n const cleanupOnExit = () => {\n fs.rmSync(absoluteProjectDir, { recursive: true, force: true });\n };\n process.once(\"exit\", cleanupOnExit);\n\n try {\n // 3. Resolve latest release ref (started before prompts)\n if (!localSourceRoot) {\n logger.step(\"Resolving latest release...\");\n }\n const ref = await refPromise;\n if (!localSourceRoot && !ref) {\n logger.warn(\"Could not resolve latest release, downloading from HEAD\");\n }\n\n // 4. Scaffold project\n logger.step(\n localSourceRoot\n ? `Copying project from local source: ${localSourceRoot}`\n : \"Downloading project...\",\n );\n let transformResult: TransformResult;\n try {\n const source = localSourceRoot\n ? { kind: \"local\" as const, rootDir: localSourceRoot }\n : {\n kind: \"github\" as const,\n ref,\n };\n await scaffoldProject(project.path, absoluteProjectDir, source);\n\n // If the template didn't exist at the release tag, retry from HEAD\n if (\n !localSourceRoot &&\n ref &&\n !fs.existsSync(path.join(absoluteProjectDir, \"package.json\"))\n ) {\n fs.rmSync(absoluteProjectDir, { recursive: true, force: true });\n logger.warn(\n \"Template not found at release tag, downloading from HEAD\",\n );\n await downloadProject(project.path, absoluteProjectDir);\n }\n\n // 5. Run transform pipeline\n transformResult = await transformProject(absoluteProjectDir, {\n hasLocalComponents: project.hasLocalComponents,\n skipInstall: opts.skipInstall,\n packageManager: pm,\n });\n\n if (installSkills) {\n logger.step(\"Adding assistant-ui agent skills...\");\n const [skillsCmd, skillsArgs] = buildSkillsAddCommand(pm, {\n stdinIsTTY,\n });\n try {\n await runSpawn(skillsCmd, skillsArgs, absoluteProjectDir);\n } catch {\n logger.warn(\n `Could not add assistant-ui agent skills. You can add them later with:\\n ${skillsCmd} ${skillsArgs.join(\" \")}`,\n );\n }\n }\n } catch (err) {\n // Clean up partially created project directory\n fs.rmSync(absoluteProjectDir, { recursive: true, force: true });\n throw err;\n }\n\n if (transformResult.registryInstallFailure) {\n process.removeListener(\"exit\", cleanupOnExit);\n logger.break();\n logger.error(\"Project created with missing components.\");\n logger.info(\"Retry the component install with:\");\n logger.info(` cd ${resolvedProjectDirectory}`);\n logger.info(` ${transformResult.registryInstallFailure.retryCommand}`);\n process.exit(1);\n }\n\n // 6. Apply preset if provided\n if (scaffoldSelector.preset) {\n const presetUrl = resolvePresetUrl(scaffoldSelector.preset);\n logger.info(\"Applying preset configuration...\");\n logger.break();\n const [dlxCmd, dlxArgs] = dlxCommand(pm);\n try {\n await runSpawn(\n dlxCmd,\n [\n ...dlxArgs,\n \"shadcn@latest\",\n \"add\",\n \"--yes\",\n \"--overwrite\",\n presetUrl,\n ],\n absoluteProjectDir,\n );\n } catch {\n logger.warn(\n `Preset application failed. You can retry manually with:\\n ${dlxCmd} ${[...dlxArgs, \"shadcn@latest\", \"add\", presetUrl].join(\" \")}`,\n );\n }\n }\n\n process.removeListener(\"exit\", cleanupOnExit);\n\n logger.break();\n logger.success(\"Project created successfully!\");\n logger.break();\n const runCmd = pm === \"npm\" ? \"npm run\" : pm;\n let devScript = \"dev\";\n let envFile = \".env.local\";\n try {\n const scaffoldedPkg = JSON.parse(\n fs.readFileSync(\n path.join(absoluteProjectDir, \"package.json\"),\n \"utf-8\",\n ),\n );\n devScript = scaffoldedPkg.scripts?.dev\n ? \"dev\"\n : scaffoldedPkg.scripts?.start\n ? \"start\"\n : \"dev\";\n envFile = scaffoldedPkg.dependencies?.next ? \".env.local\" : \".env\";\n } catch {\n // Fall back to defaults if package.json cannot be read\n }\n\n logger.info(\"Next steps:\");\n logger.info(` cd ${resolvedProjectDirectory}`);\n if (opts.skipInstall) {\n logger.info(` ${pm} install`);\n }\n logger.info(` # Set up your environment variables in ${envFile}`);\n logger.info(` ${runCmd} ${devScript}`);\n } catch (error) {\n if (error instanceof SpawnExitError) {\n logger.error(`Project creation failed with code ${error.code}`);\n process.exit(error.code);\n }\n const message = error instanceof Error ? error.message : String(error);\n logger.error(`Failed to create project: ${message}`);\n process.exit(1);\n }\n });\n"],"mappings":";;;;;;;;;;AA+BA,MAAa,mBAAsC;CAEjD;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CAEA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,UAAU;EACV,MAAM;EACN,oBAAoB;CACtB;AACF;AAWA,MAAM,gBAAgB,iBAAiB,QACpC,MAAM,EAAE,aAAa,UACxB,CAAC,CAAC,KAAK,MAAM,EAAE,IAAI;AAEnB,MAAM,eAAe,iBAAiB,QACnC,MAAM,EAAE,aAAa,SACxB,CAAC,CAAC,KAAK,MAAM,EAAE,IAAI;AAEnB,eAAsB,eAAe,QAMD;CAClC,MAAM,EACJ,UACA,SACA,aAAa,QAAQ,MAAM,OAC3B,SAAS,EAAE,QACX,WAAW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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.d.ts","names":[],"sources":["../../src/commands/doctor.ts"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","names":[],"sources":["../../src/commands/doctor.ts"],"mappings":";;UAmBiB;EACf;EACA;EACA;;iBAiKc,0BAA0B,cAAc;UAiBvC;EACf;EACA,eAAe;;iBAGD,eACd,UAAU,sBACT;iBAmBa,mBAAmB,UAAU;iBAmC7B,cAAc,WAAW;UAOxB;EACf;EACA;EACA;;iBAGc,aACd,UAAU,qBACV,QAAQ,6BACP;cAsFU,QAAM"}
|
package/dist/commands/doctor.js
CHANGED
|
@@ -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";
|
|
@@ -22,13 +23,7 @@ function readJson(file) {
|
|
|
22
23
|
}
|
|
23
24
|
}
|
|
24
25
|
function processPackageDir(pkgDir, results, visited) {
|
|
25
|
-
const real = (
|
|
26
|
-
try {
|
|
27
|
-
return fs$1.realpathSync(pkgDir);
|
|
28
|
-
} catch {
|
|
29
|
-
return pkgDir;
|
|
30
|
-
}
|
|
31
|
-
})();
|
|
26
|
+
const real = resolveRealPath(pkgDir);
|
|
32
27
|
if (visited.set.has(real)) return;
|
|
33
28
|
visited.set.add(real);
|
|
34
29
|
const pkgJson = readJson(path$1.join(pkgDir, "package.json"));
|
|
@@ -126,8 +121,14 @@ function walkPnpmStore(cwd, results, visited) {
|
|
|
126
121
|
function discoverInstalledPackages(cwd) {
|
|
127
122
|
const results = [];
|
|
128
123
|
const visited = { set: /* @__PURE__ */ new Set() };
|
|
129
|
-
|
|
130
|
-
|
|
124
|
+
let dir = resolveRealPath(cwd);
|
|
125
|
+
const scanRoot = findWorkspaceRoot(dir) ?? dir;
|
|
126
|
+
while (true) {
|
|
127
|
+
walkNodeModulesAt(dir, results, visited);
|
|
128
|
+
walkPnpmStore(dir, results, visited);
|
|
129
|
+
if (dir === scanRoot) break;
|
|
130
|
+
dir = path$1.dirname(dir);
|
|
131
|
+
}
|
|
131
132
|
return results;
|
|
132
133
|
}
|
|
133
134
|
function findDuplicates(packages) {
|
|
@@ -221,7 +222,7 @@ function reportOutdated(outdated, lines) {
|
|
|
221
222
|
lines.push(chalk.cyan(" npx assistant-ui update"));
|
|
222
223
|
}
|
|
223
224
|
const doctor = new Command().name("doctor").description("Diagnose mismatched or outdated assistant-ui packages (including transitive ones).").option("-c, --cwd <cwd>", "the working directory. defaults to the current directory.", process.cwd()).option("--no-network", "Skip the npm registry check for latest versions.").action(async (opts) => {
|
|
224
|
-
const cwd =
|
|
225
|
+
const cwd = resolveRealPath(opts.cwd);
|
|
225
226
|
const packageJsonPath = path$1.join(cwd, "package.json");
|
|
226
227
|
if (!fs$1.existsSync(packageJsonPath)) {
|
|
227
228
|
console.error(chalk.red("No package.json found in the current directory."));
|
|
@@ -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":";;;;;;AAMA,MAAM,6CAA6B,IAAI,IAAI;CACzC;CACA;CACA;AACF,CAAC;AAED,SAAS,iBAAiB,MAAmC;CAC3D,IAAI,CAAC,MAAM,OAAO;CAClB,IAAI,KAAK,WAAW,gBAAgB,GAAG,OAAO;CAC9C,OAAO,2BAA2B,IAAI,IAAI;AAC5C;AAYA,SAAS,SAAS,MAA8C;CAC9D,IAAI;EACF,OAAO,KAAK,MAAMA,KAAG,aAAa,MAAM,MAAM,CAAC;CACjD,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAS,kBACP,QACA,SACA,SACM;CACN,MAAM,cAAc;EAClB,IAAI;GACF,OAAOA,KAAG,aAAa,MAAM;EAC/B,QAAQ;GACN,OAAO;EACT;CACF,EAAA,CAAG;CACH,IAAI,QAAQ,IAAI,IAAI,IAAI,GAAG;CAC3B,QAAQ,IAAI,IAAI,IAAI;CAEpB,MAAM,UAAU,SAASC,OAAK,KAAK,QAAQ,cAAc,CAAC;CAC1D,IAAI,YAAY;CAChB,IAAI,SAAS;EACX,MAAM,OAAO,QAAQ;EACrB,MAAM,UAAU,QAAQ;EACxB,IAAI,QAAQ,WAAW,iBAAiB,IAAI,GAAG;GAC7C,QAAQ,KAAK;IAAE;IAAM;IAAS,aAAa;GAAO,CAAC;GACnD,YAAY;EACd;CACF;CAOA,IAAI,WACF,kBAAkB,QAAQ,SAAS,OAAO;AAE9C;AAEA,SAAS,kBACP,SACA,SACA,SACM;CACN,MAAM,KAAKA,OAAK,KAAK,SAAS,cAAc;CAC5C,IAAI,CAACD,KAAG,WAAW,EAAE,GAAG;CAExB,IAAI;CACJ,IAAI;EACF,UAAUA,KAAG,YAAY,IAAI,EAAE,eAAe,KAAK,CAAC;CACtD,QAAQ;EACN;CACF;CAEA,KAAK,MAAM,SAAS,SAAS;EAC3B,IAAI,MAAM,KAAK,WAAW,GAAG,GAAG;EAChC,IAAI,CAAC,MAAM,YAAY,KAAK,CAAC,MAAM,eAAe,GAAG;EAErD,IAAI,MAAM,KAAK,WAAW,GAAG,GAAG;GAC9B,MAAM,WAAWC,OAAK,KAAK,IAAI,MAAM,IAAI;GACzC,IAAI;GACJ,IAAI;IACF,SAASD,KAAG,YAAY,UAAU,EAAE,eAAe,KAAK,CAAC;GAC3D,QAAQ;IACN;GACF;GACA,KAAK,MAAM,KAAK,QAAQ;IACtB,IAAI,CAAC,EAAE,YAAY,KAAK,CAAC,EAAE,eAAe,GAAG;IAC7C,kBAAkBC,OAAK,KAAK,UAAU,EAAE,IAAI,GAAG,SAAS,OAAO;GACjE;EACF,OACE,kBAAkBA,OAAK,KAAK,IAAI,MAAM,IAAI,GAAG,SAAS,OAAO;CAEjE;AACF;AAOA,MAAM,8BAA8B;CAClC;CACA;CACA;CACA;AACF;AAEA,SAAS,mBAAmB,SAA0B;CACpD,OAAO,4BAA4B,MAAM,MAAM,QAAQ,WAAW,CAAC,CAAC;AACtE;AAEA,SAAS,yBACP,IACA,SACA,SACM;CACN,IAAI;CACJ,IAAI;EACF,UAAUD,KAAG,YAAY,IAAI,EAAE,eAAe,KAAK,CAAC;CACtD,QAAQ;EACN;CACF;CAEA,KAAK,MAAM,SAAS,SAAS;EAC3B,IAAI,MAAM,KAAK,WAAW,GAAG,GAAG;EAChC,IAAI,CAAC,MAAM,YAAY,KAAK,CAAC,MAAM,eAAe,GAAG;EAErD,IAAI,MAAM,KAAK,WAAW,GAAG,GAAG;GAC9B,MAAM,WAAWC,OAAK,KAAK,IAAI,MAAM,IAAI;GACzC,IAAI;GACJ,IAAI;IACF,SAASD,KAAG,YAAY,UAAU,EAAE,eAAe,KAAK,CAAC;GAC3D,QAAQ;IACN;GACF;GACA,KAAK,MAAM,KAAK,QAAQ;IACtB,IAAI,CAAC,EAAE,YAAY,KAAK,CAAC,EAAE,eAAe,GAAG;IAC7C,IAAI,CAAC,iBAAiB,GAAG,MAAM,KAAK,GAAG,EAAE,MAAM,GAAG;IAClD,kBAAkBC,OAAK,KAAK,UAAU,EAAE,IAAI,GAAG,SAAS,OAAO;GACjE;EACF,OAAO,IAAI,iBAAiB,MAAM,IAAI,GACpC,kBAAkBA,OAAK,KAAK,IAAI,MAAM,IAAI,GAAG,SAAS,OAAO;CAEjE;AACF;AAEA,SAAS,cACP,KACA,SACA,SACM;CACN,MAAM,WAAWA,OAAK,KAAK,KAAK,gBAAgB,OAAO;CACvD,IAAI;CACJ,IAAI;EACF,UAAUD,KAAG,YAAY,UAAU,EAAE,eAAe,KAAK,CAAC;CAC5D,QAAQ;EACN;CACF;CAEA,KAAK,MAAM,SAAS,SAAS;EAC3B,IAAI,CAAC,MAAM,YAAY,KAAK,CAAC,MAAM,eAAe,GAAG;EACrD,IAAI,CAAC,mBAAmB,MAAM,IAAI,GAAG;EACrC,yBACEC,OAAK,KAAK,UAAU,MAAM,MAAM,cAAc,GAC9C,SACA,OACF;CACF;AACF;AAMA,SAAgB,0BAA0B,KAAkC;CAC1E,MAAM,UAA+B,CAAC;CACtC,MAAM,UAAwB,EAAE,qBAAK,IAAI,IAAI,EAAE;CAC/C,kBAAkB,KAAK,SAAS,OAAO;CACvC,cAAc,KAAK,SAAS,OAAO;CACnC,OAAO;AACT;AAOA,SAAgB,eACd,UACkB;CAClB,MAAM,yBAAS,IAAI,IAAiC;CACpD,KAAK,MAAM,OAAO,UAAU;EAC1B,MAAM,OAAO,OAAO,IAAI,IAAI,IAAI,KAAK,CAAC;EACtC,KAAK,KAAK,GAAG;EACb,OAAO,IAAI,IAAI,MAAM,IAAI;CAC3B;CAEA,MAAM,aAA+B,CAAC;CACtC,KAAK,MAAM,CAAC,MAAM,kBAAkB,QAElC,IAAI,IADiB,IAAI,cAAc,KAAK,MAAM,EAAE,OAAO,CAChD,CAAC,CAAC,OAAO,GAClB,WAAW,KAAK;EAAE;EAAM;CAAc,CAAC;CAG3C,WAAW,MAAM,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;CACtD,OAAO;AACT;AAEA,SAAgB,mBAAmB,UAAyC;CAC1E,OAAO,MAAM,KAAK,IAAI,IAAI,SAAS,KAAK,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK;AAC/D;AAQA,MAAM,iBAAiB;AAEvB,eAAe,mBAAmB,MAAsC;CACtE,IAAI,CAAC,eAAe,KAAK,IAAI,GAAG,OAAO;CACvC,IAAI;EACF,MAAM,MAAM,MAAM,MAAM,8BAA8B,KAAK,UAAU,EACnE,SAAS,EAAE,QAAQ,mBAAmB,EACxC,CAAC;EACD,IAAI,CAAC,IAAI,IAAI,OAAO;EAEpB,QAAO,MADa,IAAI,KAAK,EAAA,CACjB,WAAW;CACzB,QAAQ;EACN,OAAO;CACT;AACF;AAEA,eAAe,uBACb,OACqC;CACrC,MAAM,UAAU,MAAM,QAAQ,IAC5B,MAAM,IAAI,OAAO,MAAM,CAAC,GAAG,MAAM,mBAAmB,CAAC,CAAC,CAAU,CAClE;CACA,OAAO,IAAI,IAAI,OAAO;AACxB;AAEA,SAAgB,cAAc,GAAW,GAAmB;CAC1D,MAAM,SAAS,MAAM,CAAC;CACtB,MAAM,SAAS,MAAM,CAAC;CACtB,IAAI,CAAC,UAAU,CAAC,QAAQ,OAAO,EAAE,cAAc,CAAC;CAChD,OAAO,QAAQ,QAAQ,MAAM;AAC/B;AAQA,SAAgB,aACd,UACA,QACmB;CACnB,MAAM,+BAAe,IAAI,IAAoB;CAC7C,KAAK,MAAM,OAAO,UAAU;EAC1B,MAAM,WAAW,aAAa,IAAI,IAAI,IAAI;EAC1C,IAAI,CAAC,YAAY,cAAc,IAAI,SAAS,QAAQ,IAAI,GACtD,aAAa,IAAI,IAAI,MAAM,IAAI,OAAO;CAE1C;CAEA,MAAM,SAA4B,CAAC;CACnC,KAAK,MAAM,CAAC,MAAM,YAAY,cAAc;EAC1C,MAAM,gBAAgB,OAAO,IAAI,IAAI;EACrC,IAAI,CAAC,eAAe;EACpB,IAAI,cAAc,SAAS,aAAa,IAAI,GAC1C,OAAO,KAAK;GAAE;GAAM;GAAS,QAAQ;EAAc,CAAC;CAExD;CACA,OAAO,MAAM,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;CAClD,OAAO;AACT;AAEA,SAAS,oBAAoB,aAAqB,KAAqB;CACrE,MAAM,MAAMA,OAAK,SAAS,KAAK,WAAW;CAC1C,OAAO,IAAI,WAAW,IAAI,IAAI,cAAc;AAC9C;AAEA,SAAS,iBACP,YACA,KACA,OACM;CACN,IAAI,WAAW,WAAW,GAAG;EAC3B,MAAM,KAAK,MAAM,MAAM,mCAAmC,CAAC;EAC3D;CACF;CAEA,MAAM,KAAK,MAAM,IAAI,KAAK,gCAAgC,CAAC;CAC3D,KAAK,MAAM,OAAO,YAAY;EAC5B,MAAM,WAAW,MAAM,KACrB,IAAI,IAAI,IAAI,cAAc,KAAK,MAAM,EAAE,OAAO,CAAC,CACjD,CAAC,CACE,KAAK,aAAa,CAAC,CACnB,KAAK,IAAI;EACZ,MAAM,KAAK,MAAM,IAAI,KAAK,IAAI,KAAK,KAAK,UAAU,CAAC;EACnD,KAAK,MAAM,QAAQ,IAAI,eACrB,MAAM,KACJ,MAAM,IACJ,OAAO,KAAK,QAAQ,IAAI,oBAAoB,KAAK,aAAa,GAAG,GACnE,CACF;CAEJ;CACA,MAAM,KAAK,EAAE;CACb,MAAM,KACJ,MAAM,OACJ,oHACF,CACF;CACA,MAAM,KACJ,MAAM,OACJ,4EACF,CACF;CACA,MAAM,KAAK,MAAM,KAAK,6BAA6B,CAAC;AACtD;AAEA,SAAS,eAAe,UAA6B,OAAuB;CAC1E,IAAI,SAAS,WAAW,GAAG;EACzB,MAAM,KAAK,MAAM,MAAM,6CAA6C,CAAC;EACrE;CACF;CAEA,MAAM,KAAK,MAAM,OAAO,KAAK,sBAAsB,CAAC;CACpD,MAAM,SAAS,KAAK,IAAI,GAAG,SAAS,KAAK,MAAM,EAAE,KAAK,MAAM,CAAC;CAC7D,KAAK,MAAM,KAAK,UACd,MAAM,KACJ,MAAM,OACJ,KAAK,EAAE,KAAK,OAAO,MAAM,EAAE,IAAI,EAAE,QAAQ,KAAK,EAAE,OAAO,UACzD,CACF;CAEF,MAAM,KAAK,EAAE;CACb,MAAM,KAAK,MAAM,OAAO,0CAA0C,CAAC;CACnE,MAAM,KAAK,MAAM,KAAK,6BAA6B,CAAC;AACtD;AAEA,MAAa,SAAS,IAAI,QAAQ,CAAC,CAChC,KAAK,QAAQ,CAAC,CACd,YACC,oFACF,CAAC,CACA,OACC,mBACA,6DACA,QAAQ,IAAI,CACd,CAAC,CACA,OAAO,gBAAgB,kDAAkD,CAAC,CAC1E,OAAO,OAAO,SAA4C;CACzD,MAAM,MAAMA,OAAK,QAAQ,KAAK,GAAG;CACjC,MAAM,kBAAkBA,OAAK,KAAK,KAAK,cAAc;CAErD,IAAI,CAACD,KAAG,WAAW,eAAe,GAAG;EACnC,QAAQ,MACN,MAAM,IAAI,iDAAiD,CAC7D;EACA,QAAQ,KAAK,CAAC;CAChB;CAEA,QAAQ,IAAI,EAAE;CACd,QAAQ,IAAI,MAAM,KAAK,gCAAgC,CAAC;CACxD,QAAQ,IAAI,EAAE;CAEd,MAAM,YAAY,0BAA0B,GAAG;CAE/C,IAAI,UAAU,WAAW,GAAG;EAC1B,QAAQ,IACN,MAAM,OACJ,4EACF,CACF;EACA,QAAQ,IAAI,EAAE;EACd;CACF;CAEA,MAAM,aAAa,eAAe,SAAS;CAE3C,IAAI,yBAAS,IAAI,IAA2B;CAC5C,IAAI,KAAK,SACP,SAAS,MAAM,uBAAuB,mBAAmB,SAAS,CAAC;CAErE,MAAM,WAAW,aAAa,WAAW,MAAM;CAE/C,MAAM,QAAkB,CAAC;CACzB,iBAAiB,YAAY,KAAK,KAAK;CACvC,MAAM,KAAK,EAAE;CACb,IAAI,KAAK,SACP,eAAe,UAAU,KAAK;MAE9B,MAAM,KAAK,MAAM,IAAI,4CAA4C,CAAC;CAGpE,KAAK,MAAM,QAAQ,OAAO,QAAQ,IAAI,IAAI;CAC1C,QAAQ,IAAI,EAAE;CAEd,IAAI,WAAW,SAAS,GACtB,QAAQ,WAAW;AAEvB,CAAC"}
|
|
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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"}
|
package/dist/commands/info.d.ts
CHANGED
|
@@ -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":"
|
|
1
|
+
{"version":3,"file":"info.d.ts","names":[],"sources":["../../src/commands/info.ts"],"mappings":";;;iBAgNgB,eAAe,iBAAiB;cAyMnC,MAAI"}
|