@diagrammo/dgmo 0.4.1 → 0.4.3

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 (59) hide show
  1. package/.claude/skills/dgmo-chart/SKILL.md +28 -0
  2. package/.claude/skills/dgmo-generate/SKILL.md +1 -0
  3. package/.claude/skills/dgmo-sequence/SKILL.md +24 -1
  4. package/.cursorrules +27 -2
  5. package/.github/copilot-instructions.md +36 -3
  6. package/.windsurfrules +27 -2
  7. package/README.md +12 -3
  8. package/dist/cli.cjs +611 -153
  9. package/dist/index.cjs +8371 -3200
  10. package/dist/index.cjs.map +1 -1
  11. package/dist/index.d.cts +502 -58
  12. package/dist/index.d.ts +502 -58
  13. package/dist/index.js +8594 -3444
  14. package/dist/index.js.map +1 -1
  15. package/docs/ai-integration.md +1 -1
  16. package/docs/language-reference.md +336 -17
  17. package/docs/migration-sequence-color-to-tags.md +98 -0
  18. package/package.json +1 -1
  19. package/src/c4/renderer.ts +1 -20
  20. package/src/class/renderer.ts +1 -11
  21. package/src/cli.ts +40 -0
  22. package/src/d3.ts +92 -2
  23. package/src/dgmo-router.ts +11 -0
  24. package/src/echarts.ts +74 -8
  25. package/src/er/parser.ts +29 -3
  26. package/src/er/renderer.ts +1 -15
  27. package/src/graph/flowchart-parser.ts +7 -30
  28. package/src/graph/flowchart-renderer.ts +62 -69
  29. package/src/graph/layout.ts +5 -0
  30. package/src/graph/state-parser.ts +388 -0
  31. package/src/graph/state-renderer.ts +496 -0
  32. package/src/graph/types.ts +4 -2
  33. package/src/index.ts +42 -1
  34. package/src/infra/compute.ts +1113 -0
  35. package/src/infra/layout.ts +575 -0
  36. package/src/infra/parser.ts +559 -0
  37. package/src/infra/renderer.ts +1509 -0
  38. package/src/infra/roles.ts +60 -0
  39. package/src/infra/serialize.ts +67 -0
  40. package/src/infra/types.ts +221 -0
  41. package/src/infra/validation.ts +192 -0
  42. package/src/initiative-status/layout.ts +56 -61
  43. package/src/initiative-status/renderer.ts +13 -13
  44. package/src/kanban/renderer.ts +1 -24
  45. package/src/org/layout.ts +28 -37
  46. package/src/org/parser.ts +16 -1
  47. package/src/org/renderer.ts +159 -121
  48. package/src/org/resolver.ts +90 -23
  49. package/src/palettes/color-utils.ts +30 -0
  50. package/src/render.ts +2 -0
  51. package/src/sequence/parser.ts +202 -42
  52. package/src/sequence/renderer.ts +576 -113
  53. package/src/sequence/tag-resolution.ts +163 -0
  54. package/src/sitemap/collapse.ts +187 -0
  55. package/src/sitemap/layout.ts +738 -0
  56. package/src/sitemap/parser.ts +489 -0
  57. package/src/sitemap/renderer.ts +774 -0
  58. package/src/sitemap/types.ts +42 -0
  59. package/src/utils/tag-groups.ts +119 -0
package/dist/index.d.ts CHANGED
@@ -39,6 +39,7 @@ declare function render(content: string, options?: {
39
39
  c4Level?: 'context' | 'containers' | 'components' | 'deployment';
40
40
  c4System?: string;
41
41
  c4Container?: string;
42
+ scenario?: string;
42
43
  }): Promise<string>;
43
44
 
44
45
  /**
@@ -263,6 +264,7 @@ interface ParsedSankeyLink {
263
264
  source: string;
264
265
  target: string;
265
266
  value: number;
267
+ color?: string;
266
268
  lineNumber: number;
267
269
  }
268
270
  interface ParsedFunction {
@@ -309,6 +311,7 @@ interface ParsedEChart {
309
311
  sizelabel?: string;
310
312
  showLabels?: boolean;
311
313
  categoryColors?: Record<string, string>;
314
+ nodeColors?: Record<string, string>;
312
315
  diagnostics: DgmoError[];
313
316
  error: string | null;
314
317
  }
@@ -548,8 +551,25 @@ declare function renderD3ForExport(content: string, theme: 'light' | 'dark' | 't
548
551
  c4Level?: 'context' | 'containers' | 'components' | 'deployment';
549
552
  c4System?: string;
550
553
  c4Container?: string;
554
+ scenario?: string;
551
555
  }): Promise<string>;
552
556
 
557
+ /** A single entry inside a tag group: `Value(color)` */
558
+ interface TagEntry {
559
+ value: string;
560
+ color: string;
561
+ lineNumber: number;
562
+ }
563
+ /** A tag group block: heading + entries */
564
+ interface TagGroup {
565
+ name: string;
566
+ alias?: string;
567
+ entries: TagEntry[];
568
+ /** Value of the entry marked `default` (nodes without metadata get this) */
569
+ defaultValue?: string;
570
+ lineNumber: number;
571
+ }
572
+
553
573
  /**
554
574
  * Participant types that can be declared via "Name is a type" syntax.
555
575
  */
@@ -568,6 +588,8 @@ interface SequenceParticipant {
568
588
  lineNumber: number;
569
589
  /** Explicit layout position override (0-based from left, negative from right) */
570
590
  position?: number;
591
+ /** Pipe-delimited tag metadata (e.g. `| role: Gateway`) */
592
+ metadata?: Record<string, string>;
571
593
  }
572
594
  /**
573
595
  * A message between two participants.
@@ -578,6 +600,8 @@ interface SequenceMessage {
578
600
  label: string;
579
601
  lineNumber: number;
580
602
  async?: boolean;
603
+ /** Pipe-delimited tag metadata (e.g. `| c: Caching`) */
604
+ metadata?: Record<string, string>;
581
605
  }
