mcp-dndgrid 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/PROJECT_SUMMARY.md +482 -0
  2. package/QUICKSTART.md +223 -0
  3. package/README.md +365 -0
  4. package/STATUS.md +315 -0
  5. package/USAGE_GUIDE.md +547 -0
  6. package/dist/chunk-CMGEAPA5.js +157 -0
  7. package/dist/chunk-CMGEAPA5.js.map +1 -0
  8. package/dist/chunk-QZHBI6ZI.js +5281 -0
  9. package/dist/chunk-QZHBI6ZI.js.map +1 -0
  10. package/dist/chunk-SEGVTWSK.js +44 -0
  11. package/dist/chunk-SEGVTWSK.js.map +1 -0
  12. package/dist/index.d.ts +2 -0
  13. package/dist/index.js +248012 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/stdio-FWYJXSU7.js +101 -0
  16. package/dist/stdio-FWYJXSU7.js.map +1 -0
  17. package/dist/template-JDMAVVX7.js +9 -0
  18. package/dist/template-JDMAVVX7.js.map +1 -0
  19. package/examples/claude_desktop_config.example.json +12 -0
  20. package/examples/example-complex-editor.tsx +107 -0
  21. package/examples/example-dashboard.tsx +65 -0
  22. package/examples/example-ide-layout.tsx +53 -0
  23. package/examples/test-generator.ts +37 -0
  24. package/examples/test-parser.ts +121 -0
  25. package/examples/test-scenarios.md +496 -0
  26. package/package.json +42 -0
  27. package/src/index.ts +16 -0
  28. package/src/server.ts +314 -0
  29. package/src/tools/analyze-layout.ts +193 -0
  30. package/src/tools/apply-template.ts +125 -0
  31. package/src/tools/generate-layout.ts +235 -0
  32. package/src/tools/interactive-builder.ts +100 -0
  33. package/src/tools/validate-layout.ts +113 -0
  34. package/src/types/layout.ts +48 -0
  35. package/src/types/template.ts +181 -0
  36. package/src/utils/ast-parser.ts +264 -0
  37. package/src/utils/code-generator.ts +123 -0
  38. package/src/utils/layout-analyzer.ts +105 -0
  39. package/src/utils/layout-builder.ts +127 -0
  40. package/src/utils/validator.ts +263 -0
  41. package/stderr.log +1 -0
  42. package/stdout.log +0 -0
  43. package/test-mcp.js +27 -0
  44. package/tsconfig.json +29 -0
  45. package/tsup.config.ts +16 -0
