@diagrammo/dgmo 0.8.3 → 0.8.5

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 (122) hide show
  1. package/.claude/commands/dgmo-diagram-this.md +60 -0
  2. package/.claude/commands/dgmo-document-project.md +128 -0
  3. package/.claude/commands/dgmo.md +452 -50
  4. package/.cursorrules +32 -37
  5. package/.github/copilot-instructions.md +35 -44
  6. package/.windsurfrules +32 -37
  7. package/README.md +4 -4
  8. package/dist/cli.cjs +188 -185
  9. package/dist/editor.cjs +338 -0
  10. package/dist/editor.cjs.map +1 -0
  11. package/dist/editor.d.cts +27 -0
  12. package/dist/editor.d.ts +27 -0
  13. package/dist/editor.js +307 -0
  14. package/dist/editor.js.map +1 -0
  15. package/dist/highlight.cjs +560 -0
  16. package/dist/highlight.cjs.map +1 -0
  17. package/dist/highlight.d.cts +32 -0
  18. package/dist/highlight.d.ts +32 -0
  19. package/dist/highlight.js +530 -0
  20. package/dist/highlight.js.map +1 -0
  21. package/dist/index.cjs +3467 -1078
  22. package/dist/index.cjs.map +1 -1
  23. package/dist/index.d.cts +22 -1
  24. package/dist/index.d.ts +22 -1
  25. package/dist/index.js +3466 -1078
  26. package/dist/index.js.map +1 -1
  27. package/docs/language-reference.md +46 -37
  28. package/gallery/fixtures/arc.dgmo +18 -0
  29. package/gallery/fixtures/area.dgmo +19 -0
  30. package/gallery/fixtures/bar-stacked.dgmo +10 -0
  31. package/gallery/fixtures/bar.dgmo +10 -0
  32. package/gallery/fixtures/c4-full.dgmo +52 -0
  33. package/gallery/fixtures/c4.dgmo +17 -0
  34. package/gallery/fixtures/chord.dgmo +12 -0
  35. package/gallery/fixtures/class-basic.dgmo +14 -0
  36. package/gallery/fixtures/class-full.dgmo +43 -0
  37. package/gallery/fixtures/doughnut.dgmo +8 -0
  38. package/gallery/fixtures/flowchart-basic.dgmo +3 -0
  39. package/gallery/fixtures/flowchart-colors.dgmo +5 -0
  40. package/gallery/fixtures/flowchart-complex.dgmo +17 -0
  41. package/gallery/fixtures/flowchart-decision.dgmo +5 -0
  42. package/gallery/fixtures/flowchart-full.dgmo +13 -0
  43. package/gallery/fixtures/flowchart-groups.dgmo +10 -0
  44. package/gallery/fixtures/flowchart-loop.dgmo +7 -0
  45. package/gallery/fixtures/flowchart-nested.dgmo +7 -0
  46. package/gallery/fixtures/flowchart-shapes.dgmo +5 -0
  47. package/gallery/fixtures/function.dgmo +8 -0
  48. package/gallery/fixtures/funnel.dgmo +7 -0
  49. package/gallery/fixtures/gantt-full.dgmo +49 -0
  50. package/gallery/fixtures/gantt.dgmo +42 -0
  51. package/gallery/fixtures/heatmap.dgmo +8 -0
  52. package/gallery/fixtures/infra-full.dgmo +78 -0
  53. package/gallery/fixtures/infra-overload.dgmo +25 -0
  54. package/gallery/fixtures/infra.dgmo +47 -0
  55. package/gallery/fixtures/initiative-status-full.dgmo +46 -0
  56. package/gallery/fixtures/initiative-status-phases.dgmo +29 -0
  57. package/gallery/fixtures/initiative-status.dgmo +9 -0
  58. package/gallery/fixtures/line.dgmo +19 -0
  59. package/gallery/fixtures/multi-line.dgmo +11 -0
  60. package/gallery/fixtures/org-basic.dgmo +16 -0
  61. package/gallery/fixtures/org-full.dgmo +69 -0
  62. package/gallery/fixtures/org-teams.dgmo +25 -0
  63. package/gallery/fixtures/pie.dgmo +9 -0
  64. package/gallery/fixtures/polar-area.dgmo +8 -0
  65. package/gallery/fixtures/quadrant.dgmo +18 -0
  66. package/gallery/fixtures/radar.dgmo +8 -0
  67. package/gallery/fixtures/sankey.dgmo +31 -0
  68. package/gallery/fixtures/scatter.dgmo +21 -0
  69. package/gallery/fixtures/sequence-tags-protocols.dgmo +45 -0
  70. package/gallery/fixtures/sequence-tags.dgmo +41 -0
  71. package/gallery/fixtures/sequence.dgmo +35 -0
  72. package/gallery/fixtures/sitemap-basic.dgmo +12 -0
  73. package/gallery/fixtures/sitemap-full.dgmo +156 -0
  74. package/gallery/fixtures/slope.dgmo +9 -0
  75. package/gallery/fixtures/spr-eras.dgmo +62 -0
  76. package/gallery/fixtures/state.dgmo +30 -0
  77. package/gallery/fixtures/timeline-intraday.dgmo +14 -0
  78. package/gallery/fixtures/timeline.dgmo +32 -0
  79. package/gallery/fixtures/venn.dgmo +10 -0
  80. package/gallery/fixtures/wordcloud.dgmo +24 -0
  81. package/package.json +71 -2
  82. package/src/c4/layout.ts +372 -90
  83. package/src/c4/parser.ts +100 -55
  84. package/src/chart.ts +91 -28
  85. package/src/class/parser.ts +41 -12
  86. package/src/cli.ts +211 -62
  87. package/src/completion.ts +378 -183
  88. package/src/d3.ts +1044 -303
  89. package/src/dgmo-mermaid.ts +16 -13
  90. package/src/dgmo-router.ts +69 -23
  91. package/src/echarts.ts +646 -153
  92. package/src/editor/dgmo.grammar +69 -0
  93. package/src/editor/dgmo.grammar.d.ts +2 -0
  94. package/src/editor/dgmo.grammar.js +18 -0
  95. package/src/editor/dgmo.grammar.terms.d.ts +5 -0
  96. package/src/editor/dgmo.grammar.terms.js +35 -0
  97. package/src/editor/highlight-api.ts +444 -0
  98. package/src/editor/highlight.ts +36 -0
  99. package/src/editor/index.ts +28 -0
  100. package/src/editor/keywords.ts +222 -0
  101. package/src/editor/tokens.ts +30 -0
  102. package/src/er/parser.ts +48 -14
  103. package/src/er/renderer.ts +112 -53
  104. package/src/gantt/calculator.ts +91 -29
  105. package/src/gantt/parser.ts +197 -71
  106. package/src/gantt/renderer.ts +1120 -350
  107. package/src/graph/flowchart-parser.ts +46 -25
  108. package/src/graph/state-parser.ts +47 -17
  109. package/src/index.ts +96 -31
  110. package/src/infra/parser.ts +157 -53
  111. package/src/infra/renderer.ts +723 -271
  112. package/src/initiative-status/parser.ts +138 -44
  113. package/src/kanban/parser.ts +25 -14
  114. package/src/org/layout.ts +111 -44
  115. package/src/org/parser.ts +69 -22
  116. package/src/palettes/index.ts +3 -2
  117. package/src/sequence/parser.ts +193 -61
  118. package/src/sitemap/parser.ts +65 -29
  119. package/src/utils/arrows.ts +2 -22
  120. package/src/utils/duration.ts +39 -21
  121. package/src/utils/legend-constants.ts +0 -2
  122. package/src/utils/parsing.ts +75 -31