582
606
  /**
583
607
  * A conditional or loop block in the sequence diagram.
@@ -601,7 +625,6 @@ interface SequenceBlock {
601
625
  interface SequenceSection {
602
626
  kind: 'section';
603
627
  label: string;
604
- color?: string;
605
628
  lineNumber: number;
606
629
  }
607
630
  /**
@@ -623,9 +646,10 @@ declare function isSequenceNote(el: SequenceElement): el is SequenceNote;
623
646
  */
624
647
  interface SequenceGroup {
625
648
  name: string;
626
- color?: string;
627
649
  participantIds: string[];
628
650
  lineNumber: number;
651
+ /** Pipe-delimited tag metadata (e.g. `[Backend | t: Product]`) */
652
+ metadata?: Record<string, string>;
629
653
  }
630
654
  /**
631
655
  * Parsed result from a .dgmo sequence diagram.
@@ -638,6 +662,7 @@ interface ParsedSequenceDgmo {
638
662
  elements: SequenceElement[];
639
663
  groups: SequenceGroup[];
640
664
  sections: SequenceSection[];
665
+ tagGroups: TagGroup[];
641
666
  options: Record<string, string>;
642
667
  diagnostics: DgmoError[];
643
668
  error: string | null;
@@ -704,7 +729,7 @@ declare function buildMermaidQuadrant(parsed: ParsedQuadrant, options?: {
704
729
  mutedTextColor?: string;
705
730
  }): string;
706
731
 
707
- type GraphShape = 'terminal' | 'process' | 'decision' | 'io' | 'subroutine' | 'document';
732
+ type GraphShape = 'terminal' | 'process' | 'decision' | 'io' | 'subroutine' | 'document' | 'state' | 'pseudostate';
708
733
  type GraphDirection = 'TB' | 'LR';
709
734
  interface GraphNode {
710
735
  id: string;
@@ -730,7 +755,7 @@ interface GraphGroup {
730
755
  }
731
756
 
732
757
  interface ParsedGraph {
733
- type: 'flowchart';
758
+ type: 'flowchart' | 'state';
734
759
  title?: string;
735
760
  titleLineNumber?: number;
736
761
  direction: GraphDirection;
@@ -750,6 +775,61 @@ declare function parseFlowchart(content: string, palette?: PaletteColors): Parse
750
775
  */
751
776
  declare function looksLikeFlowchart(content: string): boolean;
752
777
 
778
+ declare function parseState(content: string, palette?: PaletteColors): ParsedGraph;
779
+ /**
780
+ * Detect if content looks like a state diagram (without explicit `chart: state` header).
781
+ * Only matches if `[*]` token is present — too ambiguous to infer from bare names alone.
782
+ */
783
+ declare function looksLikeState(content: string): boolean;
784
+
785
+ interface LayoutNode {
786
+ id: string;
787
+ label: string;
788
+ shape: GraphShape;
789
+ color?: string;
790
+ group?: string;
791
+ lineNumber: number;
792
+ x: number;
793
+ y: number;
794
+ width: number;
795
+ height: number;
796
+ }
797
+ interface LayoutEdge {
798
+ source: string;
799
+ target: string;
800
+ points: {
801
+ x: number;
802
+ y: number;
803
+ }[];
804
+ label?: string;
805
+ color?: string;
806
+ lineNumber: number;
807
+ }
808
+ interface LayoutGroup {
809
+ id: string;
810
+ label: string;
811
+ color?: string;
812
+ lineNumber: number;
813
+ x: number;
814
+ y: number;
815
+ width: number;
816
+ height: number;
817
+ }
818
+ interface LayoutResult {
819
+ nodes: LayoutNode[];
820
+ edges: LayoutEdge[];
821
+ groups: LayoutGroup[];
822
+ width: number;
823
+ height: number;
824
+ }
825
+ declare function layoutGraph(graph: ParsedGraph): LayoutResult;
826
+
827
+ declare function renderState(container: HTMLDivElement, graph: ParsedGraph, layout: LayoutResult, palette: PaletteColors, isDark: boolean, onClickItem?: (lineNumber: number) => void, exportDims?: {
828
+ width?: number;
829
+ height?: number;
830
+ }): void;
831
+ declare function renderStateForExport(content: string, theme: 'light' | 'dark' | 'transparent', palette: PaletteColors): string;
832
+
753
833
  type ClassModifier = 'abstract' | 'interface' | 'enum';
754
834
  type MemberVisibility = 'public' | 'private' | 'protected';
755
835
  type RelationshipType = 'extends' | 'implements' | 'composes' | 'aggregates' | 'depends' | 'associates';
@@ -911,22 +991,6 @@ declare function renderERDiagram(container: HTMLDivElement, parsed: ParsedERDiag
911
991
  }): void;
912
992
  declare function renderERDiagramForExport(content: string, theme: 'light' | 'dark' | 'transparent', palette: PaletteColors): string;
913
993
 
