@diagrammo/dgmo 0.6.2 ā 0.6.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.
- package/.claude/commands/dgmo.md +231 -13
- package/AGENTS.md +148 -0
- package/dist/cli.cjs +327 -153
- package/dist/index.cjs +305 -177
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +24 -3
- package/dist/index.d.ts +24 -3
- package/dist/index.js +303 -177
- package/dist/index.js.map +1 -1
- package/package.json +5 -3
- package/src/c4/layout.ts +0 -5
- package/src/c4/parser.ts +0 -16
- package/src/c4/renderer.ts +1 -5
- package/src/class/layout.ts +0 -1
- package/src/class/parser.ts +28 -0
- package/src/class/renderer.ts +5 -26
- package/src/cli.ts +563 -14
- package/src/completion.ts +58 -0
- package/src/d3.ts +58 -106
- package/src/dgmo-router.ts +0 -57
- package/src/echarts.ts +96 -55
- package/src/er/parser.ts +30 -1
- package/src/er/renderer.ts +1 -2
- package/src/graph/flowchart-parser.ts +27 -4
- package/src/graph/flowchart-renderer.ts +1 -2
- package/src/graph/state-parser.ts +0 -1
- package/src/graph/state-renderer.ts +1 -3
- package/src/index.ts +10 -0
- package/src/infra/compute.ts +0 -7
- package/src/infra/layout.ts +0 -2
- package/src/infra/parser.ts +46 -4
- package/src/infra/renderer.ts +1 -15
- package/src/initiative-status/renderer.ts +5 -25
- package/src/kanban/parser.ts +0 -2
- package/src/org/layout.ts +0 -4
- package/src/org/renderer.ts +7 -28
- package/src/sequence/parser.ts +14 -11
- package/src/sequence/renderer.ts +0 -2
- package/src/sequence/tag-resolution.ts +0 -1
- package/src/sitemap/layout.ts +1 -14
- package/src/sitemap/parser.ts +1 -2
- package/src/sitemap/renderer.ts +0 -3
- package/src/utils/arrows.ts +7 -7
- package/src/utils/export-container.ts +40 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@diagrammo/dgmo",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.3",
|
|
4
4
|
"description": "DGMO diagram markup language ā parser, renderer, and color system",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -29,7 +29,8 @@
|
|
|
29
29
|
".claude/commands",
|
|
30
30
|
".github/copilot-instructions.md",
|
|
31
31
|
".cursorrules",
|
|
32
|
-
".windsurfrules"
|
|
32
|
+
".windsurfrules",
|
|
33
|
+
"AGENTS.md"
|
|
33
34
|
],
|
|
34
35
|
"sideEffects": false,
|
|
35
36
|
"scripts": {
|
|
@@ -40,6 +41,7 @@
|
|
|
40
41
|
"test:watch": "vitest",
|
|
41
42
|
"gallery": "pnpm build && node scripts/generate-gallery.mjs",
|
|
42
43
|
"check:duplication": "jscpd ./src",
|
|
44
|
+
"check:deadcode": "knip",
|
|
43
45
|
"postinstall": "node -e \"console.log('\\nš” Claude Code user? Run: dgmo --install-claude-skill\\n')\""
|
|
44
46
|
},
|
|
45
47
|
"dependencies": {
|
|
@@ -64,9 +66,9 @@
|
|
|
64
66
|
"@types/d3-scale": "^4.0.8",
|
|
65
67
|
"@types/d3-selection": "^3.0.11",
|
|
66
68
|
"@types/d3-shape": "^3.1.7",
|
|
67
|
-
"@types/dagre": "^0.7.54",
|
|
68
69
|
"@types/jsdom": "^28.0.0",
|
|
69
70
|
"jscpd": "^4.0.8",
|
|
71
|
+
"knip": "^6.0.1",
|
|
70
72
|
"tsup": "^8.5.1",
|
|
71
73
|
"typescript": "^5.7.3",
|
|
72
74
|
"vitest": "^4.0.18"
|
package/src/c4/layout.ts
CHANGED
|
@@ -86,7 +86,6 @@ const DESC_LINE_HEIGHT = 16;
|
|
|
86
86
|
const DESC_CHAR_WIDTH = 6.5;
|
|
87
87
|
const CARD_V_PAD = 14;
|
|
88
88
|
const CARD_H_PAD = 20;
|
|
89
|
-
const TECH_LINE_HEIGHT = 16;
|
|
90
89
|
const META_LINE_HEIGHT = 16;
|
|
91
90
|
const META_CHAR_WIDTH = 6.5;
|
|
92
91
|
const MARGIN = 40;
|
|
@@ -478,10 +477,6 @@ export function rollUpContextRelationships(parsed: ParsedC4): ContextRelationshi
|
|
|
478
477
|
const allRels = collectAllRelationships(parsed.elements, ownerMap);
|
|
479
478
|
|
|
480
479
|
// Also include orphan relationships
|
|
481
|
-
for (const rel of parsed.relationships) {
|
|
482
|
-
// Orphan rels have no source element name ā skip them for context roll-up
|
|
483
|
-
}
|
|
484
|
-
|
|
485
480
|
// Separate system-level (explicit) from nested (rolled-up)
|
|
486
481
|
const topLevelNames = new Set(parsed.elements.map((e) => e.name));
|
|
487
482
|
const explicitKeys = new Set<string>();
|
package/src/c4/parser.ts
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
// ============================================================
|
|
4
4
|
|
|
5
5
|
import type { PaletteColors } from '../palettes';
|
|
6
|
-
import type { DgmoError } from '../diagnostics';
|
|
7
6
|
import { makeDgmoError, formatDgmoError, suggest } from '../diagnostics';
|
|
8
7
|
import type { TagGroup } from '../utils/tag-groups';
|
|
9
8
|
import { matchTagBlockHeading } from '../utils/tag-groups';
|
|
@@ -751,21 +750,6 @@ function attachElement(
|
|
|
751
750
|
// Post-parse validation
|
|
752
751
|
// ============================================================
|
|
753
752
|
|
|
754
|
-
function collectAllNames(result: ParsedC4): Map<string, number> {
|
|
755
|
-
const names = new Map<string, number>();
|
|
756
|
-
function walk(elements: C4Element[]) {
|
|
757
|
-
for (const el of elements) {
|
|
758
|
-
names.set(el.name.toLowerCase(), el.lineNumber);
|
|
759
|
-
walk(el.children);
|
|
760
|
-
for (const g of el.groups) {
|
|
761
|
-
walk(g.children);
|
|
762
|
-
}
|
|
763
|
-
}
|
|
764
|
-
}
|
|
765
|
-
walk(result.elements);
|
|
766
|
-
return names;
|
|
767
|
-
}
|
|
768
|
-
|
|
769
753
|
function validateRelationshipTargets(
|
|
770
754
|
result: ParsedC4,
|
|
771
755
|
knownNames: Map<string, number>,
|
package/src/c4/renderer.ts
CHANGED
|
@@ -9,8 +9,7 @@ import type { PaletteColors } from '../palettes';
|
|
|
9
9
|
import { mix } from '../palettes/color-utils';
|
|
10
10
|
import { renderInlineText } from '../utils/inline-markdown';
|
|
11
11
|
import type { ParsedC4 } from './types';
|
|
12
|
-
import type {
|
|
13
|
-
import type { C4LayoutResult, C4LayoutNode, C4LayoutEdge, C4LayoutBoundary, C4LegendGroup } from './layout';
|
|
12
|
+
import type { C4LayoutResult, C4LayoutEdge, C4LegendGroup } from './layout';
|
|
14
13
|
import { parseC4 } from './parser';
|
|
15
14
|
import { layoutC4Context, layoutC4Containers, layoutC4Components, layoutC4Deployment, collectCardMetadata } from './layout';
|
|
16
15
|
import {
|
|
@@ -50,7 +49,6 @@ const CARD_V_PAD = 14;
|
|
|
50
49
|
const TYPE_LABEL_HEIGHT = 18;
|
|
51
50
|
const DIVIDER_GAP = 6;
|
|
52
51
|
const NAME_HEIGHT = 20;
|
|
53
|
-
const TECH_LINE_HEIGHT = 16;
|
|
54
52
|
const META_FONT_SIZE = 11;
|
|
55
53
|
const META_CHAR_WIDTH = 6.5;
|
|
56
54
|
const META_LINE_HEIGHT = 16;
|
|
@@ -257,7 +255,6 @@ export function renderC4Context(
|
|
|
257
255
|
const scale = Math.min(MAX_SCALE, scaleX, scaleY);
|
|
258
256
|
|
|
259
257
|
const scaledW = diagramW * scale;
|
|
260
|
-
const scaledH = diagramH * scale;
|
|
261
258
|
const offsetX = (width - scaledW) / 2;
|
|
262
259
|
const offsetY = titleHeight + DIAGRAM_PADDING;
|
|
263
260
|
|
|
@@ -1300,7 +1297,6 @@ export function renderC4Containers(
|
|
|
1300
1297
|
const scale = Math.min(MAX_SCALE, scaleX, scaleY);
|
|
1301
1298
|
|
|
1302
1299
|
const scaledW = diagramW * scale;
|
|
1303
|
-
const scaledH = diagramH * scale;
|
|
1304
1300
|
const offsetX = (width - scaledW) / 2;
|
|
1305
1301
|
const offsetY = titleHeight + DIAGRAM_PADDING;
|
|
1306
1302
|
|
package/src/class/layout.ts
CHANGED
package/src/class/parser.ts
CHANGED
|
@@ -383,3 +383,31 @@ export function looksLikeClassDiagram(content: string): boolean {
|
|
|
383
383
|
|
|
384
384
|
return false;
|
|
385
385
|
}
|
|
386
|
+
|
|
387
|
+
// ============================================================
|
|
388
|
+
// Symbol extraction (for completion API)
|
|
389
|
+
// ============================================================
|
|
390
|
+
|
|
391
|
+
import type { DiagramSymbols } from '../completion';
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* Extract class names (entities) from class diagram document text.
|
|
395
|
+
* Used by the dgmo completion API for ghost hints and popup completions.
|
|
396
|
+
*/
|
|
397
|
+
export function extractSymbols(docText: string): DiagramSymbols {
|
|
398
|
+
const entities: string[] = [];
|
|
399
|
+
let inMetadata = true;
|
|
400
|
+
for (const rawLine of docText.split('\n')) {
|
|
401
|
+
const line = rawLine.trim();
|
|
402
|
+
if (inMetadata && /^[a-z-]+\s*:/i.test(line)) continue;
|
|
403
|
+
inMetadata = false;
|
|
404
|
+
if (line.length === 0 || /^\s/.test(rawLine)) continue;
|
|
405
|
+
const m = CLASS_DECL_RE.exec(line);
|
|
406
|
+
if (m && !entities.includes(m[1]!)) entities.push(m[1]!);
|
|
407
|
+
}
|
|
408
|
+
return {
|
|
409
|
+
kind: 'class',
|
|
410
|
+
entities,
|
|
411
|
+
keywords: ['extends', 'implements', 'abstract', 'interface', 'enum'],
|
|
412
|
+
};
|
|
413
|
+
}
|
package/src/class/renderer.ts
CHANGED
|
@@ -5,10 +5,11 @@
|
|
|
5
5
|
import * as d3Selection from 'd3-selection';
|
|
6
6
|
import * as d3Shape from 'd3-shape';
|
|
7
7
|
import { FONT_FAMILY } from '../fonts';
|
|
8
|
+
import { runInExportContainer, extractExportSvg } from '../utils/export-container';
|
|
8
9
|
import type { PaletteColors } from '../palettes';
|
|
9
10
|
import { mix } from '../palettes/color-utils';
|
|
10
11
|
import type { ParsedClassDiagram, ClassModifier, RelationshipType } from './types';
|
|
11
|
-
import type { ClassLayoutResult
|
|
12
|
+
import type { ClassLayoutResult } from './layout';
|
|
12
13
|
import { parseClassDiagram } from './parser';
|
|
13
14
|
import { layoutClassDiagram } from './layout';
|
|
14
15
|
|
|
@@ -99,8 +100,6 @@ function isSourceMarker(type: RelationshipType): boolean {
|
|
|
99
100
|
// Main renderer
|
|
100
101
|
// ============================================================
|
|
101
102
|
|
|
102
|
-
type GSelection = d3Selection.Selection<SVGGElement, unknown, null, undefined>;
|
|
103
|
-
|
|
104
103
|
export function renderClassDiagram(
|
|
105
104
|
container: HTMLDivElement,
|
|
106
105
|
parsed: ParsedClassDiagram,
|
|
@@ -125,7 +124,6 @@ export function renderClassDiagram(
|
|
|
125
124
|
const scale = Math.min(MAX_SCALE, scaleX, scaleY);
|
|
126
125
|
|
|
127
126
|
const scaledW = diagramW * scale;
|
|
128
|
-
const scaledH = diagramH * scale;
|
|
129
127
|
const offsetX = (width - scaledW) / 2;
|
|
130
128
|
const offsetY = titleHeight + DIAGRAM_PADDING;
|
|
131
129
|
|
|
@@ -506,16 +504,10 @@ export function renderClassDiagramForExport(
|
|
|
506
504
|
const layout = layoutClassDiagram(parsed);
|
|
507
505
|
const isDark = theme === 'dark';
|
|
508
506
|
|
|
509
|
-
const container = document.createElement('div');
|
|
510
507
|
const exportWidth = layout.width + DIAGRAM_PADDING * 2;
|
|
511
508
|
const exportHeight = layout.height + DIAGRAM_PADDING * 2 + (parsed.title ? 40 : 0);
|
|
512
|
-
container.style.width = `${exportWidth}px`;
|
|
513
|
-
container.style.height = `${exportHeight}px`;
|
|
514
|
-
container.style.position = 'absolute';
|
|
515
|
-
container.style.left = '-9999px';
|
|
516
|
-
document.body.appendChild(container);
|
|
517
509
|
|
|
518
|
-
|
|
510
|
+
return runInExportContainer(exportWidth, exportHeight, (container) => {
|
|
519
511
|
renderClassDiagram(
|
|
520
512
|
container,
|
|
521
513
|
parsed,
|
|
@@ -525,19 +517,6 @@ export function renderClassDiagramForExport(
|
|
|
525
517
|
undefined,
|
|
526
518
|
{ width: exportWidth, height: exportHeight }
|
|
527
519
|
);
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
if (!svgEl) return '';
|
|
531
|
-
|
|
532
|
-
if (theme === 'transparent') {
|
|
533
|
-
svgEl.style.background = 'none';
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
svgEl.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
|
|
537
|
-
svgEl.style.fontFamily = FONT_FAMILY;
|
|
538
|
-
|
|
539
|
-
return svgEl.outerHTML;
|
|
540
|
-
} finally {
|
|
541
|
-
document.body.removeChild(container);
|
|
542
|
-
}
|
|
520
|
+
return extractExportSvg(container, theme);
|
|
521
|
+
});
|
|
543
522
|
}
|