@getcoherent/cli 0.6.54 → 0.6.56
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/index.js +56 -55
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -126,7 +126,7 @@ function createMinimalConfig(appName = "My App") {
|
|
|
126
126
|
light: {
|
|
127
127
|
primary: "#3B82F6",
|
|
128
128
|
secondary: "#8B5CF6",
|
|
129
|
-
accent: "#
|
|
129
|
+
accent: "#F3F4F6",
|
|
130
130
|
success: "#10B981",
|
|
131
131
|
warning: "#F59E0B",
|
|
132
132
|
error: "#EF4444",
|
|
@@ -139,7 +139,7 @@ function createMinimalConfig(appName = "My App") {
|
|
|
139
139
|
dark: {
|
|
140
140
|
primary: "#60A5FA",
|
|
141
141
|
secondary: "#A78BFA",
|
|
142
|
-
accent: "#
|
|
142
|
+
accent: "#1F2937",
|
|
143
143
|
success: "#34D399",
|
|
144
144
|
warning: "#FBBF24",
|
|
145
145
|
error: "#F87171",
|
|
@@ -1830,9 +1830,9 @@ export function cn(...inputs: ClassValue[]) {
|
|
|
1830
1830
|
if (!existsSync3(componentsUiPath)) mkdirSync3(componentsUiPath, { recursive: true });
|
|
1831
1831
|
}
|
|
1832
1832
|
async function ensureRegistryComponents(config2, projectPath) {
|
|
1833
|
-
const
|
|
1833
|
+
const provider = getComponentProvider();
|
|
1834
1834
|
const baseComponents = ["button", "card", "input", "label", "switch"];
|
|
1835
|
-
await
|
|
1835
|
+
await provider.installBatch(baseComponents, projectPath);
|
|
1836
1836
|
const generator = new ComponentGenerator(config2);
|
|
1837
1837
|
const uiDir = join3(projectPath, "components", "ui");
|
|
1838
1838
|
if (!existsSync3(uiDir)) mkdirSync3(uiDir, { recursive: true });
|
|
@@ -2110,8 +2110,8 @@ import {
|
|
|
2110
2110
|
|
|
2111
2111
|
// src/agents/modifier.ts
|
|
2112
2112
|
import chalk4 from "chalk";
|
|
2113
|
-
async function parseModification(message, context,
|
|
2114
|
-
const ai = await createAIProvider(
|
|
2113
|
+
async function parseModification(message, context, provider = "auto", options) {
|
|
2114
|
+
const ai = await createAIProvider(provider);
|
|
2115
2115
|
if (options?.planOnly) {
|
|
2116
2116
|
const prompt2 = buildPlanOnlyPrompt(message, context.config);
|
|
2117
2117
|
const raw2 = await ai.parseModification(prompt2);
|
|
@@ -3781,11 +3781,11 @@ async function updateManifestSafe(projectRoot, fn) {
|
|
|
3781
3781
|
]).catch(() => {
|
|
3782
3782
|
});
|
|
3783
3783
|
}
|
|
3784
|
-
async function splitGeneratePages(spinner, message, modCtx,
|
|
3784
|
+
async function splitGeneratePages(spinner, message, modCtx, provider, parseOpts) {
|
|
3785
3785
|
let pageNames = [];
|
|
3786
3786
|
spinner.start("Phase 1/6 \u2014 Planning pages...");
|
|
3787
3787
|
try {
|
|
3788
|
-
const planResult = await parseModification(message, modCtx,
|
|
3788
|
+
const planResult = await parseModification(message, modCtx, provider, { ...parseOpts, planOnly: true });
|
|
3789
3789
|
const pageReqs = planResult.requests.filter((r) => r.type === "add-page");
|
|
3790
3790
|
pageNames = pageReqs.map((r) => {
|
|
3791
3791
|
const c = r.changes;
|
|
@@ -3845,7 +3845,7 @@ async function splitGeneratePages(spinner, message, modCtx, provider2, parseOpts
|
|
|
3845
3845
|
if (parseOpts.projectRoot) {
|
|
3846
3846
|
spinner.start("Phase 2/6 \u2014 Generating architecture plan...");
|
|
3847
3847
|
try {
|
|
3848
|
-
const ai = await createAIProvider(
|
|
3848
|
+
const ai = await createAIProvider(provider ?? "auto");
|
|
3849
3849
|
const cachedPlan = loadPlan(parseOpts.projectRoot);
|
|
3850
3850
|
let planWarnings = [];
|
|
3851
3851
|
if (cachedPlan) {
|
|
@@ -3907,7 +3907,7 @@ async function splitGeneratePages(spinner, message, modCtx, provider2, parseOpts
|
|
|
3907
3907
|
spinner.start(`Phase 3/6 \u2014 Generating ${homePage.name} page (sets design direction)...`);
|
|
3908
3908
|
try {
|
|
3909
3909
|
const anchorPrompt = buildAnchorPagePrompt(homePage, message, allPagesList, allRoutes, plan);
|
|
3910
|
-
const homeResult = await parseModification(anchorPrompt, modCtx,
|
|
3910
|
+
const homeResult = await parseModification(anchorPrompt, modCtx, provider, parseOpts);
|
|
3911
3911
|
const codePage = homeResult.requests.find((r) => r.type === "add-page");
|
|
3912
3912
|
if (codePage) {
|
|
3913
3913
|
homeRequest = codePage;
|
|
@@ -3946,7 +3946,7 @@ async function splitGeneratePages(spinner, message, modCtx, provider2, parseOpts
|
|
|
3946
3946
|
plan,
|
|
3947
3947
|
styleContext,
|
|
3948
3948
|
projectRoot,
|
|
3949
|
-
await createAIProvider(
|
|
3949
|
+
await createAIProvider(provider ?? "auto")
|
|
3950
3950
|
);
|
|
3951
3951
|
if (generated.length > 0) {
|
|
3952
3952
|
const updatedManifest = await loadManifest3(projectRoot);
|
|
@@ -3965,7 +3965,7 @@ async function splitGeneratePages(spinner, message, modCtx, provider2, parseOpts
|
|
|
3965
3965
|
if (!shouldSkip) {
|
|
3966
3966
|
spinner.start("Phase 4.5/6 \u2014 Extracting shared components (legacy)...");
|
|
3967
3967
|
try {
|
|
3968
|
-
const extraction = await extractSharedComponents(homePageCode, projectRoot,
|
|
3968
|
+
const extraction = await extractSharedComponents(homePageCode, projectRoot, provider ?? "auto");
|
|
3969
3969
|
parseOpts.sharedComponentsSummary = extraction.summary;
|
|
3970
3970
|
if (extraction.components.length > 0) {
|
|
3971
3971
|
const names = extraction.components.map((c) => c.name).join(", ");
|
|
@@ -4070,7 +4070,7 @@ ${existingAppPageCode}
|
|
|
4070
4070
|
styleContext
|
|
4071
4071
|
].filter(Boolean).join("\n\n");
|
|
4072
4072
|
try {
|
|
4073
|
-
const result = await parseModification(prompt, modCtx,
|
|
4073
|
+
const result = await parseModification(prompt, modCtx, provider, parseOpts);
|
|
4074
4074
|
phase5Done++;
|
|
4075
4075
|
spinner.text = `Phase 5/6 \u2014 ${phase5Done}/${remainingPages.length} pages generated...`;
|
|
4076
4076
|
const codePage = result.requests.find((r) => r.type === "add-page");
|
|
@@ -4087,7 +4087,7 @@ ${existingAppPageCode}
|
|
|
4087
4087
|
const missedNames = verification.missed.map((m) => m.component);
|
|
4088
4088
|
console.log(chalk6.yellow(` \u26A0 Missed reuse in "${name}": ${missedNames.join(", ")} \u2014 patching...`));
|
|
4089
4089
|
try {
|
|
4090
|
-
const ai = await createAIProvider(
|
|
4090
|
+
const ai = await createAIProvider(provider);
|
|
4091
4091
|
if (ai.editPageCode) {
|
|
4092
4092
|
const patchLines = verification.missed.map((m) => {
|
|
4093
4093
|
const importPath = m.importPath || `@/components/shared/${m.component.replace(/([A-Z])/g, (_, c, i) => (i ? "-" : "") + c.toLowerCase()).replace(/^-/, "")}`;
|
|
@@ -4153,7 +4153,7 @@ Keep all existing functionality. Only add imports and replace inline duplicates.
|
|
|
4153
4153
|
retryPageType,
|
|
4154
4154
|
retryTieredNote
|
|
4155
4155
|
);
|
|
4156
|
-
const retryResult = await parseModification(lightweightPrompt, modCtx,
|
|
4156
|
+
const retryResult = await parseModification(lightweightPrompt, modCtx, provider, {
|
|
4157
4157
|
...parseOpts,
|
|
4158
4158
|
lightweight: true
|
|
4159
4159
|
});
|
|
@@ -4219,14 +4219,14 @@ async function extractSharedComponents(homePageCode, projectRoot, aiProvider) {
|
|
|
4219
4219
|
return true;
|
|
4220
4220
|
});
|
|
4221
4221
|
const results = [];
|
|
4222
|
-
const
|
|
4222
|
+
const provider = getComponentProvider();
|
|
4223
4223
|
for (const item of filtered) {
|
|
4224
4224
|
try {
|
|
4225
4225
|
let { code: fixedCode } = await autoFixCode(item.code);
|
|
4226
4226
|
fixedCode = fixedCode.replace(/export default function (\w+)/g, "export function $1");
|
|
4227
4227
|
const shadcnImports = [...fixedCode.matchAll(/from\s+["']@\/components\/ui\/(.+?)["']/g)];
|
|
4228
4228
|
for (const match of shadcnImports) {
|
|
4229
|
-
await
|
|
4229
|
+
await provider.installComponent(match[1], projectRoot);
|
|
4230
4230
|
}
|
|
4231
4231
|
const result = await generateSharedComponent2(projectRoot, {
|
|
4232
4232
|
name: item.name,
|
|
@@ -4915,9 +4915,9 @@ async function applyModification(request, dsm, cm, pm, projectRoot, aiProvider,
|
|
|
4915
4915
|
}
|
|
4916
4916
|
case "add-component": {
|
|
4917
4917
|
const componentData = request.changes;
|
|
4918
|
-
const
|
|
4919
|
-
if (componentData.source === "shadcn" &&
|
|
4920
|
-
const result2 = await
|
|
4918
|
+
const provider = getComponentProvider();
|
|
4919
|
+
if (componentData.source === "shadcn" && provider.has(componentData.id)) {
|
|
4920
|
+
const result2 = await provider.installComponent(componentData.id, projectRoot);
|
|
4921
4921
|
if (result2.success && result2.componentDef) {
|
|
4922
4922
|
const mergedData = {
|
|
4923
4923
|
...result2.componentDef,
|
|
@@ -5628,8 +5628,8 @@ async function interactiveChat(options, chatCommandFn) {
|
|
|
5628
5628
|
await dsm.load();
|
|
5629
5629
|
const cm = new ComponentManager3(config2);
|
|
5630
5630
|
const validProviders = ["claude", "openai", "auto"];
|
|
5631
|
-
const
|
|
5632
|
-
if (!validProviders.includes(
|
|
5631
|
+
const provider = (options.provider || "auto").toLowerCase();
|
|
5632
|
+
if (!validProviders.includes(provider)) {
|
|
5633
5633
|
console.error(chalk9.red(`
|
|
5634
5634
|
\u274C Invalid provider: ${options.provider}`));
|
|
5635
5635
|
process.exit(1);
|
|
@@ -5774,7 +5774,7 @@ async function interactiveChat(options, chatCommandFn) {
|
|
|
5774
5774
|
resolvedInput = componentMatch[2];
|
|
5775
5775
|
}
|
|
5776
5776
|
try {
|
|
5777
|
-
await chatCommandFn(resolvedInput, { provider
|
|
5777
|
+
await chatCommandFn(resolvedInput, { provider, interactive: false, _throwOnError: true, ...extraOpts });
|
|
5778
5778
|
await dsm.load();
|
|
5779
5779
|
} catch (err) {
|
|
5780
5780
|
if (!err._printed) {
|
|
@@ -5825,11 +5825,11 @@ async function chatCommand(message, options) {
|
|
|
5825
5825
|
bail("Migration in progress");
|
|
5826
5826
|
}
|
|
5827
5827
|
const validProviders = ["claude", "openai", "auto"];
|
|
5828
|
-
const
|
|
5828
|
+
const provider = (options.provider || "auto").toLowerCase();
|
|
5829
5829
|
let releaseLock;
|
|
5830
5830
|
try {
|
|
5831
5831
|
releaseLock = await acquireProjectLock(projectRoot);
|
|
5832
|
-
if (!validProviders.includes(
|
|
5832
|
+
if (!validProviders.includes(provider)) {
|
|
5833
5833
|
spinner.fail("Invalid provider");
|
|
5834
5834
|
console.error(chalk10.red(`
|
|
5835
5835
|
\u274C Invalid provider: ${options.provider}`));
|
|
@@ -5871,7 +5871,7 @@ async function chatCommand(message, options) {
|
|
|
5871
5871
|
const { generateSharedComponent: generateSharedComponent6 } = await import("@getcoherent/core");
|
|
5872
5872
|
const { autoFixCode: autoFixCode2 } = await import("./quality-validator-IM6YFKLI.js");
|
|
5873
5873
|
const { extractPropsInterface, extractDependencies } = await import("./component-extractor-VYJLT5NR.js");
|
|
5874
|
-
const aiProvider = await createAIProvider2(
|
|
5874
|
+
const aiProvider = await createAIProvider2(provider ?? "auto");
|
|
5875
5875
|
const prompt = `Generate a React component called "${componentName}". Description: ${message}.
|
|
5876
5876
|
Use shadcn/ui components and Tailwind CSS semantic tokens. Export the component as a named export.
|
|
5877
5877
|
Include a TypeScript props interface.
|
|
@@ -6002,7 +6002,7 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
|
|
|
6002
6002
|
) || []).length >= SPLIT_THRESHOLD);
|
|
6003
6003
|
if (multiPageHint) {
|
|
6004
6004
|
try {
|
|
6005
|
-
const splitResult = await splitGeneratePages(spinner, message, modCtx,
|
|
6005
|
+
const splitResult = await splitGeneratePages(spinner, message, modCtx, provider, parseOpts);
|
|
6006
6006
|
requests = splitResult.requests;
|
|
6007
6007
|
if (splitResult.plan && projectRoot) {
|
|
6008
6008
|
savePlan(projectRoot, splitResult.plan);
|
|
@@ -6012,7 +6012,7 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
|
|
|
6012
6012
|
} catch {
|
|
6013
6013
|
spinner.warn("Split generation encountered an issue \u2014 trying page-by-page...");
|
|
6014
6014
|
try {
|
|
6015
|
-
const planResult = await parseModification(message, modCtx,
|
|
6015
|
+
const planResult = await parseModification(message, modCtx, provider, { ...parseOpts, planOnly: true });
|
|
6016
6016
|
const pageReqs = planResult.requests.filter((r) => r.type === "add-page");
|
|
6017
6017
|
requests = [];
|
|
6018
6018
|
for (let i = 0; i < pageReqs.length; i++) {
|
|
@@ -6024,7 +6024,7 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
|
|
|
6024
6024
|
const single = await parseModification(
|
|
6025
6025
|
`Create ONE page called "${pageName}" at route "${pageRoute}". Context: ${message}. Generate complete pageCode for this single page only.`,
|
|
6026
6026
|
modCtx,
|
|
6027
|
-
|
|
6027
|
+
provider,
|
|
6028
6028
|
parseOpts
|
|
6029
6029
|
);
|
|
6030
6030
|
const codePage = single.requests.find((r) => r.type === "add-page");
|
|
@@ -6062,7 +6062,7 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
|
|
|
6062
6062
|
} catch {
|
|
6063
6063
|
}
|
|
6064
6064
|
try {
|
|
6065
|
-
const result = await parseModification(message, modCtx,
|
|
6065
|
+
const result = await parseModification(message, modCtx, provider, { ...parseOpts, reusePlanDirective });
|
|
6066
6066
|
requests = result.requests;
|
|
6067
6067
|
uxRecommendations = result.uxRecommendations;
|
|
6068
6068
|
const pagesWithoutCode = requests.filter(
|
|
@@ -6078,7 +6078,7 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
|
|
|
6078
6078
|
const single = await parseModification(
|
|
6079
6079
|
`Create a page called "${pageName}" at route "${page.route || "/" + (page.id || pageName.toLowerCase())}". ${message}. Generate complete pageCode for this ONE page only.`,
|
|
6080
6080
|
modCtx,
|
|
6081
|
-
|
|
6081
|
+
provider,
|
|
6082
6082
|
parseOpts
|
|
6083
6083
|
);
|
|
6084
6084
|
const codePage = single.requests.find((r) => r.type === "add-page");
|
|
@@ -6096,7 +6096,7 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
|
|
|
6096
6096
|
if (isTruncated || isJsonError) {
|
|
6097
6097
|
spinner.warn("Response too large \u2014 splitting into smaller requests...");
|
|
6098
6098
|
try {
|
|
6099
|
-
const splitResult = await splitGeneratePages(spinner, message, modCtx,
|
|
6099
|
+
const splitResult = await splitGeneratePages(spinner, message, modCtx, provider, parseOpts);
|
|
6100
6100
|
requests = splitResult.requests;
|
|
6101
6101
|
if (splitResult.plan && projectRoot) {
|
|
6102
6102
|
savePlan(projectRoot, splitResult.plan);
|
|
@@ -6230,15 +6230,15 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
|
|
|
6230
6230
|
if (missingComponents.length > 0) {
|
|
6231
6231
|
spinner.stop();
|
|
6232
6232
|
console.log(chalk10.cyan("\n\u{1F50D} Pre-flight check: Installing missing components...\n"));
|
|
6233
|
-
const
|
|
6233
|
+
const provider2 = getComponentProvider();
|
|
6234
6234
|
for (const componentId of missingComponents) {
|
|
6235
6235
|
if (DEBUG4) {
|
|
6236
6236
|
console.log(chalk10.gray(` [DEBUG] Trying to install: ${componentId}`));
|
|
6237
|
-
console.log(chalk10.gray(` [DEBUG] provider.has(${componentId}): ${
|
|
6237
|
+
console.log(chalk10.gray(` [DEBUG] provider.has(${componentId}): ${provider2.has(componentId)}`));
|
|
6238
6238
|
}
|
|
6239
|
-
if (
|
|
6239
|
+
if (provider2.has(componentId)) {
|
|
6240
6240
|
try {
|
|
6241
|
-
const result = await
|
|
6241
|
+
const result = await provider2.installComponent(componentId, projectRoot);
|
|
6242
6242
|
if (DEBUG4) console.log(chalk10.gray(` [DEBUG] installComponent result: ${result.success}`));
|
|
6243
6243
|
if (result.success && result.componentDef) {
|
|
6244
6244
|
if (!cm.read(componentId)) {
|
|
@@ -6323,7 +6323,7 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
|
|
|
6323
6323
|
spinner.start("Applying modifications...");
|
|
6324
6324
|
const results = [];
|
|
6325
6325
|
for (const request of normalizedRequests) {
|
|
6326
|
-
const result = await applyModification(request, dsm, cm, pm, projectRoot,
|
|
6326
|
+
const result = await applyModification(request, dsm, cm, pm, projectRoot, provider, message);
|
|
6327
6327
|
results.push(result);
|
|
6328
6328
|
}
|
|
6329
6329
|
for (const request of normalizedRequests) {
|
|
@@ -6414,7 +6414,7 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
|
|
|
6414
6414
|
const { requests: linkedRequests } = await parseModification(
|
|
6415
6415
|
`add ${pageName} page at route ${linkedRoute}`,
|
|
6416
6416
|
{ config: dsm.getConfig(), componentManager: cm },
|
|
6417
|
-
|
|
6417
|
+
provider
|
|
6418
6418
|
);
|
|
6419
6419
|
let anySuccess = false;
|
|
6420
6420
|
for (const raw of linkedRequests.map((r) => applyDefaults(r))) {
|
|
@@ -6423,7 +6423,7 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
|
|
|
6423
6423
|
scaffoldSpinner.warn(` Skipped scaffold: ${linkedReq.error}`);
|
|
6424
6424
|
continue;
|
|
6425
6425
|
}
|
|
6426
|
-
const linkedResult = await applyModification(linkedReq, dsm, cm, pm, projectRoot,
|
|
6426
|
+
const linkedResult = await applyModification(linkedReq, dsm, cm, pm, projectRoot, provider);
|
|
6427
6427
|
if (linkedResult.success) {
|
|
6428
6428
|
results.push(linkedResult);
|
|
6429
6429
|
normalizedRequests.push(linkedReq);
|
|
@@ -6711,7 +6711,7 @@ ${uxRecommendations}
|
|
|
6711
6711
|
console.log(chalk10.white(' coherent chat "add account page"'));
|
|
6712
6712
|
console.log(chalk10.white(' coherent chat "add settings page"'));
|
|
6713
6713
|
} else if (error.message.includes("API key not found") || error.message.includes("ANTHROPIC_API_KEY") || error.message.includes("OPENAI_API_KEY")) {
|
|
6714
|
-
const isOpenAI = error.message.includes("OpenAI") || typeof
|
|
6714
|
+
const isOpenAI = error.message.includes("OpenAI") || typeof provider !== "undefined" && provider === "openai";
|
|
6715
6715
|
const providerName = isOpenAI ? "OpenAI" : "Anthropic Claude";
|
|
6716
6716
|
const envVar = isOpenAI ? "OPENAI_API_KEY" : "ANTHROPIC_API_KEY";
|
|
6717
6717
|
const url = isOpenAI ? "https://platform.openai.com" : "https://console.anthropic.com";
|
|
@@ -7382,13 +7382,13 @@ async function fixMissingComponentExports(projectRoot) {
|
|
|
7382
7382
|
} catch {
|
|
7383
7383
|
}
|
|
7384
7384
|
const generator = new ComponentGenerator2(config2 || { components: [], pages: [], tokens: {} });
|
|
7385
|
-
const
|
|
7385
|
+
const provider = getComponentProvider();
|
|
7386
7386
|
for (const [componentId, needed] of neededExports) {
|
|
7387
7387
|
const componentFile = join9(uiDir, `${componentId}.tsx`);
|
|
7388
7388
|
if (!existsSync11(componentFile)) {
|
|
7389
|
-
if (
|
|
7389
|
+
if (provider.has(componentId)) {
|
|
7390
7390
|
try {
|
|
7391
|
-
const result = await
|
|
7391
|
+
const result = await provider.installComponent(componentId, projectRoot);
|
|
7392
7392
|
if (result.success) {
|
|
7393
7393
|
console.log(chalk11.dim(` \u2714 Installed missing ${componentId}.tsx`));
|
|
7394
7394
|
}
|
|
@@ -7421,9 +7421,9 @@ async function fixMissingComponentExports(projectRoot) {
|
|
|
7421
7421
|
}
|
|
7422
7422
|
const missing = [...needed].filter((n) => !existingExports.has(n));
|
|
7423
7423
|
if (missing.length === 0) continue;
|
|
7424
|
-
if (
|
|
7424
|
+
if (provider.has(componentId)) {
|
|
7425
7425
|
try {
|
|
7426
|
-
const result = await
|
|
7426
|
+
const result = await provider.installComponent(componentId, projectRoot, { force: true });
|
|
7427
7427
|
if (result.success) {
|
|
7428
7428
|
console.log(chalk11.dim(` \u2714 Reinstalled ${componentId}.tsx (added missing exports: ${missing.join(", ")})`));
|
|
7429
7429
|
}
|
|
@@ -7520,8 +7520,8 @@ function extractShadcnComponentFromModuleNotFound(msg) {
|
|
|
7520
7520
|
return m?.[1] ?? null;
|
|
7521
7521
|
}
|
|
7522
7522
|
async function autoInstallShadcnComponent(componentId, projectRoot) {
|
|
7523
|
-
const
|
|
7524
|
-
const result = await
|
|
7523
|
+
const provider = getComponentProvider();
|
|
7524
|
+
const result = await provider.installComponent(componentId, projectRoot);
|
|
7525
7525
|
return result.success;
|
|
7526
7526
|
}
|
|
7527
7527
|
var DEFAULT_PORT = 3e3;
|
|
@@ -8310,8 +8310,8 @@ async function fixCommand(opts = {}) {
|
|
|
8310
8310
|
if (!existsSync13(filePath)) missingFiles.push(id);
|
|
8311
8311
|
}
|
|
8312
8312
|
}
|
|
8313
|
-
const
|
|
8314
|
-
const toInstall = [.../* @__PURE__ */ new Set([...missingComponents, ...missingFiles])].filter((id) =>
|
|
8313
|
+
const provider = getComponentProvider();
|
|
8314
|
+
const toInstall = [.../* @__PURE__ */ new Set([...missingComponents, ...missingFiles])].filter((id) => provider.has(id));
|
|
8315
8315
|
if (toInstall.length > 0) {
|
|
8316
8316
|
if (dryRun) {
|
|
8317
8317
|
fixes.push(`Would install components: ${toInstall.join(", ")}`);
|
|
@@ -8320,7 +8320,7 @@ async function fixCommand(opts = {}) {
|
|
|
8320
8320
|
let installed = 0;
|
|
8321
8321
|
for (const componentId of toInstall) {
|
|
8322
8322
|
try {
|
|
8323
|
-
const result = await
|
|
8323
|
+
const result = await provider.installComponent(componentId, projectRoot);
|
|
8324
8324
|
if (!result.success) continue;
|
|
8325
8325
|
if (result.componentDef && !cm.read(componentId)) {
|
|
8326
8326
|
const regResult = await cm.register(result.componentDef);
|
|
@@ -8495,9 +8495,10 @@ async function fixCommand(opts = {}) {
|
|
|
8495
8495
|
const sidebarPath = resolve8(projectRoot, "components", "shared", "sidebar.tsx");
|
|
8496
8496
|
if (hasSidebar && !existsSync13(sidebarPath) && !dryRun) {
|
|
8497
8497
|
const sidebarUiPath = resolve8(projectRoot, "components", "ui", "sidebar.tsx");
|
|
8498
|
-
|
|
8498
|
+
const sidebarProvider = getComponentProvider();
|
|
8499
|
+
if (!existsSync13(sidebarUiPath) && sidebarProvider.has("sidebar")) {
|
|
8499
8500
|
try {
|
|
8500
|
-
await
|
|
8501
|
+
await sidebarProvider.installComponent("sidebar", projectRoot);
|
|
8501
8502
|
console.log(chalk15.green(" \u2714 Auto-installed Sidebar UI component"));
|
|
8502
8503
|
} catch {
|
|
8503
8504
|
console.log(chalk15.yellow(" \u26A0 Could not install Sidebar UI component"));
|
|
@@ -10655,8 +10656,8 @@ async function migrateAction(options) {
|
|
|
10655
10656
|
console.log(chalk28.yellow("No components/ui directory found. Nothing to migrate."));
|
|
10656
10657
|
return;
|
|
10657
10658
|
}
|
|
10658
|
-
const
|
|
10659
|
-
const managedIds = new Set(
|
|
10659
|
+
const provider = getComponentProvider();
|
|
10660
|
+
const managedIds = new Set(provider.listNames());
|
|
10660
10661
|
const files = readdirSync9(uiDir).filter((f) => f.endsWith(".tsx"));
|
|
10661
10662
|
const migratable = files.map((f) => f.replace(".tsx", "")).filter((id) => managedIds.has(id));
|
|
10662
10663
|
if (migratable.length === 0) {
|
|
@@ -10680,7 +10681,7 @@ Found ${migratable.length} component(s) to migrate:`));
|
|
|
10680
10681
|
const filePath = join16(uiDir, `${id}.tsx`);
|
|
10681
10682
|
if (existsSync19(filePath)) rmSync6(filePath);
|
|
10682
10683
|
}
|
|
10683
|
-
const results = await
|
|
10684
|
+
const results = await provider.installBatch(migratable, projectRoot, { force: true });
|
|
10684
10685
|
let migrated = 0;
|
|
10685
10686
|
for (const [id, result] of results) {
|
|
10686
10687
|
if (result.success) {
|