@@ -39,11 +39,11 @@ export interface ParsedQuadrant {
39
39
  // Parser
40
40
  // ============================================================
41
41
 
42
- /** Regex for quadrant label lines: `top-right: Promote (green)` */
42
+ /** Regex for quadrant label lines: `top-right Promote (green)` */
43
43
  const QUADRANT_LABEL_RE = /^(.+?)(?:\s*\(([^)]+)\))?\s*$/;
44
44
 
45
- /** Regex for data point lines: `Label: 0.9, 0.5` */
46
- const DATA_POINT_RE = /^(.+?):\s*([0-9]*\.?[0-9]+)\s*,\s*([0-9]*\.?[0-9]+)\s*$/;
45
+ /** Regex for data point lines: `Label 0.9, 0.5` */
46
+ const DATA_POINT_RE = /^(.+?)\s+([0-9]*\.?[0-9]+)\s*,\s*([0-9]*\.?[0-9]+)\s*$/;
47
47
 
48
48
  const QUADRANT_POSITIONS = new Set([
49
49
  'top-right',
@@ -87,16 +87,16 @@ export function parseQuadrant(content: string): ParsedQuadrant {
87
87
  // Skip the chart: directive (already consumed by router)
88
88
  if (/^chart\s*:/i.test(line)) continue;
89
89
 
90
- // title: <text>
91
- const titleMatch = line.match(/^title\s*:\s*(.+)/i);
90
+ // title <text>
91
+ const titleMatch = line.match(/^title\s+(.+)/i);
92
92
  if (titleMatch) {
93
93
  result.title = titleMatch[1].trim();
94
94
  result.titleLineNumber = lineNumber;
95
95
  continue;
96
96
  }
97
97
 
98
- // x-axis: Low, High
99
- const xMatch = line.match(/^x-axis\s*:\s*(.+)/i);
98
+ // x-label Low, High
99
+ const xMatch = line.match(/^x-label\s+(.+)/i);
100
100
  if (xMatch) {
101
101
  const parts = xMatch[1].split(',').map((s) => s.trim());
102
102
  if (parts.length >= 2) {
@@ -106,8 +106,8 @@ export function parseQuadrant(content: string): ParsedQuadrant {
106
106
  continue;
107
107
  }
108
108
 
109
- // y-axis: Low, High
110
- const yMatch = line.match(/^y-axis\s*:\s*(.+)/i);
109
+ // y-label Low, High
110
+ const yMatch = line.match(/^y-label\s+(.+)/i);
111
111
  if (yMatch) {
112
112
  const parts = yMatch[1].split(',').map((s) => s.trim());
113
113
  if (parts.length >= 2) {
@@ -117,9 +117,9 @@ export function parseQuadrant(content: string): ParsedQuadrant {
117
117
  continue;
118
118
  }
119
119
 
120
- // Quadrant position labels: top-right: Label (color)
120
+ // Quadrant position labels: top-right Label (color)
121
121
  const posMatch = line.match(
122
- /^(top-right|top-left|bottom-left|bottom-right)\s*:\s*(.+)/i
122
+ /^(top-right|top-left|bottom-left|bottom-right)\s+(.+)/i
123
123
  );
124
124
  if (posMatch) {
125
125
  const position = posMatch[1].toLowerCase();
@@ -140,7 +140,7 @@ export function parseQuadrant(content: string): ParsedQuadrant {
140
140
  continue;
141
141
  }
142
142
 
143
- // Data points: Label: x, y
143
+ // Data points: Label x, y
144
144
  const pointMatch = line.match(DATA_POINT_RE);
145
145
  if (pointMatch) {
146
146
  // Make sure this isn't a quadrant position keyword
@@ -158,7 +158,10 @@ export function parseQuadrant(content: string): ParsedQuadrant {
158
158
  }
159
159
 
160
160
  if (result.points.length === 0) {
161
- const diag = makeDgmoError(1, 'No data points found. Add lines like: Label: 0.5, 0.7');
161
+ const diag = makeDgmoError(
162
+ 1,
163
+ 'No data points found. Add lines like: Label 0.5, 0.7'
164
+ );
162
165
  result.diagnostics.push(diag);
163
166
  result.error = formatDgmoError(diag);
164
167
  }
@@ -13,25 +13,28 @@ import { parseVisualization } from './d3';
13
13
  import { parseOrg, looksLikeOrg } from './org/parser';
14
14
  import { parseKanban } from './kanban/parser';
15
15
  import { parseC4 } from './c4/parser';
16
- import { looksLikeInitiativeStatus, parseInitiativeStatus } from './initiative-status/parser';
16
+ import {
17
+ looksLikeInitiativeStatus,
18
+ parseInitiativeStatus,
19
+ } from './initiative-status/parser';
17
20
  import { looksLikeSitemap, parseSitemap } from './sitemap/parser';
18
21
  import { parseInfra } from './infra/parser';
19
22
  import { parseGantt } from './gantt/parser';
20
- import { ALL_CHART_TYPES, parseFirstLine } from './utils/parsing';
23
+ import { parseFirstLine } from './utils/parsing';
21
24
  import type { DgmoError } from './diagnostics';
22
25
 
23
26
  // ============================================================
24
27
  // Content-based chart type inference helpers
25
28
  // ============================================================
26
29
 
27
- /** Gantt duration patterns: `10bd Task` or `10bd: Task` (with or without colon) */
28
- const GANTT_DURATION_RE = /^\d+(?:\.\d+)?(?:min|bd|d|w|m|q|y|h)(?:\?)?\s*:?\s+/;
29
- /** Gantt date patterns: `2025-01-01 Task` or `2025-01-01: Task` (with or without colon) */
30
- const GANTT_DATE_RE = /^\d{4}-\d{2}-\d{2}(?:\s\d{2}:\d{2})?\s*:?\s+/;
30
+ /** Gantt duration patterns: `10bd Task` */
31
+ const GANTT_DURATION_RE = /^\d+(?:\.\d+)?(?:min|bd|d|w|m|q|y|h)(?:\?)?\s+/;
32
+ /** Gantt date patterns: `2025-01-01 Task` */
33
+ const GANTT_DATE_RE = /^\d{4}-\d{2}-\d{2}(?:\s\d{2}:\d{2})?\s+/;
31
34
 
32
35
  /**
33
36
  * Returns true if content looks like a gantt chart.
34
- * Detects duration patterns like `10bd: Task` or `5d: Task`.
37
+ * Detects duration patterns like `10bd Task` or `5d Task`.
35
38
  */
36
39
  export function looksLikeGantt(content: string): boolean {
37
40
  const lines = content.split('\n');
@@ -112,19 +115,51 @@ export function parseDgmoChartType(content: string): string | null {
112
115
  export type RenderCategory = 'data-chart' | 'visualization' | 'diagram';
113
116
 
114
117
  const DATA_CHART_TYPES = new Set([
115
- 'bar', 'line', 'pie', 'doughnut', 'area', 'polar-area', 'radar',
116
- 'bar-stacked', 'multi-line', 'scatter', 'sankey', 'chord', 'function',
117
- 'heatmap', 'funnel',
118
+ 'bar',
119
+ 'line',
120
+ 'pie',
121
+ 'doughnut',
122
+ 'area',
123
+ 'polar-area',
124
+ 'radar',
125
+ 'bar-stacked',
126
+ 'multi-line',
127
+ 'scatter',
128
+ 'sankey',
129
+ 'chord',
130
+ 'function',
131
+ 'heatmap',
132
+ 'funnel',
118
133
  ]);
119
134
  const VISUALIZATION_TYPES = new Set([
120
- 'slope', 'wordcloud', 'arc', 'timeline', 'venn', 'quadrant',
135
+ 'slope',
136
+ 'wordcloud',
137
+ 'arc',
138
+ 'timeline',
139
+ 'venn',
140
+ 'quadrant',
121
141
  ]);
122
142
  const DIAGRAM_TYPES = new Set([
123
- 'sequence', 'flowchart', 'class', 'er', 'org', 'kanban', 'c4',
124
- 'initiative-status', 'state', 'sitemap', 'infra', 'gantt',
143
+ 'sequence',
144
+ 'flowchart',
145
+ 'class',
146
+ 'er',
147
+ 'org',
148
+ 'kanban',
149
+ 'c4',
150
+ 'initiative-status',
151
+ 'state',
152
+ 'sitemap',
153
+ 'infra',
154
+ 'gantt',
125
155
  ]);
126
156
  const EXTENDED_CHART_TYPES = new Set([
127
- 'scatter', 'sankey', 'chord', 'function', 'heatmap', 'funnel',
157
+ 'scatter',
158
+ 'sankey',
159
+ 'chord',
160
+ 'function',
161
+ 'heatmap',
162
+ 'funnel',
128
163
  ]);
129
164
 
130
165
  /**
@@ -150,8 +185,15 @@ export function isExtendedChartType(chartType: string): boolean {
150
185
 
151
186
  /** Standard chart types parsed by parseChart (then rendered via ECharts). Internal use. */
152
187
  const STANDARD_CHART_TYPES = new Set([
153
- 'bar', 'line', 'multi-line', 'area', 'pie', 'doughnut',
154
- 'radar', 'polar-area', 'bar-stacked',
188
+ 'bar',
189
+ 'line',
190
+ 'multi-line',
191
+ 'area',
192
+ 'pie',
193
+ 'doughnut',
194
+ 'radar',
195
+ 'polar-area',
196
+ 'bar-stacked',
155
197
  ]);
156
198
 
157
199
  /**
@@ -159,20 +201,24 @@ const STANDARD_CHART_TYPES = new Set([
159
201
  * Useful for CLI enumeration and autocomplete.
160
202
  */
161
203
  export function getAllChartTypes(): string[] {
162
- return [
163
- ...DATA_CHART_TYPES,
164
- ...VISUALIZATION_TYPES,
165
- ...DIAGRAM_TYPES,
166
- ];
204
+ return [...DATA_CHART_TYPES, ...VISUALIZATION_TYPES, ...DIAGRAM_TYPES];
167
205
  }
168
206
 
169
207
  // ECharts-native types parsed by parseExtendedChart
170
208
  const ECHART_TYPES = new Set([
171
- 'scatter', 'sankey', 'chord', 'function', 'heatmap', 'funnel',
209
+ 'scatter',
210
+ 'sankey',
211
+ 'chord',
212
+ 'function',
213
+ 'heatmap',
214
+ 'funnel',
172
215
  ]);
173
216
 
174
217
  /** Map chart type strings to their parse function (content → { diagnostics }). */
175
- const PARSE_DISPATCH = new Map<string, (content: string) => { diagnostics: DgmoError[] }>([
218
+ const PARSE_DISPATCH = new Map<
219
+ string,
220
+ (content: string) => { diagnostics: DgmoError[] }
221
+ >([
176
222
  ['sequence', (c) => parseSequenceDgmo(c)],
177
223
  ['flowchart', (c) => parseFlowchart(c)],
178
224
  ['class', (c) => parseClassDiagram(c)],