@diagrammo/dgmo 0.47.0 → 0.48.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auto.js +1 -1
- package/dist/auto.mjs +1 -1
- package/dist/element.js +1 -1
- package/dist/element.mjs +1 -1
- package/package.json +19 -70
- package/dist/advanced.cjs +0 -71648
- package/dist/advanced.d.cts +0 -5719
- package/dist/auto.cjs +0 -70648
- package/dist/auto.d.cts +0 -54
- package/dist/block.cjs +0 -70208
- package/dist/block.d.cts +0 -115
- package/dist/editor.cjs +0 -526
- package/dist/editor.d.cts +0 -26
- package/dist/element.cjs +0 -70530
- package/dist/element.d.cts +0 -62
- package/dist/highlight.cjs +0 -852
- package/dist/highlight.d.cts +0 -49
- package/dist/index.cjs +0 -70491
- package/dist/index.d.cts +0 -160
- package/dist/pert.cjs +0 -325
- package/dist/pert.d.cts +0 -559
- package/dist/themes-1-CuKpeH.d.cts +0 -908
- package/src/advanced.ts +0 -873
- package/src/arc/parser.ts +0 -15
- package/src/arc/renderer.ts +0 -633
- package/src/auto/index.ts +0 -621
- package/src/auto/shared.ts +0 -370
- package/src/auto/styles.ts +0 -73
- package/src/block/layout.ts +0 -198
- package/src/block/parser.ts +0 -427
- package/src/block/renderer.ts +0 -484
- package/src/block/types.ts +0 -67
- package/src/boxes-and-lines/collapse.ts +0 -96
- package/src/boxes-and-lines/focus.ts +0 -257
- package/src/boxes-and-lines/label-placement.ts +0 -339
- package/src/boxes-and-lines/layout-grouped.ts +0 -912
- package/src/boxes-and-lines/layout-layered.ts +0 -722
- package/src/boxes-and-lines/layout-search.ts +0 -1678
- package/src/boxes-and-lines/layout.ts +0 -398
- package/src/boxes-and-lines/parser.ts +0 -1181
- package/src/boxes-and-lines/renderer.ts +0 -1465
- package/src/boxes-and-lines/types.ts +0 -66
- package/src/c4/layout.ts +0 -2441
- package/src/c4/parser.ts +0 -1158
- package/src/c4/renderer.ts +0 -2008
- package/src/c4/types.ts +0 -89
- package/src/chart-type-registry.ts +0 -529
- package/src/chart-types.ts +0 -225
- package/src/chart.ts +0 -685
- package/src/charts-d3/bar.ts +0 -338
- package/src/charts-d3/chord.ts +0 -140
- package/src/charts-d3/function.ts +0 -147
- package/src/charts-d3/funnel.ts +0 -104
- package/src/charts-d3/heatmap.ts +0 -145
- package/src/charts-d3/index.ts +0 -337
- package/src/charts-d3/interactions.ts +0 -477
- package/src/charts-d3/line.ts +0 -344
- package/src/charts-d3/mount.ts +0 -151
- package/src/charts-d3/pie.ts +0 -117
- package/src/charts-d3/polar.ts +0 -89
- package/src/charts-d3/radar.ts +0 -0
- package/src/charts-d3/sankey.ts +0 -0
- package/src/charts-d3/scatter.ts +0 -185
- package/src/charts-d3/shared.ts +0 -208
- package/src/class/layout.ts +0 -326
- package/src/class/parser.ts +0 -635
- package/src/class/renderer.ts +0 -793
- package/src/class/types.ts +0 -58
- package/src/cli-banner.ts +0 -106
- package/src/cli.ts +0 -1080
- package/src/colors-diagnostics.ts +0 -35
- package/src/colors.ts +0 -379
- package/src/completion-types.ts +0 -27
- package/src/completion.ts +0 -2668
- package/src/cycle/layout.ts +0 -1026
- package/src/cycle/parser.ts +0 -387
- package/src/cycle/renderer.ts +0 -653
- package/src/cycle/types.ts +0 -101
- package/src/d3.ts +0 -1434
- package/src/data-chart-parser.ts +0 -1007
- package/src/dgmo-router.ts +0 -296
- package/src/diagnostics-registry.ts +0 -108
- package/src/diagnostics.ts +0 -0
- package/src/dimensions.ts +0 -20
- package/src/directives-registry.ts +0 -396
- package/src/editor/dgmo.grammar +0 -76
- package/src/editor/dgmo.grammar.d.ts +0 -2
- package/src/editor/dgmo.grammar.js +0 -18
- package/src/editor/dgmo.grammar.terms.d.ts +0 -5
- package/src/editor/dgmo.grammar.terms.js +0 -35
- package/src/editor/highlight-api.ts +0 -596
- package/src/editor/highlight.ts +0 -36
- package/src/editor/index.ts +0 -27
- package/src/editor/keywords.ts +0 -128
- package/src/editor/tokens.ts +0 -30
- package/src/element/index.ts +0 -432
- package/src/embed/css.ts +0 -312
- package/src/embed/escape.ts +0 -15
- package/src/embed/index.ts +0 -280
- package/src/er/classify.ts +0 -228
- package/src/er/layout.ts +0 -530
- package/src/er/parser.ts +0 -750
- package/src/er/renderer.ts +0 -725
- package/src/er/types.ts +0 -52
- package/src/error-card.ts +0 -269
- package/src/event-line/diagnostics.ts +0 -117
- package/src/event-line/parser.ts +0 -643
- package/src/event-line/renderer.ts +0 -1742
- package/src/event-line/types.ts +0 -74
- package/src/fonts.ts +0 -3
- package/src/gantt/calculator.ts +0 -979
- package/src/gantt/parser.ts +0 -1641
- package/src/gantt/renderer.ts +0 -3787
- package/src/gantt/resolver.ts +0 -172
- package/src/gantt/types.ts +0 -206
- package/src/graph/diagnostics.ts +0 -64
- package/src/graph/edge-spline.ts +0 -29
- package/src/graph/flowchart-parser.ts +0 -759
- package/src/graph/flowchart-renderer.ts +0 -817
- package/src/graph/layout.ts +0 -472
- package/src/graph/notes.ts +0 -21
- package/src/graph/state-collapse.ts +0 -78
- package/src/graph/state-parser.ts +0 -574
- package/src/graph/state-renderer.ts +0 -653
- package/src/graph/types.ts +0 -65
- package/src/index.ts +0 -261
- package/src/infra/compute.ts +0 -1385
- package/src/infra/layout.ts +0 -888
- package/src/infra/parser.ts +0 -1234
- package/src/infra/renderer.ts +0 -2534
- package/src/infra/roles.ts +0 -75
- package/src/infra/types.ts +0 -216
- package/src/infra/validation.ts +0 -201
- package/src/journey-map/layout.ts +0 -490
- package/src/journey-map/parser.ts +0 -557
- package/src/journey-map/renderer.ts +0 -1580
- package/src/journey-map/types.ts +0 -47
- package/src/kanban/mutations.ts +0 -175
- package/src/kanban/parser.ts +0 -509
- package/src/kanban/renderer.ts +0 -1449
- package/src/kanban/types.ts +0 -39
- package/src/label-layout.ts +0 -368
- package/src/map/colorize.ts +0 -54
- package/src/map/completion.ts +0 -316
- package/src/map/context-labels.ts +0 -609
- package/src/map/data/PROVENANCE.json +0 -1
- package/src/map/data/README.md +0 -40
- package/src/map/data/airport-collisions.json +0 -1
- package/src/map/data/airports.json +0 -1
- package/src/map/data/gazetteer.json +0 -1
- package/src/map/data/lakes.json +0 -1
- package/src/map/data/mountain-ranges.json +0 -1
- package/src/map/data/na-lakes.json +0 -1
- package/src/map/data/na-land.json +0 -1
- package/src/map/data/region-names.json +0 -1
- package/src/map/data/rivers.json +0 -1
- package/src/map/data/types.ts +0 -121
- package/src/map/data/us-states.json +0 -1
- package/src/map/data/water-bodies.json +0 -1
- package/src/map/data/world-coarse.json +0 -1
- package/src/map/data/world-detail.json +0 -1
- package/src/map/diagnostics.ts +0 -134
- package/src/map/dimensions.ts +0 -150
- package/src/map/geo-query.ts +0 -295
- package/src/map/geo.ts +0 -438
- package/src/map/invert.ts +0 -111
- package/src/map/layout.ts +0 -5069
- package/src/map/legend-band.ts +0 -127
- package/src/map/load-data.ts +0 -186
- package/src/map/parser.ts +0 -783
- package/src/map/renderer.ts +0 -1445
- package/src/map/resolved-types.ts +0 -160
- package/src/map/resolver.ts +0 -1146
- package/src/map/types.ts +0 -194
- package/src/mindmap/collapse.ts +0 -67
- package/src/mindmap/layout.ts +0 -649
- package/src/mindmap/parser.ts +0 -430
- package/src/mindmap/renderer.ts +0 -637
- package/src/mindmap/text-wrap.ts +0 -218
- package/src/mindmap/types.ts +0 -56
- package/src/org/collapse.ts +0 -151
- package/src/org/layout.ts +0 -1262
- package/src/org/parser.ts +0 -519
- package/src/org/renderer.ts +0 -866
- package/src/org/resolver.ts +0 -636
- package/src/palettes/atlas.ts +0 -77
- package/src/palettes/blueprint.ts +0 -73
- package/src/palettes/catppuccin.ts +0 -84
- package/src/palettes/color-utils.ts +0 -443
- package/src/palettes/index.ts +0 -67
- package/src/palettes/nord.ts +0 -67
- package/src/palettes/registry.ts +0 -114
- package/src/palettes/slate.ts +0 -73
- package/src/palettes/tidewater.ts +0 -73
- package/src/palettes/tokyo-night.ts +0 -86
- package/src/palettes/types.ts +0 -88
- package/src/pert/analyzer.ts +0 -1183
- package/src/pert/diagnostics.ts +0 -110
- package/src/pert/index.ts +0 -43
- package/src/pert/internal.ts +0 -252
- package/src/pert/layout.ts +0 -971
- package/src/pert/monte-carlo.ts +0 -446
- package/src/pert/parser.ts +0 -1606
- package/src/pert/renderer.ts +0 -4009
- package/src/pert/share-normalize.ts +0 -62
- package/src/pert/types.ts +0 -604
- package/src/pyramid/parser.ts +0 -185
- package/src/pyramid/renderer.ts +0 -768
- package/src/pyramid/types.ts +0 -28
- package/src/quadrant/parser.ts +0 -18
- package/src/quadrant/renderer.ts +0 -638
- package/src/raci/diagnostics.ts +0 -213
- package/src/raci/index.ts +0 -23
- package/src/raci/mutations.ts +0 -321
- package/src/raci/parser.ts +0 -699
- package/src/raci/renderer.ts +0 -1627
- package/src/raci/types.ts +0 -82
- package/src/raci/variants.ts +0 -320
- package/src/render.ts +0 -268
- package/src/ring/parser.ts +0 -212
- package/src/ring/renderer.ts +0 -490
- package/src/ring/types.ts +0 -27
- package/src/sequence/collapse.ts +0 -174
- package/src/sequence/parser.ts +0 -1596
- package/src/sequence/participant-inference.ts +0 -152
- package/src/sequence/renderer.ts +0 -3168
- package/src/sequence/tag-resolution.ts +0 -164
- package/src/sharing.ts +0 -211
- package/src/sitemap/collapse.ts +0 -100
- package/src/sitemap/layout.ts +0 -925
- package/src/sitemap/parser.ts +0 -755
- package/src/sitemap/renderer.ts +0 -828
- package/src/sitemap/types.ts +0 -42
- package/src/slope/parser.ts +0 -18
- package/src/slope/renderer.ts +0 -378
- package/src/swimlane/diagnostics.ts +0 -94
- package/src/swimlane/layout.ts +0 -597
- package/src/swimlane/parser.ts +0 -613
- package/src/swimlane/renderer.ts +0 -681
- package/src/swimlane/types.ts +0 -151
- package/src/tech-radar/interactive.ts +0 -1129
- package/src/tech-radar/layout.ts +0 -197
- package/src/tech-radar/parser.ts +0 -436
- package/src/tech-radar/renderer.ts +0 -1239
- package/src/tech-radar/shared.ts +0 -151
- package/src/tech-radar/types.ts +0 -86
- package/src/themes.ts +0 -22
- package/src/timeline/parser.ts +0 -472
- package/src/timeline/renderer.ts +0 -3024
- package/src/timeline/types.ts +0 -33
- package/src/timeline/viz-parser.ts +0 -21
- package/src/treemap/diagnostics.ts +0 -62
- package/src/treemap/layout-radial.ts +0 -233
- package/src/treemap/layout.ts +0 -189
- package/src/treemap/parser.ts +0 -463
- package/src/treemap/renderer-radial.ts +0 -438
- package/src/treemap/renderer.ts +0 -572
- package/src/treemap/treemap-shared.ts +0 -309
- package/src/treemap/types.ts +0 -60
- package/src/utils/arrow-markers.ts +0 -51
- package/src/utils/arrows-diagnostics.ts +0 -62
- package/src/utils/arrows.ts +0 -227
- package/src/utils/brand.ts +0 -61
- package/src/utils/card.ts +0 -183
- package/src/utils/collapse-engine/tree-edges.ts +0 -115
- package/src/utils/collapse-engine/tree.ts +0 -117
- package/src/utils/d3-helpers.ts +0 -219
- package/src/utils/d3-types.ts +0 -9
- package/src/utils/description-helpers.ts +0 -38
- package/src/utils/duration.ts +0 -312
- package/src/utils/export-container.ts +0 -41
- package/src/utils/expr-eval.ts +0 -27
- package/src/utils/fit-canvas.ts +0 -64
- package/src/utils/hover-styles.ts +0 -673
- package/src/utils/inline-markdown.ts +0 -96
- package/src/utils/legend-constants.ts +0 -48
- package/src/utils/legend-d3.ts +0 -618
- package/src/utils/legend-integration.ts +0 -107
- package/src/utils/legend-layout.ts +0 -776
- package/src/utils/legend-svg.ts +0 -214
- package/src/utils/legend-types.ts +0 -272
- package/src/utils/name-normalize.ts +0 -163
- package/src/utils/note-box/constants.ts +0 -25
- package/src/utils/note-box/index.ts +0 -11
- package/src/utils/note-box/metrics.ts +0 -90
- package/src/utils/note-box/svg.ts +0 -331
- package/src/utils/notes/bounds.ts +0 -30
- package/src/utils/notes/build.ts +0 -131
- package/src/utils/notes/index.ts +0 -18
- package/src/utils/notes/model.ts +0 -19
- package/src/utils/notes/parse.ts +0 -131
- package/src/utils/notes/place.ts +0 -177
- package/src/utils/notes/resolve.ts +0 -88
- package/src/utils/number-format.ts +0 -36
- package/src/utils/parsing.ts +0 -953
- package/src/utils/reserved-key-registry.ts +0 -239
- package/src/utils/safe-href.ts +0 -38
- package/src/utils/scaling.ts +0 -97
- package/src/utils/svg-embed.ts +0 -251
- package/src/utils/tag-groups.ts +0 -607
- package/src/utils/text-measure.ts +0 -122
- package/src/utils/time-ticks.ts +0 -253
- package/src/utils/title-constants.ts +0 -24
- package/src/utils/visual-conventions.ts +0 -61
- package/src/utils/wrapped-desc.ts +0 -87
- package/src/venn/parser.ts +0 -18
- package/src/venn/renderer.ts +0 -1047
- package/src/version-control/diagnostics.ts +0 -67
- package/src/version-control/parser.ts +0 -544
- package/src/version-control/renderer.ts +0 -724
- package/src/version-control/types.ts +0 -100
- package/src/visualizations/parse.ts +0 -1560
- package/src/visualizations/types.ts +0 -262
- package/src/wireframe/layout.ts +0 -479
- package/src/wireframe/parser.ts +0 -1114
- package/src/wireframe/renderer.ts +0 -1318
- package/src/wireframe/types.ts +0 -110
- package/src/wordcloud/parser.ts +0 -18
- package/src/wordcloud/renderer.ts +0 -357
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
// ============================================================
|
|
2
|
-
// Version-Control (git graph) — Diagnostic Registry
|
|
3
|
-
// ============================================================
|
|
4
|
-
//
|
|
5
|
-
// Declarative catalog of version-control-specific diagnostics. This is
|
|
6
|
-
// the single source of truth for the codes/wording the parser emits via
|
|
7
|
-
// `emit(VERSION_CONTROL_DX.<KEY>, line, params)`. Consumers (the CLI
|
|
8
|
-
// `diagnostics` subcommand, the console error-review surface, MCP
|
|
9
|
-
// `validate_diagram`, and the spec docs) enumerate this catalog; the
|
|
10
|
-
// parser never re-types wording at the call site.
|
|
11
|
-
//
|
|
12
|
-
// Message builders mirror the parser's exact wording. They tolerate being
|
|
13
|
-
// called with `{}` so the catalog can render a representative message
|
|
14
|
-
// without live params.
|
|
15
|
-
//
|
|
16
|
-
// Notes on fidelity:
|
|
17
|
-
// - `E_VERSION_CONTROL_UNKNOWN_BRANCH` is emitted from THREE sites with
|
|
18
|
-
// slightly different wording — `merge references … (§29.4)`,
|
|
19
|
-
// `rebase references … (§29.8)`, and `reset references … (§29.8)`. The
|
|
20
|
-
// builder below parameterizes the verb (`op`), branch, and section so it
|
|
21
|
-
// reproduces any of the three exactly; the representative `{}` form uses
|
|
22
|
-
// the `merge` wording.
|
|
23
|
-
|
|
24
|
-
import type { DiagnosticSpec } from '../diagnostics';
|
|
25
|
-
|
|
26
|
-
/** Keyed specs — referenced by the parser's `emit()` call sites. */
|
|
27
|
-
export const VERSION_CONTROL_DX = {
|
|
28
|
-
NO_COMMITS: {
|
|
29
|
-
code: 'E_VERSION_CONTROL_NO_COMMITS',
|
|
30
|
-
severity: 'error',
|
|
31
|
-
chartType: 'version-control',
|
|
32
|
-
title: 'No commits',
|
|
33
|
-
message: 'version-control has no commits.',
|
|
34
|
-
hint: 'Add at least one indented commit line under a branch.',
|
|
35
|
-
example: 'version-control Empty',
|
|
36
|
-
},
|
|
37
|
-
UNKNOWN_BRANCH: {
|
|
38
|
-
code: 'E_VERSION_CONTROL_UNKNOWN_BRANCH',
|
|
39
|
-
severity: 'warning',
|
|
40
|
-
chartType: 'version-control',
|
|
41
|
-
title: 'Unknown branch reference',
|
|
42
|
-
message: (p) => {
|
|
43
|
-
const op = (p.op as string) ?? 'merge';
|
|
44
|
-
const branch = (p.branch as string) ?? 'ghostbranch';
|
|
45
|
-
const section = (p.section as string) ?? '§29.4';
|
|
46
|
-
return `${op} references unknown branch "${branch}". (${section})`;
|
|
47
|
-
},
|
|
48
|
-
hint: 'Declare the branch (a bare top-level line) before referencing it in merge/rebase/reset.',
|
|
49
|
-
example: 'version-control U\n\nmain\n A\n merge ghostbranch',
|
|
50
|
-
},
|
|
51
|
-
AMBIGUOUS_REF: {
|
|
52
|
-
code: 'E_VERSION_CONTROL_AMBIGUOUS_REF',
|
|
53
|
-
severity: 'warning',
|
|
54
|
-
chartType: 'version-control',
|
|
55
|
-
title: 'Ambiguous commit reference',
|
|
56
|
-
message: (p) => {
|
|
57
|
-
const ref = (p.ref as string) ?? 'Fix';
|
|
58
|
-
const count = (p.count as number | string) ?? 2;
|
|
59
|
-
return `Commit reference "${ref}" matches ${count} commits — use an explicit id:. (§29.10)`;
|
|
60
|
-
},
|
|
61
|
-
hint: 'Give the target commit an `id:` and reference that id, or make the message unique.',
|
|
62
|
-
example: 'version-control A\n\nmain\n Fix\n Fix\n cherry-pick Fix',
|
|
63
|
-
},
|
|
64
|
-
} satisfies Record<string, DiagnosticSpec>;
|
|
65
|
-
|
|
66
|
-
export const VERSION_CONTROL_DIAGNOSTICS: DiagnosticSpec[] =
|
|
67
|
-
Object.values(VERSION_CONTROL_DX);
|
|
@@ -1,544 +0,0 @@
|
|
|
1
|
-
// ============================================================
|
|
2
|
-
// Version-Control — Parser (spec §29)
|
|
3
|
-
// ============================================================
|
|
4
|
-
//
|
|
5
|
-
// Keyword-less grammar: a bare top-level line is a branch, a bare indented line
|
|
6
|
-
// is a commit. Re-naming a branch resumes it (replaces `checkout`). Only `merge`
|
|
7
|
-
// and `cherry-pick` are required verbs; beyond-Mermaid verbs `ref` / `rebase` /
|
|
8
|
-
// `reset` (top-level) and `revert` / `note` (indented) add HEAD + remote-tracking,
|
|
9
|
-
// the rebase/reset/revert/squash operations, and step annotations. The parser
|
|
10
|
-
// also does the topological placement (seq) and the rebase/reset/squash/revert
|
|
11
|
-
// transforms — the renderer only does pixel layout + SVG. Mirrors
|
|
12
|
-
// docs/version-control-syntax-mockups.html parse().
|
|
13
|
-
|
|
14
|
-
import type { PaletteColors } from '../palettes';
|
|
15
|
-
import { emit, formatDgmoError, makeFail, suggest } from '../diagnostics';
|
|
16
|
-
import type { DgmoError } from '../diagnostics';
|
|
17
|
-
import { VERSION_CONTROL_DX } from './diagnostics';
|
|
18
|
-
import type { Writable } from '../utils/brand';
|
|
19
|
-
import { measureIndent, parseFirstLine, extractColor } from '../utils/parsing';
|
|
20
|
-
import type {
|
|
21
|
-
ParsedVersionControl,
|
|
22
|
-
VCBranch,
|
|
23
|
-
VCDirection,
|
|
24
|
-
VCNode,
|
|
25
|
-
VCNote,
|
|
26
|
-
VCOptions,
|
|
27
|
-
VCRef,
|
|
28
|
-
} from './types';
|
|
29
|
-
|
|
30
|
-
interface WorkBranch {
|
|
31
|
-
name: string;
|
|
32
|
-
creationLane: number;
|
|
33
|
-
colorToken: string | null;
|
|
34
|
-
order: number | null;
|
|
35
|
-
tip: number | null;
|
|
36
|
-
pendingParent: number | null;
|
|
37
|
-
ab: { ahead: number; behind: number } | null;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
type Mut = Writable<VCNode>;
|
|
41
|
-
|
|
42
|
-
export function parseVersionControl(
|
|
43
|
-
content: string,
|
|
44
|
-
palette?: PaletteColors
|
|
45
|
-
): ParsedVersionControl {
|
|
46
|
-
const options: Writable<VCOptions> = {
|
|
47
|
-
direction: 'LR',
|
|
48
|
-
noLabels: false,
|
|
49
|
-
noLanes: false,
|
|
50
|
-
noHead: false,
|
|
51
|
-
};
|
|
52
|
-
const result: Writable<ParsedVersionControl> = {
|
|
53
|
-
type: 'version-control',
|
|
54
|
-
title: null,
|
|
55
|
-
titleLineNumber: null,
|
|
56
|
-
nodes: [],
|
|
57
|
-
branches: [],
|
|
58
|
-
refs: [],
|
|
59
|
-
notes: [],
|
|
60
|
-
options,
|
|
61
|
-
diagnostics: [],
|
|
62
|
-
error: null,
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
const fail = makeFail(result);
|
|
66
|
-
|
|
67
|
-
if (!content?.trim()) return fail(0, 'No content provided');
|
|
68
|
-
|
|
69
|
-
const nodes = result.nodes as Mut[];
|
|
70
|
-
const branches = new Map<string, WorkBranch>();
|
|
71
|
-
const order: string[] = [];
|
|
72
|
-
const refs = result.refs as Writable<VCRef>[];
|
|
73
|
-
const notes = result.notes as Writable<VCNote>[];
|
|
74
|
-
let active: string | null = null;
|
|
75
|
-
let seq = 0;
|
|
76
|
-
let laneCounter = 0;
|
|
77
|
-
let headerParsed = false;
|
|
78
|
-
|
|
79
|
-
const makeBranch = (
|
|
80
|
-
name: string,
|
|
81
|
-
parentName: string | null,
|
|
82
|
-
colorToken: string | null,
|
|
83
|
-
ord: number | null
|
|
84
|
-
): WorkBranch => {
|
|
85
|
-
const existing = branches.get(name);
|
|
86
|
-
if (existing) return existing;
|
|
87
|
-
const b: WorkBranch = {
|
|
88
|
-
name,
|
|
89
|
-
creationLane: laneCounter++,
|
|
90
|
-
colorToken,
|
|
91
|
-
order: ord,
|
|
92
|
-
tip: null,
|
|
93
|
-
pendingParent: null,
|
|
94
|
-
ab: null,
|
|
95
|
-
};
|
|
96
|
-
if (parentName != null) {
|
|
97
|
-
const par = branches.get(parentName);
|
|
98
|
-
b.pendingParent = par ? par.tip : null;
|
|
99
|
-
}
|
|
100
|
-
branches.set(name, b);
|
|
101
|
-
order.push(name);
|
|
102
|
-
return b;
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
const matchesRef = (ref: string): Mut[] =>
|
|
106
|
-
nodes.filter((n) => n.message === ref || n.id === ref);
|
|
107
|
-
const findByRef = (ref: string, lineNumber: number): Mut | null => {
|
|
108
|
-
const m = matchesRef(ref);
|
|
109
|
-
if (m.length === 0) return null;
|
|
110
|
-
if (m.length > 1 && !/^[0-9a-f]{4,}$/.test(ref)) {
|
|
111
|
-
result.diagnostics.push(
|
|
112
|
-
emit(VERSION_CONTROL_DX.AMBIGUOUS_REF, lineNumber, {
|
|
113
|
-
ref,
|
|
114
|
-
count: m.length,
|
|
115
|
-
})
|
|
116
|
-
);
|
|
117
|
-
}
|
|
118
|
-
return m[m.length - 1]!;
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
const addNode = (
|
|
122
|
-
fields: Pick<VCNode, 'kind' | 'message' | 'type' | 'tag' | 'lineNumber'> & {
|
|
123
|
-
id: string | null;
|
|
124
|
-
}
|
|
125
|
-
): Mut => {
|
|
126
|
-
const b = branches.get(active!)!;
|
|
127
|
-
const id = fields.id ?? null;
|
|
128
|
-
const node: Mut = {
|
|
129
|
-
key: nodes.length,
|
|
130
|
-
branch: active!,
|
|
131
|
-
lane: b.creationLane,
|
|
132
|
-
seq: seq++,
|
|
133
|
-
kind: fields.kind,
|
|
134
|
-
message: fields.message,
|
|
135
|
-
type: fields.type,
|
|
136
|
-
id,
|
|
137
|
-
tag: fields.tag,
|
|
138
|
-
lineNumber: fields.lineNumber,
|
|
139
|
-
prev: b.tip,
|
|
140
|
-
parent: null,
|
|
141
|
-
mergeFrom: null,
|
|
142
|
-
cherryFrom: null,
|
|
143
|
-
revertFrom: null,
|
|
144
|
-
squashFrom: null,
|
|
145
|
-
movedTo: null,
|
|
146
|
-
ghost: false,
|
|
147
|
-
};
|
|
148
|
-
if (b.pendingParent != null && node.prev === null) {
|
|
149
|
-
node.parent = b.pendingParent;
|
|
150
|
-
b.pendingParent = null;
|
|
151
|
-
}
|
|
152
|
-
b.tip = node.key;
|
|
153
|
-
nodes.push(node);
|
|
154
|
-
return node;
|
|
155
|
-
};
|
|
156
|
-
|
|
157
|
-
const ensureActive = (lineNumber: number): void => {
|
|
158
|
-
if (!active) {
|
|
159
|
-
makeBranch('main', null, null, null);
|
|
160
|
-
active = 'main';
|
|
161
|
-
}
|
|
162
|
-
void lineNumber;
|
|
163
|
-
};
|
|
164
|
-
|
|
165
|
-
const doRebase = (fb: string, tb: string, lineNumber: number): void => {
|
|
166
|
-
const fbr = branches.get(fb);
|
|
167
|
-
const tbr = branches.get(tb);
|
|
168
|
-
if (!fbr || !tbr) {
|
|
169
|
-
result.diagnostics.push(
|
|
170
|
-
emit(VERSION_CONTROL_DX.UNKNOWN_BRANCH, lineNumber, {
|
|
171
|
-
op: 'rebase',
|
|
172
|
-
branch: !fbr ? fb : tb,
|
|
173
|
-
section: '§29.8',
|
|
174
|
-
})
|
|
175
|
-
);
|
|
176
|
-
return;
|
|
177
|
-
}
|
|
178
|
-
const feats = nodes
|
|
179
|
-
.filter((n) => n.branch === fb)
|
|
180
|
-
.sort((a, b) => a.seq - b.seq);
|
|
181
|
-
let prev: number | null = null;
|
|
182
|
-
const first = tbr.tip;
|
|
183
|
-
for (const o of feats) {
|
|
184
|
-
o.ghost = true;
|
|
185
|
-
const copy: Mut = {
|
|
186
|
-
key: nodes.length,
|
|
187
|
-
branch: fb,
|
|
188
|
-
lane: fbr.creationLane,
|
|
189
|
-
seq: seq++,
|
|
190
|
-
kind: 'commit',
|
|
191
|
-
message: o.message,
|
|
192
|
-
type: o.type,
|
|
193
|
-
id: o.id,
|
|
194
|
-
tag: o.tag,
|
|
195
|
-
lineNumber: o.lineNumber,
|
|
196
|
-
prev,
|
|
197
|
-
parent: prev == null ? first : null,
|
|
198
|
-
mergeFrom: null,
|
|
199
|
-
cherryFrom: null,
|
|
200
|
-
revertFrom: null,
|
|
201
|
-
squashFrom: null,
|
|
202
|
-
movedTo: null,
|
|
203
|
-
ghost: false,
|
|
204
|
-
};
|
|
205
|
-
o.movedTo = copy.key;
|
|
206
|
-
nodes.push(copy);
|
|
207
|
-
prev = copy.key;
|
|
208
|
-
}
|
|
209
|
-
fbr.tip = prev;
|
|
210
|
-
active = fb;
|
|
211
|
-
};
|
|
212
|
-
|
|
213
|
-
const lines = content.split('\n');
|
|
214
|
-
for (let i = 0; i < lines.length; i++) {
|
|
215
|
-
const line = lines[i]!;
|
|
216
|
-
const lineNumber = i + 1;
|
|
217
|
-
const trimmed = line.trim();
|
|
218
|
-
if (!trimmed || trimmed.startsWith('//')) continue;
|
|
219
|
-
const indent = measureIndent(line);
|
|
220
|
-
|
|
221
|
-
// ── First line: `version-control [Title]` ──
|
|
222
|
-
if (!headerParsed) {
|
|
223
|
-
const firstLine = parseFirstLine(trimmed);
|
|
224
|
-
if (firstLine?.chartType === 'version-control') {
|
|
225
|
-
result.title = firstLine.title ?? null;
|
|
226
|
-
result.titleLineNumber = lineNumber;
|
|
227
|
-
headerParsed = true;
|
|
228
|
-
continue;
|
|
229
|
-
}
|
|
230
|
-
let msg = 'Expected "version-control [Title]" as the first line.';
|
|
231
|
-
const hint = suggest(firstLine?.chartType ?? trimmed, [
|
|
232
|
-
'version-control',
|
|
233
|
-
]);
|
|
234
|
-
if (hint) msg += ` ${hint}`;
|
|
235
|
-
return fail(lineNumber, msg);
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
// ── Directives ──
|
|
239
|
-
const dir = /^direction\s+(LR|TB|BT)$/i.exec(trimmed);
|
|
240
|
-
if (dir) {
|
|
241
|
-
options.direction = dir[1]!.toUpperCase() as VCDirection;
|
|
242
|
-
continue;
|
|
243
|
-
}
|
|
244
|
-
if (trimmed === 'no-labels') {
|
|
245
|
-
options.noLabels = true;
|
|
246
|
-
continue;
|
|
247
|
-
}
|
|
248
|
-
if (trimmed === 'no-lanes') {
|
|
249
|
-
options.noLanes = true;
|
|
250
|
-
continue;
|
|
251
|
-
}
|
|
252
|
-
if (trimmed === 'no-head') {
|
|
253
|
-
options.noHead = true;
|
|
254
|
-
continue;
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
if (indent === 0) {
|
|
258
|
-
// ── Top-level operation verbs ──
|
|
259
|
-
let m: RegExpExecArray | null;
|
|
260
|
-
if ((m = /^ref\s+(.+?)\s+at\s+(.+?)(?:\s+(remote))?$/.exec(trimmed))) {
|
|
261
|
-
const nm = m[1]!.trim();
|
|
262
|
-
const tgt = findByRef(m[2]!.trim(), lineNumber);
|
|
263
|
-
refs.push({
|
|
264
|
-
name: nm,
|
|
265
|
-
atKey: tgt ? tgt.key : null,
|
|
266
|
-
remote: !!m[3] || /^(origin|upstream)\//.test(nm),
|
|
267
|
-
head: nm === 'HEAD',
|
|
268
|
-
lineNumber,
|
|
269
|
-
});
|
|
270
|
-
continue;
|
|
271
|
-
}
|
|
272
|
-
if ((m = /^rebase\s+(.+?)\s+onto\s+(.+)$/.exec(trimmed))) {
|
|
273
|
-
doRebase(m[1]!.trim(), m[2]!.trim(), lineNumber);
|
|
274
|
-
continue;
|
|
275
|
-
}
|
|
276
|
-
if ((m = /^reset\s+(.+?)\s+to\s+(.+)$/.exec(trimmed))) {
|
|
277
|
-
const br = branches.get(m[1]!.trim());
|
|
278
|
-
const tgt = findByRef(m[2]!.trim(), lineNumber);
|
|
279
|
-
if (!br) {
|
|
280
|
-
result.diagnostics.push(
|
|
281
|
-
emit(VERSION_CONTROL_DX.UNKNOWN_BRANCH, lineNumber, {
|
|
282
|
-
op: 'reset',
|
|
283
|
-
branch: m[1]!.trim(),
|
|
284
|
-
section: '§29.8',
|
|
285
|
-
})
|
|
286
|
-
);
|
|
287
|
-
} else if (tgt) {
|
|
288
|
-
for (const n of nodes) {
|
|
289
|
-
if (n.branch === br.name && n.seq > tgt.seq) n.ghost = true;
|
|
290
|
-
}
|
|
291
|
-
br.tip = tgt.key;
|
|
292
|
-
active = br.name;
|
|
293
|
-
}
|
|
294
|
-
continue;
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
// ── Branch declaration / resume ──
|
|
298
|
-
// extractColor strips + validates the trailing token (§1.5 diagnostics) and
|
|
299
|
-
// resolves to hex; we keep the NAME so the renderer resolves per-palette.
|
|
300
|
-
const lastWord = trimmed.split(/\s+/).pop() ?? '';
|
|
301
|
-
const colored = extractColor(
|
|
302
|
-
trimmed,
|
|
303
|
-
palette,
|
|
304
|
-
result.diagnostics as DgmoError[],
|
|
305
|
-
lineNumber
|
|
306
|
-
);
|
|
307
|
-
let rest = colored.label;
|
|
308
|
-
const colorToken = colored.color !== undefined ? lastWord : null;
|
|
309
|
-
let ord: number | null = null;
|
|
310
|
-
const om = /\s+order:\s*(\d+)\s*$/.exec(rest);
|
|
311
|
-
if (om) {
|
|
312
|
-
ord = Number(om[1]);
|
|
313
|
-
rest = rest.replace(/\s+order:\s*\d+\s*$/, '');
|
|
314
|
-
}
|
|
315
|
-
let name = rest.trim();
|
|
316
|
-
let parent: string | null = null;
|
|
317
|
-
const fm = rest.split(/\s+from\s+/);
|
|
318
|
-
if (fm.length === 2) {
|
|
319
|
-
name = fm[0]!.trim();
|
|
320
|
-
parent = fm[1]!.trim();
|
|
321
|
-
}
|
|
322
|
-
const existing = branches.get(name);
|
|
323
|
-
if (existing) {
|
|
324
|
-
active = name;
|
|
325
|
-
} else {
|
|
326
|
-
makeBranch(name, parent != null ? parent : active, colorToken, ord);
|
|
327
|
-
active = name;
|
|
328
|
-
}
|
|
329
|
-
continue;
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
// ── Indented: explicit verbs, else a commit ──
|
|
333
|
-
ensureActive(lineNumber);
|
|
334
|
-
let m: RegExpExecArray | null;
|
|
335
|
-
if (/^merge\b/.test(trimmed)) {
|
|
336
|
-
const { msg, tag, id, type } = peelMeta(trimmed.slice(5).trim());
|
|
337
|
-
let src = msg.trim();
|
|
338
|
-
let strat: string | null = null;
|
|
339
|
-
const sm = /^(.*?)\s+(squash|ff|no-ff)$/.exec(src);
|
|
340
|
-
if (sm) {
|
|
341
|
-
src = sm[1]!.trim();
|
|
342
|
-
strat = sm[2]!;
|
|
343
|
-
}
|
|
344
|
-
const sb = branches.get(src);
|
|
345
|
-
if (!sb) {
|
|
346
|
-
result.diagnostics.push(
|
|
347
|
-
emit(VERSION_CONTROL_DX.UNKNOWN_BRANCH, lineNumber, {
|
|
348
|
-
op: 'merge',
|
|
349
|
-
branch: src,
|
|
350
|
-
section: '§29.4',
|
|
351
|
-
})
|
|
352
|
-
);
|
|
353
|
-
}
|
|
354
|
-
if (strat === 'squash') {
|
|
355
|
-
if (sb) for (const n of nodes) if (n.branch === src) n.ghost = true;
|
|
356
|
-
const node = addNode({
|
|
357
|
-
kind: 'commit',
|
|
358
|
-
message: `Squash ${src}`,
|
|
359
|
-
type: 'normal',
|
|
360
|
-
tag: tag ?? null,
|
|
361
|
-
id: id ?? null,
|
|
362
|
-
lineNumber,
|
|
363
|
-
});
|
|
364
|
-
node.squashFrom = sb ? sb.tip : null;
|
|
365
|
-
} else {
|
|
366
|
-
const node = addNode({
|
|
367
|
-
kind: 'merge',
|
|
368
|
-
message: src,
|
|
369
|
-
type: (type as VCNode['type']) ?? 'normal',
|
|
370
|
-
tag: tag ?? null,
|
|
371
|
-
id: id ?? null,
|
|
372
|
-
lineNumber,
|
|
373
|
-
});
|
|
374
|
-
node.mergeFrom = sb ? sb.tip : null;
|
|
375
|
-
}
|
|
376
|
-
continue;
|
|
377
|
-
}
|
|
378
|
-
if (/^cherry-pick\b/.test(trimmed)) {
|
|
379
|
-
const ref = trimmed.slice(11).trim();
|
|
380
|
-
const s = findByRef(ref, lineNumber);
|
|
381
|
-
const node = addNode({
|
|
382
|
-
kind: 'cherry',
|
|
383
|
-
message: ref,
|
|
384
|
-
type: 'normal',
|
|
385
|
-
tag: null,
|
|
386
|
-
id: null,
|
|
387
|
-
lineNumber,
|
|
388
|
-
});
|
|
389
|
-
node.cherryFrom = s ? s.key : null;
|
|
390
|
-
continue;
|
|
391
|
-
}
|
|
392
|
-
if (/^revert\b/.test(trimmed)) {
|
|
393
|
-
const ref = trimmed.slice(6).trim();
|
|
394
|
-
const s = findByRef(ref, lineNumber);
|
|
395
|
-
const node = addNode({
|
|
396
|
-
kind: 'commit',
|
|
397
|
-
message: s ? `Revert ${s.message}` : 'Revert',
|
|
398
|
-
type: 'reverse',
|
|
399
|
-
tag: null,
|
|
400
|
-
id: null,
|
|
401
|
-
lineNumber,
|
|
402
|
-
});
|
|
403
|
-
node.revertFrom = s ? s.key : null;
|
|
404
|
-
continue;
|
|
405
|
-
}
|
|
406
|
-
if ((m = /^note\b\s*(.*)$/.exec(trimmed))) {
|
|
407
|
-
const b = branches.get(active!)!;
|
|
408
|
-
notes.push({
|
|
409
|
-
num: notes.length + 1,
|
|
410
|
-
anchorKey: b.tip,
|
|
411
|
-
text: m[1]!.trim(),
|
|
412
|
-
lineNumber,
|
|
413
|
-
});
|
|
414
|
-
continue;
|
|
415
|
-
}
|
|
416
|
-
// bare commit — `commit` keyword optional (empty/dotless only)
|
|
417
|
-
const body = trimmed.replace(/^commit\b\s*/, '');
|
|
418
|
-
const { msg, tag, id, type } = peelMeta(body);
|
|
419
|
-
addNode({
|
|
420
|
-
kind: 'commit',
|
|
421
|
-
message: msg || null,
|
|
422
|
-
type: (type as VCNode['type']) ?? 'normal',
|
|
423
|
-
tag: tag ?? null,
|
|
424
|
-
id: id ?? null,
|
|
425
|
-
lineNumber,
|
|
426
|
-
});
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
// ── HEAD auto-sits on the active tip ──
|
|
430
|
-
if (!options.noHead && active) {
|
|
431
|
-
const tip = branches.get(active)!.tip;
|
|
432
|
-
if (tip != null && !refs.some((r) => r.head)) {
|
|
433
|
-
refs.push({
|
|
434
|
-
name: 'HEAD',
|
|
435
|
-
atKey: tip,
|
|
436
|
-
remote: false,
|
|
437
|
-
head: true,
|
|
438
|
-
lineNumber: 0,
|
|
439
|
-
});
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
// ── Ahead/behind: local branch X vs an origin/X ref (DAG set difference) ──
|
|
444
|
-
const ancestors = (key: number): Set<number> => {
|
|
445
|
-
const seen = new Set<number>();
|
|
446
|
-
const st = [key];
|
|
447
|
-
while (st.length) {
|
|
448
|
-
const k = st.pop()!;
|
|
449
|
-
if (seen.has(k)) continue;
|
|
450
|
-
seen.add(k);
|
|
451
|
-
const n = nodes[k];
|
|
452
|
-
if (n) {
|
|
453
|
-
if (n.prev != null) st.push(n.prev);
|
|
454
|
-
if (n.parent != null) st.push(n.parent);
|
|
455
|
-
if (n.mergeFrom != null) st.push(n.mergeFrom);
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
return seen;
|
|
459
|
-
};
|
|
460
|
-
for (const bn of order) {
|
|
461
|
-
const b = branches.get(bn)!;
|
|
462
|
-
if (b.tip == null) continue;
|
|
463
|
-
const rr = refs.find(
|
|
464
|
-
(r) =>
|
|
465
|
-
r.remote && (r.name === `origin/${bn}` || r.name.endsWith(`/${bn}`))
|
|
466
|
-
);
|
|
467
|
-
if (rr?.atKey != null) {
|
|
468
|
-
const A = ancestors(b.tip);
|
|
469
|
-
const B = ancestors(rr.atKey);
|
|
470
|
-
let ahead = 0;
|
|
471
|
-
let behind = 0;
|
|
472
|
-
A.forEach((k) => {
|
|
473
|
-
if (!B.has(k)) ahead++;
|
|
474
|
-
});
|
|
475
|
-
B.forEach((k) => {
|
|
476
|
-
if (!A.has(k)) behind++;
|
|
477
|
-
});
|
|
478
|
-
b.ab = { ahead, behind };
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
// ── Lane ordering: honor `order:`, else declaration order ──
|
|
483
|
-
const ordered = [...order].sort((a, b) => {
|
|
484
|
-
const ba = branches.get(a)!;
|
|
485
|
-
const bb = branches.get(b)!;
|
|
486
|
-
const ka = ba.order ?? ba.creationLane;
|
|
487
|
-
const kb = bb.order ?? bb.creationLane;
|
|
488
|
-
return ka - kb || ba.creationLane - bb.creationLane;
|
|
489
|
-
});
|
|
490
|
-
const laneOf = new Map<string, number>();
|
|
491
|
-
ordered.forEach((nm, idx) => laneOf.set(nm, idx));
|
|
492
|
-
for (const n of nodes) (n as Mut).lane = laneOf.get(n.branch)!;
|
|
493
|
-
|
|
494
|
-
// ── Emit branch list (declaration order preserved for legend/gutter) ──
|
|
495
|
-
result.branches = order.map((nm): VCBranch => {
|
|
496
|
-
const b = branches.get(nm)!;
|
|
497
|
-
return {
|
|
498
|
-
name: nm,
|
|
499
|
-
lane: laneOf.get(nm)!,
|
|
500
|
-
colorToken: b.colorToken,
|
|
501
|
-
order: b.order,
|
|
502
|
-
tip: b.tip,
|
|
503
|
-
ab: b.ab,
|
|
504
|
-
};
|
|
505
|
-
});
|
|
506
|
-
|
|
507
|
-
if (nodes.length === 0 && !result.error) {
|
|
508
|
-
const diag = emit(
|
|
509
|
-
VERSION_CONTROL_DX.NO_COMMITS,
|
|
510
|
-
result.titleLineNumber ?? 1
|
|
511
|
-
);
|
|
512
|
-
result.diagnostics.push(diag);
|
|
513
|
-
result.error = formatDgmoError(diag);
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
return result;
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
/** Peel same-line `id:` / `tag:` / `type:` metadata off a commit/merge body. */
|
|
520
|
-
function peelMeta(s: string): {
|
|
521
|
-
msg: string;
|
|
522
|
-
tag: string | null;
|
|
523
|
-
type: string | null;
|
|
524
|
-
id: string | null;
|
|
525
|
-
} {
|
|
526
|
-
const out = {
|
|
527
|
-
msg: s,
|
|
528
|
-
tag: null as string | null,
|
|
529
|
-
type: null as string | null,
|
|
530
|
-
id: null as string | null,
|
|
531
|
-
};
|
|
532
|
-
const idx = s.search(/\b(tag|type|id)\s*:/);
|
|
533
|
-
if (idx >= 0) {
|
|
534
|
-
out.msg = s.slice(0, idx).trim();
|
|
535
|
-
const re = /(tag|type|id)\s*:\s*([^,]+)/g;
|
|
536
|
-
let m: RegExpExecArray | null;
|
|
537
|
-
const rest = s.slice(idx);
|
|
538
|
-
while ((m = re.exec(rest)) !== null) {
|
|
539
|
-
const k = m[1] as 'tag' | 'type' | 'id';
|
|
540
|
-
out[k] = m[2]!.trim();
|
|
541
|
-
}
|
|
542
|
-
}
|
|
543
|
-
return out;
|
|
544
|
-
}
|