914
- /** A single entry inside a tag group: `Value(color)` */
915
- interface TagEntry {
916
- value: string;
917
- color: string;
918
- lineNumber: number;
919
- }
920
- /** A tag group block: heading + entries */
921
- interface TagGroup {
922
- name: string;
923
- alias?: string;
924
- entries: TagEntry[];
925
- /** Value of the entry marked `default` (nodes without metadata get this) */
926
- defaultValue?: string;
927
- lineNumber: number;
928
- }
929
-
930
994
  interface InlineSpan {
931
995
  text: string;
932
996
  bold?: boolean;
@@ -1025,7 +1089,7 @@ interface OrgLayoutResult {
1025
1089
  width: number;
1026
1090
  height: number;
1027
1091
  }
1028
- declare function layoutOrg(parsed: ParsedOrg, hiddenCounts?: Map<string, number>, activeTagGroup?: string | null, hiddenAttributes?: Set<string>): OrgLayoutResult;
1092
+ declare function layoutOrg(parsed: ParsedOrg, hiddenCounts?: Map<string, number>, activeTagGroup?: string | null, hiddenAttributes?: Set<string>, expandAllLegend?: boolean): OrgLayoutResult;
1029
1093
 
1030
1094
  declare function renderOrg(container: HTMLDivElement, parsed: ParsedOrg, layout: OrgLayoutResult, palette: PaletteColors, isDark: boolean, onClickItem?: (lineNumber: number) => void, exportDims?: {
1031
1095
  width?: number;
@@ -1354,48 +1418,68 @@ declare function renderInitiativeStatus(container: HTMLDivElement, parsed: Parse
1354
1418
  }): void;
1355
1419
  declare function renderInitiativeStatusForExport(content: string, theme: 'light' | 'dark' | 'transparent', palette: PaletteColors): string;
1356
1420
 
1357
- interface CollapsedOrgResult {
1358
- /** ParsedOrg with collapsed subtrees pruned (deep-cloned, never mutates original) */
1359
- parsed: ParsedOrg;
1360
- /** nodeId → count of hidden descendants */
1361
- hiddenCounts: Map<string, number>;
1421
+ interface SitemapNode {
1422
+ id: string;
1423
+ label: string;
1424
+ metadata: Record<string, string>;
1425
+ children: SitemapNode[];
1426
+ parentId: string | null;
1427
+ /** True for [Group Name] container nodes */
1428
+ isContainer: boolean;
1429
+ lineNumber: number;
1430
+ color?: string;
1362
1431
  }
1363
- declare function collapseOrgTree(original: ParsedOrg, collapsedIds: Set<string>): CollapsedOrgResult;
1364
-
1365
- /**
1366
- * Async or sync file reader. Receives an absolute path, returns content.
1367
- * Throwing means "file not found".
1368
- */
1369
- type ReadFileFn = (path: string) => string | Promise<string>;
1370
- interface ResolveImportsResult {
1371
- content: string;
1432
+ interface SitemapEdge {
1433
+ sourceId: string;
1434
+ targetId: string;
1435
+ label?: string;
1436
+ color?: string;
1437
+ lineNumber: number;
1438
+ }
1439
+ type SitemapDirection = 'TB' | 'LR';
1440
+ interface ParsedSitemap {
1441
+ title: string | null;
1442
+ titleLineNumber: number | null;
1443
+ direction: SitemapDirection;
1444
+ /** Top-level nodes (roots of the hierarchy) */
1445
+ roots: SitemapNode[];
1446
+ /** All cross-link edges */
1447
+ edges: SitemapEdge[];
1448
+ tagGroups: TagGroup[];
1449
+ options: Record<string, string>;
1372
1450
  diagnostics: DgmoError[];
1451
+ error: string | null;
1373
1452
  }
1453
+
1374
1454
  /**
1375
- * Pre-processes org chart content, resolving `tags:` and `import:` directives.
1376
- *
1377
- * @param content - Raw .dgmo file content
1378
- * @param filePath - Absolute path of the file (for relative path resolution)
1379
- * @param readFileFn - Function to read files (sync or async)
1380
- * @returns Merged content with all imports resolved + diagnostics
1455
+ * Returns true if content looks like a sitemap diagram.
1456
+ * Heuristic: has `->` arrows AND `[Group]` containers but does NOT have
1457
+ * flowchart shape delimiters ((...), <...>, /.../) adjacent to arrows.
1381
1458
  */
1382
- declare function resolveOrgImports(content: string, filePath: string, readFileFn: ReadFileFn): Promise<ResolveImportsResult>;
1459
+ declare function looksLikeSitemap(content: string): boolean;
1460
+ declare function parseSitemap(content: string, palette?: PaletteColors): ParsedSitemap;
1383
1461
 
1384
- interface LayoutNode {
1462
+ interface SitemapLayoutNode {
1385
1463
  id: string;
1386
1464
  label: string;
1387
- shape: GraphShape;
1388
- color?: string;
1389
- group?: string;
1465
+ metadata: Record<string, string>;
1466
+ /** Original (unfiltered) metadata for tag-based coloring and hover dimming */
1467
+ tagMetadata: Record<string, string>;
1468
+ isContainer: boolean;
1390
1469
  lineNumber: number;
1470
+ color?: string;
1391
1471
  x: number;
1392
1472
  y: number;
1393
1473
  width: number;
1394
1474
  height: number;
1475
+ /** Count of hidden descendants when collapsed */
1476
+ hiddenCount?: number;
1477
+ /** True if node has children (expanded or collapsed) — drives toggle UI */
1478
+ hasChildren?: boolean;
1395
1479
  }
1396
- interface LayoutEdge {
1397
- source: string;
1398
- target: string;
1480
+ interface SitemapLayoutEdge {
1481
+ sourceId: string;
1482
+ targetId: string;
1399
1483
  points: {
1400
1484
  x: number;
1401
1485
  y: number;
@@ -1404,23 +1488,377 @@ interface LayoutEdge {
1404
1488
  color?: string;
1405
1489
  lineNumber: number;
1406
1490
  }
1407
- interface LayoutGroup {
1491
+ interface SitemapContainerBounds {
1492
+ nodeId: string;
1493
+ label: string;
1494
+ lineNumber: number;
1495
+ color?: string;
1496
+ metadata: Record<string, string>;
1497
+ /** Original (unfiltered) metadata for tag-based coloring and hover dimming */
1498
+ tagMetadata: Record<string, string>;
1499
+ x: number;
1500
+ y: number;
1501
+ width: number;
1502
+ height: number;
1503
+ labelHeight: number;
1504
+ /** Count of hidden descendants when collapsed */
1505
+ hiddenCount?: number;
1506
+ /** True if container has children (expanded or collapsed) */
1507
+ hasChildren?: boolean;
1508
+ }
1509
+ interface SitemapLegendEntry {
1510
+ value: string;
1511
+ color: string;
1512
+ }
1513
+ interface SitemapLegendGroup {
1514
+ name: string;
1515
+ alias?: string;
1516
+ entries: SitemapLegendEntry[];
1517
+ x: number;
1518
+ y: number;
1519
+ width: number;
1520
+ height: number;
1521
+ minifiedWidth: number;
1522
+ minifiedHeight: number;
1523
+ }
1524
+ interface SitemapLayoutResult {
1525
+ nodes: SitemapLayoutNode[];
1526
+ edges: SitemapLayoutEdge[];
1527
+ containers: SitemapContainerBounds[];
1528
+ legend: SitemapLegendGroup[];
1529
+ width: number;
1530
+ height: number;
1531
+ }
1532
+ declare function layoutSitemap(parsed: ParsedSitemap, hiddenCounts?: Map<string, number>, activeTagGroup?: string | null, hiddenAttributes?: Set<string>, expandAllLegend?: boolean): SitemapLayoutResult;
1533
+
1534
+ declare function renderSitemap(container: HTMLDivElement, parsed: ParsedSitemap, layout: SitemapLayoutResult, palette: PaletteColors, isDark: boolean, onClickItem?: (lineNumber: number) => void, exportDims?: {
1535
+ width?: number;
1536
+ height?: number;
1537
+ }, activeTagGroup?: string | null, hiddenAttributes?: Set<string>): void;
1538
+ declare function renderSitemapForExport(content: string, theme: 'light' | 'dark' | 'transparent', palette?: PaletteColors): Promise<string>;
1539
+
1540
+ interface CollapsedSitemapResult {
1541
+ /** ParsedSitemap with collapsed subtrees pruned (deep-cloned, never mutates original) */
1542
+ parsed: ParsedSitemap;
1543
+ /** nodeId → count of hidden descendants */
1544
+ hiddenCounts: Map<string, number>;
1545
+ }
1546
+ declare function collapseSitemapTree(original: ParsedSitemap, collapsedIds: Set<string>): CollapsedSitemapResult;
1547
+
1548
+ /** Namespaced behavior property keys recognized by the parser. */
1549
+ type InfraBehaviorKey = 'cache-hit' | 'firewall-block' | 'ratelimit-rps' | 'latency-ms' | 'uptime' | 'instances' | 'max-rps' | 'cb-error-threshold' | 'cb-latency-threshold-ms' | 'concurrency' | 'duration-ms' | 'cold-start-ms' | 'buffer' | 'drain-rate' | 'retention-hours' | 'partitions';
1550
+ /** All recognized property keys (behavior + structural). */
1551
+ declare const INFRA_BEHAVIOR_KEYS: Set<string>;
1552
+ interface InfraProperty {
1553
+ key: string;
1554
+ value: string | number;
1555
+ lineNumber: number;
1556
+ }
1557
+ interface InfraNode {
1408
1558
  id: string;
1409
1559
  label: string;
1560
+ properties: InfraProperty[];
1561
+ groupId: string | null;
1562
+ tags: Record<string, string>;
1563
+ isEdge: boolean;
1564
+ lineNumber: number;
1565
+ }
1566
+ interface InfraEdge {
1567
+ sourceId: string;
1568
+ targetId: string;
1569
+ label: string;
1570
+ split: number | null;
1571
+ lineNumber: number;
1572
+ }
1573
+ interface InfraGroup {
1574
+ id: string;
1575
+ label: string;
1576
+ /** Number of instances (or auto-scaling range "N-M") of this group as a unit. */
1577
+ instances?: number | string;
1578
+ /** Whether this group should be collapsed by default in the source. */
1579
+ collapsed?: boolean;
1580
+ lineNumber: number;
1581
+ }
1582
+ interface InfraTagValue {
1583
+ name: string;
1410
1584
  color?: string;
1585
+ }
1586
+ interface InfraTagGroup {
1587
+ name: string;
1588
+ alias: string | null;
1589
+ values: InfraTagValue[];
1590
+ /** Value of the entry marked `default` (nodes without this tag get it automatically). */
1591
+ defaultValue?: string;
1592
+ lineNumber: number;
1593
+ }
1594
+ interface InfraScenario {
1595
+ name: string;
1596
+ /** Node property overrides: nodeId -> { key: value } */
1597
+ overrides: Record<string, Record<string, string | number>>;
1598
+ lineNumber: number;
1599
+ }
1600
+ interface ParsedInfra {
1601
+ type: 'infra';
1602
+ title: string | null;
1603
+ titleLineNumber: number | null;
1604
+ direction: 'LR' | 'TB';
1605
+ nodes: InfraNode[];
1606
+ edges: InfraEdge[];
1607
+ groups: InfraGroup[];
1608
+ tagGroups: InfraTagGroup[];
1609
+ scenarios: InfraScenario[];
1610
+ options: Record<string, string>;
1611
+ diagnostics: DgmoError[];
1612
+ error: string | null;
1613
+ }
1614
+ interface InfraComputeParams {
1615
+ rps?: number;
1616
+ instanceOverrides?: Record<string, number>;
1617
+ scenario?: InfraScenario | null;
1618
+ /** Per-node property overrides: nodeId -> { propertyKey: numericValue }.
1619
+ * Applied after scenario overrides. Lets sliders adjust cache-hit, etc. */
1620
+ propertyOverrides?: Record<string, Record<string, number>>;
1621
+ /** Set of group IDs that should be treated as collapsed (virtual nodes). */
1622
+ collapsedGroups?: Set<string>;
1623
+ }
1624
+ type InfraCbState = 'closed' | 'open' | 'half-open';
1625
+ interface ComputedInfraNode {
1626
+ id: string;
1627
+ label: string;
1628
+ groupId: string | null;
1629
+ isEdge: boolean;
1630
+ computedRps: number;
1631
+ overloaded: boolean;
1632
+ /** True when inbound RPS exceeds the node's ratelimit-rps and traffic is being shed. */
1633
+ rateLimited: boolean;
1634
+ /** Cumulative latency from edge to this node (ms). */
1635
+ computedLatencyMs: number;
1636
+ /** Latency percentiles from this node through all downstream paths (ms). */
1637
+ computedLatencyPercentiles: InfraLatencyPercentiles;
1638
+ /** Component uptime (product of uptimes along path, 0-1). */
1639
+ computedUptime: number;
1640
+ /** Local availability at this node (0-1), factoring in uptime, overload shed, and rate-limit reject. */
1641
+ computedAvailability: number;
1642
+ /** Availability percentiles through all downstream paths from this node (0-1 fractions). */
1643
+ computedAvailabilityPercentiles: InfraAvailabilityPercentiles;
1644
+ /** Circuit breaker state. */
1645
+ computedCbState: InfraCbState;
1646
+ /** Computed instance count for auto-scaling (min-max) ranges. */
1647
+ computedInstances: number;
1648
+ /** For serverless nodes: estimated concurrent invocations (Little's Law: RPS × duration_ms / 1000). */
1649
+ computedConcurrentInvocations: number;
1650
+ /** For collapsed group virtual nodes: worst health state of any child.
1651
+ * 'overloaded' > 'warning' > 'normal'. Undefined for regular nodes. */
1652
+ childHealthState?: 'normal' | 'warning' | 'overloaded';
1653
+ /** Queue metrics — only present when buffer property exists. */
1654
+ queueMetrics?: {
1655
+ /** Messages per second filling the buffer (inbound - drain-rate, clamped to 0). */
1656
+ fillRate: number;
1657
+ /** Seconds until buffer overflow at sustained fill rate. Infinity if not filling. */
1658
+ timeToOverflow: number;
1659
+ /** Queue wait time in ms (pending_messages / drain_rate * 1000). */
1660
+ waitTimeMs: number;
1661
+ };
1662
+ properties: InfraProperty[];
1663
+ tags: Record<string, string>;
1664
+ lineNumber: number;
1665
+ }
1666
+ interface ComputedInfraEdge {
1667
+ sourceId: string;
1668
+ targetId: string;
1669
+ label: string;
1670
+ computedRps: number;
1671
+ split: number;
1672
+ lineNumber: number;
1673
+ }
1674
+ interface InfraDiagnostic {
1675
+ type: 'SPLIT_SUM' | 'CYCLE' | 'OVERLOAD' | 'RATE_LIMITED' | 'ORPHAN' | 'SYNTAX' | 'UPTIME';
1676
+ line: number;
1677
+ message: string;
1678
+ }
1679
+ interface InfraLatencyPercentiles {
1680
+ p50: number;
1681
+ p90: number;
1682
+ p99: number;
1683
+ }
1684
+ interface InfraAvailabilityPercentiles {
1685
+ p50: number;
1686
+ p90: number;
1687
+ p99: number;
1688
+ }
1689
+ interface ComputedInfraModel {
1690
+ nodes: ComputedInfraNode[];
1691
+ edges: ComputedInfraEdge[];
1692
+ groups: InfraGroup[];
1693
+ tagGroups: InfraTagGroup[];
1694
+ title: string | null;
1695
+ direction: 'LR' | 'TB';
1696
+ /** Diagram-level options (e.g., default-latency-ms, default-uptime). */
1697
+ options: Record<string, string>;
1698
+ /** Latency percentiles at the edge entry point (weighted by traffic probability). */
1699
+ edgeLatency: InfraLatencyPercentiles;
1700
+ /** System uptime at edge (weighted average across all paths). */
1701
+ systemUptime: number;
1702
+ /** System availability at edge (weighted average of compound availability across all paths). */
1703
+ systemAvailability: number;
1704
+ diagnostics: InfraDiagnostic[];
1705
+ }
1706
+
1707
+ declare function parseInfra(content: string): ParsedInfra;
1708
+
1709
+ declare function computeInfra(parsed: ParsedInfra, params?: InfraComputeParams): ComputedInfraModel;
1710
+
1711
+ declare function validateInfra(parsed: ParsedInfra): InfraDiagnostic[];
1712
+ /**
1713
+ * Validate computed model (post-computation warnings).
1714
+ * Call after computeInfra() to get uptime/SLA warnings.
1715
+ */
1716
+ declare function validateComputed(computed: ComputedInfraModel): InfraDiagnostic[];
1717
+
1718
+ interface InfraRole {
1719
+ name: string;
1720
+ color: string;
1721
+ }
1722
+ /**
1723
+ * Infer roles from a component's properties.
1724
+ * A component can have multiple roles (e.g., Cache + Rate Limiter).
1725
+ */
1726
+ declare function inferRoles(properties: InfraProperty[]): InfraRole[];
1727
+ /**
1728
+ * Collect all unique roles present in the diagram (for legend).
1729
+ */
1730
+ declare function collectDiagramRoles(allProperties: InfraProperty[][]): InfraRole[];
1731
+
1732
+ interface InfraLayoutNode {
1733
+ id: string;
1734
+ label: string;
1411
1735
  x: number;
1412
1736
  y: number;
1413
1737
  width: number;
1414
1738
  height: number;
1739
+ computedRps: number;
1740
+ overloaded: boolean;
1741
+ rateLimited: boolean;
1742
+ isEdge: boolean;
1743
+ groupId: string | null;
1744
+ computedLatencyMs: number;
1745
+ computedLatencyPercentiles: ComputedInfraNode['computedLatencyPercentiles'];
1746
+ computedUptime: number;
1747
+ computedAvailability: number;
1748
+ computedAvailabilityPercentiles: ComputedInfraNode['computedAvailabilityPercentiles'];
1749
+ computedInstances: number;
1750
+ computedConcurrentInvocations: number;
1751
+ computedCbState: ComputedInfraNode['computedCbState'];
1752
+ childHealthState?: ComputedInfraNode['childHealthState'];
1753
+ properties: ComputedInfraNode['properties'];
1754
+ queueMetrics?: ComputedInfraNode['queueMetrics'];
1755
+ tags: Record<string, string>;
1756
+ lineNumber: number;
1415
1757
  }
1416
- interface LayoutResult {
1417
- nodes: LayoutNode[];
1418
- edges: LayoutEdge[];
1419
- groups: LayoutGroup[];
1758
+ interface InfraLayoutEdge {
1759
+ sourceId: string;
1760
+ targetId: string;
1761
+ label: string;
1762
+ computedRps: number;
1763
+ split: number;
1764
+ points: {
1765
+ x: number;
1766
+ y: number;
1767
+ }[];
1768
+ lineNumber: number;
1769
+ }
1770
+ interface InfraLayoutGroup {
1771
+ id: string;
1772
+ label: string;
1773
+ x: number;
1774
+ y: number;
1420
1775
  width: number;
1421
1776
  height: number;
1777
+ instances?: number | string;
1778
+ lineNumber: number;
1422
1779
  }
1423
- declare function layoutGraph(graph: ParsedGraph): LayoutResult;
1780
+ interface InfraLayoutResult {
1781
+ nodes: InfraLayoutNode[];
1782
+ edges: InfraLayoutEdge[];
1783
+ groups: InfraLayoutGroup[];
1784
+ /** Diagram-level options (e.g., default-latency-ms, default-uptime). */
1785
+ options: Record<string, string>;
1786
+ width: number;
1787
+ height: number;
1788
+ }
1789
+ declare function layoutInfra(computed: ComputedInfraModel, selectedNodeId?: string | null): InfraLayoutResult;
1790
+
1791
+ interface InfraLegendEntry {
1792
+ value: string;
1793
+ color: string;
1794
+ /** For role: kebab-case role name. For tag: lowercase tag value. */
1795
+ key: string;
1796
+ }
1797
+ interface InfraLegendGroup {
1798
+ name: string;
1799
+ type: 'role' | 'tag';
1800
+ /** For tag groups: the key used in data-tag-* attributes (alias or name). */
1801
+ tagKey?: string;
1802
+ entries: InfraLegendEntry[];
1803
+ width: number;
1804
+ minifiedWidth: number;
1805
+ }
1806
+ /** Build legend groups from roles + tags. */
1807
+ declare function computeInfraLegendGroups(nodes: InfraLayoutNode[], tagGroups: InfraTagGroup[], palette: PaletteColors): InfraLegendGroup[];
1808
+ interface InfraPlaybackState {
1809
+ expanded: boolean;
1810
+ paused: boolean;
1811
+ speed: number;
1812
+ speedOptions: readonly number[];
1813
+ }
1814
+ declare function renderInfra(container: HTMLDivElement, layout: InfraLayoutResult, palette: PaletteColors, isDark: boolean, title: string | null, titleLineNumber: number | null, tagGroups?: InfraTagGroup[], activeGroup?: string | null, animate?: boolean, playback?: InfraPlaybackState | null, selectedNodeId?: string | null, exportMode?: boolean): void;
1815
+ declare function parseAndLayoutInfra(content: string): {
1816
+ parsed: ParsedInfra;
1817
+ computed: null;
1818
+ layout: null;
1819
+ } | {
1820
+ parsed: ParsedInfra;
1821
+ computed: ComputedInfraModel;
1822
+ layout: InfraLayoutResult;
1823
+ };
1824
+
1825
+ interface CollapsedOrgResult {
1826
+ /** ParsedOrg with collapsed subtrees pruned (deep-cloned, never mutates original) */
1827
+ parsed: ParsedOrg;
1828
+ /** nodeId → count of hidden descendants */
1829
+ hiddenCounts: Map<string, number>;
1830
+ }
1831
+ declare function collapseOrgTree(original: ParsedOrg, collapsedIds: Set<string>): CollapsedOrgResult;
1832
+
1833
+ /**
1834
+ * Async or sync file reader. Receives an absolute path, returns content.
1835
+ * Throwing means "file not found".
1836
+ */
1837
+ type ReadFileFn = (path: string) => string | Promise<string>;
1838
+ /** Tracks the original source file and line for an imported line. */
1839
+ interface ImportSource {
1840
+ /** Absolute path of the file this line originates from */
1841
+ filePath: string;
1842
+ /** 1-based line number in the original (pre-resolution) source file */
1843
+ sourceLine: number;
1844
+ }
1845
+ interface ResolveImportsResult {
1846
+ content: string;
1847
+ diagnostics: DgmoError[];
1848
+ /** resolvedLine (1-based index) → originalLine (1-based) or null for inserted lines */
1849
+ lineMap: (number | null)[];
1850
+ /** resolvedLine (1-based index) → import source info or null for non-imported lines */
1851
+ importSourceMap: (ImportSource | null)[];
1852
+ }
1853
+ /**
1854
+ * Pre-processes org chart content, resolving `tags:` and `import:` directives.
1855
+ *
1856
+ * @param content - Raw .dgmo file content
1857
+ * @param filePath - Absolute path of the file (for relative path resolution)
1858
+ * @param readFileFn - Function to read files (sync or async)
1859
+ * @returns Merged content with all imports resolved + diagnostics
1860
+ */
1861
+ declare function resolveOrgImports(content: string, filePath: string, readFileFn: ReadFileFn): Promise<ResolveImportsResult>;
1424
1862
 
1425
1863
  declare function renderFlowchart(container: HTMLDivElement, graph: ParsedGraph, layout: LayoutResult, palette: PaletteColors, isDark: boolean, onClickItem?: (lineNumber: number) => void, exportDims?: {
1426
1864
  width?: number;
@@ -1436,6 +1874,7 @@ interface SequenceRenderOptions {
1436
1874
  collapsedSections?: Set<number>;
1437
1875
  expandedNoteLines?: Set<number>;
1438
1876
  exportWidth?: number;
1877
+ activeTagGroup?: string | null;
1439
1878
  }
1440
1879
  /**
1441
1880
  * Group messages by the top-level section that precedes them.
@@ -1476,9 +1915,14 @@ declare function computeActivations(steps: RenderStep[]): Activation[];
1476
1915
  declare function applyPositionOverrides(participants: SequenceParticipant[]): SequenceParticipant[];
1477
1916
  /**
1478
1917
  * Reorder participants so that members of the same group are adjacent.
1479
- * Groups appear in declaration order, followed by ungrouped participants.
1918
+ * Groups are positioned at the point where their first member would naturally
1919
+ * appear based on message order (first-occurrence positioning). This prevents
1920
+ * groups declared at the top of the file from being placed before participants
1921
+ * that appear in messages earlier.
1922
+ *
1923
+ * Explicit `position` overrides are handled separately by `applyPositionOverrides`.
1480
1924
  */
1481
- declare function applyGroupOrdering(participants: SequenceParticipant[], groups: SequenceGroup[]): SequenceParticipant[];
1925
+ declare function applyGroupOrdering(participants: SequenceParticipant[], groups: SequenceGroup[], messages?: SequenceMessage[]): SequenceParticipant[];
1482
1926
  /**
1483
1927
  * Render a sequence diagram into the given container element.
1484
1928
  */
@@ -1567,4 +2011,4 @@ declare function decodeDiagramUrl(hash: string): DecodedDiagramUrl;
1567
2011
  */
1568
2012
  declare function injectBranding(svgHtml: string, mutedColor: string): string;
1569
2013
 
1570
- export { type Activation, type ArcLink, type ArcNodeGroup, type C4ArrowType, type C4DeploymentNode, type C4Element, type C4ElementType, type C4Group, type C4LayoutBoundary, type C4LayoutEdge, type C4LayoutNode, type C4LayoutResult, type C4LegendEntry, type C4LegendGroup, type C4Relationship, type C4Shape, type C4TagEntry, type C4TagGroup, type ChartDataPoint, type ChartType, type ClassLayoutEdge, type ClassLayoutNode, type ClassLayoutResult, type ClassMember, type ClassModifier, type ClassNode, type ClassRelationship, type CollapsedOrgResult, type ContextRelationship, type D3ChartType, type D3ExportDimensions, DGMO_CHART_TYPE_MAP, type DecodedDiagramUrl, type DgmoError, type DgmoFramework, type DgmoSeverity, type DiagramViewState, type EChartsChartType, type ERCardinality, type ERColumn, type ERConstraint, type ERLayoutEdge, type ERLayoutNode, type ERLayoutResult, type ERRelationship, type ERTable, type ElseIfBranch, type EncodeDiagramUrlOptions, type EncodeDiagramUrlResult, type GraphDirection, type GraphEdge, type GraphGroup, type GraphNode, type GraphShape, type ISEdge, type ISGroup, type ISLayoutEdge, type ISLayoutGroup, type ISLayoutNode, type ISLayoutResult, type ISNode, type InitiativeStatus, type InlineSpan, type KanbanCard, type KanbanColumn, type KanbanTagEntry, type KanbanTagGroup, type LayoutEdge, type LayoutGroup, type LayoutNode, type LayoutResult, type MemberVisibility, type OrgContainerBounds, type OrgLayoutEdge, type OrgLayoutNode, type OrgLayoutResult, type OrgNode, type OrgTagEntry, type OrgTagGroup, type PaletteColors, type PaletteConfig, type ParsedC4, type ParsedChart, type ParsedClassDiagram, type ParsedD3, type ParsedEChart, type ParsedERDiagram, type ParsedGraph, type ParsedInitiativeStatus, type ParsedKanban, type ParsedOrg, type ParsedQuadrant, type ParsedSequenceDgmo, type ParticipantType, RULE_COUNT, type ReadFileFn, type RelationshipType, type RenderStep, type ResolveImportsResult, STANDARD_CHART_TYPES, type SectionMessageGroup, type SequenceBlock, type SequenceElement, type SequenceGroup, type SequenceMessage, type SequenceNote, type SequenceParticipant, type SequenceRenderOptions, type SequenceSection, type TagEntry, type TagGroup, addDurationToDate, applyGroupOrdering, applyPositionOverrides, boldPalette, buildEChartsOption, buildEChartsOptionFromChart, buildMermaidQuadrant, buildMermaidThemeVars, buildNoteMessageMap, buildRenderSequence, buildThemeCSS, catppuccinPalette, collapseOrgTree, colorNames, computeActivations, computeCardArchive, computeCardMove, computeTimeTicks, contrastText, decodeDiagramUrl, encodeDiagramUrl, formatDateLabel, formatDgmoError, getAvailablePalettes, getDgmoFramework, getPalette, getSeriesColors, groupMessagesBySection, gruvboxPalette, hexToHSL, hexToHSLString, hslToHex, inferParticipantType, injectBranding, isArchiveColumn, isSequenceBlock, isSequenceNote, isValidHex, layoutC4Components, layoutC4Containers, layoutC4Context, layoutC4Deployment, layoutClassDiagram, layoutERDiagram, layoutGraph, layoutInitiativeStatus, layoutOrg, looksLikeClassDiagram, looksLikeERDiagram, looksLikeFlowchart, looksLikeInitiativeStatus, looksLikeSequence, makeDgmoError, mute, nord, nordPalette, oneDarkPalette, orderArcNodes, parseC4, parseChart, parseClassDiagram, parseD3, parseDgmo, parseDgmoChartType, parseEChart, parseERDiagram, parseFlowchart, parseInitiativeStatus, parseInlineMarkdown, parseKanban, parseOrg, parseQuadrant, parseSequenceDgmo, parseTimelineDate, registerPalette, render, renderArcDiagram, renderC4ComponentsForExport, renderC4Containers, renderC4ContainersForExport, renderC4Context, renderC4ContextForExport, renderC4Deployment, renderC4DeploymentForExport, renderClassDiagram, renderClassDiagramForExport, renderD3ForExport, renderEChartsForExport, renderERDiagram, renderERDiagramForExport, renderFlowchart, renderFlowchartForExport, renderInitiativeStatus, renderInitiativeStatusForExport, renderKanban, renderKanbanForExport, renderOrg, renderOrgForExport, renderQuadrant, renderSequenceDiagram, renderSlopeChart, renderTimeline, renderVenn, renderWordCloud, resolveColor, resolveOrgImports, rollUpContextRelationships, rosePinePalette, seriesColors, shade, solarizedPalette, tint, tokyoNightPalette, truncateBareUrl };
2014
+ export { type Activation, type ArcLink, type ArcNodeGroup, type C4ArrowType, type C4DeploymentNode, type C4Element, type C4ElementType, type C4Group, type C4LayoutBoundary, type C4LayoutEdge, type C4LayoutNode, type C4LayoutResult, type C4LegendEntry, type C4LegendGroup, type C4Relationship, type C4Shape, type C4TagEntry, type C4TagGroup, type ChartDataPoint, type ChartType, type ClassLayoutEdge, type ClassLayoutNode, type ClassLayoutResult, type ClassMember, type ClassModifier, type ClassNode, type ClassRelationship, type CollapsedOrgResult, type CollapsedSitemapResult, type ComputedInfraEdge, type ComputedInfraModel, type ComputedInfraNode, type ContextRelationship, type D3ChartType, type D3ExportDimensions, DGMO_CHART_TYPE_MAP, type DecodedDiagramUrl, type DgmoError, type DgmoFramework, type DgmoSeverity, type DiagramViewState, type EChartsChartType, type ERCardinality, type ERColumn, type ERConstraint, type ERLayoutEdge, type ERLayoutNode, type ERLayoutResult, type ERRelationship, type ERTable, type ElseIfBranch, type EncodeDiagramUrlOptions, type EncodeDiagramUrlResult, type GraphDirection, type GraphEdge, type GraphGroup, type GraphNode, type GraphShape, INFRA_BEHAVIOR_KEYS, type ISEdge, type ISGroup, type ISLayoutEdge, type ISLayoutGroup, type ISLayoutNode, type ISLayoutResult, type ISNode, type ImportSource, type InfraAvailabilityPercentiles, type InfraBehaviorKey, type InfraCbState, type InfraComputeParams, type InfraDiagnostic, type InfraEdge, type InfraGroup, type InfraLatencyPercentiles, type InfraLayoutEdge, type InfraLayoutGroup, type InfraLayoutNode, type InfraLayoutResult, type InfraLegendGroup, type InfraNode, type InfraPlaybackState, type InfraProperty, type InfraRole, type InfraScenario, type InfraTagGroup, type InitiativeStatus, type InlineSpan, type KanbanCard, type KanbanColumn, type KanbanTagEntry, type KanbanTagGroup, type LayoutEdge, type LayoutGroup, type LayoutNode, type LayoutResult, type MemberVisibility, type OrgContainerBounds, type OrgLayoutEdge, type OrgLayoutNode, type OrgLayoutResult, type OrgNode, type OrgTagEntry, type OrgTagGroup, type PaletteColors, type PaletteConfig, type ParsedC4, type ParsedChart, type ParsedClassDiagram, type ParsedD3, type ParsedEChart, type ParsedERDiagram, type ParsedGraph, type ParsedInfra, type ParsedInitiativeStatus, type ParsedKanban, type ParsedOrg, type ParsedQuadrant, type ParsedSequenceDgmo, type ParsedSitemap, type ParticipantType, RULE_COUNT, type ReadFileFn, type RelationshipType, type RenderStep, type ResolveImportsResult, STANDARD_CHART_TYPES, type SectionMessageGroup, type SequenceBlock, type SequenceElement, type SequenceGroup, type SequenceMessage, type SequenceNote, type SequenceParticipant, type SequenceRenderOptions, type SequenceSection, type SitemapContainerBounds, type SitemapDirection, type SitemapEdge, type SitemapLayoutEdge, type SitemapLayoutNode, type SitemapLayoutResult, type SitemapLegendEntry, type SitemapLegendGroup, type SitemapNode, type TagEntry, type TagGroup, addDurationToDate, applyGroupOrdering, applyPositionOverrides, boldPalette, buildEChartsOption, buildEChartsOptionFromChart, buildMermaidQuadrant, buildMermaidThemeVars, buildNoteMessageMap, buildRenderSequence, buildThemeCSS, catppuccinPalette, collapseOrgTree, collapseSitemapTree, collectDiagramRoles, colorNames, computeActivations, computeCardArchive, computeCardMove, computeInfra, computeInfraLegendGroups, computeTimeTicks, contrastText, decodeDiagramUrl, encodeDiagramUrl, formatDateLabel, formatDgmoError, getAvailablePalettes, getDgmoFramework, getPalette, getSeriesColors, groupMessagesBySection, gruvboxPalette, hexToHSL, hexToHSLString, hslToHex, inferParticipantType, inferRoles, injectBranding, isArchiveColumn, isSequenceBlock, isSequenceNote, isValidHex, layoutC4Components, layoutC4Containers, layoutC4Context, layoutC4Deployment, layoutClassDiagram, layoutERDiagram, layoutGraph, layoutInfra, layoutInitiativeStatus, layoutOrg, layoutSitemap, looksLikeClassDiagram, looksLikeERDiagram, looksLikeFlowchart, looksLikeInitiativeStatus, looksLikeSequence, looksLikeSitemap, looksLikeState, makeDgmoError, mute, nord, nordPalette, oneDarkPalette, orderArcNodes, parseAndLayoutInfra, parseC4, parseChart, parseClassDiagram, parseD3, parseDgmo, parseDgmoChartType, parseEChart, parseERDiagram, parseFlowchart, parseInfra, parseInitiativeStatus, parseInlineMarkdown, parseKanban, parseOrg, parseQuadrant, parseSequenceDgmo, parseSitemap, parseState, parseTimelineDate, registerPalette, render, renderArcDiagram, renderC4ComponentsForExport, renderC4Containers, renderC4ContainersForExport, renderC4Context, renderC4ContextForExport, renderC4Deployment, renderC4DeploymentForExport, renderClassDiagram, renderClassDiagramForExport, renderD3ForExport, renderEChartsForExport, renderERDiagram, renderERDiagramForExport, renderFlowchart, renderFlowchartForExport, renderInfra, renderInitiativeStatus, renderInitiativeStatusForExport, renderKanban, renderKanbanForExport, renderOrg, renderOrgForExport, renderQuadrant, renderSequenceDiagram, renderSitemap, renderSitemapForExport, renderSlopeChart, renderState, renderStateForExport, renderTimeline, renderVenn, renderWordCloud, resolveColor, resolveOrgImports, rollUpContextRelationships, rosePinePalette, seriesColors, shade, solarizedPalette, tint, tokyoNightPalette, truncateBareUrl, validateComputed, validateInfra };