@getcoherent/cli 0.6.21 → 0.6.23

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Sergei Kovtun
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -258,6 +258,7 @@ Requirements:
258
258
  - Use Tailwind CSS classes matching the style context
259
259
  - TypeScript with proper props interface
260
260
  - Each component is a standalone file
261
+ - Icon props MUST use \`icon: React.ElementType\` (NOT React.ReactNode) and render as \`<Icon className="size-4" />\` where \`const Icon = icon\`. Lucide icons are forwardRef components, not elements.
261
262
 
262
263
  Return JSON with { requests: [{ type: "add-page", changes: { name: "ComponentName", pageCode: "..." } }, ...] }`;
263
264
  const results = [];
@@ -1186,6 +1186,11 @@ ${selectImport}`
1186
1186
  if (fixed !== beforePlaceholder) {
1187
1187
  fixes.push("placeholder content \u2192 contextual content");
1188
1188
  }
1189
+ const beforeIconProp = fixed;
1190
+ fixed = fixed.replace(/(\bicon\s*:\s*)React\.ReactNode\b/g, "$1React.ElementType");
1191
+ if (fixed !== beforeIconProp) {
1192
+ fixes.push("icon prop: ReactNode \u2192 ElementType (forwardRef compat)");
1193
+ }
1189
1194
  return { code: fixed, fixes };
1190
1195
  }
1191
1196
  function formatIssues(issues) {
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  formatIssues,
8
8
  validatePageQuality,
9
9
  verifyIncrementalEdit
10
- } from "./chunk-VKGZRKWD.js";
10
+ } from "./chunk-SKQRPBPF.js";
11
11
  import {
12
12
  generateArchitecturePlan,
13
13
  getPageGroup,
@@ -16,7 +16,7 @@ import {
16
16
  routeToKey,
17
17
  savePlan,
18
18
  updateArchitecturePlan
19
- } from "./chunk-PVJJ2YXP.js";
19
+ } from "./chunk-FAV3UHFM.js";
20
20
  import {
21
21
  CORE_CONSTRAINTS,
22
22
  DESIGN_QUALITY,
@@ -4393,6 +4393,12 @@ PAGE WRAPPER (CRITICAL \u2014 the layout provides width/padding automatically):
4393
4393
  - ALL app pages must follow this exact same structure so content aligns consistently across pages
4394
4394
  - Landing/marketing pages are an exception: they render outside the app layout and should use full-width <section> elements with inner "mx-auto max-w-6xl" for content.
4395
4395
 
4396
+ ICON PROPS (CRITICAL \u2014 prevents runtime crash):
4397
+ - When passing lucide-react icons as props, the component prop MUST be typed as \`React.ElementType\` (NOT React.ReactNode).
4398
+ - Render icon props as: \`const Icon = props.icon; <Icon className="size-4" />\`
4399
+ - Pass icons as: \`icon={FolderOpen}\` (component reference, not JSX element)
4400
+ - Lucide icons are forwardRef components \u2014 passing them as ReactNode causes "Objects are not valid as a React child" error.
4401
+
4396
4402
  PAGE CONTENT (CRITICAL \u2014 prevents empty or duplicate pages):
4397
4403
  - Every page MUST have substantial content. NEVER generate a page with only metadata and an empty <main> element.
4398
4404
  - NEVER create an inline preview/demo of another page (e.g., embedding a "dashboard view" inside the landing page with a toggle). Each page should be its own route.
@@ -5096,7 +5102,7 @@ async function warnInlineDuplicates(projectRoot, pageName, route, pageCode, mani
5096
5102
  if (pageTokens.includes(t)) overlap++;
5097
5103
  }
5098
5104
  const overlapRatio = sharedTokens.size > 0 ? overlap / sharedTokens.size : 0;
5099
- if (overlap >= 20 && overlapRatio >= 0.6) {
5105
+ if (overlap >= 25 && overlapRatio >= 0.7) {
5100
5106
  console.log(
5101
5107
  chalk7.yellow(
5102
5108
  `
