diagram-tool 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.
- package/README.md +64 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +239 -0
- package/dist/cli.js.map +1 -0
- package/dist/context.d.ts +27 -0
- package/dist/context.js +55 -0
- package/dist/context.js.map +1 -0
- package/dist/diagram.d.ts +51 -0
- package/dist/diagram.js +519 -0
- package/dist/diagram.js.map +1 -0
- package/dist/dom-shim.d.ts +1 -0
- package/dist/dom-shim.js +59 -0
- package/dist/dom-shim.js.map +1 -0
- package/dist/guide.d.ts +9 -0
- package/dist/guide.js +99 -0
- package/dist/guide.js.map +1 -0
- package/dist/library.d.ts +76 -0
- package/dist/library.js +364 -0
- package/dist/library.js.map +1 -0
- package/dist/llm.d.ts +23 -0
- package/dist/llm.js +124 -0
- package/dist/llm.js.map +1 -0
- package/dist/mcp-install.d.ts +1 -0
- package/dist/mcp-install.js +68 -0
- package/dist/mcp-install.js.map +1 -0
- package/dist/mcp.d.ts +6 -0
- package/dist/mcp.js +262 -0
- package/dist/mcp.js.map +1 -0
- package/dist/public/Assistant-Bold-ZDZZ6JHA.woff2 +0 -0
- package/dist/public/Assistant-Medium-DZ25RZU3.woff2 +0 -0
- package/dist/public/Assistant-Regular-PLF2XOGW.woff2 +0 -0
- package/dist/public/Assistant-SemiBold-CZ5MX6FK.woff2 +0 -0
- package/dist/public/viewer.css +2 -0
- package/dist/public/viewer.css.map +7 -0
- package/dist/public/viewer.js +3092 -0
- package/dist/public/viewer.js.map +7 -0
- package/dist/server.d.ts +9 -0
- package/dist/server.js +166 -0
- package/dist/server.js.map +1 -0
- package/libraries/UML-ER-library.excalidrawlib +5380 -0
- package/libraries/awesome-icons.excalidrawlib +4081 -0
- package/libraries/dev_ops.excalidrawlib +35468 -0
- package/libraries/network-topology-icons.excalidrawlib +5290 -0
- package/libraries/system-icons.excalidrawlib +4521 -0
- package/libraries/systemdesignicons.excalidrawlib +1307 -0
- package/package.json +38 -0
package/dist/diagram.js
ADDED
|
@@ -0,0 +1,519 @@
|
|
|
1
|
+
import "./dom-shim.js";
|
|
2
|
+
import mermaid from "mermaid";
|
|
3
|
+
import { parseMermaidToExcalidraw } from "@excalidraw/mermaid-to-excalidraw";
|
|
4
|
+
import { complete } from "./llm.js";
|
|
5
|
+
import { instantiateIcon, loadIconTemplates } from "./library.js";
|
|
6
|
+
import { existsSync } from "node:fs";
|
|
7
|
+
const SYSTEM = `You author Mermaid diagrams like a diagramming craftsman. Output ONLY one fenced \`\`\`mermaid block (one short sentence before it allowed). Never prose instead of a diagram.
|
|
8
|
+
|
|
9
|
+
TYPE CHOICE:
|
|
10
|
+
- processes / decisions / architecture -> flowchart (LR for wide, TD for tall)
|
|
11
|
+
- interactions over time -> sequenceDiagram; data models -> erDiagram
|
|
12
|
+
- OOP structure -> classDiagram; states -> stateDiagram-v2
|
|
13
|
+
- Supported types ONLY: flowchart/graph, sequenceDiagram, erDiagram, classDiagram, stateDiagram-v2.
|
|
14
|
+
|
|
15
|
+
FLOWCHART CRAFT (applies to every flowchart):
|
|
16
|
+
- Start with this init line for breathing room (exact syntax):
|
|
17
|
+
%%{init: {"flowchart": {"nodeSpacing": 60, "rankSpacing": 90, "curve": "linear"}}}%%
|
|
18
|
+
- Use SELF-EXPLANATORY node ids (CLI, CTXFILE, WEBUI — never A/B/C).
|
|
19
|
+
- Declare ALL nodes first (one per line), then edges grouped with blank lines between logical groups. Add %% comments per group.
|
|
20
|
+
- Structure with %% section comments + blank lines, NOT subgraphs: the renderer cannot draw subgraphs and degrades the whole diagram. Example:
|
|
21
|
+
%% -- agent loop --
|
|
22
|
+
AGENT["OpenCode agent loop"]
|
|
23
|
+
LLM["OpenRouter LLM"]
|
|
24
|
+
AGENT-->|prompts|LLM
|
|
25
|
+
LLM-->|completion|AGENT
|
|
26
|
+
- Shared nodes (one target, many sources) get their own line each — never hide a fan-in inside a chain.
|
|
27
|
+
- Edge labels use pipe syntax ONLY: -->|reads| (never -- reads -->). Every non-obvious edge gets a label.
|
|
28
|
+
- Quote labels with special chars: ["label (x)"].
|
|
29
|
+
- Shape by role, renderer-safe only: rhombus {..} for decisions, plain [...] for everything else (stadium/cylinder silently collapse to rectangles, so don't rely on them).
|
|
30
|
+
- End every flowchart with this palette + a class on EVERY node:
|
|
31
|
+
classDef actor fill:#e3f2fd,stroke:#1e88e5,stroke-width:2px
|
|
32
|
+
classDef store fill:#fff3e0,stroke:#fb8c00,stroke-width:2px
|
|
33
|
+
classDef flow fill:#e8f5e9,stroke:#43a047,stroke-width:2px
|
|
34
|
+
classDef ext fill:#f3e5f5,stroke:#8e24aa,stroke-width:2px
|
|
35
|
+
(actor = people/agents, store = files/data, flow = processes, ext = external services)
|
|
36
|
+
- Max ~12 nodes. Split unrelated concerns instead of shrinking. LR for wide flows, TD for tall ones.
|
|
37
|
+
- Hub content (many edges through one shared node) → use TD: hubs laid horizontally always collide; vertical stacking gives edges room.
|
|
38
|
+
- Fan-in discipline: max 3 edges into any single node. More than that, introduce an intermediate collector node (e.g. CTXWRITE["writes"] vs CTXREAD["reads"]) or split the flow — hub-and-spoke layouts always overlap.
|
|
39
|
+
- One edge per node pair, always: if several actions share the same source and target, combine them into ONE edge with a joint label (CLI-->|generate · edit · render · serve|CTXWRITE). Parallel duplicate arrows are forbidden.
|
|
40
|
+
- People/nodes with real-world meaning get an icon class IN ADDITION to their color class: class USER icon_user (available: icon_user, icon_users, icon_home, icon_lock, icon_search, icon_chart, icon_email, icon_calendar, icon_location, icon_payment). Example: class USER actor,icon_user. Only use these ten — never invent others.
|
|
41
|
+
|
|
42
|
+
SEQUENCE CRAFT: participants declared first with aliases (participant C as Client); every request has a matching -->> reply; activate/deactivate around long handlers.
|
|
43
|
+
|
|
44
|
+
Example (note ids, declare-first, section comments, classes):
|
|
45
|
+
\`\`\`mermaid
|
|
46
|
+
%%{init: {"flowchart": {"nodeSpacing": 60, "rankSpacing": 90, "curve": "linear"}}}%%
|
|
47
|
+
flowchart LR
|
|
48
|
+
USER(["User"])
|
|
49
|
+
CLI["diagram-tool CLI"]
|
|
50
|
+
CTXFILE["diagram-tool.context.json"]
|
|
51
|
+
WEBUI["React Excalidraw UI"]
|
|
52
|
+
|
|
53
|
+
%% invoke + generate
|
|
54
|
+
USER-->|invokes|CLI
|
|
55
|
+
CLI-->|writes rev|CTXFILE
|
|
56
|
+
|
|
57
|
+
%% view loop (no subgraphs — the renderer cannot draw them)
|
|
58
|
+
CTXFILE-->|polls|WEBUI
|
|
59
|
+
|
|
60
|
+
classDef actor fill:#e3f2fd,stroke:#1e88e5,stroke-width:2px
|
|
61
|
+
classDef store fill:#fff3e0,stroke:#fb8c00,stroke-width:2px
|
|
62
|
+
classDef flow fill:#e8f5e9,stroke:#43a047,stroke-width:2px
|
|
63
|
+
classDef ext fill:#f3e5f5,stroke:#8e24aa,stroke-width:2px
|
|
64
|
+
class USER actor
|
|
65
|
+
class CLI,WEBUI flow
|
|
66
|
+
class CTXFILE store
|
|
67
|
+
\`\`\`
|
|
68
|
+
`;
|
|
69
|
+
const SUPPORTED = new Set(["flowchart", "graph", "sequenceDiagram", "erDiagram", "classDiagram", "stateDiagram-v2", "stateDiagram"]);
|
|
70
|
+
let mermaidInit = false;
|
|
71
|
+
function ensureMermaid() {
|
|
72
|
+
if (!mermaidInit) {
|
|
73
|
+
mermaid.initialize({ startOnLoad: false, securityLevel: "strict" });
|
|
74
|
+
mermaidInit = true;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
export function extractMermaid(raw) {
|
|
78
|
+
const m = /```mermaid\s*([\s\S]*?)```/i.exec(raw);
|
|
79
|
+
if (m?.[1]?.trim())
|
|
80
|
+
return m[1].trim();
|
|
81
|
+
throw new Error("Model did not return a ```mermaid block. Raw output:\n" + raw.slice(0, 1000));
|
|
82
|
+
}
|
|
83
|
+
export async function validateMermaid(source) {
|
|
84
|
+
ensureMermaid();
|
|
85
|
+
// Strip leading %% comments / %%{init}%% directives before type detection.
|
|
86
|
+
const code = source
|
|
87
|
+
.split("\n")
|
|
88
|
+
.filter((l) => !l.trimStart().startsWith("%%"))
|
|
89
|
+
.join("\n")
|
|
90
|
+
.trim();
|
|
91
|
+
const diagramType = code.split(/\s+/)[0] ?? "";
|
|
92
|
+
if (!SUPPORTED.has(diagramType)) {
|
|
93
|
+
throw new Error(`Unsupported diagram type "${diagramType}". Supported: flowchart, sequenceDiagram, erDiagram, classDiagram, stateDiagram-v2.`);
|
|
94
|
+
}
|
|
95
|
+
await mermaid.parse(source); // strict: throws on syntax errors
|
|
96
|
+
return diagramType;
|
|
97
|
+
}
|
|
98
|
+
export async function convertToScene(mermaidSource) {
|
|
99
|
+
const { elements } = await parseMermaidToExcalidraw(mermaidSource, {
|
|
100
|
+
flowchart: { curve: "linear" },
|
|
101
|
+
themeVariables: { fontSize: "20px" },
|
|
102
|
+
maxEdges: 500,
|
|
103
|
+
});
|
|
104
|
+
const els = (elements ?? []);
|
|
105
|
+
// The converter degrades to a single `image` placeholder (or empty) when it
|
|
106
|
+
// hits constructs it can't render (e.g. subgraphs). Never save that —
|
|
107
|
+
// throw so the caller repairs/retries instead of persisting a broken scene.
|
|
108
|
+
if (els.length === 0 || els.every((e) => e.type === "image")) {
|
|
109
|
+
throw new Error("Converter produced no drawable elements (likely an unsupported construct such as subgraph — flatten it into plain nodes + edges).");
|
|
110
|
+
}
|
|
111
|
+
return {
|
|
112
|
+
type: "excalidraw",
|
|
113
|
+
version: 2,
|
|
114
|
+
source: "diagram-tool",
|
|
115
|
+
elements: declutter(await applyIcons(declutter(dedupeArrows(withBoundLabels(els))), mermaidSource)),
|
|
116
|
+
appState: {},
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
/** nodeId -> icon slug from `class NODE icon_slug` statements in the source. */
|
|
120
|
+
export function parseIconClasses(mermaidSource) {
|
|
121
|
+
const out = new Map();
|
|
122
|
+
for (const line of mermaidSource.split("\n")) {
|
|
123
|
+
const m = /^\s*class\s+([\w,\s]+?)\s+([\w,\s]+?)\s*$/.exec(line);
|
|
124
|
+
if (!m)
|
|
125
|
+
continue;
|
|
126
|
+
const nodes = m[1].split(",").map((s) => s.trim()).filter(Boolean);
|
|
127
|
+
const classes = m[2].split(",").map((s) => s.trim()).filter(Boolean);
|
|
128
|
+
if (nodes.includes("classDef") || classes.includes("classDef"))
|
|
129
|
+
continue;
|
|
130
|
+
for (const n of nodes) {
|
|
131
|
+
for (const c of classes) {
|
|
132
|
+
if (c.startsWith("icon_"))
|
|
133
|
+
out.set(n, c);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return out;
|
|
138
|
+
}
|
|
139
|
+
let iconCache = null;
|
|
140
|
+
/**
|
|
141
|
+
* Dress node cards with library artwork: icon glyph fitted into the top of
|
|
142
|
+
* the box, node caption pinned to the bottom strip, all grouped for UI drag.
|
|
143
|
+
* Unknown slugs / missing libraries degrade to plain boxes (never throw).
|
|
144
|
+
*/
|
|
145
|
+
export async function applyIcons(elements, mermaidSource, libraryDir = "libraries") {
|
|
146
|
+
const mapping = parseIconClasses(mermaidSource);
|
|
147
|
+
if (mapping.size === 0 || !existsSync(libraryDir))
|
|
148
|
+
return elements;
|
|
149
|
+
if (!iconCache)
|
|
150
|
+
iconCache = loadIconTemplates(libraryDir);
|
|
151
|
+
const templates = await iconCache;
|
|
152
|
+
const num = (v, d = 0) => (typeof v === "number" && isFinite(v) ? v : d);
|
|
153
|
+
for (const [nodeId, slug] of mapping) {
|
|
154
|
+
const node = elements.find((e) => String(e.id) === nodeId && (e.type === "rectangle" || e.type === "diamond"));
|
|
155
|
+
const template = templates.get(slug);
|
|
156
|
+
if (!node || !template)
|
|
157
|
+
continue;
|
|
158
|
+
// Grow small converter boxes into icon cards (centered), then re-anchor
|
|
159
|
+
// attached arrow endpoints onto the new border.
|
|
160
|
+
const caption = elements.find((e) => e.type === "text" && e.containerId === nodeId);
|
|
161
|
+
const capW = caption ? num(caption.width, 40) + 34 : 0;
|
|
162
|
+
const oldBox = { x: num(node.x), y: num(node.y), w: Math.max(1, num(node.width, 80)), h: Math.max(1, num(node.height, 40)) };
|
|
163
|
+
const newW = Math.max(oldBox.w, 132, capW);
|
|
164
|
+
const newH = Math.max(oldBox.h, 108);
|
|
165
|
+
node.x = oldBox.x - (newW - oldBox.w) / 2;
|
|
166
|
+
node.y = oldBox.y - (newH - oldBox.h) / 2;
|
|
167
|
+
node.width = newW;
|
|
168
|
+
node.height = newH;
|
|
169
|
+
const box = { x: num(node.x), y: num(node.y), w: newW, h: newH };
|
|
170
|
+
reanchor(elements, nodeId, box);
|
|
171
|
+
const groupId = `icon-${nodeId}`;
|
|
172
|
+
const art = instantiateIcon(template, box, groupId);
|
|
173
|
+
if (art.length === 0)
|
|
174
|
+
continue;
|
|
175
|
+
if (caption) {
|
|
176
|
+
const c = caption;
|
|
177
|
+
const fs = num(c.fontSize, 16);
|
|
178
|
+
c.y = box.y + box.h - fs * 1.5 - 6;
|
|
179
|
+
c.x = box.x + box.w / 2 - num(c.width, 40) / 2;
|
|
180
|
+
const g = c.groupIds;
|
|
181
|
+
c.groupIds = [...(g ?? []), groupId];
|
|
182
|
+
}
|
|
183
|
+
const g = node.groupIds;
|
|
184
|
+
node.groupIds = [...(g ?? []), groupId];
|
|
185
|
+
elements.push(...art);
|
|
186
|
+
}
|
|
187
|
+
return elements;
|
|
188
|
+
}
|
|
189
|
+
/** Move arrow endpoints attached to `id` out onto the border of `box`. */
|
|
190
|
+
function reanchor(elements, id, box) {
|
|
191
|
+
const num = (v) => (typeof v === "number" ? v : 0);
|
|
192
|
+
const cx = box.x + box.w / 2;
|
|
193
|
+
const cy = box.y + box.h / 2;
|
|
194
|
+
const anchor = (px, py) => {
|
|
195
|
+
const dx = px - cx;
|
|
196
|
+
const dy = py - cy;
|
|
197
|
+
if (dx === 0 && dy === 0)
|
|
198
|
+
return [cx, box.y - 2];
|
|
199
|
+
const sx = dx !== 0 ? box.w / 2 / Math.abs(dx) : Infinity;
|
|
200
|
+
const sy = dy !== 0 ? box.h / 2 / Math.abs(dy) : Infinity;
|
|
201
|
+
const t = Math.min(sx, sy) + 2 / Math.max(Math.abs(dx), Math.abs(dy), 1);
|
|
202
|
+
return [cx + dx * t, cy + dy * t];
|
|
203
|
+
};
|
|
204
|
+
for (const e of elements) {
|
|
205
|
+
if (e.type !== "arrow")
|
|
206
|
+
continue;
|
|
207
|
+
const pts = e.points;
|
|
208
|
+
if (!pts || pts.length === 0)
|
|
209
|
+
continue;
|
|
210
|
+
const ox = num(e.x);
|
|
211
|
+
const oy = num(e.y);
|
|
212
|
+
const start = e.start;
|
|
213
|
+
const end = e.end;
|
|
214
|
+
if (start?.id === id && pts[0]) {
|
|
215
|
+
const [ax, ay] = anchor(ox + pts[0][0], oy + pts[0][1]);
|
|
216
|
+
const ddx = ax - (ox + pts[0][0]);
|
|
217
|
+
const ddy = ay - (oy + pts[0][1]);
|
|
218
|
+
pts[0] = [pts[0][0] + ddx, pts[0][1] + ddy];
|
|
219
|
+
shiftArrowLabel(elements, e, ddx / 2, ddy / 2);
|
|
220
|
+
}
|
|
221
|
+
if (end?.id === id && pts.length > 1) {
|
|
222
|
+
const last = pts[pts.length - 1];
|
|
223
|
+
const [ax, ay] = anchor(ox + last[0], oy + last[1]);
|
|
224
|
+
const ddx = ax - (ox + last[0]);
|
|
225
|
+
const ddy = ay - (oy + last[1]);
|
|
226
|
+
pts[pts.length - 1] = [last[0] + ddx, last[1] + ddy];
|
|
227
|
+
shiftArrowLabel(elements, e, ddx / 2, ddy / 2);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
function shiftArrowLabel(elements, arrow, dx, dy) {
|
|
232
|
+
const num = (v, d = 0) => (typeof v === "number" && isFinite(v) ? v : d);
|
|
233
|
+
for (const t of elements) {
|
|
234
|
+
if (t.type === "text" && t.containerId === arrow.id) {
|
|
235
|
+
t.x = num(t.x) + dx;
|
|
236
|
+
t.y = num(t.y) + dy;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Merge parallel arrows (same source id -> same target id) into one. The
|
|
242
|
+
* model sometimes emits one edge per action (generate/edit/render/serve),
|
|
243
|
+
* which renders as stacked duplicate arrows. Keeper = first arrow; labels
|
|
244
|
+
* are concatenated with " · " and surplus arrows + labels removed.
|
|
245
|
+
*/
|
|
246
|
+
export function dedupeArrows(elements) {
|
|
247
|
+
const keyOf = (e) => {
|
|
248
|
+
const s = e.start?.id;
|
|
249
|
+
const t = e.end?.id;
|
|
250
|
+
return s && t ? `${s}\u0000${t}` : null;
|
|
251
|
+
};
|
|
252
|
+
const seen = new Map();
|
|
253
|
+
const drop = new Set();
|
|
254
|
+
const labelOf = (arrowId) => elements.find((e) => e.type === "text" && e.containerId === arrowId && !drop.has(String(e.id)));
|
|
255
|
+
for (const e of elements) {
|
|
256
|
+
if (e.type !== "arrow")
|
|
257
|
+
continue;
|
|
258
|
+
const k = keyOf(e);
|
|
259
|
+
if (!k)
|
|
260
|
+
continue;
|
|
261
|
+
const keeper = seen.get(k);
|
|
262
|
+
if (!keeper) {
|
|
263
|
+
seen.set(k, e);
|
|
264
|
+
continue;
|
|
265
|
+
}
|
|
266
|
+
// duplicate: fold its label into the keeper's, then remove arrow + label
|
|
267
|
+
const dupLabel = labelOf(String(e.id));
|
|
268
|
+
if (dupLabel && typeof dupLabel.text === "string" && dupLabel.text) {
|
|
269
|
+
const keepLabel = labelOf(String(keeper.id));
|
|
270
|
+
if (keepLabel && typeof keepLabel.text === "string" && keepLabel.text) {
|
|
271
|
+
const merged = `${keepLabel.text} · ${dupLabel.text}`;
|
|
272
|
+
keepLabel.text = merged;
|
|
273
|
+
keepLabel.originalText = merged;
|
|
274
|
+
const fs = typeof keepLabel.fontSize === "number" ? keepLabel.fontSize : 16;
|
|
275
|
+
keepLabel.width = Math.max(20, merged.length * fs * 0.55);
|
|
276
|
+
}
|
|
277
|
+
else if (!keepLabel) {
|
|
278
|
+
dupLabel.containerId = keeper.id;
|
|
279
|
+
const bound = keeper.boundElements;
|
|
280
|
+
if (Array.isArray(bound))
|
|
281
|
+
bound.push({ id: String(dupLabel.id), type: "text" });
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
drop.add(String(e.id));
|
|
285
|
+
if (dupLabel && dupLabel.containerId === e.id)
|
|
286
|
+
drop.add(String(dupLabel.id));
|
|
287
|
+
}
|
|
288
|
+
if (drop.size === 0)
|
|
289
|
+
return elements;
|
|
290
|
+
return elements.filter((e) => !drop.has(String(e.id)));
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Breathing space pass. The converter packs nodes per its own (often wrong)
|
|
294
|
+
* measurements, so labels collide. This iteratively pushes overlapping boxes
|
|
295
|
+
* apart and drags attached arrow endpoints + labels along (arrows here are
|
|
296
|
+
* free-floating: start/end are plain id refs, no live bindings).
|
|
297
|
+
*/
|
|
298
|
+
export function declutter(elements) {
|
|
299
|
+
const PAD = 36;
|
|
300
|
+
const num = (v, d = 0) => (typeof v === "number" && isFinite(v) ? v : d);
|
|
301
|
+
const boxOf = (e) => ({
|
|
302
|
+
x: num(e.x),
|
|
303
|
+
y: num(e.y),
|
|
304
|
+
w: Math.max(1, num(e.width, 10)),
|
|
305
|
+
h: Math.max(1, num(e.height, 10)),
|
|
306
|
+
});
|
|
307
|
+
const movers = elements.filter((e) => e.type === "rectangle" || e.type === "diamond" || e.type === "ellipse");
|
|
308
|
+
const moveText = (containerId, dx, dy) => {
|
|
309
|
+
for (const e of elements) {
|
|
310
|
+
if (e.type === "text" && e.containerId === containerId) {
|
|
311
|
+
e.x = num(e.x) + dx;
|
|
312
|
+
e.y = num(e.y) + dy;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
};
|
|
316
|
+
/** Shift arrow endpoints attached to `id` by (dx,dy); returns actual applied delta for labels. */
|
|
317
|
+
const moveArrowEnds = (id, dx, dy) => {
|
|
318
|
+
const deltas = [];
|
|
319
|
+
for (const e of elements) {
|
|
320
|
+
if (e.type !== "arrow")
|
|
321
|
+
continue;
|
|
322
|
+
const pts = e.points;
|
|
323
|
+
if (!pts || pts.length === 0)
|
|
324
|
+
continue;
|
|
325
|
+
const start = e.start;
|
|
326
|
+
const end = e.end;
|
|
327
|
+
let usedDx = 0;
|
|
328
|
+
let usedDy = 0;
|
|
329
|
+
if (start?.id === id && pts[0]) {
|
|
330
|
+
pts[0] = [pts[0][0] + dx, pts[0][1] + dy];
|
|
331
|
+
usedDx += dx;
|
|
332
|
+
usedDy += dy;
|
|
333
|
+
}
|
|
334
|
+
const last = pts[pts.length - 1];
|
|
335
|
+
if (end?.id === id && pts.length > 1) {
|
|
336
|
+
pts[pts.length - 1] = [last[0] + dx, last[1] + dy];
|
|
337
|
+
usedDx += dx;
|
|
338
|
+
usedDy += dy;
|
|
339
|
+
}
|
|
340
|
+
if (usedDx !== 0 || usedDy !== 0) {
|
|
341
|
+
deltas.push({ dx: usedDx / 2, dy: usedDy / 2 });
|
|
342
|
+
// drag the arrow's own label along with the midpoint shift
|
|
343
|
+
for (const t of elements) {
|
|
344
|
+
if (t.type === "text" && t.containerId === e.id) {
|
|
345
|
+
t.x = num(t.x) + usedDx / 2;
|
|
346
|
+
t.y = num(t.y) + usedDy / 2;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
return deltas;
|
|
352
|
+
};
|
|
353
|
+
const overlaps = (a, b) => {
|
|
354
|
+
const ox = Math.min(a.x + a.w, b.x + b.w) - Math.max(a.x, b.x) + PAD;
|
|
355
|
+
const oy = Math.min(a.y + a.h, b.y + b.h) - Math.max(a.y, b.y) + PAD;
|
|
356
|
+
return ox > 0 && oy > 0 ? { ox, oy } : null;
|
|
357
|
+
};
|
|
358
|
+
for (let iter = 0; iter < 60; iter++) {
|
|
359
|
+
let moved = false;
|
|
360
|
+
for (let i = 0; i < movers.length; i++) {
|
|
361
|
+
for (let j = i + 1; j < movers.length; j++) {
|
|
362
|
+
const A = movers[i];
|
|
363
|
+
const B = movers[j];
|
|
364
|
+
const ov = overlaps(boxOf(A), boxOf(B));
|
|
365
|
+
if (!ov)
|
|
366
|
+
continue;
|
|
367
|
+
moved = true;
|
|
368
|
+
// Push along the axis of least overlap.
|
|
369
|
+
let dxA = 0;
|
|
370
|
+
let dyA = 0;
|
|
371
|
+
let dxB = 0;
|
|
372
|
+
let dyB = 0;
|
|
373
|
+
if (ov.ox < ov.oy) {
|
|
374
|
+
const dir = boxOf(A).x + boxOf(A).w / 2 <= boxOf(B).x + boxOf(B).w / 2 ? -1 : 1;
|
|
375
|
+
dxA = (dir * ov.ox) / 2;
|
|
376
|
+
dxB = (-dir * ov.ox) / 2;
|
|
377
|
+
}
|
|
378
|
+
else {
|
|
379
|
+
const dir = boxOf(A).y + boxOf(A).h / 2 <= boxOf(B).y + boxOf(B).h / 2 ? -1 : 1;
|
|
380
|
+
dyA = (dir * ov.oy) / 2;
|
|
381
|
+
dyB = (-dir * ov.oy) / 2;
|
|
382
|
+
}
|
|
383
|
+
A.x = num(A.x) + dxA;
|
|
384
|
+
A.y = num(A.y) + dyA;
|
|
385
|
+
B.x = num(B.x) + dxB;
|
|
386
|
+
B.y = num(B.y) + dyB;
|
|
387
|
+
moveText(String(A.id), dxA, dyA);
|
|
388
|
+
moveText(String(B.id), dxB, dyB);
|
|
389
|
+
moveArrowEnds(String(A.id), dxA, dyA);
|
|
390
|
+
moveArrowEnds(String(B.id), dxB, dyB);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
if (!moved)
|
|
394
|
+
break;
|
|
395
|
+
}
|
|
396
|
+
// Keep arrow labels near their (possibly moved) arrows: re-seat each label
|
|
397
|
+
// at its arrow's midpoint if it drifted more than 120px away.
|
|
398
|
+
for (const e of elements) {
|
|
399
|
+
if (e.type !== "arrow")
|
|
400
|
+
continue;
|
|
401
|
+
const pts = e.points;
|
|
402
|
+
if (!pts || pts.length === 0)
|
|
403
|
+
continue;
|
|
404
|
+
const ox = num(e.x);
|
|
405
|
+
const oy = num(e.y);
|
|
406
|
+
const mid = pts[Math.floor(pts.length / 2)];
|
|
407
|
+
const mx = ox + mid[0];
|
|
408
|
+
const my = oy + mid[1];
|
|
409
|
+
for (const t of elements) {
|
|
410
|
+
if (t.type === "text" && t.containerId === e.id) {
|
|
411
|
+
const cx = num(t.x) + num(t.width, 0) / 2;
|
|
412
|
+
const cy = num(t.y) + num(t.height, 0) / 2;
|
|
413
|
+
if (Math.hypot(mx - cx, my - cy) > 120) {
|
|
414
|
+
t.x = mx - num(t.width, 0) / 2;
|
|
415
|
+
t.y = my - num(t.height, 0) / 2;
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
return elements;
|
|
421
|
+
}
|
|
422
|
+
/**
|
|
423
|
+
* @excalidraw/mermaid-to-excalidraw v2 emits node text as a non-standard
|
|
424
|
+
* `label: { text, fontSize }` prop that the canvas ignores. Rewrite each into
|
|
425
|
+
* a real bound `text` element wired via containerId/boundElements.
|
|
426
|
+
*/
|
|
427
|
+
export function withBoundLabels(elements) {
|
|
428
|
+
const out = [...elements];
|
|
429
|
+
for (const el of elements) {
|
|
430
|
+
const label = el.label;
|
|
431
|
+
if (!label || typeof label.text !== "string" || !label.text)
|
|
432
|
+
continue;
|
|
433
|
+
const fontSize = label.fontSize ?? 20;
|
|
434
|
+
const w = typeof el.width === "number" ? el.width : 80;
|
|
435
|
+
const h = typeof el.height === "number" ? el.height : 30;
|
|
436
|
+
const x = typeof el.x === "number" ? el.x : 0;
|
|
437
|
+
const y = typeof el.y === "number" ? el.y : 0;
|
|
438
|
+
const textW = Math.max(20, label.text.length * fontSize * 0.55);
|
|
439
|
+
const textId = `${String(el.id)}-label`;
|
|
440
|
+
out.push({
|
|
441
|
+
id: textId,
|
|
442
|
+
type: "text",
|
|
443
|
+
x: x + w / 2 - textW / 2,
|
|
444
|
+
y: y + h / 2 - fontSize * 0.65,
|
|
445
|
+
width: textW,
|
|
446
|
+
height: fontSize * 1.3,
|
|
447
|
+
angle: 0,
|
|
448
|
+
strokeColor: el.strokeColor ?? "#1e1e1e",
|
|
449
|
+
backgroundColor: "transparent",
|
|
450
|
+
fillStyle: "solid",
|
|
451
|
+
strokeWidth: 1,
|
|
452
|
+
strokeStyle: "solid",
|
|
453
|
+
roughness: 1,
|
|
454
|
+
opacity: 100,
|
|
455
|
+
seed: typeof el.seed === "number" ? el.seed + 1 : 1,
|
|
456
|
+
version: 1,
|
|
457
|
+
versionNonce: Math.floor(Math.random() * 2 ** 31),
|
|
458
|
+
isDeleted: false,
|
|
459
|
+
groupIds: [],
|
|
460
|
+
frameId: null,
|
|
461
|
+
roundness: null,
|
|
462
|
+
boundElements: [],
|
|
463
|
+
updated: Date.now(),
|
|
464
|
+
locked: false,
|
|
465
|
+
text: label.text,
|
|
466
|
+
originalText: label.text,
|
|
467
|
+
fontSize,
|
|
468
|
+
fontFamily: 1,
|
|
469
|
+
textAlign: "center",
|
|
470
|
+
verticalAlign: "middle",
|
|
471
|
+
containerId: el.id,
|
|
472
|
+
autoResize: true,
|
|
473
|
+
});
|
|
474
|
+
el.boundElements = [...(el.boundElements ?? []), { id: textId, type: "text" }];
|
|
475
|
+
delete el.label;
|
|
476
|
+
}
|
|
477
|
+
return out;
|
|
478
|
+
}
|
|
479
|
+
/** Prompt -> Mermaid -> validate (2 repairs, error fed back) -> Excalidraw scene. */
|
|
480
|
+
export async function generate(prompt, opts) {
|
|
481
|
+
const base = [{ role: "system", content: SYSTEM }];
|
|
482
|
+
let user = `Request: ${prompt}\n\nReturn the diagram as one \`\`\`mermaid block.`;
|
|
483
|
+
if (opts.existingMermaid?.trim()) {
|
|
484
|
+
user =
|
|
485
|
+
`Current diagram (EDIT it, preserve node IDs unless told otherwise):\n\`\`\`mermaid\n${opts.existingMermaid.trim()}\n\`\`\`\n\nEdit instruction: ${prompt}\n\nReturn the FULL updated diagram as one \`\`\`mermaid block.`;
|
|
486
|
+
}
|
|
487
|
+
let messages = [...base, { role: "user", content: user }];
|
|
488
|
+
let lastErr = "";
|
|
489
|
+
for (let attempt = 1; attempt <= 3; attempt++) {
|
|
490
|
+
const raw = await complete(messages, opts);
|
|
491
|
+
let source;
|
|
492
|
+
try {
|
|
493
|
+
source = extractMermaid(raw);
|
|
494
|
+
await validateMermaid(source);
|
|
495
|
+
}
|
|
496
|
+
catch (e) {
|
|
497
|
+
lastErr = e instanceof Error ? e.message : String(e);
|
|
498
|
+
console.error(`attempt ${attempt}: ${lastErr.split("\n")[0]}`);
|
|
499
|
+
if (attempt === 3)
|
|
500
|
+
throw new Error(`Mermaid invalid after 3 attempts. Last error: ${lastErr}`);
|
|
501
|
+
messages = [...base, { role: "user", content: `Your previous Mermaid failed:\n${lastErr}\n\nPrevious output:\n\`\`\`mermaid\n${raw.slice(0, 2000)}\n\`\`\`\n\nFix ONLY the syntax and return the full diagram as one \`\`\`mermaid block.` }];
|
|
502
|
+
continue;
|
|
503
|
+
}
|
|
504
|
+
const scene = await convertToScene(source).catch((e) => {
|
|
505
|
+
lastErr = e instanceof Error ? e.message : String(e);
|
|
506
|
+
console.error(`attempt ${attempt}: conversion failed: ${lastErr.split("\n")[0]}`);
|
|
507
|
+
return null;
|
|
508
|
+
});
|
|
509
|
+
if (!scene) {
|
|
510
|
+
if (attempt === 3)
|
|
511
|
+
throw new Error(`Conversion failed after 3 attempts. Last error: ${lastErr}`);
|
|
512
|
+
messages = [...base, { role: "user", content: `Your Mermaid parses but cannot be rendered:\n${lastErr}\n\nPrevious output:\n\`\`\`mermaid\n${source.slice(0, 2000)}\n\`\`\`\n\nRewrite WITHOUT the unsupported construct (flatten subgraphs into plain nodes + edges) and return the full diagram as one \`\`\`mermaid block.` }];
|
|
513
|
+
continue;
|
|
514
|
+
}
|
|
515
|
+
return { scene, mermaidSource: source, attempts: attempt, repaired: attempt > 1 };
|
|
516
|
+
}
|
|
517
|
+
throw new Error(`unreachable (last: ${lastErr})`);
|
|
518
|
+
}
|
|
519
|
+
//# sourceMappingURL=diagram.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagram.js","sourceRoot":"","sources":["../src/diagram.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/dom-shim.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/** Minimal DOM so mermaid works in Node. Import BEFORE mermaid. */
|
|
2
|
+
import { JSDOM } from "jsdom";
|
|
3
|
+
const dom = new JSDOM("<!DOCTYPE html><html><body></body></html>", { pretendToBeVisual: true });
|
|
4
|
+
function setGlobal(key, value) {
|
|
5
|
+
const g = globalThis;
|
|
6
|
+
if (g[key] !== undefined)
|
|
7
|
+
return;
|
|
8
|
+
try {
|
|
9
|
+
g[key] = value;
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
try {
|
|
13
|
+
Object.defineProperty(globalThis, key, { value, writable: true, configurable: true });
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
/* leave built-in (e.g. Node 22 getter-only navigator) */
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
const w = dom.window;
|
|
21
|
+
setGlobal("window", dom.window);
|
|
22
|
+
setGlobal("document", dom.window.document);
|
|
23
|
+
for (const k of [
|
|
24
|
+
"DOMParser", "XMLSerializer", "Element", "SVGElement", "SVGSVGElement",
|
|
25
|
+
"HTMLElement", "Node", "Text", "CSSStyleSheet", "CustomEvent", "Event",
|
|
26
|
+
"MutationObserver", "navigator", "location", "self", "DOMRect",
|
|
27
|
+
]) {
|
|
28
|
+
setGlobal(k, w[k]);
|
|
29
|
+
}
|
|
30
|
+
for (const k of ["getComputedStyle", "requestAnimationFrame", "cancelAnimationFrame", "matchMedia"]) {
|
|
31
|
+
const v = w[k];
|
|
32
|
+
setGlobal(k, typeof v === "function" ? v.bind(dom.window) : v);
|
|
33
|
+
}
|
|
34
|
+
// jsdom has no SVG geometry; mermaid's renderer calls getBBox while measuring.
|
|
35
|
+
// Approximate from text length — browser canvas is the source of truth.
|
|
36
|
+
try {
|
|
37
|
+
const scope = dom.window;
|
|
38
|
+
const svgProto = scope.SVGElement?.prototype ?? scope.Element?.prototype;
|
|
39
|
+
if (svgProto && typeof svgProto.getBBox !== "function") {
|
|
40
|
+
svgProto.getBBox = function () {
|
|
41
|
+
// ~Excalidraw/Virgil metrics at the converter's default 20px: wider is
|
|
42
|
+
// safer than narrow — underestimates collapse the whole layout.
|
|
43
|
+
const text = (this.textContent ?? "").replace(/\s+/g, " ").trim();
|
|
44
|
+
const width = Math.max(30, text.length * 11);
|
|
45
|
+
const height = 28;
|
|
46
|
+
return { x: 0, y: 0, width, height, top: 0, left: 0, right: width, bottom: height };
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
const textProto = scope.SVGTextContentElement?.prototype;
|
|
50
|
+
if (textProto && typeof textProto.getComputedTextLength !== "function") {
|
|
51
|
+
textProto.getComputedTextLength = function () {
|
|
52
|
+
return Math.max(30, (this.textContent ?? "").length * 11);
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
/* best-effort */
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=dom-shim.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dom-shim.js","sourceRoot":"","sources":["../src/dom-shim.ts"],"names":[],"mappings":"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"}
|
package/dist/guide.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Single source of truth for agent-facing docs (plan §5).
|
|
2
|
+
* Reused by: MCP `initialize` instructions (summary), tool descriptions,
|
|
3
|
+
* `diagram-tool://guide` resource (full), and GUIDE.md generation. */
|
|
4
|
+
export declare const SERVER_INSTRUCTIONS = "Diagram Tool turns Mermaid into an Excalidraw scene with a live localhost UI.\nUse it when the user asks to draw, visualize, diagram, or whiteboard anything.\nWorkflow: 1) get_diagram for current state (edits need it), 2) author the FULL mermaid source yourself, 3) render_diagram to validate+render \u2014 share the returned url. Open the url once; it live-updates on every render.\nStructural changes = new mermaid + render. Never hand-edit scene.elements.\nSupported types: flowchart, sequenceDiagram, erDiagram, classDiagram, stateDiagram-v2.";
|
|
5
|
+
export declare const RENDER_DESCRIPTION = "Validate + render Mermaid into the shared Excalidraw scene (bumps rev, writes .excalidraw.json + .mmd sidecars, live UI updates). You author the mermaid \u2014 the server never calls an LLM.\n\nTYPE CHOICE: processes/decisions/architecture -> flowchart (LR wide, TD tall); interactions over time -> sequenceDiagram; data models -> erDiagram; OOP -> classDiagram; states -> stateDiagram-v2.\n\nFLOWCHART RULES: init line first: %%{init: {\"flowchart\": {\"nodeSpacing\": 60, \"rankSpacing\": 90, \"curve\": \"linear\"}}}%%. SELF-EXPLANATORY node ids (CLI, CTXFILE \u2014 never A/B/C). Declare ALL nodes first, then edges grouped with %% comments + blank lines (NO subgraphs \u2014 the renderer cannot draw them). Edge labels pipe-only: -->|reads|. Shape by role: rhombus {..} for decisions, [...] for everything else. End with palette + class on EVERY node: classDef actor fill:#e3f2fd,stroke:#1e88e5,stroke-width:2px / store fill:#fff3e0,stroke:#fb8c00 / flow fill:#e8f5e9,stroke:#43a047 / ext fill:#f3e5f5,stroke:#8e24aa. Max ~12 nodes. Hub with many edges -> TD. Max 3 edges per node; one edge per node pair (merge labels with \" \u00B7 \").\n\nExample:\n```mermaid\n%%{init: {\"flowchart\": {\"nodeSpacing\": 60, \"rankSpacing\": 90, \"curve\": \"linear\"}}}%%\nflowchart LR\n USER[\"User\"]\n CLI[\"diagram-tool CLI\"]\n CTXFILE[\"diagram-tool.context.json\"]\n USER-->|invokes|CLI\n CLI-->|writes rev|CTXFILE\n classDef actor fill:#e3f2fd,stroke:#1e88e5,stroke-width:2px\n classDef store fill:#fff3e0,stroke:#fb8c00,stroke-width:2px\n classDef flow fill:#e8f5e9,stroke:#43a047,stroke-width:2px\n classDef ext fill:#f3e5f5,stroke:#8e24aa,stroke-width:2px\n class USER actor\n class CLI flow\n class CTXFILE store\n```\n\nLIBRARIES: cloud/architecture/system-design -> consider list_libraries (AWS/GCP/Azure/K8s icons via decorations, max ~6, decorate not replace). Logic flowcharts, sequence/ER/class diagrams -> NO libs, pure mermaid.\nOn parse error the server returns the error verbatim: fix ONLY the syntax and retry with the full source.";
|
|
6
|
+
export declare const GET_DESCRIPTION = "Read the current diagram state {rev, prompt, mermaidSource}. Call first for edits/follow-ups so you preserve node IDs. Returns empty mermaidSource when nothing exists yet \u2014 then just render fresh.";
|
|
7
|
+
export declare const LIST_LIBRARIES_DESCRIPTION = "Search the Excalidraw library catalog (all ~100 MIT libraries from libraries.excalidraw.com). Use for cloud/architecture/network diagrams where vendor icons help. Returns {slug, name, description, itemCount, sampleItems}. Empty query returns the curated top picks. Logic-only flowcharts, sequence/ER/class diagrams -> skip libs entirely (pure mermaid reads better).";
|
|
8
|
+
export declare const LIST_ITEMS_DESCRIPTION = "List items inside one library {index, name, kind} so you can pick exact itemIndex values for render_diagram decorations. Call after list_libraries. Unbundled libraries are fetched on demand and cached \u2014 first call may take a few seconds.";
|
|
9
|
+
export declare const GUIDE = "# Diagram Tool agent guide\n\n## Concepts\n- One context file (default `diagram-tool.context.json`) is the source of truth: `{rev, prompt, mermaidSource, scene}`.\n- Every render bumps `rev`, rewrites sidecars (`.excalidraw.json` for excalidraw.com import, `.mmd` source), and the localhost UI (SSE `GET /api/live` push, refetches on rev change) applies the new rev without reload.\n- UI canvas edits autosave back (`POST /api/scene`, stale rev -> 409). Prefer mermaid edits for structure; canvas for nudges.\n\n## Recipes\n- Create: author full mermaid -> `render_diagram` -> share `url`.\n- Edit: `get_diagram` -> modify source preserving node IDs -> `render_diagram`.\n- Restyle: same as edit (change classDefs/labels only).\n- Import: paste an existing `.mmd` as `mermaidSource` and render.\n\n## Few-shot: flowchart LR\n```mermaid\n%%{init: {\"flowchart\": {\"nodeSpacing\": 60, \"rankSpacing\": 90, \"curve\": \"linear\"}}}%%\nflowchart LR\n USER[\"User\"]\n CLI[\"diagram-tool CLI\"]\n CTXFILE[\"diagram-tool.context.json\"]\n WEBUI[\"React Excalidraw UI\"]\n USER-->|invokes|CLI\n CLI-->|writes rev|CTXFILE\n CTXFILE-->|polls|WEBUI\n classDef actor fill:#e3f2fd,stroke:#1e88e5,stroke-width:2px\n classDef store fill:#fff3e0,stroke:#fb8c00,stroke-width:2px\n classDef flow fill:#e8f5e9,stroke:#43a047,stroke-width:2px\n classDef ext fill:#f3e5f5,stroke:#8e24aa,stroke-width:2px\n class USER actor\n class CLI,WEBUI flow\n class CTXFILE store\n```\n\n## Few-shot: sequenceDiagram\n```mermaid\nsequenceDiagram\n participant C as Client\n participant S as Server\n C->>S: GET /api/context\n activate S\n S-->>C: 200 context\n deactivate S\n```\n\n## Libraries: when icons vs no icons\n- Cloud/architecture/system-design -> `list_libraries` (aws/gcp/azure/kubernetes), pick <=6 icons, pass as `decorations`. Icons decorate labeled boxes; never drop labels.\n- Network topologies -> `network-topology-icons`.\n- Flowcharts of logic, sequence/ER/class/state diagrams -> NO libraries.\n- Node icon classes (`class USER actor,icon_user`) also work with the 10 bundled slugs: icon_user, icon_users, icon_home, icon_lock, icon_search, icon_chart, icon_email, icon_calendar, icon_location, icon_payment.\n\n## Troubleshooting\n| Symptom | Fix |\n|---|---|\n| Mermaid parse error (returned verbatim) | Fix syntax only, resend full source |\n| Converter: no drawable elements / subgraph | Flatten subgraphs into plain nodes + edges |\n| 409 rev conflict (UI edited meanwhile) | `get_diagram`, rebase, render again |\n| Port 3000 taken | Server falls back to a free port; use returned `url` |\n| Viewer bundle missing | Run the package build once (`node src/viewer/build.mjs`) |\n| Library item index out of range | Error lists valid range; `list_library_items` to repick |\n| Offline + uncached library | Connect once (fetch+cache) or stick to the 6 bundled libs |\n";
|