@documonster/mcp 0.10.0 → 0.11.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 +170 -51
- package/dist/capabilities.d.ts.map +1 -1
- package/dist/capabilities.js +28 -0
- package/dist/capabilities.js.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +10 -2
- package/dist/config.js.map +1 -1
- package/dist/tools/diagram-inspect.d.ts +20 -0
- package/dist/tools/diagram-inspect.d.ts.map +1 -0
- package/dist/tools/diagram-inspect.js +91 -0
- package/dist/tools/diagram-inspect.js.map +1 -0
- package/dist/tools/diagram-markdown.d.ts +45 -0
- package/dist/tools/diagram-markdown.d.ts.map +1 -0
- package/dist/tools/diagram-markdown.js +127 -0
- package/dist/tools/diagram-markdown.js.map +1 -0
- package/dist/tools/diagram-render.d.ts +14 -0
- package/dist/tools/diagram-render.d.ts.map +1 -0
- package/dist/tools/diagram-render.js +117 -0
- package/dist/tools/diagram-render.js.map +1 -0
- package/dist/tools/diagram.d.ts +217 -0
- package/dist/tools/diagram.d.ts.map +1 -0
- package/dist/tools/diagram.js +760 -0
- package/dist/tools/diagram.js.map +1 -0
- package/dist/tools/doc-convert.d.ts.map +1 -1
- package/dist/tools/doc-convert.js +26 -4
- package/dist/tools/doc-convert.js.map +1 -1
- package/dist/tools/doc-read.d.ts.map +1 -1
- package/dist/tools/doc-read.js +32 -4
- package/dist/tools/doc-read.js.map +1 -1
- package/dist/tools/doc-write.d.ts.map +1 -1
- package/dist/tools/doc-write.js +21 -3
- package/dist/tools/doc-write.js.map +1 -1
- package/dist/tools/document.d.ts +1 -1
- package/dist/tools/document.d.ts.map +1 -1
- package/dist/tools/document.js +13 -1
- package/dist/tools/document.js.map +1 -1
- package/dist/tools/help.d.ts +263 -15
- package/dist/tools/help.d.ts.map +1 -1
- package/dist/tools/help.js +263 -15
- package/dist/tools/help.js.map +1 -1
- package/dist/tools/image.d.ts +147 -0
- package/dist/tools/image.d.ts.map +1 -0
- package/dist/tools/image.js +749 -0
- package/dist/tools/image.js.map +1 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +4 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/inspect.d.ts.map +1 -1
- package/dist/tools/inspect.js +98 -6
- package/dist/tools/inspect.js.map +1 -1
- package/dist/tools/pdf-edit.d.ts +13 -6
- package/dist/tools/pdf-edit.d.ts.map +1 -1
- package/dist/tools/pdf-edit.js +93 -8
- package/dist/tools/pdf-edit.js.map +1 -1
- package/dist/tools/sheet-edit.d.ts.map +1 -1
- package/dist/tools/sheet-edit.js +37 -2
- package/dist/tools/sheet-edit.js.map +1 -1
- package/dist/tools/sheet-image.d.ts +58 -0
- package/dist/tools/sheet-image.d.ts.map +1 -0
- package/dist/tools/sheet-image.js +156 -0
- package/dist/tools/sheet-image.js.map +1 -0
- package/dist/tools/sheet-read.d.ts.map +1 -1
- package/dist/tools/sheet-read.js +18 -1
- package/dist/tools/sheet-read.js.map +1 -1
- package/dist/tools/sheet-write.d.ts.map +1 -1
- package/dist/tools/sheet-write.js +41 -4
- package/dist/tools/sheet-write.js.map +1 -1
- package/dist/tools/template.d.ts +19 -0
- package/dist/tools/template.d.ts.map +1 -1
- package/dist/tools/template.js +436 -11
- package/dist/tools/template.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mermaid fences inside Markdown, for `doc_write` and `doc_convert`.
|
|
3
|
+
*
|
|
4
|
+
* A ` ```mermaid ` fence carried into a Word document as monospace text is
|
|
5
|
+
* useless — the whole point of the fence is that it is a picture. So each one is
|
|
6
|
+
* rendered to a PNG and spliced in as an inline image before the Markdown reaches
|
|
7
|
+
* the converter.
|
|
8
|
+
*
|
|
9
|
+
* The seam is `markdownToDocx`'s `resolveImage` callback: the fence is rewritten
|
|
10
|
+
* to `` and the callback answers that one URL scheme
|
|
11
|
+
* and nothing else. Rewriting to a *file* path instead would need a writable
|
|
12
|
+
* scratch directory and would leak the diagrams as loose files beside the
|
|
13
|
+
* document; going through the callback keeps them in memory and inside the
|
|
14
|
+
* package.
|
|
15
|
+
*
|
|
16
|
+
* The width cap is not cosmetic. A flowchart is routinely wider than a page's text
|
|
17
|
+
* column, and Word does not shrink an oversized inline image — it runs off the
|
|
18
|
+
* edge of the paper. Fitting to the text width is the difference between a
|
|
19
|
+
* document and a broken one.
|
|
20
|
+
*/
|
|
21
|
+
import { toolError } from "../errors.js";
|
|
22
|
+
import { EMU_PER_POINT, buildDrawList, findMermaidFences, parseDiagram, renderDiagram, toRenderOptions } from "./diagram.js";
|
|
23
|
+
import { newImageBudget } from "./image.js";
|
|
24
|
+
/**
|
|
25
|
+
* Widest an embedded diagram may be, in points.
|
|
26
|
+
*
|
|
27
|
+
* US Letter (the Word writer's default page) less one-inch margins is 6.5 inches
|
|
28
|
+
* of text column. A wider image is not clipped by Word, it overflows the page.
|
|
29
|
+
*/
|
|
30
|
+
const MAX_EMBED_WIDTH_POINTS = 468;
|
|
31
|
+
/** Pixels per point for an embedded diagram — 144 DPI, sharp in print and on screen. */
|
|
32
|
+
const EMBED_SCALE = 2;
|
|
33
|
+
/** URL scheme the rewritten fences use. Deliberately not a real one. */
|
|
34
|
+
const DIAGRAM_URL_PREFIX = "documonster-diagram:";
|
|
35
|
+
/** Fences one document may carry, so a pathological input cannot exhaust memory. */
|
|
36
|
+
const MAX_EMBEDDED_DIAGRAMS = 20;
|
|
37
|
+
/** Aggregate rendering budget for one document's fences. */
|
|
38
|
+
const MAX_EMBED_TOTAL_BYTES = 64 * 1024 * 1024;
|
|
39
|
+
const MAX_EMBED_TOTAL_PIXELS = 80_000_000;
|
|
40
|
+
/**
|
|
41
|
+
* Render every mermaid fence in `markdown` and rewrite it as an inline image.
|
|
42
|
+
*
|
|
43
|
+
* A fence that does not parse is left exactly as it was — a code block — and
|
|
44
|
+
* reported. Failing the whole document because one diagram is malformed would
|
|
45
|
+
* throw away the nine paragraphs that were fine, and the note names the line to
|
|
46
|
+
* fix.
|
|
47
|
+
*/
|
|
48
|
+
export async function prepareMarkdownDiagrams(markdown, style = {}) {
|
|
49
|
+
const fences = findMermaidFences(markdown);
|
|
50
|
+
if (fences.length === 0) {
|
|
51
|
+
return { markdown, count: 0, notes: [] };
|
|
52
|
+
}
|
|
53
|
+
if (fences.length > MAX_EMBEDDED_DIAGRAMS) {
|
|
54
|
+
throw toolError.tooLarge(`this document has ${fences.length} mermaid fences, over the ${MAX_EMBEDDED_DIAGRAMS} limit for one call`, "Every diagram is rendered and held in memory until the document is written. Split the document, or pass diagrams: false and render the ones you need with diagram_render.");
|
|
55
|
+
}
|
|
56
|
+
const options = toRenderOptions(style);
|
|
57
|
+
const images = new Map();
|
|
58
|
+
const failures = [];
|
|
59
|
+
// One budget across every fence: ten diagrams each just under the rasteriser's
|
|
60
|
+
// own per-image cap is gigabytes, and each is held until the document is written.
|
|
61
|
+
const budget = newImageBudget();
|
|
62
|
+
let rewritten = markdown;
|
|
63
|
+
// Back to front, so each splice leaves the earlier fences' offsets valid.
|
|
64
|
+
for (const fence of [...fences].reverse()) {
|
|
65
|
+
let image;
|
|
66
|
+
let alt;
|
|
67
|
+
try {
|
|
68
|
+
const diagram = parseDiagram(fence.source);
|
|
69
|
+
const list = buildDrawList(fence.source, options);
|
|
70
|
+
const fit = Math.min(1, MAX_EMBED_WIDTH_POINTS / list.width);
|
|
71
|
+
// Rasterised at the size it will be *displayed*, not at its natural size.
|
|
72
|
+
// A 1034-point flowchart in a 468-point column was previously rendered in
|
|
73
|
+
// full and then merely declared smaller, so most of the pixels — and the CPU
|
|
74
|
+
// and memory that produced them — were discarded by Word.
|
|
75
|
+
const rendered = await renderDiagram(list, "png", { scale: EMBED_SCALE * fit }, options.background);
|
|
76
|
+
spendEmbedBudget(budget, rendered, fence.line);
|
|
77
|
+
alt = diagram.title ?? `${diagram.kind} diagram`;
|
|
78
|
+
image = {
|
|
79
|
+
data: rendered.bytes,
|
|
80
|
+
mediaType: "png",
|
|
81
|
+
width: Math.round(list.width * fit * EMU_PER_POINT),
|
|
82
|
+
height: Math.round(list.height * fit * EMU_PER_POINT)
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
catch (cause) {
|
|
86
|
+
failures.push(`- **diagram at line ${fence.line} left as a code block**: ${cause instanceof Error ? cause.message : String(cause)}`);
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
const url = `${DIAGRAM_URL_PREFIX}${fence.ordinal}`;
|
|
90
|
+
images.set(url, image);
|
|
91
|
+
// A blank line either side: an image reference that lands against a
|
|
92
|
+
// neighbouring line is parsed as part of that paragraph.
|
|
93
|
+
rewritten = `${rewritten.slice(0, fence.start)}\n\n${rewritten.slice(fence.end)}`;
|
|
94
|
+
}
|
|
95
|
+
const notes = images.size === 0
|
|
96
|
+
? failures
|
|
97
|
+
: [
|
|
98
|
+
`- ${images.size} mermaid diagram(s) rendered and embedded as PNG, fitted to the text column`,
|
|
99
|
+
...failures
|
|
100
|
+
];
|
|
101
|
+
return {
|
|
102
|
+
markdown: rewritten,
|
|
103
|
+
count: images.size,
|
|
104
|
+
...(images.size === 0 ? {} : { resolveImage: (url) => images.get(url) }),
|
|
105
|
+
notes
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Charge one rendered diagram against the call's budget.
|
|
110
|
+
*
|
|
111
|
+
* A `too_large` here aborts the whole conversion rather than being collected as a
|
|
112
|
+
* per-fence failure: the limit is about the call, and continuing would keep spending
|
|
113
|
+
* exactly the resource that ran out.
|
|
114
|
+
*/
|
|
115
|
+
function spendEmbedBudget(budget, rendered, line) {
|
|
116
|
+
budget.count += 1;
|
|
117
|
+
budget.bytes += rendered.bytes.length;
|
|
118
|
+
budget.pixels += rendered.width * rendered.height;
|
|
119
|
+
if (budget.bytes > MAX_EMBED_TOTAL_BYTES || budget.pixels > MAX_EMBED_TOTAL_PIXELS) {
|
|
120
|
+
throw toolError.tooLarge(`the diagrams in this document exceed the per-call rendering budget (reached at the fence on line ${line})`, "Split the document, or pass diagrams: false and render the large ones separately with diagram_render.");
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/** `[` and `]` in alt text would close the image reference early. */
|
|
124
|
+
function escapeAlt(text) {
|
|
125
|
+
return text.replace(/[[\]]/g, "");
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=diagram-markdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagram-markdown.js","sourceRoot":"","sources":["../../src/tools/diagram-markdown.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EACL,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,eAAe,EAEhB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,cAAc,EAAoB,MAAM,YAAY,CAAC;AAE9D;;;;;GAKG;AACH,MAAM,sBAAsB,GAAG,GAAG,CAAC;AAEnC,wFAAwF;AACxF,MAAM,WAAW,GAAG,CAAC,CAAC;AAEtB,wEAAwE;AACxE,MAAM,kBAAkB,GAAG,sBAAsB,CAAC;AAElD,oFAAoF;AACpF,MAAM,qBAAqB,GAAG,EAAE,CAAC;AAEjC,4DAA4D;AAC5D,MAAM,qBAAqB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAC/C,MAAM,sBAAsB,GAAG,UAAU,CAAC;AAgB1C;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,QAAgB,EAChB,KAAK,GAAqB,EAAE;IAE5B,MAAM,MAAM,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IAC3C,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;IAC3C,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,GAAG,qBAAqB,EAAE,CAAC;QAC1C,MAAM,SAAS,CAAC,QAAQ,CACtB,qBAAqB,MAAM,CAAC,MAAM,6BAA6B,qBAAqB,qBAAqB,EACzG,2KAA2K,CAC5K,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IACvC,MAAM,MAAM,GAAG,IAAI,GAAG,EAA6B,CAAC;IACpD,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,+EAA+E;IAC/E,kFAAkF;IAClF,MAAM,MAAM,GAAG,cAAc,EAAE,CAAC;IAChC,IAAI,SAAS,GAAG,QAAQ,CAAC;IAEzB,0EAA0E;IAC1E,KAAK,MAAM,KAAK,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;QAC1C,IAAI,KAAwB,CAAC;QAC7B,IAAI,GAAW,CAAC;QAChB,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAC3C,MAAM,IAAI,GAAG,aAAa,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAClD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,sBAAsB,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;YAC7D,0EAA0E;YAC1E,0EAA0E;YAC1E,6EAA6E;YAC7E,0DAA0D;YAC1D,MAAM,QAAQ,GAAG,MAAM,aAAa,CAClC,IAAI,EACJ,KAAK,EACL,EAAE,KAAK,EAAE,WAAW,GAAG,GAAG,EAAE,EAC5B,OAAO,CAAC,UAAU,CACnB,CAAC;YACF,gBAAgB,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YAC/C,GAAG,GAAG,OAAO,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,UAAU,CAAC;YACjD,KAAK,GAAG;gBACN,IAAI,EAAE,QAAQ,CAAC,KAAK;gBACpB,SAAS,EAAE,KAAK;gBAChB,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,GAAG,GAAG,aAAa,CAAC;gBACnD,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,GAAG,GAAG,aAAa,CAAC;aACtD,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,QAAQ,CAAC,IAAI,CACX,uBAAuB,KAAK,CAAC,IAAI,4BAA4B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CACtH,CAAC;YACF,SAAS;QACX,CAAC;QAED,MAAM,GAAG,GAAG,GAAG,kBAAkB,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;QACpD,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACvB,oEAAoE;QACpE,yDAAyD;QACzD,SAAS,GAAG,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,GAAG,CAAC,KAAK,GAAG,MAAM,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;IAChH,CAAC;IAED,MAAM,KAAK,GACT,MAAM,CAAC,IAAI,KAAK,CAAC;QACf,CAAC,CAAC,QAAQ;QACV,CAAC,CAAC;YACE,KAAK,MAAM,CAAC,IAAI,6EAA6E;YAC7F,GAAG,QAAQ;SACZ,CAAC;IAER,OAAO;QACL,QAAQ,EAAE,SAAS;QACnB,KAAK,EAAE,MAAM,CAAC,IAAI;QAClB,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;QAChF,KAAK;KACN,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,SAAS,gBAAgB,CACvB,MAAmB,EACnB,QAAyF,EACzF,IAAY;IAEZ,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC;IAClB,MAAM,CAAC,KAAK,IAAI,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC;IACtC,MAAM,CAAC,MAAM,IAAI,QAAQ,CAAC,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC;IAClD,IAAI,MAAM,CAAC,KAAK,GAAG,qBAAqB,IAAI,MAAM,CAAC,MAAM,GAAG,sBAAsB,EAAE,CAAC;QACnF,MAAM,SAAS,CAAC,QAAQ,CACtB,oGAAoG,IAAI,GAAG,EAC3G,uGAAuG,CACxG,CAAC;IACJ,CAAC;AACH,CAAC;AAED,qEAAqE;AACrE,SAAS,SAAS,CAAC,IAAY;IAC7B,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;AACpC,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `diagram_render` — draw a Mermaid diagram as SVG, PNG or PDF.
|
|
3
|
+
*
|
|
4
|
+
* The model cannot see the file it just produced, so the result reports what the
|
|
5
|
+
* *parser* made of the source alongside the byte count. "Wrote 14 KB" is not
|
|
6
|
+
* evidence that the diagram says what was meant; "3 nodes, 3 edges, A→B→C" is.
|
|
7
|
+
*
|
|
8
|
+
* One display list, three backends: the diagram is converted once and SVG, PNG and
|
|
9
|
+
* PDF are three readings of that one list. That is the drawing engine's central
|
|
10
|
+
* claim, and this tool is a consumer of the published API exercising it from
|
|
11
|
+
* outside the library.
|
|
12
|
+
*/
|
|
13
|
+
export declare const diagramRenderTool: import("./types.js").AnyToolDefinition;
|
|
14
|
+
//# sourceMappingURL=diagram-render.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagram-render.d.ts","sourceRoot":"","sources":["../../src/tools/diagram-render.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAoBH,eAAO,MAAM,iBAAiB,wCAwH5B,CAAC"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `diagram_render` — draw a Mermaid diagram as SVG, PNG or PDF.
|
|
3
|
+
*
|
|
4
|
+
* The model cannot see the file it just produced, so the result reports what the
|
|
5
|
+
* *parser* made of the source alongside the byte count. "Wrote 14 KB" is not
|
|
6
|
+
* evidence that the diagram says what was meant; "3 nodes, 3 edges, A→B→C" is.
|
|
7
|
+
*
|
|
8
|
+
* One display list, three backends: the diagram is converted once and SVG, PNG and
|
|
9
|
+
* PDF are three readings of that one list. That is the drawing engine's central
|
|
10
|
+
* claim, and this tool is a consumer of the published API exercising it from
|
|
11
|
+
* outside the library.
|
|
12
|
+
*/
|
|
13
|
+
import { z } from "zod";
|
|
14
|
+
import { toolError } from "../errors.js";
|
|
15
|
+
import { assertWritable, outputDisplay, resolveOutputPath } from "../sandbox.js";
|
|
16
|
+
import { buildDrawList, describeDiagram, diagramStyleShape, parseDiagram, renderDiagram, requireDiagramFormat, resolveDiagramSource, toRenderOptions } from "./diagram.js";
|
|
17
|
+
import { writeBytesWithPolicy } from "./fs-helpers.js";
|
|
18
|
+
import { formatBytes, textResult } from "./result.js";
|
|
19
|
+
import { defineTool } from "./types.js";
|
|
20
|
+
export const diagramRenderTool = defineTool({
|
|
21
|
+
name: "diagram_render",
|
|
22
|
+
group: "diagram",
|
|
23
|
+
title: "Render a Mermaid diagram",
|
|
24
|
+
description: "Draw a Mermaid diagram as .svg, .png or .pdf. Takes the diagram text in `source`, or reads it from a .mmd file or a ```mermaid fence in a .md file via `from`. Supports flowchart, sequenceDiagram, classDiagram, stateDiagram, erDiagram, gantt, gitGraph, mindmap, timeline, journey, kanban, quadrantChart, xychart, radar, sankey, packet, block, pie, C4, requirementDiagram and architecture. The result reports the parsed structure, which is the only way to verify the picture is right.",
|
|
25
|
+
inputSchema: {
|
|
26
|
+
source: z
|
|
27
|
+
.string()
|
|
28
|
+
.optional()
|
|
29
|
+
.describe("Mermaid diagram text. Use this or `from`, not both. A ```mermaid wrapper is stripped for you."),
|
|
30
|
+
from: z
|
|
31
|
+
.string()
|
|
32
|
+
.optional()
|
|
33
|
+
.describe("Read the diagram from a file instead: a .mmd/.mermaid file, or a .md file containing ```mermaid fences."),
|
|
34
|
+
index: z
|
|
35
|
+
.number()
|
|
36
|
+
.int()
|
|
37
|
+
.positive()
|
|
38
|
+
.optional()
|
|
39
|
+
.describe("Which ```mermaid fence to use when `from` is a Markdown file with several. 1-based, defaults to 1."),
|
|
40
|
+
to: z
|
|
41
|
+
.string()
|
|
42
|
+
.min(1)
|
|
43
|
+
.describe("Destination path below --output-root. The extension picks the format: .svg, .png or .pdf. Returned as @output/<path>."),
|
|
44
|
+
width: z
|
|
45
|
+
.number()
|
|
46
|
+
.positive()
|
|
47
|
+
.max(20_000)
|
|
48
|
+
.optional()
|
|
49
|
+
.describe("Output width in points. Omit to use the diagram's natural size; the drawing is fitted into the box uniformly, never stretched."),
|
|
50
|
+
height: z.number().positive().max(20_000).optional().describe("Output height in points."),
|
|
51
|
+
scale: z
|
|
52
|
+
.number()
|
|
53
|
+
.min(0.5)
|
|
54
|
+
.max(8)
|
|
55
|
+
.optional()
|
|
56
|
+
.describe("PNG only — rejected for .svg/.pdf, which have no pixels. Pixels per point, so the file is width × scale pixels wide. Defaults to 2 (144 DPI)."),
|
|
57
|
+
...diagramStyleShape,
|
|
58
|
+
overwrite: z
|
|
59
|
+
.boolean()
|
|
60
|
+
.optional()
|
|
61
|
+
.describe("Replace the destination if it exists. Defaults to false.")
|
|
62
|
+
},
|
|
63
|
+
annotations: {
|
|
64
|
+
readOnlyHint: false,
|
|
65
|
+
destructiveHint: false,
|
|
66
|
+
idempotentHint: true,
|
|
67
|
+
openWorldHint: false
|
|
68
|
+
},
|
|
69
|
+
mutates: true,
|
|
70
|
+
handler: async (args, context) => {
|
|
71
|
+
const { config } = context;
|
|
72
|
+
assertWritable(config);
|
|
73
|
+
const format = requireDiagramFormat(args.to, "to");
|
|
74
|
+
if (args.scale !== undefined && format !== "png") {
|
|
75
|
+
// Accepting it and ignoring it is the problem: a caller who set `scale: 4`
|
|
76
|
+
// for a PDF got the same file as `scale: 1` and no indication why. SVG and
|
|
77
|
+
// PDF are resolution-independent, so the knob has no meaning there.
|
|
78
|
+
throw toolError.invalidInput(`\`scale\` applies to PNG output only, not ${format}`, `${format.toUpperCase()} is resolution-independent — it has no pixels to scale. Use \`width\`/\`height\` to change its size, or write a .png if you want a specific pixel count.`);
|
|
79
|
+
}
|
|
80
|
+
const target = await resolveOutputPath(config, args.to);
|
|
81
|
+
const resolved = await resolveDiagramSource(config, args);
|
|
82
|
+
// Parsed separately from the draw list so the structural read-back reports the
|
|
83
|
+
// same tree that was drawn, without drawing it twice.
|
|
84
|
+
const diagram = parseDiagram(resolved.source);
|
|
85
|
+
const style = toRenderOptions(args);
|
|
86
|
+
const list = buildDrawList(resolved.source, style);
|
|
87
|
+
const rendered = await renderDiagram(list, format, {
|
|
88
|
+
...(args.width === undefined ? {} : { width: args.width }),
|
|
89
|
+
...(args.height === undefined ? {} : { height: args.height }),
|
|
90
|
+
...(args.scale === undefined ? {} : { scale: args.scale })
|
|
91
|
+
}, style.background);
|
|
92
|
+
await writeBytesWithPolicy(target, args.overwrite === true, rendered.bytes);
|
|
93
|
+
const unit = format === "png" ? "px" : "pt";
|
|
94
|
+
return textResult(config, [
|
|
95
|
+
`Rendered **${outputDisplay(args.to)}** (${format}, ${formatBytes(rendered.bytes.byteLength)}, ${round(rendered.width)}×${round(rendered.height)} ${unit}).`,
|
|
96
|
+
// Only when it came from a file; an inline source has nothing to name.
|
|
97
|
+
...(resolved.origin === "inline"
|
|
98
|
+
? []
|
|
99
|
+
: [
|
|
100
|
+
`- source: ${resolved.origin}${resolved.selected === undefined ? "" : ` (mermaid fence ${resolved.selected} of ${resolved.fences.length})`}`
|
|
101
|
+
]),
|
|
102
|
+
"",
|
|
103
|
+
"## What was drawn",
|
|
104
|
+
"",
|
|
105
|
+
...describeDiagram(diagram),
|
|
106
|
+
"",
|
|
107
|
+
"Check that list against what you intended. The parser implements a subset of",
|
|
108
|
+
"Mermaid and a statement it does not recognise is **dropped silently** — a missing",
|
|
109
|
+
"node or edge here is the only sign, since nothing about the file itself looks wrong."
|
|
110
|
+
].join("\n"));
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
/** One decimal place: a diagram's natural size is rarely a whole number. */
|
|
114
|
+
function round(value) {
|
|
115
|
+
return Math.round(value * 10) / 10;
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=diagram-render.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagram-render.js","sourceRoot":"","sources":["../../src/tools/diagram-render.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mermaid diagram helpers shared by `diagram_render`, `diagram_inspect` and the
|
|
3
|
+
* Markdown fence rendering in `doc_write` / `doc_convert`.
|
|
4
|
+
*
|
|
5
|
+
* Three things live here that no tool should re-derive:
|
|
6
|
+
*
|
|
7
|
+
* 1. **Where the source comes from.** A model supplies a diagram inline, or names
|
|
8
|
+
* a `.mmd` file, or names a Markdown file with several ` ```mermaid ` fences in
|
|
9
|
+
* it. All three resolve to the same thing, and fence positions are needed again
|
|
10
|
+
* later to splice rendered images back into the Markdown.
|
|
11
|
+
* 2. **What "render" means per format.** The diagram is converted to a display
|
|
12
|
+
* list *once*; SVG, PNG and PDF are three readings of that one list. Doing it
|
|
13
|
+
* any other way is how three backends come to disagree about one picture.
|
|
14
|
+
* 3. **What the parser actually saw.** A model cannot look at the output, so the
|
|
15
|
+
* only way it can verify a diagram is a structural read-back. That is
|
|
16
|
+
* {@link describeDiagram}, and it is the reason `diagram_inspect` exists.
|
|
17
|
+
*
|
|
18
|
+
* Theme presets are deliberately *this package's* own, not a claim of parity with
|
|
19
|
+
* Mermaid's named themes: only `default` is token-for-token Mermaid (the library
|
|
20
|
+
* reproduces Mermaid's `base` exactly). `themeOverrides` exposes every colour
|
|
21
|
+
* token, so nothing is reachable through the library that is not reachable here.
|
|
22
|
+
*/
|
|
23
|
+
import type { DrawList } from "documonster/draw";
|
|
24
|
+
import type { MermaidDiagram, MermaidRenderOptions, ThemeOptions } from "documonster/mermaid";
|
|
25
|
+
import { z } from "zod";
|
|
26
|
+
import type { ServerConfig } from "../config.js";
|
|
27
|
+
/** Output formats a diagram can be written as. */
|
|
28
|
+
export type DiagramFormat = "svg" | "png" | "pdf";
|
|
29
|
+
/** EMU per PDF point — a display list's unit is a point, as the PDF backend proves. */
|
|
30
|
+
export declare const EMU_PER_POINT = 12700;
|
|
31
|
+
/** Format a diagram output path denotes, or a tool error naming what is possible. */
|
|
32
|
+
export declare function requireDiagramFormat(filePath: string, field: string): DiagramFormat;
|
|
33
|
+
/**
|
|
34
|
+
* Named colour sets, so a model asking for a dark diagram does not have to invent
|
|
35
|
+
* eleven hex values — and cannot get half of them wrong, which produces a diagram
|
|
36
|
+
* with unreadable labels that the model has no way to see.
|
|
37
|
+
*
|
|
38
|
+
* `default` is empty on purpose: the library's own default already reproduces
|
|
39
|
+
* Mermaid's `base` theme token for token, so overriding anything here would move
|
|
40
|
+
* away from it.
|
|
41
|
+
*/
|
|
42
|
+
export type ThemePreset = "default" | "dark" | "neutral";
|
|
43
|
+
export declare const THEME_PRESETS: Readonly<Record<ThemePreset, ThemeOptions>>;
|
|
44
|
+
/**
|
|
45
|
+
* The rendering fields both the render tool and the fence renderer accept.
|
|
46
|
+
*
|
|
47
|
+
* Exported as a raw shape so `diagram_render` can spread it into its own schema
|
|
48
|
+
* without the two drifting apart.
|
|
49
|
+
*/
|
|
50
|
+
export declare const diagramStyleShape: {
|
|
51
|
+
readonly theme: z.ZodOptional<z.ZodEnum<{
|
|
52
|
+
dark: "dark";
|
|
53
|
+
default: "default";
|
|
54
|
+
neutral: "neutral";
|
|
55
|
+
}>>;
|
|
56
|
+
readonly themeOverrides: z.ZodOptional<z.ZodObject<{
|
|
57
|
+
background: z.ZodOptional<z.ZodString>;
|
|
58
|
+
nodeFill: z.ZodOptional<z.ZodString>;
|
|
59
|
+
nodeStroke: z.ZodOptional<z.ZodString>;
|
|
60
|
+
nodeText: z.ZodOptional<z.ZodString>;
|
|
61
|
+
edge: z.ZodOptional<z.ZodString>;
|
|
62
|
+
edgeText: z.ZodOptional<z.ZodString>;
|
|
63
|
+
edgeLabelBackground: z.ZodOptional<z.ZodString>;
|
|
64
|
+
groupFill: z.ZodOptional<z.ZodString>;
|
|
65
|
+
groupStroke: z.ZodOptional<z.ZodString>;
|
|
66
|
+
title: z.ZodOptional<z.ZodString>;
|
|
67
|
+
paletteText: z.ZodOptional<z.ZodString>;
|
|
68
|
+
palette: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
69
|
+
}, z.core.$strip>>;
|
|
70
|
+
readonly background: z.ZodOptional<z.ZodString>;
|
|
71
|
+
readonly fontSize: z.ZodOptional<z.ZodNumber>;
|
|
72
|
+
readonly fontFamily: z.ZodOptional<z.ZodString>;
|
|
73
|
+
readonly rankGap: z.ZodOptional<z.ZodNumber>;
|
|
74
|
+
readonly nodeGap: z.ZodOptional<z.ZodNumber>;
|
|
75
|
+
readonly maxLabelWidth: z.ZodOptional<z.ZodNumber>;
|
|
76
|
+
readonly padding: z.ZodOptional<z.ZodNumber>;
|
|
77
|
+
};
|
|
78
|
+
/** The parsed form of {@link diagramStyleShape}. */
|
|
79
|
+
export interface DiagramStyleArgs {
|
|
80
|
+
readonly theme?: ThemePreset;
|
|
81
|
+
readonly themeOverrides?: ThemeOptions;
|
|
82
|
+
readonly background?: string;
|
|
83
|
+
readonly fontSize?: number;
|
|
84
|
+
readonly fontFamily?: string;
|
|
85
|
+
readonly rankGap?: number;
|
|
86
|
+
readonly nodeGap?: number;
|
|
87
|
+
readonly maxLabelWidth?: number;
|
|
88
|
+
readonly padding?: number;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Turn tool arguments into library render options.
|
|
92
|
+
*
|
|
93
|
+
* The background is resolved here rather than left to the library because the
|
|
94
|
+
* library's default is `"transparent"` — right for a caller compositing the list
|
|
95
|
+
* onto something else, wrong for a file a human opens.
|
|
96
|
+
*/
|
|
97
|
+
export declare function toRenderOptions(args: DiagramStyleArgs): MermaidRenderOptions & {
|
|
98
|
+
readonly background: string;
|
|
99
|
+
};
|
|
100
|
+
/** One ` ```mermaid ` fence found in a Markdown document. */
|
|
101
|
+
export interface MermaidFence {
|
|
102
|
+
/** 1-based position among the mermaid fences in the document. */
|
|
103
|
+
readonly ordinal: number;
|
|
104
|
+
/** 1-based line the opening fence sits on, for a message a human can act on. */
|
|
105
|
+
readonly line: number;
|
|
106
|
+
/** The diagram source between the fences, without the fence lines. */
|
|
107
|
+
readonly source: string;
|
|
108
|
+
/** Character offset of the opening fence's first character. */
|
|
109
|
+
readonly start: number;
|
|
110
|
+
/** Character offset just past the closing fence's newline. */
|
|
111
|
+
readonly end: number;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Find every mermaid fence in a Markdown document.
|
|
115
|
+
*
|
|
116
|
+
* Scanned line by line rather than with one regular expression because a fence
|
|
117
|
+
* may be opened with backticks or tildes, of any length from three up, and must
|
|
118
|
+
* be closed by at least as many of the same character — a rule a single pattern
|
|
119
|
+
* expresses badly and an unterminated fence at the end of a file breaks outright.
|
|
120
|
+
* An unterminated fence is treated as running to the end of the document, which
|
|
121
|
+
* is what every Markdown renderer does.
|
|
122
|
+
*/
|
|
123
|
+
export declare function findMermaidFences(markdown: string): MermaidFence[];
|
|
124
|
+
/**
|
|
125
|
+
* Strip a fence a model wrapped its own answer in.
|
|
126
|
+
*
|
|
127
|
+
* A model asked for "mermaid source" very often produces a fenced block, because
|
|
128
|
+
* that is how it has seen mermaid written everywhere. Passing that through to the
|
|
129
|
+
* parser fails on the first line with "unsupported diagram type '```mermaid'",
|
|
130
|
+
* which is a confusing report of the model's own formatting habit rather than of
|
|
131
|
+
* anything wrong with the diagram.
|
|
132
|
+
*/
|
|
133
|
+
export declare function unwrapFence(source: string): string;
|
|
134
|
+
/** Where a diagram's text came from, and what else was in the same file. */
|
|
135
|
+
export interface ResolvedSource {
|
|
136
|
+
readonly source: string;
|
|
137
|
+
/** How to name it in a message: `inline`, or the caller's own path. */
|
|
138
|
+
readonly origin: string;
|
|
139
|
+
/** Every mermaid fence in the file, when the file was Markdown. */
|
|
140
|
+
readonly fences: readonly MermaidFence[];
|
|
141
|
+
/** Which fence was selected, 1-based, when there were several. */
|
|
142
|
+
readonly selected?: number;
|
|
143
|
+
}
|
|
144
|
+
export interface SourceArgs {
|
|
145
|
+
readonly source?: string;
|
|
146
|
+
readonly from?: string;
|
|
147
|
+
readonly index?: number;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Resolve the diagram text from `source` or `from`.
|
|
151
|
+
*
|
|
152
|
+
* @throws {McpToolError} `invalid_input` when neither or both were given, or when
|
|
153
|
+
* a Markdown file holds no mermaid fence, or `index` names one that is not there.
|
|
154
|
+
*/
|
|
155
|
+
export declare function resolveDiagramSource(config: ServerConfig, args: SourceArgs): Promise<ResolvedSource>;
|
|
156
|
+
/** Parse mermaid text, reporting a syntax error as a model-facing tool error. */
|
|
157
|
+
export declare function parseDiagram(source: string): MermaidDiagram;
|
|
158
|
+
/** Build the display list, mapping a syntax error the same way. */
|
|
159
|
+
export declare function buildDrawList(source: string, options: MermaidRenderOptions): DrawList;
|
|
160
|
+
export interface RenderSizeArgs {
|
|
161
|
+
/**
|
|
162
|
+
* Output width in the diagram's own unit (a point). The drawing is fitted into
|
|
163
|
+
* it uniformly. Defaults to the diagram's natural width.
|
|
164
|
+
*/
|
|
165
|
+
readonly width?: number;
|
|
166
|
+
readonly height?: number;
|
|
167
|
+
/** PNG only: pixels per point, so the file is `width * scale` pixels wide. */
|
|
168
|
+
readonly scale?: number;
|
|
169
|
+
}
|
|
170
|
+
export interface RenderedDiagram {
|
|
171
|
+
readonly bytes: Uint8Array;
|
|
172
|
+
/** Size of the artefact, in the format's own unit. */
|
|
173
|
+
readonly width: number;
|
|
174
|
+
readonly height: number;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Render one display list to one format.
|
|
178
|
+
*
|
|
179
|
+
* The list is built once by the caller and read here — which is the whole claim
|
|
180
|
+
* the drawing engine makes, tested from outside the library by this very function.
|
|
181
|
+
*/
|
|
182
|
+
export declare function renderDiagram(list: DrawList, format: DiagramFormat, size: RenderSizeArgs, background: string): Promise<RenderedDiagram>;
|
|
183
|
+
/** Every diagram type the parser accepts, for help text and error hints. */
|
|
184
|
+
export declare const SUPPORTED_DIAGRAM_KEYWORDS: readonly string[];
|
|
185
|
+
/**
|
|
186
|
+
* Describe what the parser made of a diagram, in full.
|
|
187
|
+
*
|
|
188
|
+
* This is the tool surface's answer to a hard problem: the model cannot see the
|
|
189
|
+
* picture, so "it rendered" is not evidence the diagram says what was meant. The
|
|
190
|
+
* parser implements a subset of Mermaid, and the way a subset fails is by
|
|
191
|
+
* *silently omitting* what it did not recognise — a mistyped arrow simply produces
|
|
192
|
+
* one fewer edge. Reporting counts and labels is what lets that be caught.
|
|
193
|
+
*/
|
|
194
|
+
export declare function describeDiagram(diagram: MermaidDiagram): string[];
|
|
195
|
+
/**
|
|
196
|
+
* The same facts on one line, for a report that has no room for a list.
|
|
197
|
+
*
|
|
198
|
+
* Used by `pdf_edit`, where a diagram is one entry in a numbered list of
|
|
199
|
+
* operations and the alternative — saying only "drew a diagram" — would leave the
|
|
200
|
+
* model with no way to check what it drew short of another tool call.
|
|
201
|
+
*/
|
|
202
|
+
export declare function summariseDiagram(diagram: MermaidDiagram): string;
|
|
203
|
+
/**
|
|
204
|
+
* List the mermaid fences in a Markdown document, for a reader that will not
|
|
205
|
+
* render them.
|
|
206
|
+
*
|
|
207
|
+
* `doc_inspect` and `doc_read` both hand back Markdown as text, so a fence
|
|
208
|
+
* arrives at the model as source code. Without this note the model's next move is
|
|
209
|
+
* to copy that source into its own output and pass it back as `source` — spending
|
|
210
|
+
* tokens on data the server already has, which is the one habit this server's
|
|
211
|
+
* whole design tries to break. Naming the index makes `{ from, index }` the
|
|
212
|
+
* obvious call instead.
|
|
213
|
+
*/
|
|
214
|
+
export declare function describeFences(markdown: string, options?: {
|
|
215
|
+
readonly sampled?: boolean;
|
|
216
|
+
}): string[];
|
|
217
|
+
//# sourceMappingURL=diagram.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagram.d.ts","sourceRoot":"","sources":["../../src/tools/diagram.ts"],"names":[],"mappings":"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"}
|