@@ -6309,7 +6315,7 @@ async function splitGeneratePages(spinner, message, modCtx, provider, parseOpts)
6309
6315
  if (plan && plan.sharedComponents.length > 0) {
6310
6316
  spinner.start(`Phase 4.5/6 \u2014 Generating ${plan.sharedComponents.length} shared components from plan...`);
6311
6317
  try {
6312
- const { generateSharedComponentsFromPlan } = await import("./plan-generator-ITHYNYJI.js");
6318
+ const { generateSharedComponentsFromPlan } = await import("./plan-generator-5I6BPEVL.js");
6313
6319
  const generated = await generateSharedComponentsFromPlan(
6314
6320
  plan,
6315
6321
  styleContext,
@@ -6769,7 +6775,7 @@ async function regeneratePage(pageId, config2, projectRoot) {
6769
6775
  const code = await generator.generate(page, appType);
6770
6776
  const route = page.route || "/";
6771
6777
  const isAuth = isAuthRoute(route) || isAuthRoute(page.name || page.id || "");
6772
- const { loadPlan: loadPlanForPath } = await import("./plan-generator-ITHYNYJI.js");
6778
+ const { loadPlan: loadPlanForPath } = await import("./plan-generator-5I6BPEVL.js");
6773
6779
  const planForPath = loadPlanForPath(projectRoot);
6774
6780
  const filePath = routeToFsPath(projectRoot, route, planForPath || isAuth);
6775
6781
  await mkdir3(dirname5(filePath), { recursive: true });
@@ -7512,7 +7518,7 @@ async function applyModification(request, dsm, cm, pm, projectRoot, aiProvider,
7512
7518
  sharedId: resolved.id,
7513
7519
  sharedName: resolved.name,
7514
7520
  pageTarget,
7515
- route: route ?? `/${routePath}`,
7521
+ route,
7516
7522
  postFixes: fixes
7517
7523
  });
7518
7524
  try {
@@ -8528,7 +8534,7 @@ async function chatCommand(message, options) {
8528
8534
  spinner.start(`Creating shared component: ${componentName}...`);
8529
8535
  const { createAIProvider: createAIProvider2 } = await import("./ai-provider-CGSIYFZT.js");
8530
8536
  const { generateSharedComponent: generateSharedComponent7 } = await import("@getcoherent/core");
8531
- const { autoFixCode: autoFixCode2 } = await import("./quality-validator-P572ZUW5.js");
8537
+ const { autoFixCode: autoFixCode2 } = await import("./quality-validator-OX25OLIR.js");
8532
8538
  const { extractPropsInterface, extractDependencies } = await import("./component-extractor-VYJLT5NR.js");
8533
8539
  const aiProvider = await createAIProvider2(provider ?? "auto");
8534
8540
  const prompt = `Generate a React component called "${componentName}". Description: ${message}.
@@ -11,7 +11,7 @@ import {
11
11
  routeToKey,
12
12
  savePlan,
13
13
  updateArchitecturePlan
14
- } from "./chunk-PVJJ2YXP.js";
14
+ } from "./chunk-FAV3UHFM.js";
15
15
  import "./chunk-5AHG4NNX.js";
16
16
  import "./chunk-3RG5ZIWI.js";
17
17
  export {
@@ -4,7 +4,7 @@ import {
4
4
  formatIssues,
5
5
  validatePageQuality,
6
6
  verifyIncrementalEdit
7
- } from "./chunk-VKGZRKWD.js";
7
+ } from "./chunk-SKQRPBPF.js";
8
8
  import "./chunk-3RG5ZIWI.js";
9
9
  export {
10
10
  autoFixCode,
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.6.21",
6
+ "version": "0.6.23",
7
7
  "description": "CLI interface for Coherent Design Method",
8
8
  "type": "module",
9
9
  "main": "./dist/index.js",
@@ -33,15 +33,8 @@
33
33
  ],
34
34
  "author": "Coherent Design Method",
35
35
  "license": "MIT",
36
- "scripts": {
37
- "dev": "tsup --watch",
38
- "build": "tsup",
39
- "typecheck": "tsc --noEmit",
40
- "test": "vitest"
41
- },
42
36
  "dependencies": {
43
37
  "@anthropic-ai/sdk": "^0.32.0",
44
- "@getcoherent/core": "workspace:*",
45
38
  "chalk": "^5.3.0",
46
39
  "chokidar": "^4.0.1",
47
40
  "commander": "^11.1.0",
@@ -49,7 +42,8 @@
49
42
  "open": "^10.1.0",
50
43
  "ora": "^7.0.1",
51
44
  "prompts": "^2.4.2",
52
- "zod": "^3.22.4"
45
+ "zod": "^3.22.4",
46
+ "@getcoherent/core": "0.6.23"
53
47
  },
54
48
  "devDependencies": {
55
49
  "@types/node": "^20.11.0",
@@ -58,5 +52,11 @@
58
52
  "react": "^19.2.4",
59
53
  "tsup": "^8.0.1",
60
54
  "typescript": "^5.3.3"
55
+ },
56
+ "scripts": {
57
+ "dev": "tsup --watch",
58
+ "build": "tsup",
59
+ "typecheck": "tsc --noEmit",
60
+ "test": "vitest"
61
61
  }
62
- }
62
+ }