@@ -0,0 +1,101 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ JSONRPCMessageSchema
4
+ } from "./chunk-QZHBI6ZI.js";
5
+ import "./chunk-SEGVTWSK.js";
6
+
7
+ // node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
8
+ import process from "process";
9
+
10
+ // node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.js
11
+ var ReadBuffer = class {
12
+ append(chunk) {
13
+ this._buffer = this._buffer ? Buffer.concat([this._buffer, chunk]) : chunk;
14
+ }
15
+ readMessage() {
16
+ if (!this._buffer) {
17
+ return null;
18
+ }
19
+ const index = this._buffer.indexOf("\n");
20
+ if (index === -1) {
21
+ return null;
22
+ }
23
+ const line = this._buffer.toString("utf8", 0, index).replace(/\r$/, "");
24
+ this._buffer = this._buffer.subarray(index + 1);
25
+ return deserializeMessage(line);
26
+ }
27
+ clear() {
28
+ this._buffer = void 0;
29
+ }
30
+ };
31
+ function deserializeMessage(line) {
32
+ return JSONRPCMessageSchema.parse(JSON.parse(line));
33
+ }
34
+ function serializeMessage(message) {
35
+ return JSON.stringify(message) + "\n";
36
+ }
37
+
38
+ // node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
39
+ var StdioServerTransport = class {
40
+ constructor(_stdin = process.stdin, _stdout = process.stdout) {
41
+ this._stdin = _stdin;
42
+ this._stdout = _stdout;
43
+ this._readBuffer = new ReadBuffer();
44
+ this._started = false;
45
+ this._ondata = (chunk) => {
46
+ this._readBuffer.append(chunk);
47
+ this.processReadBuffer();
48
+ };
49
+ this._onerror = (error) => {
50
+ this.onerror?.(error);
51
+ };
52
+ }
53
+ /**
54
+ * Starts listening for messages on stdin.
55
+ */
56
+ async start() {
57
+ if (this._started) {
58
+ throw new Error("StdioServerTransport already started! If using Server class, note that connect() calls start() automatically.");
59
+ }
60
+ this._started = true;
61
+ this._stdin.on("data", this._ondata);
62
+ this._stdin.on("error", this._onerror);
63
+ }
64
+ processReadBuffer() {
65
+ while (true) {
66
+ try {
67
+ const message = this._readBuffer.readMessage();
68
+ if (message === null) {
69
+ break;
70
+ }
71
+ this.onmessage?.(message);
72
+ } catch (error) {
73
+ this.onerror?.(error);
74
+ }
75
+ }
76
+ }
77
+ async close() {
78
+ this._stdin.off("data", this._ondata);
79
+ this._stdin.off("error", this._onerror);
80
+ const remainingDataListeners = this._stdin.listenerCount("data");
81
+ if (remainingDataListeners === 0) {
82
+ this._stdin.pause();
83
+ }
84
+ this._readBuffer.clear();
85
+ this.onclose?.();
86
+ }
87
+ send(message) {
88
+ return new Promise((resolve) => {
89
+ const json = serializeMessage(message);
90
+ if (this._stdout.write(json)) {
91
+ resolve();
92
+ } else {
93
+ this._stdout.once("drain", resolve);
94
+ }
95
+ });
96
+ }
97
+ };
98
+ export {
99
+ StdioServerTransport
100
+ };
101
+ //# sourceMappingURL=stdio-FWYJXSU7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../node_modules/@modelcontextprotocol/sdk/src/server/stdio.ts","../node_modules/@modelcontextprotocol/sdk/src/shared/stdio.ts"],"sourcesContent":[null,null],"mappings":";;;;;;;AAAA,OAAO,aAAa;;;ACKd,IAAO,aAAP,MAAiB;EAGnB,OAAO,OAAa;AAChB,SAAK,UAAU,KAAK,UAAU,OAAO,OAAO,CAAC,KAAK,SAAS,KAAK,CAAC,IAAI;EACzE;EAEA,cAAW;AACP,QAAI,CAAC,KAAK,SAAS;AACf,aAAO;IACX;AAEA,UAAM,QAAQ,KAAK,QAAQ,QAAQ,IAAI;AACvC,QAAI,UAAU,IAAI;AACd,aAAO;IACX;AAEA,UAAM,OAAO,KAAK,QAAQ,SAAS,QAAQ,GAAG,KAAK,EAAE,QAAQ,OAAO,EAAE;AACtE,SAAK,UAAU,KAAK,QAAQ,SAAS,QAAQ,CAAC;AAC9C,WAAO,mBAAmB,IAAI;EAClC;EAEA,QAAK;AACD,SAAK,UAAU;EACnB;;AAGE,SAAU,mBAAmB,MAAY;AAC3C,SAAO,qBAAqB,MAAM,KAAK,MAAM,IAAI,CAAC;AACtD;AAEM,SAAU,iBAAiB,SAAuB;AACpD,SAAO,KAAK,UAAU,OAAO,IAAI;AACrC;;;AD3BM,IAAO,uBAAP,MAA2B;EAI7B,YACY,SAAmB,QAAQ,OAC3B,UAAoB,QAAQ,QAAM;AADlC,SAAA,SAAA;AACA,SAAA,UAAA;AALJ,SAAA,cAA0B,IAAI,WAAU;AACxC,SAAA,WAAW;AAYnB,SAAA,UAAU,CAAC,UAAiB;AACxB,WAAK,YAAY,OAAO,KAAK;AAC7B,WAAK,kBAAiB;IAC1B;AACA,SAAA,WAAW,CAAC,UAAgB;AACxB,WAAK,UAAU,KAAK;IACxB;EAbG;;;;EAkBH,MAAM,QAAK;AACP,QAAI,KAAK,UAAU;AACf,YAAM,IAAI,MACN,+GAA+G;IAEvH;AAEA,SAAK,WAAW;AAChB,SAAK,OAAO,GAAG,QAAQ,KAAK,OAAO;AACnC,SAAK,OAAO,GAAG,SAAS,KAAK,QAAQ;EACzC;EAEQ,oBAAiB;AACrB,WAAO,MAAM;AACT,UAAI;AACA,cAAM,UAAU,KAAK,YAAY,YAAW;AAC5C,YAAI,YAAY,MAAM;AAClB;QACJ;AAEA,aAAK,YAAY,OAAO;MAC5B,SAAS,OAAO;AACZ,aAAK,UAAU,KAAc;MACjC;IACJ;EACJ;EAEA,MAAM,QAAK;AAEP,SAAK,OAAO,IAAI,QAAQ,KAAK,OAAO;AACpC,SAAK,OAAO,IAAI,SAAS,KAAK,QAAQ;AAGtC,UAAM,yBAAyB,KAAK,OAAO,cAAc,MAAM;AAC/D,QAAI,2BAA2B,GAAG;AAG9B,WAAK,OAAO,MAAK;IACrB;AAGA,SAAK,YAAY,MAAK;AACtB,SAAK,UAAS;EAClB;EAEA,KAAK,SAAuB;AACxB,WAAO,IAAI,QAAQ,aAAU;AACzB,YAAM,OAAO,iBAAiB,OAAO;AACrC,UAAI,KAAK,QAAQ,MAAM,IAAI,GAAG;AAC1B,gBAAO;MACX,OAAO;AACH,aAAK,QAAQ,KAAK,SAAS,OAAO;MACtC;IACJ,CAAC;EACL;;","names":[]}
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ BUILTIN_TEMPLATES
4
+ } from "./chunk-CMGEAPA5.js";
5
+ import "./chunk-SEGVTWSK.js";
6
+ export {
7
+ BUILTIN_TEMPLATES
8
+ };
9
+ //# sourceMappingURL=template-JDMAVVX7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,12 @@
1
+ {
2
+ "$schema": "https://modelcontextprotocol.io/schema/config.json",
3
+ "mcpServers": {
4
+ "dndgrid": {
5
+ "command": "node",
6
+ "args": [
7
+ "/absolute/path/to/zerojin-core/mcp/dist/index.js"
8
+ ],
9
+ "env": {}
10
+ }
11
+ }
12
+ }
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Example: Complex Editor Layout
3
+ *
4
+ * Generated using: generate-layout
5
+ * Description: Complex IDE with multiple nested panels
6
+ * Components: Navigation, FileTree, Editor, Preview, Console, Terminal, Properties
7
+ *
8
+ * This demonstrates a complex editor layout with:
9
+ * - Top navigation bar (8%)
10
+ * - Left sidebar (15%): File tree
11
+ * - Center (50%): Editor with preview (60/40 split)
12
+ * - Right sidebar (15%): Properties panel
13
+ * - Bottom panel (12%): Console and terminal (50/50 split)
14
+ */
15
+
16
+ "use client";
17
+
18
+ import { DndGridContainer, DndGridSplit, DndGridItem } from 'zerojin/components';
19
+ import { Navigation } from './components/Navigation';
20
+ import { FileTree } from './components/FileTree';
21
+ import { Editor } from './components/Editor';
22
+ import { Preview } from './components/Preview';
23
+ import { Console } from './components/Console';
24
+ import { Terminal } from './components/Terminal';
25
+ import { Properties } from './components/Properties';
26
+
27
+ export default function ComplexEditorLayout() {
28
+ return (
29
+ <DndGridContainer width={1920} height={1080}>
30
+ {/* Top: Navigation */}
31
+ <DndGridSplit direction="horizontal" ratio={0.08}>
32
+ <DndGridItem>
33
+ <Navigation />
34
+ </DndGridItem>
35
+
36
+ {/* Main content area */}
37
+ <DndGridSplit direction="vertical" ratio={0.15}>
38
+ {/* Left: File tree */}
39
+ <DndGridItem>
40
+ <FileTree />
41
+ </DndGridItem>
42
+
43
+ {/* Center + Right + Bottom */}
44
+ <DndGridSplit direction="vertical" ratio={0.77}>
45
+ {/* Center + Right */}
46
+ <DndGridSplit direction="horizontal" ratio={0.88}>
47
+ {/* Center: Editor + Preview */}
48
+ <DndGridSplit direction="vertical" ratio={0.6}>
49
+ <DndGridItem>
50
+ <Editor />
51
+ </DndGridItem>
52
+ <DndGridItem>
53
+ <Preview />
54
+ </DndGridItem>
55
+ </DndGridSplit>
56
+
57
+ {/* Bottom: Console + Terminal */}
58
+ <DndGridSplit direction="vertical" ratio={0.5}>
59
+ <DndGridItem>
60
+ <Console />
61
+ </DndGridItem>
62
+ <DndGridItem>
63
+ <Terminal />
64
+ </DndGridItem>
65
+ </DndGridSplit>
66
+ </DndGridSplit>
67
+
68
+ {/* Right: Properties */}
69
+ <DndGridItem>
70
+ <Properties />
71
+ </DndGridItem>
72
+ </DndGridSplit>
73
+ </DndGridSplit>
74
+ </DndGridSplit>
75
+ </DndGridContainer>
76
+ );
77
+ }
78
+
79
+ /**
80
+ * Performance Metrics:
81
+ * - Items: 7
82
+ * - Splits: 6
83
+ * - Max Depth: 4
84
+ * - Estimated Performance: Good
85
+ *
86
+ * Complexity Analysis:
87
+ * ⚠️ Approaching recommended depth limit (4 levels)
88
+ * ✅ Item count well within limits (< 20)
89
+ * ⚠️ Complex nesting - consider simplifying if adding more panels
90
+ *
91
+ * Refactoring Opportunities:
92
+ * - Consider extracting bottom panel into separate component
93
+ * - Could use composition for editor+preview section
94
+ * - May benefit from lazy loading for heavy components
95
+ *
96
+ * Best Practices Followed:
97
+ * ✅ "use client" directive
98
+ * ✅ Descriptive component names
99
+ * ✅ Logical grouping of related panels
100
+ * ✅ Ratios within usable ranges
101
+ *
102
+ * Usage Notes:
103
+ * - This is near the upper complexity limit
104
+ * - Adding more panels may impact performance
105
+ * - Consider user feedback on panel sizes
106
+ * - Test drag-and-drop performance with actual data
107
+ */
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Example: Dashboard 2x2 Grid
3
+ *
4
+ * Generated using: apply-template
5
+ * Template: dashboard-2x2
6
+ * Components: UserStats, RevenueChart, ActivityLog, QuickActions
7
+ *
8
+ * This demonstrates a 2x2 dashboard grid layout:
9
+ * - Top-left: User statistics
10
+ * - Top-right: Revenue chart
11
+ * - Bottom-left: Activity log
12
+ * - Bottom-right: Quick actions
13
+ */
14
+
15
+ "use client";
16
+
17
+ import { DndGridContainer, DndGridSplit, DndGridItem } from 'zerojin/components';
18
+ import { UserStats } from './components/UserStats';
19
+ import { RevenueChart } from './components/RevenueChart';
20
+ import { ActivityLog } from './components/ActivityLog';
21
+ import { QuickActions } from './components/QuickActions';
22
+
23
+ export default function Dashboard() {
24
+ return (
25
+ <DndGridContainer width={1400} height={900}>
26
+ <DndGridSplit direction="horizontal" ratio={0.5}>
27
+ <DndGridSplit direction="vertical" ratio={0.5}>
28
+ <DndGridItem>
29
+ <UserStats />
30
+ </DndGridItem>
31
+ <DndGridItem>
32
+ <RevenueChart />
33
+ </DndGridItem>
34
+ </DndGridSplit>
35
+ <DndGridSplit direction="vertical" ratio={0.5}>
36
+ <DndGridItem>
37
+ <ActivityLog />
38
+ </DndGridItem>
39
+ <DndGridItem>
40
+ <QuickActions />
41
+ </DndGridItem>
42
+ </DndGridSplit>
43
+ </DndGridSplit>
44
+ </DndGridContainer>
45
+ );
46
+ }
47
+
48
+ /**
49
+ * Performance Metrics:
50
+ * - Items: 4
51
+ * - Splits: 3
52
+ * - Max Depth: 2
53
+ * - Estimated Performance: Excellent
54
+ *
55
+ * Best Practices:
56
+ * ✅ Equal ratios (0.5) for balanced grid
57
+ * ✅ Symmetrical structure
58
+ * ✅ Low complexity
59
+ * ✅ Easy to rearrange via drag-and-drop
60
+ *
61
+ * Usage Tips:
62
+ * - Perfect for admin dashboards
63
+ * - Can easily expand to 2x3 or 3x3 by adding more splits
64
+ * - Each widget is independently draggable
65
+ */
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Example: IDE Layout
3
+ *
4
+ * Generated using: apply-template
5
+ * Template: ide-layout
6
+ * Components: FileExplorer, CodeEditor, Terminal
7
+ *
8
+ * This demonstrates a typical 3-panel IDE layout:
9
+ * - Left sidebar (20%): File explorer
10
+ * - Right top (56%): Code editor
11
+ * - Right bottom (24%): Terminal
12
+ */
13
+
14
+ "use client";
15
+
16
+ import { DndGridContainer, DndGridSplit, DndGridItem } from 'zerojin/components';
17
+ import { FileExplorer } from './components/FileExplorer';
18
+ import { CodeEditor } from './components/CodeEditor';
19
+ import { Terminal } from './components/Terminal';
20
+
21
+ export default function IDELayout() {
22
+ return (
23
+ <DndGridContainer width={1600} height={900}>
24
+ <DndGridSplit direction="vertical" ratio={0.2}>
25
+ <DndGridItem>
26
+ <FileExplorer />
27
+ </DndGridItem>
28
+ <DndGridSplit direction="horizontal" ratio={0.7}>
29
+ <DndGridItem>
30
+ <CodeEditor />
31
+ </DndGridItem>
32
+ <DndGridItem>
33
+ <Terminal />
34
+ </DndGridItem>
35
+ </DndGridSplit>
36
+ </DndGridSplit>
37
+ </DndGridContainer>
38
+ );
39
+ }
40
+
41
+ /**
42
+ * Performance Metrics:
43
+ * - Items: 3
44
+ * - Splits: 2
45
+ * - Max Depth: 2
46
+ * - Estimated Performance: Excellent
47
+ *
48
+ * Best Practices:
49
+ * ✅ "use client" directive for Next.js App Router
50
+ * ✅ Ratios within recommended range (0.2-0.8)
51
+ * ✅ Low item count (< 20)
52
+ * ✅ Shallow nesting (< 4 levels)
53
+ */
@@ -0,0 +1,37 @@
1
+ import { LayoutBuilder, L } from '../src/utils/layout-builder.js';
2
+ import { CodeGenerator } from '../src/utils/code-generator.js';
3
+ import { LayoutAnalyzer } from '../src/utils/layout-analyzer.js';
4
+
5
+ /**
6
+ * Test the code generator with a simple IDE layout
7
+ */
8
+
9
+ // Build an IDE layout
10
+ const ideLayout = new LayoutBuilder(1200, 800)
11
+ .setRoot(
12
+ L.v(
13
+ 0.2,
14
+ L.item('Sidebar'),
15
+ L.h(0.7, L.item('CodeEditor'), L.item('Terminal'))
16
+ )
17
+ )
18
+ .build();
19
+
20
+ console.log('=== IDE Layout Tree ===');
21
+ console.log(JSON.stringify(ideLayout, null, 2));
22
+
23
+ // Analyze the layout
24
+ const metadata = LayoutAnalyzer.calculateMetadata(ideLayout);
25
+ console.log('\n=== Layout Metadata ===');
26
+ console.log(metadata);
27
+
28
+ // Generate code
29
+ const generator = new CodeGenerator({
30
+ framework: 'nextjs-app',
31
+ width: ideLayout.width,
32
+ height: ideLayout.height,
33
+ });
34
+
35
+ const code = generator.generate(ideLayout);
36
+ console.log('\n=== Generated Code ===');
37
+ console.log(code);
@@ -0,0 +1,121 @@
1
+ import { ASTParser } from '../src/utils/ast-parser.js';
2
+ import { Validator } from '../src/utils/validator.js';
3
+
4
+ /**
5
+ * Test AST parser and validator
6
+ */
7
+
8
+ const sampleCode = `
9
+ "use client";
10
+
11
+ import { DndGridContainer, DndGridSplit, DndGridItem } from 'zerojin/components';
12
+
13
+ export default function Layout() {
14
+ return (
15
+ <DndGridContainer width={1200} height={800}>
16
+ <DndGridSplit direction="vertical" ratio={0.2}>
17
+ <DndGridItem>
18
+ <Sidebar />
19
+ </DndGridItem>
20
+ <DndGridSplit direction="horizontal" ratio={0.7}>
21
+ <DndGridItem>
22
+ <CodeEditor />
23
+ </DndGridItem>
24
+ <DndGridItem>
25
+ <Terminal />
26
+ </DndGridItem>
27
+ </DndGridSplit>
28
+ </DndGridSplit>
29
+ </DndGridContainer>
30
+ );
31
+ }
32
+ `;
33
+
34
+ console.log('=== Testing AST Parser ===\n');
35
+
36
+ // Parse the code
37
+ const parser = new ASTParser();
38
+ const layout = parser.parse(sampleCode);
39
+
40
+ if (layout) {
41
+ console.log('✅ Successfully parsed layout tree:');
42
+ console.log(JSON.stringify(layout, null, 2));
43
+ } else {
44
+ console.log('❌ Failed to parse layout');
45
+ }
46
+
47
+ console.log('\n=== Testing Validator ===\n');
48
+
49
+ // Validate the code
50
+ const validator = new Validator();
51
+ const codeValidation = validator.validateCode(sampleCode, false);
52
+
53
+ console.log('Code Validation:');
54
+ console.log(`Valid: ${codeValidation.valid}`);
55
+ console.log(`Errors: ${codeValidation.errors.length}`);
56
+ console.log(`Warnings: ${codeValidation.warnings.length}`);
57
+
58
+ if (codeValidation.errors.length > 0) {
59
+ console.log('\nErrors:');
60
+ codeValidation.errors.forEach((err, i) => {
61
+ console.log(` ${i + 1}. [${err.type}] ${err.message}`);
62
+ if (err.fix) console.log(` Fix: ${err.fix}`);
63
+ });
64
+ }
65
+
66
+ if (codeValidation.warnings.length > 0) {
67
+ console.log('\nWarnings:');
68
+ codeValidation.warnings.forEach((warn, i) => {
69
+ console.log(` ${i + 1}. ${warn.message}`);
70
+ if (warn.suggestion) console.log(` Suggestion: ${warn.suggestion}`);
71
+ });
72
+ }
73
+
74
+ // Validate the parsed layout tree
75
+ if (layout) {
76
+ console.log('\n=== Validating Layout Tree ===\n');
77
+ const treeValidation = validator.validate(layout, true);
78
+
79
+ console.log(`Valid: ${treeValidation.valid}`);
80
+ console.log(`Errors: ${treeValidation.errors.length}`);
81
+ console.log(`Warnings: ${treeValidation.warnings.length}`);
82
+ console.log(`Suggestions: ${treeValidation.suggestions.length}`);
83
+
84
+ if (treeValidation.warnings.length > 0) {
85
+ console.log('\nWarnings:');
86
+ treeValidation.warnings.forEach((warn, i) => {
87
+ console.log(` ${i + 1}. ${warn.message}`);
88
+ });
89
+ }
90
+
91
+ if (treeValidation.suggestions.length > 0) {
92
+ console.log('\nSuggestions:');
93
+ treeValidation.suggestions.forEach((sugg, i) => {
94
+ console.log(` ${i + 1}. ${sugg}`);
95
+ });
96
+ }
97
+ }
98
+
99
+ // Test with invalid code
100
+ console.log('\n=== Testing Invalid Code ===\n');
101
+
102
+ const invalidCode = `
103
+ <DndGridContainer width={1200} height={800}>
104
+ <DndGridSplit direction="vertical" ratio={1.5}>
105
+ <DndGridItem>
106
+ <ComponentA />
107
+ </DndGridItem>
108
+ </DndGridSplit>
109
+ </DndGridContainer>
110
+ `;
111
+
112
+ const invalidValidation = validator.validateCode(invalidCode, false);
113
+ console.log(`Valid: ${invalidValidation.valid}`);
114
+ console.log(`Errors: ${invalidValidation.errors.length}`);
115
+
116
+ if (invalidValidation.errors.length > 0) {
117
+ console.log('\nErrors found:');
118
+ invalidValidation.errors.forEach((err, i) => {
119
+ console.log(` ${i + 1}. [${err.type}] ${err.message}`);
120
+ });
121
+ }