dodraw-mcp-server 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 (37) hide show
  1. package/README.md +63 -0
  2. package/dist/src/index.js +45 -0
  3. package/dist/src/tools/diagramTools.js +426 -0
  4. package/dist/src/types.js +2 -0
  5. package/dist/src/utils/fileHandler.js +53 -0
  6. package/dist/test/test-auto-placement.js +83 -0
  7. package/dist/test/test-client.js +100 -0
  8. package/dist/test/test-collision.js +84 -0
  9. package/dist/test/test-constraints.js +88 -0
  10. package/dist/test/test-debug.js +41 -0
  11. package/dist/test/test-directional.js +90 -0
  12. package/dist/test/test-layer-support.js +69 -0
  13. package/dist/test/test-refined-spacing.js +58 -0
  14. package/dist/test/verify_types.js +29 -0
  15. package/package.json +24 -0
  16. package/src/index.ts +54 -0
  17. package/src/tools/diagramTools.ts +440 -0
  18. package/src/types.ts +78 -0
  19. package/src/utils/fileHandler.ts +51 -0
  20. package/test/test-auto-placement.ts +88 -0
  21. package/test/test-client.ts +116 -0
  22. package/test/test-collision.ts +93 -0
  23. package/test/test-constraints.ts +95 -0
  24. package/test/test-debug.ts +40 -0
  25. package/test/test-directional.ts +95 -0
  26. package/test/test-layer-support.ts +77 -0
  27. package/test/test-refined-spacing.ts +62 -0
  28. package/test/verify_types.ts +28 -0
  29. package/test_output/test_autoplacement.3duml +0 -0
  30. package/test_output/test_collision.3duml +0 -0
  31. package/test_output/test_constraints.3duml +0 -0
  32. package/test_output/test_debug.3duml +0 -0
  33. package/test_output/test_diagram.3duml +0 -0
  34. package/test_output/test_directional.3duml +0 -0
  35. package/test_output/test_layers.3duml +0 -0
  36. package/test_output/test_refined_spacing.3duml +0 -0
  37. package/tsconfig.json +13 -0
