@getcoherent/cli 0.6.55 → 0.6.57

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.
@@ -2,7 +2,7 @@ import {
2
2
  CORE_CONSTRAINTS,
3
3
  getDesignQualityForType,
4
4
  inferPageTypeFromRoute
5
- } from "./chunk-NLL3SHN3.js";
5
+ } from "./chunk-PVVL26FX.js";
6
6
  import {
7
7
  autoFixCode
8
8
  } from "./chunk-U5SNPHVU.js";
@@ -1007,17 +1007,18 @@ var CONTEXTUAL_CATEGORIES = [
1007
1007
  rules: RULES_SHADCN_APIS
1008
1008
  }
1009
1009
  ];
1010
- function selectContextualRules(message) {
1010
+ function selectContextualRules(message, pageSections) {
1011
1011
  const matched = /* @__PURE__ */ new Set();
1012
+ const matchTarget = pageSections && pageSections.length > 0 ? pageSections.join(" ") : message;
1012
1013
  for (const category of CONTEXTUAL_CATEGORIES) {
1013
- if (category.keywords.test(message)) {
1014
+ if (category.keywords.test(matchTarget)) {
1014
1015
  matched.add(category.rules);
1015
1016
  }
1016
1017
  }
1017
1018
  if (matched.size === 0) {
1018
1019
  return "";
1019
1020
  }
1020
- return [...matched].join("\n");
1021
+ return [...matched].slice(0, 3).join("\n");
1021
1022
  }
1022
1023
  var DESIGN_CONSTRAINTS = `${DESIGN_THINKING}
1023
1024
  ${CORE_CONSTRAINTS}
@@ -6,7 +6,7 @@ import {
6
6
  getPageGroup,
7
7
  installPackages,
8
8
  sanitizeMetadataStrings
9
- } from "./chunk-IFJK5OPI.js";
9
+ } from "./chunk-BNHIEEXH.js";
10
10
  import {
11
11
  toKebabCase
12
12
  } from "./chunk-4TLYDTT3.js";
@@ -2147,7 +2147,7 @@ async function regeneratePage(pageId, config, projectRoot) {
2147
2147
  const code = await generator.generate(page, appType);
2148
2148
  const route = page.route || "/";
2149
2149
  const isAuth = isAuthRoute(route) || isAuthRoute(page.name || page.id || "");
2150
- const { loadPlan: loadPlanForPath } = await import("./plan-generator-D2UBTVCN.js");
2150
+ const { loadPlan: loadPlanForPath } = await import("./plan-generator-A3YN473Q.js");
2151
2151
  const planForPath = loadPlanForPath(projectRoot);
2152
2152
  const filePath = routeToFsPath(projectRoot, route, planForPath || isAuth);
2153
2153
  await mkdir3(dirname3(filePath), { recursive: true });
@@ -12,10 +12,10 @@ import {
12
12
  regeneratePage,
13
13
  scanAndInstallSharedDeps,
14
14
  validateAndFixGeneratedCode
15
- } from "./chunk-UZGT5APM.js";
16
- import "./chunk-IFJK5OPI.js";
15
+ } from "./chunk-XBX4WND7.js";
16
+ import "./chunk-BNHIEEXH.js";
17
17
  import "./chunk-4TLYDTT3.js";
18
- import "./chunk-NLL3SHN3.js";
18
+ import "./chunk-PVVL26FX.js";
19
19
  import "./chunk-U5SNPHVU.js";
20
20
  import "./chunk-3RG5ZIWI.js";
21
21
  export {
@@ -18,7 +18,7 @@ import {
18
18
  getDesignQualityForType,
19
19
  inferPageTypeFromRoute,
20
20
  selectContextualRules
21
- } from "./chunk-NLL3SHN3.js";
21
+ } from "./chunk-PVVL26FX.js";
22
22
  import "./chunk-3RG5ZIWI.js";
23
23
  export {
24
24
  CORE_CONSTRAINTS,
package/dist/index.js CHANGED
@@ -34,7 +34,7 @@ import {
34
34
  warnIfVolatile,
35
35
  warnInlineDuplicates,
36
36
  writeFile
37
- } from "./chunk-UZGT5APM.js";
37
+ } from "./chunk-XBX4WND7.js";
38
38
  import {
39
39
  COHERENT_REQUIRED_PACKAGES,
40
40
  ensureUseClientIfNeeded,
@@ -52,7 +52,7 @@ import {
52
52
  sanitizeMetadataStrings,
53
53
  savePlan,
54
54
  updateArchitecturePlan
55
- } from "./chunk-IFJK5OPI.js";
55
+ } from "./chunk-BNHIEEXH.js";
56
56
  import {
57
57
  isValidTsx,
58
58
  safeWrite
@@ -74,7 +74,7 @@ import {
74
74
  getDesignQualityForType,
75
75
  inferPageTypeFromRoute,
76
76
  selectContextualRules
77
- } from "./chunk-NLL3SHN3.js";
77
+ } from "./chunk-PVVL26FX.js";
78
78
  import {
79
79
  fixGlobalsCss,
80
80
  generateV4GlobalsCss,
@@ -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 provider2 = getComponentProvider();
1833
+ const provider = getComponentProvider();
1834
1834
  const baseComponents = ["button", "card", "input", "label", "switch"];
1835
- await provider2.installBatch(baseComponents, projectPath);
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, provider2 = "auto", options) {
2114
- const ai = await createAIProvider(provider2);
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);
@@ -2143,7 +2143,8 @@ async function parseModification(message, context, provider2 = "auto", options)
2143
2143
  isExpandedPageRequest,
2144
2144
  sharedComponentsSummary: options?.sharedComponentsSummary,
2145
2145
  tieredComponentsPrompt: options?.tieredComponentsPrompt,
2146
- reusePlanDirective: options?.reusePlanDirective
2146
+ reusePlanDirective: options?.reusePlanDirective,
2147
+ pageSections: options?.pageSections
2147
2148
  });
2148
2149
  const raw = await ai.parseModification(prompt);
2149
2150
  const requestsArray = Array.isArray(raw) ? raw : raw?.requests ?? [];
@@ -2243,7 +2244,7 @@ For editing an existing shared component use type "modify-layout-block" with tar
2243
2244
  const coreRules = CORE_CONSTRAINTS;
2244
2245
  const designQuality = DESIGN_QUALITY;
2245
2246
  const visualDepth = VISUAL_DEPTH;
2246
- const contextualRules = selectContextualRules(message);
2247
+ const contextualRules = selectContextualRules(message, options?.pageSections);
2247
2248
  const interactionPatterns = INTERACTION_PATTERNS;
2248
2249
  const light = config2.tokens.colors.light;
2249
2250
  const dark = config2.tokens.colors.dark;
@@ -3511,12 +3512,24 @@ function verifyReusePlan(generatedCode, plan) {
3511
3512
  }
3512
3513
 
3513
3514
  // src/commands/chat/split-generator.ts
3514
- var MAX_EXISTING_PAGES_CONTEXT = 10;
3515
- function buildExistingPagesContext(config2) {
3515
+ var MAX_EXISTING_PAGES_CONTEXT = 3;
3516
+ function filterManifestForPage(manifest, plan, route) {
3517
+ const plannedForPage = plan.sharedComponents.filter((c) => c.usedBy.includes(route)).map((c) => c.name.toLowerCase());
3518
+ if (plannedForPage.length === 0) return manifest;
3519
+ const filtered = manifest.shared.filter((e) => plannedForPage.includes(e.name.toLowerCase()) || e.type === "layout");
3520
+ if (filtered.length === 0) return manifest;
3521
+ return { ...manifest, shared: filtered };
3522
+ }
3523
+ function buildExistingPagesContext(config2, forPageType) {
3516
3524
  const pages = config2.pages || [];
3517
3525
  const analyzed = pages.filter((p) => p.pageAnalysis);
3518
3526
  if (analyzed.length === 0) return "";
3519
- const capped = analyzed.slice(0, MAX_EXISTING_PAGES_CONTEXT);
3527
+ let relevant = analyzed;
3528
+ if (forPageType) {
3529
+ const sameType = analyzed.filter((p) => inferPageTypeFromRoute(p.route) === forPageType);
3530
+ relevant = sameType.length > 0 ? sameType : analyzed;
3531
+ }
3532
+ const capped = relevant.slice(0, MAX_EXISTING_PAGES_CONTEXT);
3520
3533
  const lines = capped.map((p) => {
3521
3534
  return summarizePageAnalysis(p.name || p.id, p.route, p.pageAnalysis);
3522
3535
  });
@@ -3781,11 +3794,11 @@ async function updateManifestSafe(projectRoot, fn) {
3781
3794
  ]).catch(() => {
3782
3795
  });
3783
3796
  }
3784
- async function splitGeneratePages(spinner, message, modCtx, provider2, parseOpts) {
3797
+ async function splitGeneratePages(spinner, message, modCtx, provider, parseOpts) {
3785
3798
  let pageNames = [];
3786
3799
  spinner.start("Phase 1/6 \u2014 Planning pages...");
3787
3800
  try {
3788
- const planResult = await parseModification(message, modCtx, provider2, { ...parseOpts, planOnly: true });
3801
+ const planResult = await parseModification(message, modCtx, provider, { ...parseOpts, planOnly: true });
3789
3802
  const pageReqs = planResult.requests.filter((r) => r.type === "add-page");
3790
3803
  pageNames = pageReqs.map((r) => {
3791
3804
  const c = r.changes;
@@ -3845,7 +3858,7 @@ async function splitGeneratePages(spinner, message, modCtx, provider2, parseOpts
3845
3858
  if (parseOpts.projectRoot) {
3846
3859
  spinner.start("Phase 2/6 \u2014 Generating architecture plan...");
3847
3860
  try {
3848
- const ai = await createAIProvider(provider2 ?? "auto");
3861
+ const ai = await createAIProvider(provider ?? "auto");
3849
3862
  const cachedPlan = loadPlan(parseOpts.projectRoot);
3850
3863
  let planWarnings = [];
3851
3864
  if (cachedPlan) {
@@ -3907,7 +3920,7 @@ async function splitGeneratePages(spinner, message, modCtx, provider2, parseOpts
3907
3920
  spinner.start(`Phase 3/6 \u2014 Generating ${homePage.name} page (sets design direction)...`);
3908
3921
  try {
3909
3922
  const anchorPrompt = buildAnchorPagePrompt(homePage, message, allPagesList, allRoutes, plan);
3910
- const homeResult = await parseModification(anchorPrompt, modCtx, provider2, parseOpts);
3923
+ const homeResult = await parseModification(anchorPrompt, modCtx, provider, parseOpts);
3911
3924
  const codePage = homeResult.requests.find((r) => r.type === "add-page");
3912
3925
  if (codePage) {
3913
3926
  homeRequest = codePage;
@@ -3941,12 +3954,12 @@ async function splitGeneratePages(spinner, message, modCtx, provider2, parseOpts
3941
3954
  if (plan && plan.sharedComponents.length > 0) {
3942
3955
  spinner.start(`Phase 4.5/6 \u2014 Generating ${plan.sharedComponents.length} shared components from plan...`);
3943
3956
  try {
3944
- const { generateSharedComponentsFromPlan } = await import("./plan-generator-D2UBTVCN.js");
3957
+ const { generateSharedComponentsFromPlan } = await import("./plan-generator-A3YN473Q.js");
3945
3958
  const generated = await generateSharedComponentsFromPlan(
3946
3959
  plan,
3947
3960
  styleContext,
3948
3961
  projectRoot,
3949
- await createAIProvider(provider2 ?? "auto")
3962
+ await createAIProvider(provider ?? "auto")
3950
3963
  );
3951
3964
  if (generated.length > 0) {
3952
3965
  const updatedManifest = await loadManifest3(projectRoot);
@@ -3965,7 +3978,7 @@ async function splitGeneratePages(spinner, message, modCtx, provider2, parseOpts
3965
3978
  if (!shouldSkip) {
3966
3979
  spinner.start("Phase 4.5/6 \u2014 Extracting shared components (legacy)...");
3967
3980
  try {
3968
- const extraction = await extractSharedComponents(homePageCode, projectRoot, provider2 ?? "auto");
3981
+ const extraction = await extractSharedComponents(homePageCode, projectRoot, provider ?? "auto");
3969
3982
  parseOpts.sharedComponentsSummary = extraction.summary;
3970
3983
  if (extraction.components.length > 0) {
3971
3984
  const names = extraction.components.map((c) => c.name).join(", ");
@@ -3994,7 +4007,6 @@ EXISTING APP PAGE (match these UI patterns for consistency):
3994
4007
  ${existingAppPageCode}
3995
4008
  \`\`\`
3996
4009
  ` : "";
3997
- const existingPagesContext = buildExistingPagesContext(modCtx.config);
3998
4010
  const existingPageCode = {};
3999
4011
  if (projectRoot) {
4000
4012
  const appDir = resolve2(projectRoot, "app");
@@ -4021,9 +4033,11 @@ ${existingAppPageCode}
4021
4033
  const pageType = plan ? getPageType(route, plan) : inferPageTypeFromRoute(route);
4022
4034
  const designConstraints = getDesignQualityForType(pageType);
4023
4035
  const authNote = isAuth ? 'For this auth page: the auth layout already provides centering (flex items-center justify-center min-h-svh). Do NOT add your own centering wrapper or min-h-svh. Just output a div with className="w-full max-w-md" containing the Card. Do NOT use section containers or full-width wrappers.' : void 0;
4036
+ const existingPagesContext = buildExistingPagesContext(modCtx.config, pageType);
4024
4037
  const layoutForPage = getGroupLayoutForRoute(route, plan);
4025
4038
  const layoutNote = buildLayoutNote(layoutForPage);
4026
- const tieredNote = currentManifest ? buildTieredComponentsPrompt(currentManifest, pageType) : void 0;
4039
+ const filteredManifest = currentManifest && plan ? filterManifestForPage(currentManifest, plan, route) : currentManifest;
4040
+ const tieredNote = filteredManifest ? buildTieredComponentsPrompt(filteredManifest, pageType) : void 0;
4027
4041
  const pageKey = route.replace(/^\//, "") || "home";
4028
4042
  const pageSections = plan?.pageNotes?.[pageKey]?.sections || [];
4029
4043
  let reusePlanDirective = "";
@@ -4070,7 +4084,7 @@ ${existingAppPageCode}
4070
4084
  styleContext
4071
4085
  ].filter(Boolean).join("\n\n");
4072
4086
  try {
4073
- const result = await parseModification(prompt, modCtx, provider2, parseOpts);
4087
+ const result = await parseModification(prompt, modCtx, provider, { ...parseOpts, pageSections });
4074
4088
  phase5Done++;
4075
4089
  spinner.text = `Phase 5/6 \u2014 ${phase5Done}/${remainingPages.length} pages generated...`;
4076
4090
  const codePage = result.requests.find((r) => r.type === "add-page");
@@ -4087,7 +4101,7 @@ ${existingAppPageCode}
4087
4101
  const missedNames = verification.missed.map((m) => m.component);
4088
4102
  console.log(chalk6.yellow(` \u26A0 Missed reuse in "${name}": ${missedNames.join(", ")} \u2014 patching...`));
4089
4103
  try {
4090
- const ai = await createAIProvider(provider2);
4104
+ const ai = await createAIProvider(provider);
4091
4105
  if (ai.editPageCode) {
4092
4106
  const patchLines = verification.missed.map((m) => {
4093
4107
  const importPath = m.importPath || `@/components/shared/${m.component.replace(/([A-Z])/g, (_, c, i) => (i ? "-" : "") + c.toLowerCase()).replace(/^-/, "")}`;
@@ -4153,7 +4167,7 @@ Keep all existing functionality. Only add imports and replace inline duplicates.
4153
4167
  retryPageType,
4154
4168
  retryTieredNote
4155
4169
  );
4156
- const retryResult = await parseModification(lightweightPrompt, modCtx, provider2, {
4170
+ const retryResult = await parseModification(lightweightPrompt, modCtx, provider, {
4157
4171
  ...parseOpts,
4158
4172
  lightweight: true
4159
4173
  });
@@ -4219,14 +4233,14 @@ async function extractSharedComponents(homePageCode, projectRoot, aiProvider) {
4219
4233
  return true;
4220
4234
  });
4221
4235
  const results = [];
4222
- const provider2 = getComponentProvider();
4236
+ const provider = getComponentProvider();
4223
4237
  for (const item of filtered) {
4224
4238
  try {
4225
4239
  let { code: fixedCode } = await autoFixCode(item.code);
4226
4240
  fixedCode = fixedCode.replace(/export default function (\w+)/g, "export function $1");
4227
4241
  const shadcnImports = [...fixedCode.matchAll(/from\s+["']@\/components\/ui\/(.+?)["']/g)];
4228
4242
  for (const match of shadcnImports) {
4229
- await provider2.installComponent(match[1], projectRoot);
4243
+ await provider.installComponent(match[1], projectRoot);
4230
4244
  }
4231
4245
  const result = await generateSharedComponent2(projectRoot, {
4232
4246
  name: item.name,
@@ -4915,9 +4929,9 @@ async function applyModification(request, dsm, cm, pm, projectRoot, aiProvider,
4915
4929
  }
4916
4930
  case "add-component": {
4917
4931
  const componentData = request.changes;
4918
- const provider2 = getComponentProvider();
4919
- if (componentData.source === "shadcn" && provider2.has(componentData.id)) {
4920
- const result2 = await provider2.installComponent(componentData.id, projectRoot);
4932
+ const provider = getComponentProvider();
4933
+ if (componentData.source === "shadcn" && provider.has(componentData.id)) {
4934
+ const result2 = await provider.installComponent(componentData.id, projectRoot);
4921
4935
  if (result2.success && result2.componentDef) {
4922
4936
  const mergedData = {
4923
4937
  ...result2.componentDef,
@@ -5628,8 +5642,8 @@ async function interactiveChat(options, chatCommandFn) {
5628
5642
  await dsm.load();
5629
5643
  const cm = new ComponentManager3(config2);
5630
5644
  const validProviders = ["claude", "openai", "auto"];
5631
- const provider2 = (options.provider || "auto").toLowerCase();
5632
- if (!validProviders.includes(provider2)) {
5645
+ const provider = (options.provider || "auto").toLowerCase();
5646
+ if (!validProviders.includes(provider)) {
5633
5647
  console.error(chalk9.red(`
5634
5648
  \u274C Invalid provider: ${options.provider}`));
5635
5649
  process.exit(1);
@@ -5774,7 +5788,7 @@ async function interactiveChat(options, chatCommandFn) {
5774
5788
  resolvedInput = componentMatch[2];
5775
5789
  }
5776
5790
  try {
5777
- await chatCommandFn(resolvedInput, { provider: provider2, interactive: false, _throwOnError: true, ...extraOpts });
5791
+ await chatCommandFn(resolvedInput, { provider, interactive: false, _throwOnError: true, ...extraOpts });
5778
5792
  await dsm.load();
5779
5793
  } catch (err) {
5780
5794
  if (!err._printed) {
@@ -5825,11 +5839,11 @@ async function chatCommand(message, options) {
5825
5839
  bail("Migration in progress");
5826
5840
  }
5827
5841
  const validProviders = ["claude", "openai", "auto"];
5828
- const provider2 = (options.provider || "auto").toLowerCase();
5842
+ const provider = (options.provider || "auto").toLowerCase();
5829
5843
  let releaseLock;
5830
5844
  try {
5831
5845
  releaseLock = await acquireProjectLock(projectRoot);
5832
- if (!validProviders.includes(provider2)) {
5846
+ if (!validProviders.includes(provider)) {
5833
5847
  spinner.fail("Invalid provider");
5834
5848
  console.error(chalk10.red(`
5835
5849
  \u274C Invalid provider: ${options.provider}`));
@@ -5871,7 +5885,7 @@ async function chatCommand(message, options) {
5871
5885
  const { generateSharedComponent: generateSharedComponent6 } = await import("@getcoherent/core");
5872
5886
  const { autoFixCode: autoFixCode2 } = await import("./quality-validator-IM6YFKLI.js");
5873
5887
  const { extractPropsInterface, extractDependencies } = await import("./component-extractor-VYJLT5NR.js");
5874
- const aiProvider = await createAIProvider2(provider2 ?? "auto");
5888
+ const aiProvider = await createAIProvider2(provider ?? "auto");
5875
5889
  const prompt = `Generate a React component called "${componentName}". Description: ${message}.
5876
5890
  Use shadcn/ui components and Tailwind CSS semantic tokens. Export the component as a named export.
5877
5891
  Include a TypeScript props interface.
@@ -6002,7 +6016,7 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
6002
6016
  ) || []).length >= SPLIT_THRESHOLD);
6003
6017
  if (multiPageHint) {
6004
6018
  try {
6005
- const splitResult = await splitGeneratePages(spinner, message, modCtx, provider2, parseOpts);
6019
+ const splitResult = await splitGeneratePages(spinner, message, modCtx, provider, parseOpts);
6006
6020
  requests = splitResult.requests;
6007
6021
  if (splitResult.plan && projectRoot) {
6008
6022
  savePlan(projectRoot, splitResult.plan);
@@ -6012,7 +6026,7 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
6012
6026
  } catch {
6013
6027
  spinner.warn("Split generation encountered an issue \u2014 trying page-by-page...");
6014
6028
  try {
6015
- const planResult = await parseModification(message, modCtx, provider2, { ...parseOpts, planOnly: true });
6029
+ const planResult = await parseModification(message, modCtx, provider, { ...parseOpts, planOnly: true });
6016
6030
  const pageReqs = planResult.requests.filter((r) => r.type === "add-page");
6017
6031
  requests = [];
6018
6032
  for (let i = 0; i < pageReqs.length; i++) {
@@ -6024,7 +6038,7 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
6024
6038
  const single = await parseModification(
6025
6039
  `Create ONE page called "${pageName}" at route "${pageRoute}". Context: ${message}. Generate complete pageCode for this single page only.`,
6026
6040
  modCtx,
6027
- provider2,
6041
+ provider,
6028
6042
  parseOpts
6029
6043
  );
6030
6044
  const codePage = single.requests.find((r) => r.type === "add-page");
@@ -6062,7 +6076,7 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
6062
6076
  } catch {
6063
6077
  }
6064
6078
  try {
6065
- const result = await parseModification(message, modCtx, provider2, { ...parseOpts, reusePlanDirective });
6079
+ const result = await parseModification(message, modCtx, provider, { ...parseOpts, reusePlanDirective });
6066
6080
  requests = result.requests;
6067
6081
  uxRecommendations = result.uxRecommendations;
6068
6082
  const pagesWithoutCode = requests.filter(
@@ -6078,7 +6092,7 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
6078
6092
  const single = await parseModification(
6079
6093
  `Create a page called "${pageName}" at route "${page.route || "/" + (page.id || pageName.toLowerCase())}". ${message}. Generate complete pageCode for this ONE page only.`,
6080
6094
  modCtx,
6081
- provider2,
6095
+ provider,
6082
6096
  parseOpts
6083
6097
  );
6084
6098
  const codePage = single.requests.find((r) => r.type === "add-page");
@@ -6096,7 +6110,7 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
6096
6110
  if (isTruncated || isJsonError) {
6097
6111
  spinner.warn("Response too large \u2014 splitting into smaller requests...");
6098
6112
  try {
6099
- const splitResult = await splitGeneratePages(spinner, message, modCtx, provider2, parseOpts);
6113
+ const splitResult = await splitGeneratePages(spinner, message, modCtx, provider, parseOpts);
6100
6114
  requests = splitResult.requests;
6101
6115
  if (splitResult.plan && projectRoot) {
6102
6116
  savePlan(projectRoot, splitResult.plan);
@@ -6230,15 +6244,15 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
6230
6244
  if (missingComponents.length > 0) {
6231
6245
  spinner.stop();
6232
6246
  console.log(chalk10.cyan("\n\u{1F50D} Pre-flight check: Installing missing components...\n"));
6233
- const provider3 = getComponentProvider();
6247
+ const provider2 = getComponentProvider();
6234
6248
  for (const componentId of missingComponents) {
6235
6249
  if (DEBUG4) {
6236
6250
  console.log(chalk10.gray(` [DEBUG] Trying to install: ${componentId}`));
6237
- console.log(chalk10.gray(` [DEBUG] provider.has(${componentId}): ${provider3.has(componentId)}`));
6251
+ console.log(chalk10.gray(` [DEBUG] provider.has(${componentId}): ${provider2.has(componentId)}`));
6238
6252
  }
6239
- if (provider3.has(componentId)) {
6253
+ if (provider2.has(componentId)) {
6240
6254
  try {
6241
- const result = await provider3.installComponent(componentId, projectRoot);
6255
+ const result = await provider2.installComponent(componentId, projectRoot);
6242
6256
  if (DEBUG4) console.log(chalk10.gray(` [DEBUG] installComponent result: ${result.success}`));
6243
6257
  if (result.success && result.componentDef) {
6244
6258
  if (!cm.read(componentId)) {
@@ -6323,7 +6337,7 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
6323
6337
  spinner.start("Applying modifications...");
6324
6338
  const results = [];
6325
6339
  for (const request of normalizedRequests) {
6326
- const result = await applyModification(request, dsm, cm, pm, projectRoot, provider2, message);
6340
+ const result = await applyModification(request, dsm, cm, pm, projectRoot, provider, message);
6327
6341
  results.push(result);
6328
6342
  }
6329
6343
  for (const request of normalizedRequests) {
@@ -6339,7 +6353,7 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
6339
6353
  }
6340
6354
  try {
6341
6355
  const { validateReuse } = await import("./reuse-validator-XR2ZEYC4.js");
6342
- const { inferPageTypeFromRoute: inferPageTypeFromRoute2 } = await import("./design-constraints-PFZDW2XW.js");
6356
+ const { inferPageTypeFromRoute: inferPageTypeFromRoute2 } = await import("./design-constraints-PFCUSBMG.js");
6343
6357
  const manifest2 = await loadManifest6(projectRoot);
6344
6358
  const reuseplan = projectRoot ? loadPlan(projectRoot) : null;
6345
6359
  if (manifest2.shared.length > 0) {
@@ -6414,7 +6428,7 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
6414
6428
  const { requests: linkedRequests } = await parseModification(
6415
6429
  `add ${pageName} page at route ${linkedRoute}`,
6416
6430
  { config: dsm.getConfig(), componentManager: cm },
6417
- provider2
6431
+ provider
6418
6432
  );
6419
6433
  let anySuccess = false;
6420
6434
  for (const raw of linkedRequests.map((r) => applyDefaults(r))) {
@@ -6423,7 +6437,7 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
6423
6437
  scaffoldSpinner.warn(` Skipped scaffold: ${linkedReq.error}`);
6424
6438
  continue;
6425
6439
  }
6426
- const linkedResult = await applyModification(linkedReq, dsm, cm, pm, projectRoot, provider2);
6440
+ const linkedResult = await applyModification(linkedReq, dsm, cm, pm, projectRoot, provider);
6427
6441
  if (linkedResult.success) {
6428
6442
  results.push(linkedResult);
6429
6443
  normalizedRequests.push(linkedReq);
@@ -6711,7 +6725,7 @@ ${uxRecommendations}
6711
6725
  console.log(chalk10.white(' coherent chat "add account page"'));
6712
6726
  console.log(chalk10.white(' coherent chat "add settings page"'));
6713
6727
  } 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 provider2 !== "undefined" && provider2 === "openai";
6728
+ const isOpenAI = error.message.includes("OpenAI") || typeof provider !== "undefined" && provider === "openai";
6715
6729
  const providerName = isOpenAI ? "OpenAI" : "Anthropic Claude";
6716
6730
  const envVar = isOpenAI ? "OPENAI_API_KEY" : "ANTHROPIC_API_KEY";
6717
6731
  const url = isOpenAI ? "https://platform.openai.com" : "https://console.anthropic.com";
@@ -7382,13 +7396,13 @@ async function fixMissingComponentExports(projectRoot) {
7382
7396
  } catch {
7383
7397
  }
7384
7398
  const generator = new ComponentGenerator2(config2 || { components: [], pages: [], tokens: {} });
7385
- const provider2 = getComponentProvider();
7399
+ const provider = getComponentProvider();
7386
7400
  for (const [componentId, needed] of neededExports) {
7387
7401
  const componentFile = join9(uiDir, `${componentId}.tsx`);
7388
7402
  if (!existsSync11(componentFile)) {
7389
- if (provider2.has(componentId)) {
7403
+ if (provider.has(componentId)) {
7390
7404
  try {
7391
- const result = await provider2.installComponent(componentId, projectRoot);
7405
+ const result = await provider.installComponent(componentId, projectRoot);
7392
7406
  if (result.success) {
7393
7407
  console.log(chalk11.dim(` \u2714 Installed missing ${componentId}.tsx`));
7394
7408
  }
@@ -7421,9 +7435,9 @@ async function fixMissingComponentExports(projectRoot) {
7421
7435
  }
7422
7436
  const missing = [...needed].filter((n) => !existingExports.has(n));
7423
7437
  if (missing.length === 0) continue;
7424
- if (provider2.has(componentId)) {
7438
+ if (provider.has(componentId)) {
7425
7439
  try {
7426
- const result = await provider2.installComponent(componentId, projectRoot, { force: true });
7440
+ const result = await provider.installComponent(componentId, projectRoot, { force: true });
7427
7441
  if (result.success) {
7428
7442
  console.log(chalk11.dim(` \u2714 Reinstalled ${componentId}.tsx (added missing exports: ${missing.join(", ")})`));
7429
7443
  }
@@ -7520,8 +7534,8 @@ function extractShadcnComponentFromModuleNotFound(msg) {
7520
7534
  return m?.[1] ?? null;
7521
7535
  }
7522
7536
  async function autoInstallShadcnComponent(componentId, projectRoot) {
7523
- const provider2 = getComponentProvider();
7524
- const result = await provider2.installComponent(componentId, projectRoot);
7537
+ const provider = getComponentProvider();
7538
+ const result = await provider.installComponent(componentId, projectRoot);
7525
7539
  return result.success;
7526
7540
  }
7527
7541
  var DEFAULT_PORT = 3e3;
@@ -8310,8 +8324,8 @@ async function fixCommand(opts = {}) {
8310
8324
  if (!existsSync13(filePath)) missingFiles.push(id);
8311
8325
  }
8312
8326
  }
8313
- const provider2 = getComponentProvider();
8314
- const toInstall = [.../* @__PURE__ */ new Set([...missingComponents, ...missingFiles])].filter((id) => provider2.has(id));
8327
+ const provider = getComponentProvider();
8328
+ const toInstall = [.../* @__PURE__ */ new Set([...missingComponents, ...missingFiles])].filter((id) => provider.has(id));
8315
8329
  if (toInstall.length > 0) {
8316
8330
  if (dryRun) {
8317
8331
  fixes.push(`Would install components: ${toInstall.join(", ")}`);
@@ -8320,7 +8334,7 @@ async function fixCommand(opts = {}) {
8320
8334
  let installed = 0;
8321
8335
  for (const componentId of toInstall) {
8322
8336
  try {
8323
- const result = await provider2.installComponent(componentId, projectRoot);
8337
+ const result = await provider.installComponent(componentId, projectRoot);
8324
8338
  if (!result.success) continue;
8325
8339
  if (result.componentDef && !cm.read(componentId)) {
8326
8340
  const regResult = await cm.register(result.componentDef);
@@ -8479,8 +8493,8 @@ async function fixCommand(opts = {}) {
8479
8493
  console.log(chalk15.green(` \u2714 ${verb} syntax: ${syntaxFixed} file(s) (use client, metadata, quotes)`));
8480
8494
  }
8481
8495
  try {
8482
- const { loadPlan: loadPlan2 } = await import("./plan-generator-D2UBTVCN.js");
8483
- const { ensurePlanGroupLayouts: ensurePlanGroupLayouts2 } = await import("./code-generator-IZ6XM6WG.js");
8496
+ const { loadPlan: loadPlan2 } = await import("./plan-generator-A3YN473Q.js");
8497
+ const { ensurePlanGroupLayouts: ensurePlanGroupLayouts2 } = await import("./code-generator-SKXX6PQG.js");
8484
8498
  const plan = loadPlan2(projectRoot);
8485
8499
  if (plan) {
8486
8500
  if (!dsm) {
@@ -8495,9 +8509,10 @@ async function fixCommand(opts = {}) {
8495
8509
  const sidebarPath = resolve8(projectRoot, "components", "shared", "sidebar.tsx");
8496
8510
  if (hasSidebar && !existsSync13(sidebarPath) && !dryRun) {
8497
8511
  const sidebarUiPath = resolve8(projectRoot, "components", "ui", "sidebar.tsx");
8498
- if (!existsSync13(sidebarUiPath) && provider.has("sidebar")) {
8512
+ const sidebarProvider = getComponentProvider();
8513
+ if (!existsSync13(sidebarUiPath) && sidebarProvider.has("sidebar")) {
8499
8514
  try {
8500
- await provider.installComponent("sidebar", projectRoot);
8515
+ await sidebarProvider.installComponent("sidebar", projectRoot);
8501
8516
  console.log(chalk15.green(" \u2714 Auto-installed Sidebar UI component"));
8502
8517
  } catch {
8503
8518
  console.log(chalk15.yellow(" \u26A0 Could not install Sidebar UI component"));
@@ -8543,7 +8558,7 @@ async function fixCommand(opts = {}) {
8543
8558
  const publicExists = existsSync13(publicLayoutPath);
8544
8559
  const needsPublicLayout = !publicExists || !readFileSync10(publicLayoutPath, "utf-8").includes("<Header");
8545
8560
  if (needsPublicLayout) {
8546
- const { buildPublicLayoutCodeForSidebar } = await import("./code-generator-IZ6XM6WG.js");
8561
+ const { buildPublicLayoutCodeForSidebar } = await import("./code-generator-SKXX6PQG.js");
8547
8562
  mkdirSync7(resolve8(projectRoot, "app", "(public)"), { recursive: true });
8548
8563
  const publicResult = safeWrite(publicLayoutPath, buildPublicLayoutCodeForSidebar(), projectRoot, backups);
8549
8564
  if (publicResult.ok) {
@@ -8592,7 +8607,7 @@ async function fixCommand(opts = {}) {
8592
8607
  }
8593
8608
  const themeTogglePath = resolve8(projectRoot, "components", "shared", "theme-toggle.tsx");
8594
8609
  if (!existsSync13(themeTogglePath)) {
8595
- const { generateThemeToggleCode } = await import("./code-generator-IZ6XM6WG.js");
8610
+ const { generateThemeToggleCode } = await import("./code-generator-SKXX6PQG.js");
8596
8611
  mkdirSync7(resolve8(projectRoot, "components", "shared"), { recursive: true });
8597
8612
  const themeResult = safeWrite(themeTogglePath, generateThemeToggleCode(), projectRoot, backups);
8598
8613
  if (themeResult.ok) {
@@ -8613,7 +8628,7 @@ async function fixCommand(opts = {}) {
8613
8628
  const isMinimal = appLayoutCode.length < 500 && !appLayoutCode.includes("Header") && !appLayoutCode.includes("Footer") && !appLayoutCode.includes("Sidebar") && !appLayoutCode.includes("SidebarProvider") && !appLayoutCode.includes("SidebarTrigger") && !appLayoutCode.includes("Sheet");
8614
8629
  const navType = dsm.getConfig().navigation?.type || "header";
8615
8630
  if (isMinimal && navType !== "none") {
8616
- const { buildAppLayoutCode, buildGroupLayoutCode } = await import("./code-generator-IZ6XM6WG.js");
8631
+ const { buildAppLayoutCode, buildGroupLayoutCode } = await import("./code-generator-SKXX6PQG.js");
8617
8632
  const isSidebar = navType === "sidebar" || navType === "both";
8618
8633
  const newLayout = isSidebar ? buildAppLayoutCode(navType, dsm.getConfig().name) : buildGroupLayoutCode("header", dsm.getConfig().pages?.map((p) => p.name) || [], dsm.getConfig().name);
8619
8634
  if (!dryRun) {
@@ -9160,7 +9175,7 @@ async function checkCommand(opts = {}) {
9160
9175
  if (!skipShared) {
9161
9176
  try {
9162
9177
  const { validateReuse } = await import("./reuse-validator-XR2ZEYC4.js");
9163
- const { inferPageTypeFromRoute: inferPageTypeFromRoute2 } = await import("./design-constraints-PFZDW2XW.js");
9178
+ const { inferPageTypeFromRoute: inferPageTypeFromRoute2 } = await import("./design-constraints-PFCUSBMG.js");
9164
9179
  const manifest = await loadManifest9(projectRoot);
9165
9180
  const appDir = resolve9(projectRoot, "app");
9166
9181
  const pageFiles = existsSync14(appDir) ? findTsxFiles(appDir) : [];
@@ -10655,8 +10670,8 @@ async function migrateAction(options) {
10655
10670
  console.log(chalk28.yellow("No components/ui directory found. Nothing to migrate."));
10656
10671
  return;
10657
10672
  }
10658
- const provider2 = getComponentProvider();
10659
- const managedIds = new Set(provider2.listNames());
10673
+ const provider = getComponentProvider();
10674
+ const managedIds = new Set(provider.listNames());
10660
10675
  const files = readdirSync9(uiDir).filter((f) => f.endsWith(".tsx"));
10661
10676
  const migratable = files.map((f) => f.replace(".tsx", "")).filter((id) => managedIds.has(id));
10662
10677
  if (migratable.length === 0) {
@@ -10680,7 +10695,7 @@ Found ${migratable.length} component(s) to migrate:`));
10680
10695
  const filePath = join16(uiDir, `${id}.tsx`);
10681
10696
  if (existsSync19(filePath)) rmSync6(filePath);
10682
10697
  }
10683
- const results = await provider2.installBatch(migratable, projectRoot, { force: true });
10698
+ const results = await provider.installBatch(migratable, projectRoot, { force: true });
10684
10699
  let migrated = 0;
10685
10700
  for (const [id, result] of results) {
10686
10701
  if (result.success) {
@@ -11,8 +11,8 @@ import {
11
11
  routeToKey,
12
12
  savePlan,
13
13
  updateArchitecturePlan
14
- } from "./chunk-IFJK5OPI.js";
15
- import "./chunk-NLL3SHN3.js";
14
+ } from "./chunk-BNHIEEXH.js";
15
+ import "./chunk-PVVL26FX.js";
16
16
  import "./chunk-U5SNPHVU.js";
17
17
  import "./chunk-3RG5ZIWI.js";
18
18
  export {
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.6.55",
6
+ "version": "0.6.57",
7
7
  "description": "CLI interface for Coherent Design Method",
8
8
  "type": "module",
9
9
  "main": "./dist/index.js",