@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.
Files changed (2) hide show
  1. package/dist/index.js +229 -39
  2. 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: "Georgia, Times New Roman, serif",
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(/^(\w[\w.-]*)=/);
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") meta.theme = String(v);
1792
- else if (k === "direction" || k === "layout") meta.direction = String(v).toUpperCase();
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
- if (role.toLowerCase() !== selector.roleEquals.toLowerCase()) return false;
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.nodes);
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 width=1440 height=760
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 width=1440 height=760
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 width=1440 height=760
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 width=1440 height=800
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 width=1440 height=720
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 width=1440 height=720
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 width=1440 height=760
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
- frame RedisPrimary RedisReplica AuroraGlobal zoom=1.15
4746
- RedisPrimary ~> RedisReplica "async sync" & AuroraGlobal ~> AuroraGlobal "storage replication"`
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 width=1280 height=720 type=flowchart
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.1.7",
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.1.7",
43
- "@markdy/core": "1.1.7"
42
+ "@markdy/compat": "1.3.0",
43
+ "@markdy/core": "1.3.0"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@types/node": "^25.9.5",