From 14f29af9390c9a6e034a8193cbafafa743d53ae7 Mon Sep 17 00:00:00 2001 From: "dayuan.jiang" Date: Mon, 12 Oct 2026 08:27:28 +0900 Subject: [PATCH] refactor(prompt): share the Styles paragraphs with the MCP drawing guide lib/system-prompts.ts takes the three Styles paragraphs from styleRules() in packages/mcp-server/src/xml-examples.ts; the generated prompt is byte-identical. packages/mcp-server/tests/load-diagram.test.ts drops its own DOM polyfill setup now that vitest installs it once. --- lib/system-prompts.ts | 13 +++++++++---- packages/mcp-server/tests/load-diagram.test.ts | 8 +------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/lib/system-prompts.ts b/lib/system-prompts.ts index aae7c6e6..f355ddfd 100644 --- a/lib/system-prompts.ts +++ b/lib/system-prompts.ts @@ -2,7 +2,10 @@ * System prompt for the chat route */ -import { STYLE_CLASS_EXAMPLE } from "@/packages/mcp-server/src/xml-examples.ts" +import { + STYLE_CLASS_EXAMPLE, + styleRules, +} from "@/packages/mcp-server/src/xml-examples.ts" const DEFAULT_SYSTEM_PROMPT = ` You are an expert diagram creation assistant specializing in draw.io XML generation. @@ -177,14 +180,16 @@ When creating edges/connectors, you MUST follow these rules to avoid overlapping ` // Style instructions - only included when minimalStyle is false +// The three Styles paragraphs are shared with the MCP drawing guide +const rules = styleRules("display_diagram", "the app") const STYLE_INSTRUCTIONS = ` ## Styles -Define each style used by several cells ONCE, as a named style before the cells, and use the name in the cells like a CSS class. A cell's style can combine a shape token, a name and overrides; later pairs win. Name only styles that two or more cells share; a style used by one cell stays inline. Names must not be draw.io's own style names: shapes such as text, ellipse, rhombus, swimlane, label, image, and colors such as blue, green, red, gray, yellow, orange, purple, pink. A definition applies to the call it is in: each display_diagram call defines the names it uses. The app expands the names, so the saved file is standard draw.io XML. +${rules.namedStyles} \`\`\`xml ${STYLE_CLASS_EXAMPLE} \`\`\` -- NEVER write html=1 or whiteSpace=wrap: the app adds html=1 to every cell and whiteSpace=wrap to shapes. Labels are HTML: use <br> for a line break and <b> for bold, never \\n; a literal < or > in a label is written &lt; or &gt;. -- Do NOT repeat what draw.io already uses. For a plain shape: rounded=0, align=center, verticalAlign=middle, fontSize=12, strokeWidth=1, fillColor=#ffffff, strokeColor=#000000, fontColor=#000000. For an edge: endArrow=classic, strokeColor=#000000. Writing one of them is right only when it overrides what a name or the shape sets: an edge is rounded by default, so rounded=0 on an edge is a real setting, and a text cell is left/top aligned by default, so there align=center or verticalAlign=middle are real settings. +- ${rules.noHtml} +- ${rules.noDefaults} - Keys: shapes rounded=1, fillColor=#hex, strokeColor=#hex; edges endArrow=block/open/none, startArrow=classic, curved=1, dashed=1, edgeStyle=orthogonalEdgeStyle; text fontSize=14, fontStyle=1 (bold), align=center/right. ` diff --git a/packages/mcp-server/tests/load-diagram.test.ts b/packages/mcp-server/tests/load-diagram.test.ts index 065bc555..1749ff8f 100644 --- a/packages/mcp-server/tests/load-diagram.test.ts +++ b/packages/mcp-server/tests/load-diagram.test.ts @@ -9,13 +9,7 @@ import { deflateRawSync } from "node:zlib" import { DOMParser } from "linkedom" -import { beforeAll, describe, expect, it } from "vitest" -import { installDomPolyfill } from "../src/dom.ts" - -// Install the DOM polyfills exactly as index.ts does at runtime. -beforeAll(() => { - installDomPolyfill() -}) +import { describe, expect, it } from "vitest" import { decompressPageContent,