@coral-viz/mcp-server 0.2.3
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 +4 -0
- package/README.md +17 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +87 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/convert.d.ts +59 -0
- package/dist/tools/convert.d.ts.map +1 -0
- package/dist/tools/convert.js +152 -0
- package/dist/tools/convert.js.map +1 -0
- package/dist/tools/explain.d.ts +36 -0
- package/dist/tools/explain.d.ts.map +1 -0
- package/dist/tools/explain.js +393 -0
- package/dist/tools/explain.js.map +1 -0
- package/dist/tools/generate.d.ts +38 -0
- package/dist/tools/generate.d.ts.map +1 -0
- package/dist/tools/generate.js +242 -0
- package/dist/tools/generate.js.map +1 -0
- package/dist/tools/layout.d.ts +97 -0
- package/dist/tools/layout.d.ts.map +1 -0
- package/dist/tools/layout.js +142 -0
- package/dist/tools/layout.js.map +1 -0
- package/dist/tools/render.d.ts +58 -0
- package/dist/tools/render.d.ts.map +1 -0
- package/dist/tools/render.js +150 -0
- package/dist/tools/render.js.map +1 -0
- package/dist/tools/validate.d.ts +27 -0
- package/dist/tools/validate.d.ts.map +1 -0
- package/dist/tools/validate.js +55 -0
- package/dist/tools/validate.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* coral_generate tool
|
|
3
|
+
*
|
|
4
|
+
* Generate Coral DSL or Graph-IR from natural language descriptions.
|
|
5
|
+
*/
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
export const generateTool = {
|
|
8
|
+
name: "coral_generate",
|
|
9
|
+
description: "Heuristically extract a basic Coral diagram from a natural-language description. Review the result before use.",
|
|
10
|
+
inputSchema: {
|
|
11
|
+
type: "object",
|
|
12
|
+
properties: {
|
|
13
|
+
description: {
|
|
14
|
+
type: "string",
|
|
15
|
+
description: "Natural language description of the system architecture to diagram",
|
|
16
|
+
},
|
|
17
|
+
format: {
|
|
18
|
+
type: "string",
|
|
19
|
+
enum: ["dsl", "json"],
|
|
20
|
+
description: "Output format: 'dsl' for Coral DSL (default), 'json' for Graph-IR JSON",
|
|
21
|
+
default: "dsl",
|
|
22
|
+
},
|
|
23
|
+
style: {
|
|
24
|
+
type: "string",
|
|
25
|
+
enum: ["minimal", "detailed"],
|
|
26
|
+
description: "Output style: 'minimal' for basic diagram, 'detailed' for descriptions and metadata",
|
|
27
|
+
default: "minimal",
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
required: ["description"],
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
const GenerateArgsSchema = z.object({
|
|
34
|
+
description: z.string(),
|
|
35
|
+
format: z.enum(["dsl", "json"]).default("dsl"),
|
|
36
|
+
style: z.enum(["minimal", "detailed"]).default("minimal"),
|
|
37
|
+
});
|
|
38
|
+
/**
|
|
39
|
+
* Parse natural language to extract diagram components.
|
|
40
|
+
* This intentionally uses deterministic keyword heuristics; it does not claim
|
|
41
|
+
* semantic natural-language understanding.
|
|
42
|
+
*/
|
|
43
|
+
function parseDescription(description) {
|
|
44
|
+
const nodes = [];
|
|
45
|
+
const edges = [];
|
|
46
|
+
const nodeMap = new Map();
|
|
47
|
+
// Keywords that indicate node types
|
|
48
|
+
const typeKeywords = {
|
|
49
|
+
service: ["service", "microservice", "api", "server", "backend", "frontend", "app", "application"],
|
|
50
|
+
database: ["database", "db", "postgres", "mysql", "mongo", "store", "storage"],
|
|
51
|
+
external_api: ["external", "third-party", "stripe", "aws", "cloud"],
|
|
52
|
+
actor: ["user", "client", "customer", "admin"],
|
|
53
|
+
group: ["group", "cluster", "tier", "layer"],
|
|
54
|
+
};
|
|
55
|
+
// Relationship keywords
|
|
56
|
+
const relationKeywords = {
|
|
57
|
+
http_request: ["calls", "requests", "sends to", "connects to"],
|
|
58
|
+
data_flow: ["stores", "reads", "writes", "queries", "persists"],
|
|
59
|
+
dependency: ["depends on", "uses", "requires"],
|
|
60
|
+
event: ["publishes", "emits", "triggers", "subscribes"],
|
|
61
|
+
};
|
|
62
|
+
// Convert label to snake_case ID
|
|
63
|
+
function toId(label) {
|
|
64
|
+
return label
|
|
65
|
+
.toLowerCase()
|
|
66
|
+
.replace(/[^a-z0-9\s]/g, "")
|
|
67
|
+
.replace(/\s+/g, "_")
|
|
68
|
+
.substring(0, 50);
|
|
69
|
+
}
|
|
70
|
+
// Infer node type from label
|
|
71
|
+
function inferType(label) {
|
|
72
|
+
const lowerLabel = label.toLowerCase();
|
|
73
|
+
for (const [type, keywords] of Object.entries(typeKeywords)) {
|
|
74
|
+
if (keywords.some((kw) => lowerLabel.includes(kw))) {
|
|
75
|
+
return type;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return "service"; // Default
|
|
79
|
+
}
|
|
80
|
+
// Simple extraction: split by common connectors and look for nouns
|
|
81
|
+
const words = description.toLowerCase();
|
|
82
|
+
// Extract potential components (simple heuristic)
|
|
83
|
+
const componentPattern = /(?:a|an|the|with)?\s*(\w+(?:\s+\w+)?)\s*(?:service|database|api|server|app|client|cache|queue)?/gi;
|
|
84
|
+
const matches = [...description.matchAll(componentPattern)];
|
|
85
|
+
// Look for common architecture patterns
|
|
86
|
+
const patterns = [
|
|
87
|
+
{ pattern: /(\w+)\s*->\s*(\w+)/gi, relation: "dependency" },
|
|
88
|
+
{ pattern: /(\w+)\s+(?:connects?|calls?|sends?)\s+(?:to\s+)?(\w+)/gi, relation: "http_request" },
|
|
89
|
+
{ pattern: /(\w+)\s+(?:stores?|writes?|reads?|queries?)\s+(?:from\s+|to\s+)?(\w+)/gi, relation: "data_flow" },
|
|
90
|
+
];
|
|
91
|
+
// Extract from "with" clauses: "system with A, B, and C"
|
|
92
|
+
const withMatch = description.match(/with\s+(.+?)(?:\.|$)/i);
|
|
93
|
+
if (withMatch) {
|
|
94
|
+
const components = withMatch[1].split(/,\s*|\s+and\s+/);
|
|
95
|
+
for (const comp of components) {
|
|
96
|
+
const trimmed = comp.trim();
|
|
97
|
+
if (trimmed && trimmed.length > 1) {
|
|
98
|
+
const id = toId(trimmed);
|
|
99
|
+
if (!nodeMap.has(id)) {
|
|
100
|
+
nodeMap.set(id, trimmed);
|
|
101
|
+
nodes.push({
|
|
102
|
+
id,
|
|
103
|
+
type: inferType(trimmed),
|
|
104
|
+
label: trimmed.charAt(0).toUpperCase() + trimmed.slice(1),
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// If we haven't extracted anything, create a basic structure
|
|
111
|
+
if (nodes.length === 0) {
|
|
112
|
+
// Look for specific components mentioned
|
|
113
|
+
const mentioned = description.match(/\b(api|database|web|app|server|service|client|cache|frontend|backend)\b/gi);
|
|
114
|
+
if (mentioned) {
|
|
115
|
+
const unique = [...new Set(mentioned.map((m) => m.toLowerCase()))];
|
|
116
|
+
for (const comp of unique) {
|
|
117
|
+
const id = toId(comp);
|
|
118
|
+
if (!nodeMap.has(id)) {
|
|
119
|
+
nodeMap.set(id, comp);
|
|
120
|
+
nodes.push({
|
|
121
|
+
id,
|
|
122
|
+
type: inferType(comp),
|
|
123
|
+
label: comp.charAt(0).toUpperCase() + comp.slice(1),
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
// Create edges based on typical flow patterns
|
|
130
|
+
if (nodes.length >= 2) {
|
|
131
|
+
// Simple heuristic: services connect to databases, frontends connect to backends
|
|
132
|
+
const services = nodes.filter((n) => n.type === "service");
|
|
133
|
+
const databases = nodes.filter((n) => n.type === "database");
|
|
134
|
+
for (const service of services) {
|
|
135
|
+
for (const db of databases) {
|
|
136
|
+
edges.push({
|
|
137
|
+
source: service.id,
|
|
138
|
+
target: db.id,
|
|
139
|
+
relation: "data_flow",
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
// Connect services in a chain if no other pattern detected
|
|
144
|
+
if (edges.length === 0 && services.length >= 2) {
|
|
145
|
+
for (let i = 0; i < services.length - 1; i++) {
|
|
146
|
+
edges.push({
|
|
147
|
+
source: services[i].id,
|
|
148
|
+
target: services[i + 1].id,
|
|
149
|
+
relation: "http_request",
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return { nodes, edges };
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Generate Coral DSL from diagram data
|
|
158
|
+
*/
|
|
159
|
+
function toDsl(data, detailed) {
|
|
160
|
+
const lines = [];
|
|
161
|
+
lines.push("// Generated by coral_generate");
|
|
162
|
+
lines.push("");
|
|
163
|
+
// Group nodes by type for organization
|
|
164
|
+
const byType = new Map();
|
|
165
|
+
for (const node of data.nodes) {
|
|
166
|
+
const existing = byType.get(node.type) || [];
|
|
167
|
+
existing.push(node);
|
|
168
|
+
byType.set(node.type, existing);
|
|
169
|
+
}
|
|
170
|
+
// Output nodes grouped by type
|
|
171
|
+
for (const [type, nodes] of byType) {
|
|
172
|
+
for (const node of nodes) {
|
|
173
|
+
if (detailed && node.description) {
|
|
174
|
+
lines.push(`${type} "${node.label}" {`);
|
|
175
|
+
lines.push(` description: "${node.description}"`);
|
|
176
|
+
lines.push("}");
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
lines.push(`${type} "${node.label}"`);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
lines.push("");
|
|
183
|
+
}
|
|
184
|
+
// Output edges
|
|
185
|
+
for (const edge of data.edges) {
|
|
186
|
+
if (edge.relation && edge.relation !== "dependency") {
|
|
187
|
+
lines.push(`${edge.source} -> ${edge.target} [${edge.relation}]`);
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
lines.push(`${edge.source} -> ${edge.target}`);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return lines.join("\n");
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Generate Graph-IR JSON from diagram data
|
|
197
|
+
*/
|
|
198
|
+
function toJson(data) {
|
|
199
|
+
const ir = {
|
|
200
|
+
version: "1.0.0",
|
|
201
|
+
id: "generated-graph",
|
|
202
|
+
nodes: data.nodes.map((n) => ({
|
|
203
|
+
id: n.id,
|
|
204
|
+
type: n.type,
|
|
205
|
+
label: n.label,
|
|
206
|
+
...(n.description && { metadata: { description: n.description } }),
|
|
207
|
+
})),
|
|
208
|
+
edges: data.edges.map((e, i) => ({
|
|
209
|
+
id: `edge_${i}`,
|
|
210
|
+
source: e.source,
|
|
211
|
+
target: e.target,
|
|
212
|
+
...(e.relation && { relation: e.relation }),
|
|
213
|
+
...(e.label && { label: e.label }),
|
|
214
|
+
})),
|
|
215
|
+
};
|
|
216
|
+
return JSON.stringify(ir, null, 2);
|
|
217
|
+
}
|
|
218
|
+
export async function handleGenerate(args) {
|
|
219
|
+
const parsed = GenerateArgsSchema.parse(args);
|
|
220
|
+
const { description, format, style } = parsed;
|
|
221
|
+
// Parse the description to extract diagram components
|
|
222
|
+
const diagramData = parseDescription(description);
|
|
223
|
+
// Generate output in requested format
|
|
224
|
+
let output;
|
|
225
|
+
if (format === "json") {
|
|
226
|
+
output = toJson(diagramData);
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
output = toDsl(diagramData, style === "detailed");
|
|
230
|
+
}
|
|
231
|
+
// Add summary
|
|
232
|
+
const summary = `Generated diagram with ${diagramData.nodes.length} nodes and ${diagramData.edges.length} edges.`;
|
|
233
|
+
return {
|
|
234
|
+
content: [
|
|
235
|
+
{
|
|
236
|
+
type: "text",
|
|
237
|
+
text: `${summary}\n\n${output}`,
|
|
238
|
+
},
|
|
239
|
+
],
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
//# sourceMappingURL=generate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../src/tools/generate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { type GraphIR } from '@coral-viz/language';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
export declare const layoutTool: {
|
|
4
|
+
name: string;
|
|
5
|
+
description: string;
|
|
6
|
+
inputSchema: {
|
|
7
|
+
type: "object";
|
|
8
|
+
properties: {
|
|
9
|
+
content: {
|
|
10
|
+
type: string;
|
|
11
|
+
description: string;
|
|
12
|
+
};
|
|
13
|
+
options: {
|
|
14
|
+
type: string;
|
|
15
|
+
properties: {
|
|
16
|
+
direction: {
|
|
17
|
+
type: string;
|
|
18
|
+
enum: string[];
|
|
19
|
+
default: string;
|
|
20
|
+
};
|
|
21
|
+
nodeSpacing: {
|
|
22
|
+
type: string;
|
|
23
|
+
default: number;
|
|
24
|
+
};
|
|
25
|
+
layerSpacing: {
|
|
26
|
+
type: string;
|
|
27
|
+
default: number;
|
|
28
|
+
};
|
|
29
|
+
algorithm: {
|
|
30
|
+
type: string;
|
|
31
|
+
enum: string[];
|
|
32
|
+
default: string;
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
required: string[];
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
export declare const LayoutOptionsSchema: z.ZodObject<{
|
|
41
|
+
direction: z.ZodDefault<z.ZodEnum<{
|
|
42
|
+
RIGHT: "RIGHT";
|
|
43
|
+
DOWN: "DOWN";
|
|
44
|
+
LEFT: "LEFT";
|
|
45
|
+
UP: "UP";
|
|
46
|
+
}>>;
|
|
47
|
+
nodeSpacing: z.ZodDefault<z.ZodNumber>;
|
|
48
|
+
layerSpacing: z.ZodDefault<z.ZodNumber>;
|
|
49
|
+
algorithm: z.ZodDefault<z.ZodEnum<{
|
|
50
|
+
layered: "layered";
|
|
51
|
+
mrtree: "mrtree";
|
|
52
|
+
force: "force";
|
|
53
|
+
box: "box";
|
|
54
|
+
}>>;
|
|
55
|
+
}, z.core.$strip>;
|
|
56
|
+
export type LayoutOptions = z.infer<typeof LayoutOptionsSchema>;
|
|
57
|
+
export declare function readGraph(content: string): GraphIR;
|
|
58
|
+
interface PositionedNode {
|
|
59
|
+
id: string;
|
|
60
|
+
x: number;
|
|
61
|
+
y: number;
|
|
62
|
+
width: number;
|
|
63
|
+
height: number;
|
|
64
|
+
parentId?: string;
|
|
65
|
+
}
|
|
66
|
+
export interface ComputedLayout {
|
|
67
|
+
nodes: PositionedNode[];
|
|
68
|
+
edges: Array<{
|
|
69
|
+
id: string;
|
|
70
|
+
sections: Array<{
|
|
71
|
+
startPoint: {
|
|
72
|
+
x: number;
|
|
73
|
+
y: number;
|
|
74
|
+
};
|
|
75
|
+
bendPoints: Array<{
|
|
76
|
+
x: number;
|
|
77
|
+
y: number;
|
|
78
|
+
}>;
|
|
79
|
+
endPoint: {
|
|
80
|
+
x: number;
|
|
81
|
+
y: number;
|
|
82
|
+
};
|
|
83
|
+
}>;
|
|
84
|
+
}>;
|
|
85
|
+
width: number;
|
|
86
|
+
height: number;
|
|
87
|
+
}
|
|
88
|
+
export declare function handleLayout(args: unknown): Promise<{
|
|
89
|
+
content: {
|
|
90
|
+
type: "text";
|
|
91
|
+
text: string;
|
|
92
|
+
}[];
|
|
93
|
+
}>;
|
|
94
|
+
/** Shared recursive ELK adapter used by both coral_layout and coral_render. */
|
|
95
|
+
export declare function computeLayout(graph: GraphIR, options: LayoutOptions): Promise<ComputedLayout>;
|
|
96
|
+
export {};
|
|
97
|
+
//# sourceMappingURL=layout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../src/tools/layout.ts"],"names":[],"mappings":"AAGA,OAAO,EAAS,KAAK,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmBtB,CAAC;AAEF,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;iBAK9B,CAAC;AAGH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAelD;AAWD,UAAU,cAAc;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,KAAK,EAAE,KAAK,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;QACX,QAAQ,EAAE,KAAK,CAAC;YACd,UAAU,EAAE;gBAAE,CAAC,EAAE,MAAM,CAAC;gBAAC,CAAC,EAAE,MAAM,CAAA;aAAE,CAAC;YACrC,UAAU,EAAE,KAAK,CAAC;gBAAE,CAAC,EAAE,MAAM,CAAC;gBAAC,CAAC,EAAE,MAAM,CAAA;aAAE,CAAC,CAAC;YAC5C,QAAQ,EAAE;gBAAE,CAAC,EAAE,MAAM,CAAC;gBAAC,CAAC,EAAE,MAAM,CAAA;aAAE,CAAC;SACpC,CAAC,CAAC;KACJ,CAAC,CAAC;IACH,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAwED,wBAAsB,YAAY,CAAC,IAAI,EAAE,OAAO;;;;;GAY/C;AAED,+EAA+E;AAC/E,wBAAsB,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC,CAuBnG"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/** Compute node and edge geometry with ELK. */
|
|
2
|
+
import ELK from 'elkjs';
|
|
3
|
+
import { parse } from '@coral-viz/language';
|
|
4
|
+
import { validateIR } from '@graph-ir/core';
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
export const layoutTool = {
|
|
7
|
+
name: 'coral_layout',
|
|
8
|
+
description: 'Run ELK on Graph-IR JSON or Coral DSL and return computed geometry.',
|
|
9
|
+
inputSchema: {
|
|
10
|
+
type: 'object',
|
|
11
|
+
properties: {
|
|
12
|
+
content: { type: 'string', description: 'Graph-IR JSON or Coral DSL to lay out' },
|
|
13
|
+
options: {
|
|
14
|
+
type: 'object',
|
|
15
|
+
properties: {
|
|
16
|
+
direction: { type: 'string', enum: ['RIGHT', 'DOWN', 'LEFT', 'UP'], default: 'RIGHT' },
|
|
17
|
+
nodeSpacing: { type: 'number', default: 50 },
|
|
18
|
+
layerSpacing: { type: 'number', default: 50 },
|
|
19
|
+
algorithm: { type: 'string', enum: ['layered', 'mrtree', 'force', 'box'], default: 'layered' },
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
required: ['content'],
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
export const LayoutOptionsSchema = z.object({
|
|
27
|
+
direction: z.enum(['RIGHT', 'DOWN', 'LEFT', 'UP']).default('RIGHT'),
|
|
28
|
+
nodeSpacing: z.number().positive().default(50),
|
|
29
|
+
layerSpacing: z.number().positive().default(50),
|
|
30
|
+
algorithm: z.enum(['layered', 'mrtree', 'force', 'box']).default('layered'),
|
|
31
|
+
});
|
|
32
|
+
const Args = z.object({ content: z.string(), options: LayoutOptionsSchema.optional() });
|
|
33
|
+
export function readGraph(content) {
|
|
34
|
+
if (content.trimStart().startsWith('{')) {
|
|
35
|
+
const graph = JSON.parse(content);
|
|
36
|
+
return {
|
|
37
|
+
...graph,
|
|
38
|
+
version: graph.version === '1.0' ? '1.0.0' : graph.version,
|
|
39
|
+
nodes: graph.nodes ?? [],
|
|
40
|
+
edges: graph.edges ?? [],
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
const parsed = parse(content);
|
|
44
|
+
if (!parsed.success || !parsed.graph) {
|
|
45
|
+
throw new Error(parsed.errors.map((error) => `line ${error.line}: ${error.message}`).join('; '));
|
|
46
|
+
}
|
|
47
|
+
return parsed.graph;
|
|
48
|
+
}
|
|
49
|
+
function toElkNode(node) {
|
|
50
|
+
return {
|
|
51
|
+
id: node.id,
|
|
52
|
+
width: node.dimensions?.width ?? 150,
|
|
53
|
+
height: node.dimensions?.height ?? 60,
|
|
54
|
+
...(node.children?.length ? { children: node.children.map(toElkNode) } : {}),
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function flattenLayoutNodes(nodes, parentId, offsetX = 0, offsetY = 0) {
|
|
58
|
+
return (nodes ?? []).flatMap((node) => {
|
|
59
|
+
const x = offsetX + (node.x ?? 0);
|
|
60
|
+
const y = offsetY + (node.y ?? 0);
|
|
61
|
+
const current = {
|
|
62
|
+
id: node.id,
|
|
63
|
+
x,
|
|
64
|
+
y,
|
|
65
|
+
width: node.width ?? 0,
|
|
66
|
+
height: node.height ?? 0,
|
|
67
|
+
...(parentId ? { parentId } : {}),
|
|
68
|
+
};
|
|
69
|
+
return [current, ...flattenLayoutNodes(node.children, node.id, x, y)];
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
function collectContainerOffsets(nodes, offsetX = 0, offsetY = 0, result = new Map()) {
|
|
73
|
+
for (const node of nodes ?? []) {
|
|
74
|
+
const current = { x: offsetX + (node.x ?? 0), y: offsetY + (node.y ?? 0) };
|
|
75
|
+
result.set(node.id, current);
|
|
76
|
+
collectContainerOffsets(node.children, current.x, current.y, result);
|
|
77
|
+
}
|
|
78
|
+
return result;
|
|
79
|
+
}
|
|
80
|
+
function flattenLayoutEdges(node, containerOffsets, storageOffset = { x: 0, y: 0 }) {
|
|
81
|
+
return [
|
|
82
|
+
...(node.edges ?? []).map((edge) => {
|
|
83
|
+
const container = edge.container;
|
|
84
|
+
const offset = typeof container === 'string'
|
|
85
|
+
? containerOffsets.get(container) ?? storageOffset
|
|
86
|
+
: storageOffset;
|
|
87
|
+
const shift = (point) => ({
|
|
88
|
+
x: point.x + offset.x,
|
|
89
|
+
y: point.y + offset.y,
|
|
90
|
+
});
|
|
91
|
+
return {
|
|
92
|
+
id: edge.id,
|
|
93
|
+
sections: (edge.sections ?? []).map((section) => ({
|
|
94
|
+
startPoint: shift(section.startPoint),
|
|
95
|
+
bendPoints: (section.bendPoints ?? []).map(shift),
|
|
96
|
+
endPoint: shift(section.endPoint),
|
|
97
|
+
})),
|
|
98
|
+
};
|
|
99
|
+
}),
|
|
100
|
+
...(node.children ?? []).flatMap((child) => flattenLayoutEdges(child, containerOffsets, {
|
|
101
|
+
x: storageOffset.x + (child.x ?? 0),
|
|
102
|
+
y: storageOffset.y + (child.y ?? 0),
|
|
103
|
+
})),
|
|
104
|
+
];
|
|
105
|
+
}
|
|
106
|
+
export async function handleLayout(args) {
|
|
107
|
+
const parsed = Args.parse(args);
|
|
108
|
+
const options = LayoutOptionsSchema.parse(parsed.options ?? {});
|
|
109
|
+
const graph = readGraph(parsed.content);
|
|
110
|
+
const validation = validateIR(graph);
|
|
111
|
+
if (!validation.valid) {
|
|
112
|
+
throw new Error(validation.errors.map((error) => error.message).join('; '));
|
|
113
|
+
}
|
|
114
|
+
const layout = await computeLayout(graph, options);
|
|
115
|
+
return { content: [{ type: 'text',
|
|
116
|
+
text: `Layout computed with ELK for ${layout.nodes.length} nodes.\n\n${JSON.stringify({ options, layout }, null, 2)}` }] };
|
|
117
|
+
}
|
|
118
|
+
/** Shared recursive ELK adapter used by both coral_layout and coral_render. */
|
|
119
|
+
export async function computeLayout(graph, options) {
|
|
120
|
+
const ElkConstructor = ELK;
|
|
121
|
+
const elkGraph = {
|
|
122
|
+
id: graph.id,
|
|
123
|
+
layoutOptions: {
|
|
124
|
+
'elk.algorithm': options.algorithm,
|
|
125
|
+
'elk.direction': options.direction,
|
|
126
|
+
'elk.hierarchyHandling': 'INCLUDE_CHILDREN',
|
|
127
|
+
'elk.spacing.nodeNode': String(options.nodeSpacing),
|
|
128
|
+
'elk.layered.spacing.nodeNodeBetweenLayers': String(options.layerSpacing),
|
|
129
|
+
},
|
|
130
|
+
children: graph.nodes.map(toElkNode),
|
|
131
|
+
edges: graph.edges.map((edge) => ({ id: edge.id, sources: [edge.source], targets: [edge.target] })),
|
|
132
|
+
};
|
|
133
|
+
const output = await new ElkConstructor().layout(elkGraph);
|
|
134
|
+
const containerOffsets = collectContainerOffsets(output.children);
|
|
135
|
+
return {
|
|
136
|
+
nodes: flattenLayoutNodes(output.children),
|
|
137
|
+
edges: flattenLayoutEdges(output, containerOffsets),
|
|
138
|
+
width: output.width ?? 0,
|
|
139
|
+
height: output.height ?? 0,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=layout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout.js","sourceRoot":"","sources":["../../src/tools/layout.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/** Generate deterministic SVG or standalone HTML from GraphIR or Coral DSL. */
|
|
2
|
+
export declare const renderTool: {
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
inputSchema: {
|
|
6
|
+
type: "object";
|
|
7
|
+
properties: {
|
|
8
|
+
content: {
|
|
9
|
+
type: string;
|
|
10
|
+
description: string;
|
|
11
|
+
};
|
|
12
|
+
options: {
|
|
13
|
+
type: string;
|
|
14
|
+
description: string;
|
|
15
|
+
properties: {
|
|
16
|
+
format: {
|
|
17
|
+
type: string;
|
|
18
|
+
enum: string[];
|
|
19
|
+
description: string;
|
|
20
|
+
default: string;
|
|
21
|
+
};
|
|
22
|
+
direction: {
|
|
23
|
+
type: string;
|
|
24
|
+
enum: string[];
|
|
25
|
+
description: string;
|
|
26
|
+
default: string;
|
|
27
|
+
};
|
|
28
|
+
theme: {
|
|
29
|
+
type: string;
|
|
30
|
+
enum: string[];
|
|
31
|
+
description: string;
|
|
32
|
+
default: string;
|
|
33
|
+
};
|
|
34
|
+
nodeSpacing: {
|
|
35
|
+
type: string;
|
|
36
|
+
description: string;
|
|
37
|
+
default: number;
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
required: string[];
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
export declare function handleRender(args: unknown): Promise<{
|
|
46
|
+
content: {
|
|
47
|
+
type: "text";
|
|
48
|
+
text: string;
|
|
49
|
+
}[];
|
|
50
|
+
isError: boolean;
|
|
51
|
+
} | {
|
|
52
|
+
content: {
|
|
53
|
+
type: "text";
|
|
54
|
+
text: string;
|
|
55
|
+
}[];
|
|
56
|
+
isError?: undefined;
|
|
57
|
+
}>;
|
|
58
|
+
//# sourceMappingURL=render.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/tools/render.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAQ/E,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmCtB,CAAC;AAwGF,wBAAsB,YAAY,CAAC,IAAI,EAAE,OAAO;;;;;;;;;;;;GAuB/C"}
|