@markdy/mcp-server 1.1.7 → 1.3.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/dist/index.js +229 -39
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -411,6 +411,7 @@ var CONTROL_KEYS = [
|
|
|
411
411
|
"resetView",
|
|
412
412
|
"fullscreen",
|
|
413
413
|
"svg",
|
|
414
|
+
"gif",
|
|
414
415
|
"share",
|
|
415
416
|
"code",
|
|
416
417
|
"theme"
|
|
@@ -462,6 +463,11 @@ var CONTROLS = {
|
|
|
462
463
|
svg: { group: "controls", key: "svg", type: "boolean" },
|
|
463
464
|
exportSvg: { group: "controls", key: "svg", type: "boolean" },
|
|
464
465
|
export_svg: { group: "controls", key: "svg", type: "boolean" },
|
|
466
|
+
gif: { group: "controls", key: "gif", type: "boolean" },
|
|
467
|
+
exportGif: { group: "controls", key: "gif", type: "boolean" },
|
|
468
|
+
export_gif: { group: "controls", key: "gif", type: "boolean" },
|
|
469
|
+
gifButton: { group: "controls", key: "gif", type: "boolean" },
|
|
470
|
+
gif_button: { group: "controls", key: "gif", type: "boolean" },
|
|
465
471
|
share: { group: "controls", key: "share", type: "boolean" },
|
|
466
472
|
shareLink: { group: "controls", key: "share", type: "boolean" },
|
|
467
473
|
share_link: { group: "controls", key: "share", type: "boolean" },
|
|
@@ -542,6 +548,11 @@ var FLAT = {
|
|
|
542
548
|
fullscreen_button: CONTROLS.fullscreen_button,
|
|
543
549
|
exportSvg: CONTROLS.exportSvg,
|
|
544
550
|
export_svg: CONTROLS.export_svg,
|
|
551
|
+
gif: CONTROLS.gif,
|
|
552
|
+
exportGif: CONTROLS.exportGif,
|
|
553
|
+
export_gif: CONTROLS.export_gif,
|
|
554
|
+
gifButton: CONTROLS.gifButton,
|
|
555
|
+
gif_button: CONTROLS.gif_button,
|
|
545
556
|
shareLink: CONTROLS.shareLink,
|
|
546
557
|
share_link: CONTROLS.share_link,
|
|
547
558
|
code: CONTROLS.code,
|
|
@@ -657,7 +668,8 @@ var EDGE_OPERATORS = {
|
|
|
657
668
|
"->": "request",
|
|
658
669
|
"<-": "response",
|
|
659
670
|
"~>": "event",
|
|
660
|
-
"--": "dependency"
|
|
671
|
+
"--": "dependency",
|
|
672
|
+
"..>": "dependency"
|
|
661
673
|
};
|
|
662
674
|
var RESERVED_SELECTORS = /* @__PURE__ */ new Set(["$title", "$nodes", "$edges"]);
|
|
663
675
|
var CUE_ALIASES = {
|
|
@@ -905,7 +917,7 @@ var THEMES = {
|
|
|
905
917
|
dependency: "#818cf8"
|
|
906
918
|
},
|
|
907
919
|
fonts: {
|
|
908
|
-
title: "
|
|
920
|
+
title: "ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Inter, sans-serif",
|
|
909
921
|
nodeName: "ui-sans-serif, system-ui, sans-serif",
|
|
910
922
|
mono: "ui-monospace, SFMono-Regular, Menlo, monospace"
|
|
911
923
|
},
|
|
@@ -1002,6 +1014,116 @@ var THEMES = {
|
|
|
1002
1014
|
},
|
|
1003
1015
|
radiusMd: 4,
|
|
1004
1016
|
spacing: { xs: 4, sm: 8, md: 16, lg: 24, xl: 40 }
|
|
1017
|
+
},
|
|
1018
|
+
ink: {
|
|
1019
|
+
name: "ink",
|
|
1020
|
+
canvas: "#f8fafd",
|
|
1021
|
+
surface: "#ffffff",
|
|
1022
|
+
surfaceRaised: "#eff6ff",
|
|
1023
|
+
border: "#1d4ed8",
|
|
1024
|
+
text: "#0f172a",
|
|
1025
|
+
textMuted: "#3b629b",
|
|
1026
|
+
paper: "#f8fafd",
|
|
1027
|
+
ink: "#1e40af",
|
|
1028
|
+
muted: "#4776b2",
|
|
1029
|
+
rule: "rgba(29, 78, 216, 0.14)",
|
|
1030
|
+
soft: "#60a5fa",
|
|
1031
|
+
link: "#2563eb",
|
|
1032
|
+
gridMinor: "rgba(37, 99, 235, 0.05)",
|
|
1033
|
+
gridMajor: "rgba(37, 99, 235, 0.10)",
|
|
1034
|
+
vignette: "rgba(219, 234, 254, 0.45)",
|
|
1035
|
+
accent: "#1d4ed8",
|
|
1036
|
+
accentTint: "rgba(29, 78, 216, 0.08)",
|
|
1037
|
+
nodeSurface: "#ffffff",
|
|
1038
|
+
nodeSurfaceRaised: "#f4f8ff",
|
|
1039
|
+
hairline: "rgba(29, 78, 216, 0.20)",
|
|
1040
|
+
shadow: "rgba(15, 35, 90, 0.09)",
|
|
1041
|
+
labelPlate: "#ffffff",
|
|
1042
|
+
flatCards: false,
|
|
1043
|
+
roles: {
|
|
1044
|
+
...ROLE_COLORS,
|
|
1045
|
+
compute: "#1d4ed8",
|
|
1046
|
+
code: "#2563eb",
|
|
1047
|
+
client: "#0284c7",
|
|
1048
|
+
data: "#0369a1",
|
|
1049
|
+
messaging: "#4338ca",
|
|
1050
|
+
network: "#0284c7",
|
|
1051
|
+
security: "#1e3a8a",
|
|
1052
|
+
platform: "#3b82f6",
|
|
1053
|
+
observability: "#0891b2",
|
|
1054
|
+
delivery: "#4f46e5",
|
|
1055
|
+
flow: "#2563eb",
|
|
1056
|
+
distributed: "#475569"
|
|
1057
|
+
},
|
|
1058
|
+
edges: {
|
|
1059
|
+
request: "#1d4ed8",
|
|
1060
|
+
response: "#3b82f6",
|
|
1061
|
+
event: "#0284c7",
|
|
1062
|
+
dependency: "#64748b"
|
|
1063
|
+
},
|
|
1064
|
+
fonts: {
|
|
1065
|
+
title: 'ui-serif, "Charter", "Newsreader", "Georgia", "Songti SC", "Noto Serif", serif',
|
|
1066
|
+
nodeName: 'ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Inter, sans-serif',
|
|
1067
|
+
mono: '"JetBrains Mono", "SF Mono", ui-monospace, Menlo, monospace'
|
|
1068
|
+
},
|
|
1069
|
+
radiusMd: 6,
|
|
1070
|
+
spacing: { xs: 4, sm: 8, md: 16, lg: 24, xl: 40 },
|
|
1071
|
+
series: ["#1d4ed8", "#0284c7", "#4338ca", "#0891b2", "#1e3a8a"]
|
|
1072
|
+
},
|
|
1073
|
+
doodle: {
|
|
1074
|
+
name: "doodle",
|
|
1075
|
+
canvas: "#fffef9",
|
|
1076
|
+
surface: "#ffffff",
|
|
1077
|
+
surfaceRaised: "#fdf8ec",
|
|
1078
|
+
border: "#18181b",
|
|
1079
|
+
text: "#18181b",
|
|
1080
|
+
textMuted: "#52525b",
|
|
1081
|
+
paper: "#fffef9",
|
|
1082
|
+
ink: "#18181b",
|
|
1083
|
+
muted: "#52525b",
|
|
1084
|
+
rule: "rgba(24, 24, 27, 0.16)",
|
|
1085
|
+
soft: "#71717a",
|
|
1086
|
+
link: "#f43f5e",
|
|
1087
|
+
gridMinor: "rgba(24, 24, 27, 0.05)",
|
|
1088
|
+
gridMajor: "rgba(24, 24, 27, 0.08)",
|
|
1089
|
+
vignette: "rgba(245, 235, 210, 0.35)",
|
|
1090
|
+
accent: "#f43f5e",
|
|
1091
|
+
accentTint: "rgba(244, 63, 94, 0.12)",
|
|
1092
|
+
nodeSurface: "#ffffff",
|
|
1093
|
+
nodeSurfaceRaised: "#fffdf5",
|
|
1094
|
+
hairline: "rgba(24, 24, 27, 0.25)",
|
|
1095
|
+
shadow: "rgba(24, 24, 27, 0.15)",
|
|
1096
|
+
labelPlate: "#ffffff",
|
|
1097
|
+
flatCards: true,
|
|
1098
|
+
roles: {
|
|
1099
|
+
...ROLE_COLORS,
|
|
1100
|
+
compute: "#2563eb",
|
|
1101
|
+
code: "#2563eb",
|
|
1102
|
+
client: "#f43f5e",
|
|
1103
|
+
data: "#10b981",
|
|
1104
|
+
messaging: "#8b5cf6",
|
|
1105
|
+
network: "#06b6d4",
|
|
1106
|
+
security: "#ef4444",
|
|
1107
|
+
platform: "#f59e0b",
|
|
1108
|
+
observability: "#14b8a6",
|
|
1109
|
+
delivery: "#f59e0b",
|
|
1110
|
+
flow: "#ec4899",
|
|
1111
|
+
distributed: "#71717a"
|
|
1112
|
+
},
|
|
1113
|
+
edges: {
|
|
1114
|
+
request: "#18181b",
|
|
1115
|
+
response: "#71717a",
|
|
1116
|
+
event: "#f43f5e",
|
|
1117
|
+
dependency: "#a1a1aa"
|
|
1118
|
+
},
|
|
1119
|
+
fonts: {
|
|
1120
|
+
title: '"Caveat", "Comic Neue", "Chalkboard SE", "Patrick Hand", "Comic Sans MS", cursive, sans-serif',
|
|
1121
|
+
nodeName: 'ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, Roboto, sans-serif',
|
|
1122
|
+
mono: '"JetBrains Mono", "SF Mono", ui-monospace, Menlo, monospace'
|
|
1123
|
+
},
|
|
1124
|
+
radiusMd: 12,
|
|
1125
|
+
spacing: { xs: 4, sm: 8, md: 16, lg: 24, xl: 40 },
|
|
1126
|
+
series: ["#f43f5e", "#2563eb", "#10b981", "#8b5cf6", "#f59e0b"]
|
|
1005
1127
|
}
|
|
1006
1128
|
};
|
|
1007
1129
|
|
|
@@ -1016,7 +1138,7 @@ var ParseError = class extends Error {
|
|
|
1016
1138
|
this.column = column;
|
|
1017
1139
|
}
|
|
1018
1140
|
};
|
|
1019
|
-
var FLOW_OP_RE = /(
|
|
1141
|
+
var FLOW_OP_RE = /(->|<-|~>|--|\.\.>|<->)/;
|
|
1020
1142
|
function stripComment(line) {
|
|
1021
1143
|
let inString = false;
|
|
1022
1144
|
let escaped = false;
|
|
@@ -1068,7 +1190,7 @@ function parseProps(raw) {
|
|
|
1068
1190
|
i = raw.length - parsed.rest.length;
|
|
1069
1191
|
continue;
|
|
1070
1192
|
}
|
|
1071
|
-
const keyMatch = raw.slice(i).match(/^(
|
|
1193
|
+
const keyMatch = raw.slice(i).match(/^(@?[\w.-]+)=/);
|
|
1072
1194
|
if (!keyMatch) {
|
|
1073
1195
|
i++;
|
|
1074
1196
|
continue;
|
|
@@ -1186,6 +1308,14 @@ function tokenizeFlowChain(line) {
|
|
|
1186
1308
|
current += ch;
|
|
1187
1309
|
continue;
|
|
1188
1310
|
}
|
|
1311
|
+
const op3 = line.slice(i, i + 3);
|
|
1312
|
+
if (op3 === "..>" || op3 === "<->") {
|
|
1313
|
+
if (current.trim()) parts.push(current.trim());
|
|
1314
|
+
parts.push(op3);
|
|
1315
|
+
current = "";
|
|
1316
|
+
i += 2;
|
|
1317
|
+
continue;
|
|
1318
|
+
}
|
|
1189
1319
|
const op = line.slice(i, i + 2);
|
|
1190
1320
|
if (op === "->" || op === "<-" || op === "~>" || op === "--") {
|
|
1191
1321
|
if (current.trim()) parts.push(current.trim());
|
|
@@ -1209,11 +1339,27 @@ function parseFlowChain(line, lineNo) {
|
|
|
1209
1339
|
let from = splitTargetLabel(parts[i++], lineNo).node;
|
|
1210
1340
|
while (i < parts.length) {
|
|
1211
1341
|
const opToken = parts[i++];
|
|
1212
|
-
const op = EDGE_OPERATORS[opToken];
|
|
1213
|
-
if (!op) throw new ParseError(`unknown flow operator '${opToken}'`, lineNo);
|
|
1214
1342
|
if (i >= parts.length) throw new ParseError(`expected target after '${opToken}'`, lineNo);
|
|
1215
1343
|
const { node: to, label } = splitTargetLabel(parts[i++], lineNo);
|
|
1216
1344
|
if (!to) throw new ParseError(`expected target node after '${opToken}'`, lineNo);
|
|
1345
|
+
if (opToken === "<->") {
|
|
1346
|
+
segments.push({
|
|
1347
|
+
from,
|
|
1348
|
+
op: "request",
|
|
1349
|
+
to,
|
|
1350
|
+
label
|
|
1351
|
+
});
|
|
1352
|
+
segments.push({
|
|
1353
|
+
from: to,
|
|
1354
|
+
op: "response",
|
|
1355
|
+
to: from,
|
|
1356
|
+
label
|
|
1357
|
+
});
|
|
1358
|
+
from = to;
|
|
1359
|
+
continue;
|
|
1360
|
+
}
|
|
1361
|
+
const op = EDGE_OPERATORS[opToken];
|
|
1362
|
+
if (!op) throw new ParseError(`unknown flow operator '${opToken}'`, lineNo);
|
|
1217
1363
|
segments.push({
|
|
1218
1364
|
from: op === "response" ? to : from,
|
|
1219
1365
|
op,
|
|
@@ -1564,7 +1710,7 @@ function validateReferences(ast) {
|
|
|
1564
1710
|
}
|
|
1565
1711
|
}
|
|
1566
1712
|
for (const node of Object.values(ast.nodes)) {
|
|
1567
|
-
if (node.style && !ast.styles[node.style]) {
|
|
1713
|
+
if (typeof node.style === "string" && !ast.styles[node.style]) {
|
|
1568
1714
|
pushWarning(ast.diagnostics, seen, node.line, `node '${node.id}' references unknown style '${node.style}'`);
|
|
1569
1715
|
}
|
|
1570
1716
|
}
|
|
@@ -1668,6 +1814,7 @@ function parse(source, opts = {}) {
|
|
|
1668
1814
|
height: 720,
|
|
1669
1815
|
fps: 60,
|
|
1670
1816
|
theme: "paper",
|
|
1817
|
+
explicitTheme: false,
|
|
1671
1818
|
direction: "LR"
|
|
1672
1819
|
};
|
|
1673
1820
|
const styles = {};
|
|
@@ -1766,6 +1913,7 @@ function parse(source, opts = {}) {
|
|
|
1766
1913
|
const str = parseStringToken(rest2);
|
|
1767
1914
|
if (str) {
|
|
1768
1915
|
title = str.value;
|
|
1916
|
+
meta.title = title;
|
|
1769
1917
|
remainder = str.rest;
|
|
1770
1918
|
}
|
|
1771
1919
|
const inlineLayout = remainder.match(/\blayout\s+(LR|RL|TB|BT)\b/i);
|
|
@@ -1788,8 +1936,11 @@ function parse(source, opts = {}) {
|
|
|
1788
1936
|
} else if (k === "fps") {
|
|
1789
1937
|
meta.fps = Number(v);
|
|
1790
1938
|
} else if (k === "duration") meta.duration = Number(v);
|
|
1791
|
-
else if (k === "theme")
|
|
1792
|
-
|
|
1939
|
+
else if (k === "theme") {
|
|
1940
|
+
const val = String(v).toLowerCase();
|
|
1941
|
+
meta.theme = val;
|
|
1942
|
+
meta.explicitTheme = val !== "auto";
|
|
1943
|
+
} else if (k === "direction" || k === "layout") meta.direction = String(v).toUpperCase();
|
|
1793
1944
|
else if (PLAYER_FLAT_KEY_SET.has(k)) {
|
|
1794
1945
|
const error = applyPlayerSetting(meta.player ??= {}, "player", k, String(v));
|
|
1795
1946
|
if (error) diagnostics.push({ severity: "warning", message: error, line: lineNo });
|
|
@@ -1808,6 +1959,16 @@ function parse(source, opts = {}) {
|
|
|
1808
1959
|
i++;
|
|
1809
1960
|
continue;
|
|
1810
1961
|
}
|
|
1962
|
+
if (/^theme\s*[:=]?\s*([a-zA-Z0-9_-]+)/i.test(line)) {
|
|
1963
|
+
const match = line.match(/^theme\s*[:=]?\s*([a-zA-Z0-9_-]+)/i);
|
|
1964
|
+
if (match) {
|
|
1965
|
+
const val = match[1].toLowerCase();
|
|
1966
|
+
meta.theme = val;
|
|
1967
|
+
meta.explicitTheme = val !== "auto";
|
|
1968
|
+
}
|
|
1969
|
+
i++;
|
|
1970
|
+
continue;
|
|
1971
|
+
}
|
|
1811
1972
|
const directiveMatch = line.match(PLAYER_DIRECTIVE_RE);
|
|
1812
1973
|
if (directiveMatch) {
|
|
1813
1974
|
const error = applyPlayerSetting(meta.player ??= {}, "player", directiveMatch[1], directiveMatch[2] ?? "");
|
|
@@ -1995,7 +2156,13 @@ function matchNode(node, selector) {
|
|
|
1995
2156
|
if (selector.kindEquals && node.kind.toLowerCase() !== selector.kindEquals.toLowerCase()) return false;
|
|
1996
2157
|
if (selector.roleEquals) {
|
|
1997
2158
|
const role = nodeRole(node.kind);
|
|
1998
|
-
|
|
2159
|
+
const targetRole = selector.roleEquals.toLowerCase();
|
|
2160
|
+
if (targetRole === "gateway") {
|
|
2161
|
+
const isGateway = role === "network" || ["gateway", "api_gateway", "reverse_proxy", "proxy", "router"].includes(node.kind.toLowerCase());
|
|
2162
|
+
if (!isGateway) return false;
|
|
2163
|
+
} else if (role.toLowerCase() !== targetRole) {
|
|
2164
|
+
return false;
|
|
2165
|
+
}
|
|
1999
2166
|
}
|
|
2000
2167
|
if (selector.labelContains) {
|
|
2001
2168
|
const target = (node.label || node.id).toLowerCase();
|
|
@@ -2156,6 +2323,30 @@ var ARCH_RULE_PRESETS = {
|
|
|
2156
2323
|
from: { roleEquals: "security" }
|
|
2157
2324
|
}
|
|
2158
2325
|
]
|
|
2326
|
+
},
|
|
2327
|
+
deploymentOwnership: {
|
|
2328
|
+
id: "deployment-ownership",
|
|
2329
|
+
name: "Deployment Ownership & Regional Governance",
|
|
2330
|
+
description: "Ensure production stateful stores and services are guarded in explicit group perimeters",
|
|
2331
|
+
rules: [
|
|
2332
|
+
{
|
|
2333
|
+
id: "no-unprotected-public-database",
|
|
2334
|
+
name: "No Public Database Exposure",
|
|
2335
|
+
description: "Databases and stateful stores must not be directly accessed from public browser/mobile clients.",
|
|
2336
|
+
severity: "error",
|
|
2337
|
+
type: "cannot-connect",
|
|
2338
|
+
from: { roleEquals: "client" },
|
|
2339
|
+
to: { roleEquals: "data" }
|
|
2340
|
+
},
|
|
2341
|
+
{
|
|
2342
|
+
id: "no-cross-region-sync-bypasses",
|
|
2343
|
+
name: "Synchronous Request Cycle Prevention",
|
|
2344
|
+
description: "Synchronous requests must not form cycles across microservices.",
|
|
2345
|
+
severity: "error",
|
|
2346
|
+
type: "forbidden-cycle",
|
|
2347
|
+
edge: { kind: "request" }
|
|
2348
|
+
}
|
|
2349
|
+
]
|
|
2159
2350
|
}
|
|
2160
2351
|
};
|
|
2161
2352
|
function validateArchitecture(ast, rules = [
|
|
@@ -2163,7 +2354,7 @@ function validateArchitecture(ast, rules = [
|
|
|
2163
2354
|
...ARCH_RULE_PRESETS.microservicesGovernance.rules
|
|
2164
2355
|
]) {
|
|
2165
2356
|
const violations = [];
|
|
2166
|
-
const nodes = Object.values(ast
|
|
2357
|
+
const nodes = Object.values(ast?.nodes || {});
|
|
2167
2358
|
const nodeMap = new Map(nodes.map((n) => [n.id, n]));
|
|
2168
2359
|
const edges = extractAllEdges(ast);
|
|
2169
2360
|
for (const rule of rules) {
|
|
@@ -2210,6 +2401,11 @@ function validateArchitecture(ast, rules = [
|
|
|
2210
2401
|
break;
|
|
2211
2402
|
}
|
|
2212
2403
|
case "forbidden-cycle": {
|
|
2404
|
+
const dtype = ast.meta?.type || ast.config?.type || "architecture";
|
|
2405
|
+
const nonServiceArchetypes = ["state", "sequence", "layers", "flywheel", "loop", "venn"];
|
|
2406
|
+
if (nonServiceArchetypes.includes(dtype)) {
|
|
2407
|
+
break;
|
|
2408
|
+
}
|
|
2213
2409
|
const cycleInfo = detectCycleInGraph(nodes, edges, rule.edge);
|
|
2214
2410
|
if (cycleInfo) {
|
|
2215
2411
|
violations.push({
|
|
@@ -2674,7 +2870,7 @@ function diagnoseMarkdyCode(code, options = {}) {
|
|
|
2674
2870
|
snippet: trimmed,
|
|
2675
2871
|
suggestion: closeTheme ? `Use theme '${closeTheme.match}'.` : `Choose from: ${THEME_NAMES.join(", ")}.`,
|
|
2676
2872
|
didYouMean: closeTheme?.match,
|
|
2677
|
-
ruleExplanation: "Supported themes: paper, editorial, midnight, blueprint, graphite, nebula, sketchy, terminal.",
|
|
2873
|
+
ruleExplanation: "Supported themes: paper, editorial, midnight, blueprint, graphite, nebula, sketchy, terminal, ink, doodle.",
|
|
2678
2874
|
fix: closeTheme ? { original: themeMatch[0], replacement: `theme=${closeTheme.match}` } : void 0
|
|
2679
2875
|
});
|
|
2680
2876
|
}
|
|
@@ -3472,7 +3668,9 @@ function getIntelliCodeCompletions(docText, cursorLine, cursorCol) {
|
|
|
3472
3668
|
{ name: "editorial", desc: "High-contrast serif luxury publication layout" },
|
|
3473
3669
|
{ name: "graphite", desc: "Sleek slate monochrome engineering aesthetic" },
|
|
3474
3670
|
{ name: "terminal", desc: "Retro phosphor CRT hacker terminal green on black" },
|
|
3475
|
-
{ name: "sketchy", desc: "Hand-drawn sketchy whiteboard marker design" }
|
|
3671
|
+
{ name: "sketchy", desc: "Hand-drawn sketchy whiteboard marker design" },
|
|
3672
|
+
{ name: "ink", desc: "Monochromatic blue ink style inspired by ballpoint pens, fountain pens, cyanotypes & porcelain" },
|
|
3673
|
+
{ name: "doodle", desc: "Playful hand-drawn doodle sketchbook with felt-tip marker pens and comic block shadows" }
|
|
3476
3674
|
];
|
|
3477
3675
|
for (const t of themeEntries) {
|
|
3478
3676
|
items.push({
|
|
@@ -4517,7 +4715,7 @@ var ARCHITECTURE_TEMPLATES = [
|
|
|
4517
4715
|
title: "Cloud Microservices & Database Tier",
|
|
4518
4716
|
category: "Cloud / Microservices",
|
|
4519
4717
|
description: "Multi-tier microservices architecture with API gateway, auth, database, and Redis cache.",
|
|
4520
|
-
code: `scene theme=paper
|
|
4718
|
+
code: `scene theme=paper
|
|
4521
4719
|
layout LR
|
|
4522
4720
|
|
|
4523
4721
|
browser WebApp "Web Application"
|
|
@@ -4537,24 +4735,23 @@ beat reveal "System Overview":
|
|
|
4537
4735
|
show $nodes stagger=40ms
|
|
4538
4736
|
|
|
4539
4737
|
beat authFlow "Authenticate Request":
|
|
4540
|
-
frame clients ApiGateway AuthService zoom=1.12
|
|
4541
4738
|
WebApp -> ApiGateway "GET /profile" -> AuthService "validate_jwt"
|
|
4542
4739
|
WebApp <- ApiGateway "200 OK (Claims)"
|
|
4543
4740
|
|
|
4544
4741
|
beat checkout "Process Order":
|
|
4545
|
-
frame ApiGateway OrderService PaymentService dataTier zoom=1.1
|
|
4546
4742
|
MobileApp -> ApiGateway "POST /checkout" -> OrderService "create_order"
|
|
4547
4743
|
OrderService -> RedisCache "check inventory"
|
|
4548
4744
|
OrderService -> PaymentService "authorize charge"
|
|
4549
4745
|
PaymentService -> MainDB "record transaction"
|
|
4550
|
-
MobileApp <- ApiGateway "201 Created"
|
|
4746
|
+
MobileApp <- ApiGateway "201 Created"
|
|
4747
|
+
glow MainDB color=#10b981`
|
|
4551
4748
|
},
|
|
4552
4749
|
{
|
|
4553
4750
|
id: "ai-rag-pipeline",
|
|
4554
4751
|
title: "AI Agent & RAG Pipeline",
|
|
4555
4752
|
category: "AI / Machine Learning",
|
|
4556
4753
|
description: "Retrieval-Augmented Generation agent flow with embedding vector search, LLM synthesis, and sandbox tool execution.",
|
|
4557
|
-
code: `scene theme=editorial
|
|
4754
|
+
code: `scene theme=editorial
|
|
4558
4755
|
layout LR
|
|
4559
4756
|
|
|
4560
4757
|
user User "Engineer"
|
|
@@ -4572,13 +4769,11 @@ beat init "System Reveal":
|
|
|
4572
4769
|
show $nodes stagger=50ms
|
|
4573
4770
|
|
|
4574
4771
|
beat retrieve "Query & Vector Search":
|
|
4575
|
-
frame User ChatUI Orchestrator aiCore zoom=1.12
|
|
4576
4772
|
User -> ChatUI "Ask technical question" -> Orchestrator "parse intent"
|
|
4577
4773
|
Orchestrator -> Embedder "embed(query)" -> VectorDB "cosine search (k=5)"
|
|
4578
4774
|
Orchestrator <- VectorDB "retrieved context chunks"
|
|
4579
4775
|
|
|
4580
4776
|
beat generate "Synthesis & Tool Execution":
|
|
4581
|
-
frame Orchestrator LLM Tools zoom=1.15
|
|
4582
4777
|
Orchestrator -> LLM "prompt + context"
|
|
4583
4778
|
LLM -> Tools "execute_code(sql)"
|
|
4584
4779
|
LLM <- Tools "tool_result"
|
|
@@ -4590,7 +4785,7 @@ beat generate "Synthesis & Tool Execution":
|
|
|
4590
4785
|
title: "Event-Driven Architecture & Kafka Fan-Out",
|
|
4591
4786
|
category: "Messaging / Streaming",
|
|
4592
4787
|
description: "Event ingestion and parallel asynchronous consumer worker fan-out with dead-letter queue.",
|
|
4593
|
-
code: `scene theme=midnight
|
|
4788
|
+
code: `scene theme=midnight
|
|
4594
4789
|
layout LR
|
|
4595
4790
|
|
|
4596
4791
|
service IngestionAPI "Ingestion API"
|
|
@@ -4608,22 +4803,21 @@ beat reveal "Topology":
|
|
|
4608
4803
|
show $nodes stagger=40ms
|
|
4609
4804
|
|
|
4610
4805
|
beat publish "Publish Event":
|
|
4611
|
-
frame IngestionAPI KafkaTopic zoom=1.15
|
|
4612
4806
|
IngestionAPI ~> KafkaTopic "publish(OrderPlaced)"
|
|
4613
4807
|
glow KafkaTopic color=#38bdf8
|
|
4614
4808
|
|
|
4615
4809
|
beat fanout "Parallel Fan-out Processing":
|
|
4616
|
-
frame KafkaTopic workers zoom=1.12
|
|
4617
4810
|
KafkaTopic ~> InventoryWorker "consume event" & KafkaTopic ~> NotificationWorker "consume event" & KafkaTopic ~> AnalyticsWorker "consume event"
|
|
4618
4811
|
InventoryWorker -> InventoryDB "UPDATE stock"
|
|
4619
|
-
AnalyticsWorker -> AnalyticsDB "INSERT analytics"
|
|
4812
|
+
AnalyticsWorker -> AnalyticsDB "INSERT analytics"
|
|
4813
|
+
glow AnalyticsDB color=#10b981`
|
|
4620
4814
|
},
|
|
4621
4815
|
{
|
|
4622
4816
|
id: "k8s-ingress-cluster",
|
|
4623
4817
|
title: "Kubernetes Cluster & Cloud Ingress",
|
|
4624
4818
|
category: "DevOps / Infrastructure",
|
|
4625
4819
|
description: "Cloudflare edge, Traefik ingress controller, pod deployments, ClusterIP routing, and persistent storage volumes.",
|
|
4626
|
-
code: `scene theme=blueprint
|
|
4820
|
+
code: `scene theme=blueprint
|
|
4627
4821
|
layout LR
|
|
4628
4822
|
|
|
4629
4823
|
cloud CDN "Cloudflare CDN"
|
|
@@ -4642,18 +4836,18 @@ beat reveal "Cluster Architecture":
|
|
|
4642
4836
|
show $nodes stagger=40ms
|
|
4643
4837
|
|
|
4644
4838
|
beat routing "Ingress Traffic Routing":
|
|
4645
|
-
frame CDN Ingress frontendPods zoom=1.12
|
|
4646
4839
|
CDN -> Ingress "HTTPS Request" -> WebPod1 "reverse proxy"
|
|
4647
4840
|
WebPod1 -> ClusterIP "internal call" -> ApiPod1 "gRPC invocation"
|
|
4648
4841
|
ApiPod1 -> PV "read/write volume"
|
|
4649
|
-
CDN <- Ingress "200 HTTP OK"
|
|
4842
|
+
CDN <- Ingress "200 HTTP OK"
|
|
4843
|
+
glow ApiPod1 color=#10b981`
|
|
4650
4844
|
},
|
|
4651
4845
|
{
|
|
4652
4846
|
id: "cicd-gitops-pipeline",
|
|
4653
4847
|
title: "CI/CD GitOps Delivery Pipeline",
|
|
4654
4848
|
category: "DevOps / CI-CD",
|
|
4655
4849
|
description: "GitHub commits, automated GitHub Actions testing, container registry push, and ArgoCD production deployment.",
|
|
4656
|
-
code: `scene theme=graphite
|
|
4850
|
+
code: `scene theme=graphite
|
|
4657
4851
|
layout LR
|
|
4658
4852
|
|
|
4659
4853
|
user Dev "Developer"
|
|
@@ -4667,7 +4861,6 @@ beat reveal "Pipeline Infrastructure":
|
|
|
4667
4861
|
show $nodes stagger=45ms
|
|
4668
4862
|
|
|
4669
4863
|
beat build "Commit & Build Validation":
|
|
4670
|
-
frame Dev GitHub Actions DockerHub zoom=1.12
|
|
4671
4864
|
Dev -> GitHub "git push origin main"
|
|
4672
4865
|
GitHub ~> Actions "trigger workflow"
|
|
4673
4866
|
Actions -> Actions "run unit & visual tests"
|
|
@@ -4675,7 +4868,6 @@ beat build "Commit & Build Validation":
|
|
|
4675
4868
|
glow DockerHub color=#10b981
|
|
4676
4869
|
|
|
4677
4870
|
beat deploy "GitOps Sync & Deployment":
|
|
4678
|
-
frame DockerHub ArgoCD Production zoom=1.15
|
|
4679
4871
|
ArgoCD -> GitHub "detect manifest drift"
|
|
4680
4872
|
ArgoCD -> DockerHub "pull image:v1.0.7"
|
|
4681
4873
|
ArgoCD -> Production "apply rollout"
|
|
@@ -4686,7 +4878,7 @@ beat deploy "GitOps Sync & Deployment":
|
|
|
4686
4878
|
title: "OAuth2 / OIDC Authentication Flow",
|
|
4687
4879
|
category: "Security / Identity",
|
|
4688
4880
|
description: "End-to-end authorization code grant flow with IdP redirect, consent, token exchange, and protected API access.",
|
|
4689
|
-
code: `scene theme=paper
|
|
4881
|
+
code: `scene theme=paper
|
|
4690
4882
|
layout LR
|
|
4691
4883
|
|
|
4692
4884
|
browser User "End User Browser"
|
|
@@ -4698,14 +4890,12 @@ beat reveal "System Overview":
|
|
|
4698
4890
|
show $nodes stagger=50ms
|
|
4699
4891
|
|
|
4700
4892
|
beat redirect "Authorize & Consent":
|
|
4701
|
-
frame User ClientApp IdP zoom=1.15
|
|
4702
4893
|
User -> ClientApp "click 'Login with IdP'"
|
|
4703
4894
|
User <- ClientApp "302 Redirect to /authorize"
|
|
4704
4895
|
User -> IdP "submit credentials & consent"
|
|
4705
4896
|
User <- IdP "302 Redirect with ?code=AUTH_CODE"
|
|
4706
4897
|
|
|
4707
4898
|
beat exchange "Token Exchange & API Access":
|
|
4708
|
-
frame ClientApp IdP ResourceServer zoom=1.15
|
|
4709
4899
|
ClientApp -> IdP "POST /token (code + secret)"
|
|
4710
4900
|
ClientApp <- IdP "200 OK (access_token + id_token)"
|
|
4711
4901
|
ClientApp -> ResourceServer "GET /userinfo (Bearer Token)"
|
|
@@ -4717,7 +4907,7 @@ beat exchange "Token Exchange & API Access":
|
|
|
4717
4907
|
title: "Resilient Multi-Region High Availability & Cache-Aside",
|
|
4718
4908
|
category: "Distributed Systems",
|
|
4719
4909
|
description: "GeoDNS global routing, primary/failover regions, Redis master/replica cache-aside pattern, and Aurora global storage replication.",
|
|
4720
|
-
code: `scene theme=midnight
|
|
4910
|
+
code: `scene theme=midnight
|
|
4721
4911
|
layout LR
|
|
4722
4912
|
|
|
4723
4913
|
gateway GeoDNS "Global Route53 / Anycast"
|
|
@@ -4734,23 +4924,23 @@ beat reveal "Global Infrastructure":
|
|
|
4734
4924
|
show $nodes stagger=40ms
|
|
4735
4925
|
|
|
4736
4926
|
beat readCache "Cache-Aside Read Flow":
|
|
4737
|
-
frame GeoDNS eastTier AuroraGlobal zoom=1.12
|
|
4738
4927
|
GeoDNS -> RegionEast "route nearest user" -> RedisPrimary "GET item:101"
|
|
4739
4928
|
RegionEast <- RedisPrimary "cache miss"
|
|
4740
4929
|
RegionEast -> AuroraGlobal "SELECT FROM db"
|
|
4741
4930
|
RegionEast -> RedisPrimary "SET item:101 (TTL 60s)"
|
|
4742
4931
|
GeoDNS <- RegionEast "200 OK (Payload)"
|
|
4932
|
+
glow RedisPrimary color=#38bdf8
|
|
4743
4933
|
|
|
4744
4934
|
beat replication "Global Storage Replication":
|
|
4745
|
-
|
|
4746
|
-
|
|
4935
|
+
RedisPrimary ~> RedisReplica "async sync" & AuroraGlobal ~> AuroraGlobal "storage replication"
|
|
4936
|
+
glow AuroraGlobal color=#10b981`
|
|
4747
4937
|
},
|
|
4748
4938
|
{
|
|
4749
4939
|
id: "decision-flowchart",
|
|
4750
4940
|
title: "Quality Gate Decision Flowchart",
|
|
4751
4941
|
category: "Workflows / Flowcharts",
|
|
4752
4942
|
description: "Top-down pull request quality evaluation workflow with branch decision diamonds and fallback rejection states.",
|
|
4753
|
-
code: `scene theme=sketchy
|
|
4943
|
+
code: `scene theme=sketchy type=flowchart
|
|
4754
4944
|
layout TB
|
|
4755
4945
|
|
|
4756
4946
|
start PR "New Pull Request"
|
|
@@ -5361,7 +5551,7 @@ function createMarkdyMcpServer() {
|
|
|
5361
5551
|
},
|
|
5362
5552
|
{
|
|
5363
5553
|
name: "theme",
|
|
5364
|
-
description: "Preferred visual theme (paper, editorial, midnight, blueprint, graphite, nebula, sketchy, terminal).",
|
|
5554
|
+
description: "Preferred visual theme (paper, editorial, midnight, blueprint, graphite, nebula, sketchy, terminal, ink, doodle).",
|
|
5365
5555
|
required: false
|
|
5366
5556
|
},
|
|
5367
5557
|
{
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@markdy/mcp-server",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Model Context Protocol server for Markdy diagram validation, transpilation, and generation.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -39,8 +39,8 @@
|
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"@modelcontextprotocol/sdk": "^1.6.1",
|
|
42
|
-
"@markdy/compat": "1.
|
|
43
|
-
"@markdy/core": "1.
|
|
42
|
+
"@markdy/compat": "1.3.0",
|
|
43
|
+
"@markdy/core": "1.3.0"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@types/node": "^25.9.5",
|