@@ -0,0 +1,116 @@
1
+
2
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
3
+ import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
4
+ import path from "path";
5
+ import fs from "fs";
6
+
7
+ async function main() {
8
+ const serverPath = path.join(process.cwd(), "dist/src/index.js");
9
+
10
+ const transport = new StdioClientTransport({
11
+ command: "node",
12
+ args: [serverPath]
13
+ });
14
+
15
+ const client = new Client(
16
+ {
17
+ name: "test-client",
18
+ version: "1.0.0",
19
+ },
20
+ {
21
+ capabilities: {},
22
+ }
23
+ );
24
+
25
+ console.log("Connecting to server...");
26
+ await client.connect(transport);
27
+
28
+ // List tools
29
+ console.log("Listing tools...");
30
+ const tools = await client.listTools();
31
+ console.log("Tools found:", tools.tools.map(t => t.name).join(", "));
32
+
33
+ // Create diagram
34
+ const testDir = path.join(__dirname, "../../test_output");
35
+ if (!fs.existsSync(testDir)){
36
+ fs.mkdirSync(testDir);
37
+ }
38
+ const filePath = path.join(testDir, "test_diagram.3duml");
39
+
40
+ // Clean up previous run
41
+ if (fs.existsSync(filePath)) {
42
+ fs.unlinkSync(filePath);
43
+ }
44
+
45
+ console.log(`Creating diagram at ${filePath}...`);
46
+ await client.callTool({
47
+ name: "create_new_diagram",
48
+ arguments: { filePath }
49
+ });
50
+ console.log("Created diagram.");
51
+
52
+ // Add node
53
+ console.log("Adding node...");
54
+ const nodeResult = await client.callTool({
55
+ name: "add_node",
56
+ arguments: {
57
+ filePath,
58
+ label: "Test Node 1",
59
+ shape: "rectangle",
60
+ x: 0,
61
+ y: 0,
62
+ backgroundColor: "#ff0000"
63
+ }
64
+ });
65
+ console.log("Added node result:", nodeResult);
66
+
67
+ // Add another node
68
+ await client.callTool({
69
+ name: "add_node",
70
+ arguments: {
71
+ filePath,
72
+ label: "Test Node 2",
73
+ shape: "rounded",
74
+ x: 5,
75
+ y: 0
76
+ }
77
+ });
78
+
79
+ // Read structure to find IDs
80
+ const structure: any = await client.callTool({
81
+ name: "read_diagram_structure",
82
+ arguments: { filePath }
83
+ });
84
+
85
+ const content = JSON.parse(structure.content[0].text);
86
+ const id1 = content.nodes[0].id;
87
+ const id2 = content.nodes[1].id;
88
+
89
+ console.log(`Nodes created: ${id1}, ${id2}`);
90
+
91
+ // Add edge
92
+ console.log("Adding edge...");
93
+ await client.callTool({
94
+ name: "add_edge",
95
+ arguments: {
96
+ filePath,
97
+ sourceId: id1,
98
+ targetId: id2,
99
+ sourcePointIndex: 1, // Right
100
+ targetPointIndex: 3, // Left
101
+ label: "Connects to"
102
+ }
103
+ });
104
+ console.log("Added edge.");
105
+
106
+ // Final read
107
+ const finalStructure = await client.callTool({
108
+ name: "read_diagram_structure",
109
+ arguments: { filePath }
110
+ });
111
+ console.log("Final Structure:", (finalStructure as any).content[0].text);
112
+
113
+ await client.close();
114
+ }
115
+
116
+ main().catch(console.error);
@@ -0,0 +1,93 @@
1
+
2
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
3
+ import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
4
+ import path from "path";
5
+ import process from "process";
6
+
7
+ async function main() {
8
+ console.log("Connecting...");
9
+ const transport = new StdioClientTransport({
10
+ command: "node",
11
+ args: [path.join(process.cwd(), "dist", "src", "index.js")],
12
+ });
13
+ const client = new Client({ name: "test-collision", version: "1.0" }, { capabilities: {} });
14
+ await client.connect(transport);
15
+
16
+ try {
17
+ const filePath = path.join(process.cwd(), "test_output", "test_collision.3duml");
18
+ await client.callTool({ name: "create_new_diagram", arguments: { filePath } });
19
+
20
+ // 1. Add Root Node
21
+ console.log("Adding Root Node...");
22
+ const rootNode = await client.callTool({
23
+ name: "add_node",
24
+ arguments: { filePath, label: "Root", x: 0, y: 0, width: 2, height: 1.5 }
25
+ }) as any;
26
+ const rootId: string = rootNode.content[0].text.match(/Added node ([a-zA-Z0-9-]+)/)[1];
27
+
28
+ // 2. Add Node A to RIGHT
29
+ console.log("Adding Node A (RIGHT)...");
30
+ await client.callTool({
31
+ name: "add_directional_node",
32
+ arguments: { filePath, sourceNodeId: rootId, direction: "RIGHT", label: "Node A" }
33
+ });
34
+
35
+ // 3. Add Node B to RIGHT (Collision with A?)
36
+ console.log("Adding Node B (RIGHT) - Should Collide with A...");
37
+ await client.callTool({
38
+ name: "add_directional_node",
39
+ arguments: { filePath, sourceNodeId: rootId, direction: "RIGHT", label: "Node B" }
40
+ });
41
+
42
+ // Verify state
43
+ const result = await client.callTool({ name: "read_diagram_structure", arguments: { filePath } }) as any;
44
+ const state = JSON.parse(result.content[0].text);
45
+
46
+ const nodeA = state.nodes.find((n: any) => n.label === "Node A");
47
+ const nodeB = state.nodes.find((n: any) => n.label === "Node B");
48
+ const root = state.nodes.find((n: any) => n.label === "Root");
49
+
50
+ console.log(`Root: (${root.x}, ${root.z})`);
51
+ console.log(`Node A: (${nodeA.x}, ${nodeA.z})`);
52
+ console.log(`Node B: (${nodeB.x}, ${nodeB.z})`);
53
+
54
+ // Check Spacing Logic
55
+ // Spacing = 2. Width = 2.
56
+ // Node A should be at: Root.x + (2 + 2) = 4?
57
+ // Let's check formula: newX = source.x + (dirX * (srcW + INITIAL_SPACING))
58
+ // srcW = 2. Spacing = 2.
59
+ // newX = 0 + 1 * (2 + 2) = 4.
60
+
61
+ if (Math.abs(nodeA.x - 4) > 0.1) {
62
+ throw new Error(`Node A X position incorrect. Expected 4, got ${nodeA.x}`);
63
+ }
64
+ if (Math.abs(nodeA.z - 0) > 0.1) {
65
+ throw new Error(`Node A Z position incorrect. Expected 0, got ${nodeA.z}`);
66
+ }
67
+
68
+ // Check Collision Logic
69
+ // Node B initially tries to go to (4, 0). Collides with A.
70
+ // Shift Rule: Horizontal move -> Shift Z (Down).
71
+ // Shift Z step: srcH + COLLISION_SPACING = 1.5 + 0.5 = 2.0.
72
+ // New Z should be 0 + 2 = 2. (Or z + step)
73
+ // Wait, loop says: newZ += shiftStepZ.
74
+ // So Node B should be at (4, 2).
75
+
76
+ if (Math.abs(nodeB.x - 4) > 0.1) {
77
+ throw new Error(`Node B X position incorrect. Expected 4, got ${nodeB.x}`);
78
+ }
79
+ if (Math.abs(nodeB.z - 2) > 0.1) {
80
+ throw new Error(`Node B Z position incorrect. Expected 2, got ${nodeB.z}`);
81
+ }
82
+
83
+ console.log("SUCCESS: Collision avoidance verified.");
84
+
85
+ } catch (e: any) {
86
+ console.error("FAIL:", e);
87
+ process.exit(1);
88
+ } finally {
89
+ await client.close();
90
+ }
91
+ }
92
+
93
+ main();
@@ -0,0 +1,95 @@
1
+
2
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
3
+ import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
4
+ import path from "path";
5
+ import process from "process";
6
+
7
+ async function main() {
8
+ console.log("Connecting...");
9
+ const transport = new StdioClientTransport({
10
+ command: "node",
11
+ args: [path.join(process.cwd(), "dist", "src", "index.js")],
12
+ });
13
+ const client = new Client({ name: "test-constraints", version: "1.0" }, { capabilities: {} });
14
+ await client.connect(transport);
15
+
16
+ try {
17
+ const filePath = path.join(process.cwd(), "test_output", "test_constraints.3duml");
18
+ await client.callTool({ name: "create_new_diagram", arguments: { filePath } });
19
+
20
+ // 1. Test Layer Auto-Stacking
21
+ console.log("Adding Layer 2 (auto)...");
22
+ const l2 = await client.callTool({
23
+ name: "add_layer",
24
+ arguments: { filePath, name: "Layer 2" }
25
+ }) as any;
26
+ console.log("L2 Output:", l2.content[0].text);
27
+
28
+ console.log("Adding Layer 3 (auto)...");
29
+ const l3 = await client.callTool({
30
+ name: "add_layer",
31
+ arguments: { filePath, name: "Layer 3" }
32
+ }) as any;
33
+ console.log("L3 Output:", l3.content[0].text);
34
+
35
+ // 2. Test Node Constraints (Max Width)
36
+ console.log("Adding Giant Node...");
37
+ await client.callTool({
38
+ name: "add_node",
39
+ arguments: { filePath, label: "Giant Node", width: 1000, height: 1000 }
40
+ });
41
+
42
+ // 3. Test Edge Constraints (Max Thickness)
43
+ console.log("Add Tiny Edge...");
44
+ // Add nodes to connect
45
+ await client.callTool({ name: "add_node", arguments: { filePath, label: "N1" } });
46
+ await client.callTool({ name: "add_node", arguments: { filePath, label: "N2" } });
47
+
48
+ await client.callTool({
49
+ name: "add_edge",
50
+ arguments: {
51
+ filePath,
52
+ sourceId: (await getNodes(client, filePath))[1].id,
53
+ targetId: (await getNodes(client, filePath))[2].id,
54
+ sourcePointIndex: 0, targetPointIndex: 0,
55
+ thickness: 10 // Huge thickness
56
+ }
57
+ });
58
+
59
+ // Verify
60
+ const state = await getState(client, filePath);
61
+
62
+ // Check Layers
63
+ const layer2 = state.layers.find((l: any) => l.name === "Layer 2");
64
+ const layer3 = state.layers.find((l: any) => l.name === "Layer 3");
65
+
66
+ if (layer2.position.y !== 50) throw new Error(`Layer 2 should be at Y=50, got ${layer2.position.y}`);
67
+ if (layer3.position.y !== 100) throw new Error(`Layer 3 should be at Y=100, got ${layer3.position.y}`);
68
+
69
+ // Check Node Size
70
+ const giantNode = state.nodes.find((n: any) => n.label === "Giant Node");
71
+ if (giantNode.width > 50) throw new Error(`Giant Node width should be capped at 50, got ${giantNode.width}`);
72
+
73
+ // Check Edge Thickness
74
+ const edge = state.edges[0];
75
+ if (edge && edge.thickness > 0.5) throw new Error(`Edge thickness should be capped at 0.5, got ${edge.thickness}`);
76
+
77
+ console.log("SUCCESS: All constraints and auto-positioning verified.");
78
+
79
+ } catch (e: any) {
80
+ console.error("FAIL:", e);
81
+ } finally {
82
+ await client.close();
83
+ }
84
+ }
85
+
86
+ async function getState(client: any, filePath: string) {
87
+ const result = await client.callTool({ name: "read_diagram_structure", arguments: { filePath } }) as any;
88
+ return JSON.parse(result.content[0].text);
89
+ }
90
+
91
+ async function getNodes(client: any, filePath: string) {
92
+ return (await getState(client, filePath)).nodes;
93
+ }
94
+
95
+ main();
@@ -0,0 +1,40 @@
1
+
2
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
3
+ import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
4
+ import path from "path";
5
+ import process from "process";
6
+
7
+ async function main() {
8
+ console.log("Connecting...");
9
+ const transport = new StdioClientTransport({
10
+ command: "node",
11
+ args: [path.join(process.cwd(), "dist", "src", "index.js")],
12
+ });
13
+ const client = new Client({ name: "debug", version: "1.0" }, { capabilities: {} });
14
+ await client.connect(transport);
15
+
16
+ try {
17
+ const filePath = path.join(process.cwd(), "test_output", "test_debug.3duml");
18
+ await client.callTool({ name: "create_new_diagram", arguments: { filePath } });
19
+
20
+ console.log("Adding Node C...");
21
+ await client.callTool({
22
+ name: "add_node",
23
+ arguments: { filePath, label: "Node C", x: 10, y: 10 }
24
+ });
25
+ console.log("Node C added.");
26
+
27
+ console.log("Adding Node D...");
28
+ await client.callTool({
29
+ name: "add_node",
30
+ arguments: { filePath, label: "Node D" }
31
+ });
32
+ console.log("Node D added.");
33
+
34
+ } catch (e: any) {
35
+ console.error("FAIL:", e);
36
+ } finally {
37
+ await client.close();
38
+ }
39
+ }
40
+ main();
@@ -0,0 +1,95 @@
1
+
2
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
3
+ import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
4
+ import path from "path";
5
+ import process from "process";
6
+
7
+ async function main() {
8
+ console.log("Connecting...");
9
+ const transport = new StdioClientTransport({
10
+ command: "node",
11
+ args: [path.join(process.cwd(), "dist", "src", "index.js")],
12
+ });
13
+ const client = new Client({ name: "test-directional", version: "1.0" }, { capabilities: {} });
14
+ await client.connect(transport);
15
+
16
+ try {
17
+ const filePath = path.join(process.cwd(), "test_output", "test_directional.3duml");
18
+ await client.callTool({ name: "create_new_diagram", arguments: { filePath } });
19
+
20
+ // 1. Add Root Node
21
+ console.log("Adding Root Node...");
22
+ const rootNode = await client.callTool({
23
+ name: "add_node",
24
+ arguments: { filePath, label: "Root", x: 0, y: 0 } // Central point
25
+ }) as any;
26
+ const rootId: string = rootNode.content[0].text.match(/Added node ([a-zA-Z0-9-]+)/)[1];
27
+ console.log(`Root ID: ${rootId}`);
28
+
29
+ // 2. Add RIGHT Node
30
+ console.log("Adding RIGHT Node...");
31
+ await client.callTool({
32
+ name: "add_directional_node",
33
+ arguments: { filePath, sourceNodeId: rootId, direction: "RIGHT", label: "Right Node" }
34
+ });
35
+
36
+ // 3. Add LEFT Node
37
+ console.log("Adding LEFT Node...");
38
+ await client.callTool({
39
+ name: "add_directional_node",
40
+ arguments: { filePath, sourceNodeId: rootId, direction: "LEFT", label: "Left Node" }
41
+ });
42
+
43
+ // 4. Add DOWN Node
44
+ console.log("Adding DOWN Node...");
45
+ await client.callTool({
46
+ name: "add_directional_node",
47
+ arguments: { filePath, sourceNodeId: rootId, direction: "DOWN", label: "Down Node" }
48
+ });
49
+
50
+ // 5. Add UP Node
51
+ console.log("Adding UP Node...");
52
+ await client.callTool({
53
+ name: "add_directional_node",
54
+ arguments: { filePath, sourceNodeId: rootId, direction: "UP", label: "Up Node" }
55
+ });
56
+
57
+ // Verify state
58
+ const result = await client.callTool({ name: "read_diagram_structure", arguments: { filePath } }) as any;
59
+ const state = JSON.parse(result.content[0].text);
60
+
61
+ console.log("Verifying nodes and edges...");
62
+
63
+ const rightNode = state.nodes.find((n: any) => n.label === "Right Node");
64
+ const leftNode = state.nodes.find((n: any) => n.label === "Left Node");
65
+ const downNode = state.nodes.find((n: any) => n.label === "Down Node");
66
+ const upNode = state.nodes.find((n: any) => n.label === "Up Node");
67
+
68
+ // Verify Positions
69
+ // Expected: Right(5, 0), Left(-5, 0), Down(0, 4), Up(0, -4)
70
+ console.log(`Right: (${rightNode.x}, ${rightNode.z})`); // z is diagram Y
71
+ console.log(`Left: (${leftNode.x}, ${leftNode.z})`);
72
+ console.log(`Down: (${downNode.x}, ${downNode.z})`);
73
+ console.log(`Up: (${upNode.x}, ${upNode.z})`);
74
+
75
+ if (rightNode.x !== 5) throw new Error("Right node X incorrect");
76
+ if (leftNode.x !== -5) throw new Error("Left node X incorrect");
77
+ if (downNode.z !== 4) throw new Error("Down node Z incorrect");
78
+ if (upNode.z !== -4) throw new Error("Up node Z incorrect");
79
+
80
+ // Verify Connections
81
+ // Start counting edges connected to Root
82
+ const edges = state.edges.filter((e: any) => e.sourceId === rootId || e.targetId === rootId);
83
+ console.log(`Edges connected to Root: ${edges.length}`);
84
+ if (edges.length !== 4) throw new Error("Should be 4 edges connecting to Root");
85
+
86
+ console.log("SUCCESS: Directional node creation verified.");
87
+
88
+ } catch (e: any) {
89
+ console.error("FAIL:", e);
90
+ } finally {
91
+ await client.close();
92
+ }
93
+ }
94
+
95
+ main();
@@ -0,0 +1,77 @@
1
+
2
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
3
+ import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
4
+ import path from "path";
5
+ import process from "process";
6
+
7
+ async function main() {
8
+ console.log("Connecting to server...");
9
+ const transport = new StdioClientTransport({
10
+ command: "node",
11
+ args: [path.join(process.cwd(), "dist", "src", "index.js")],
12
+ });
13
+
14
+ const client = new Client(
15
+ { name: "dodraw-test-client", version: "1.0.0" },
16
+ { capabilities: {} }
17
+ );
18
+
19
+ await client.connect(transport);
20
+ console.log("Connected.");
21
+
22
+ try {
23
+ const filePath = path.join(process.cwd(), "test_output", "test_layers.3duml");
24
+
25
+ // 1. Create Diagram
26
+ await client.callTool({ name: "create_new_diagram", arguments: { filePath } });
27
+ console.log("Created diagram.");
28
+
29
+ // 2. Add Layer
30
+ const layerResult = await client.callTool({
31
+ name: "add_layer",
32
+ arguments: {
33
+ filePath,
34
+ name: "Upper Layer",
35
+ position: { x: 0, y: 50, z: 0 }
36
+ }
37
+ }) as any;
38
+ console.log(layerResult.content[0].text);
39
+
40
+ // Extract Layer ID (hacky parsing for test)
41
+ const outputText = layerResult.content[0].text;
42
+ const layerId = outputText.match(/ID ([0-9a-f-]+)/)[1];
43
+ console.log(`Extracted Layer ID: ${layerId}`);
44
+
45
+ // 3. Add Node to new Layer
46
+ await client.callTool({
47
+ name: "add_node",
48
+ arguments: {
49
+ filePath,
50
+ label: "Node on Upper Layer",
51
+ x: 0,
52
+ y: 0,
53
+ layerId: layerId
54
+ }
55
+ });
56
+ console.log("Added node to upper layer.");
57
+
58
+ // 4. Read Structure
59
+ const structureResult = await client.callTool({
60
+ name: "read_diagram_structure",
61
+ arguments: { filePath }
62
+ }) as any;
63
+
64
+ const structure = JSON.parse(structureResult.content[0].text);
65
+ console.log("Structure:", JSON.stringify(structure, null, 2));
66
+
67
+ if (structure.layerCount !== 2) throw new Error("Expected 2 layers (default + new)");
68
+ if (structure.nodes[0].layerId !== layerId) throw new Error("Node layer ID mismatch");
69
+
70
+ } catch (error) {
71
+ console.error("Test failed:", error);
72
+ } finally {
73
+ await client.close();
74
+ }
75
+ }
76
+
77
+ main();
@@ -0,0 +1,62 @@
1
+
2
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
3
+ import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
4
+ import path from "path";
5
+ import process from "process";
6
+
7
+ async function main() {
8
+ console.log("Connecting...");
9
+ const transport = new StdioClientTransport({
10
+ command: "node",
11
+ args: [path.join(process.cwd(), "dist", "src", "index.js")],
12
+ });
13
+ const client = new Client({ name: "test-refined", version: "1.0" }, { capabilities: {} });
14
+ await client.connect(transport);
15
+
16
+ try {
17
+ const filePath = path.join(process.cwd(), "test_output", "test_refined_spacing.3duml");
18
+ await client.callTool({ name: "create_new_diagram", arguments: { filePath } });
19
+
20
+ // Default Layer 1 is at Y=0
21
+
22
+ // 1. Add Layer 2 (auto) -> Should be -2
23
+ console.log("Adding Layer 2...");
24
+ const l2 = await client.callTool({
25
+ name: "add_layer",
26
+ arguments: { filePath, name: "Layer 2" }
27
+ }) as any;
28
+ console.log("L2 Output:", l2.content[0].text);
29
+
30
+ // 2. Add Layer 3 (auto) -> Should be -4
31
+ console.log("Adding Layer 3...");
32
+ const l3 = await client.callTool({
33
+ name: "add_layer",
34
+ arguments: { filePath, name: "Layer 3" }
35
+ }) as any;
36
+ console.log("L3 Output:", l3.content[0].text);
37
+
38
+ // Verify state
39
+ const result = await client.callTool({ name: "read_diagram_structure", arguments: { filePath } }) as any;
40
+ const state = JSON.parse(result.content[0].text);
41
+
42
+ const layer1 = state.layers[0];
43
+ const layer2 = state.layers.find((l: any) => l.name === "Layer 2");
44
+ const layer3 = state.layers.find((l: any) => l.name === "Layer 3");
45
+
46
+ console.log(`Layer 1 Y: ${layer1.position.y}`);
47
+ console.log(`Layer 2 Y: ${layer2.position.y}`);
48
+ console.log(`Layer 3 Y: ${layer3.position.y}`);
49
+
50
+ if (layer2.position.y !== -2) throw new Error(`Layer 2 should be at Y=-2, got ${layer2.position.y}`);
51
+ if (layer3.position.y !== -4) throw new Error(`Layer 3 should be at Y=-4, got ${layer3.position.y}`);
52
+
53
+ console.log("SUCCESS: Refined spacing verified.");
54
+
55
+ } catch (e: any) {
56
+ console.error("FAIL:", e);
57
+ } finally {
58
+ await client.close();
59
+ }
60
+ }
61
+
62
+ main();
@@ -0,0 +1,28 @@
1
+
2
+ import fs from 'fs/promises';
3
+ import JSZip from 'jszip';
4
+
5
+ async function checkFile(filePath: string, label: string) {
6
+ try {
7
+ console.log(`Checking ${label}: ${filePath}`);
8
+ const content = await fs.readFile(filePath);
9
+ const zip = await JSZip.loadAsync(content);
10
+ const jsonStr = await zip.file("diagram.json")?.async("string");
11
+ if (!jsonStr) throw new Error("No diagram.json");
12
+ const json = JSON.parse(jsonStr);
13
+
14
+ console.log(`Layer Count: ${json.layers.length}`);
15
+ json.layers.forEach((l: any) => {
16
+ console.log(`Layer '${l.name}': Y=${l.transform.position.y}`);
17
+ });
18
+
19
+ } catch (e: any) {
20
+ console.log(`Error checking ${label}: ${e.message}`);
21
+ }
22
+ }
23
+
24
+ async function main() {
25
+ await checkFile("q:/source/Antigravity/Learn/3DUML/mcp_layer_refined_test.3duml", "Refined Layer Auto-Pos Check");
26
+ }
27
+
28
+ main();
Binary file
Binary file
Binary file
Binary file
package/tsconfig.json ADDED
@@ -0,0 +1,13 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "commonjs",
5
+ "outDir": "./dist",
6
+ "rootDir": ".",
7
+ "strict": true,
8
+ "esModuleInterop": true,
9
+ "skipLibCheck": true,
10
+ "forceConsistentCasingInFileNames": true
11
+ },
12
+ "include": ["src/**/*", "test/**/*"]
13
+ }