@sgummalla-works/sketchon 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/LICENSE +34 -0
  2. package/README.md +197 -0
  3. package/assets/emoji/1f4a1.svg +1 -0
  4. package/assets/emoji/1f4c8.svg +1 -0
  5. package/assets/emoji/1f4ca.svg +1 -0
  6. package/assets/emoji/1f4cb.svg +1 -0
  7. package/assets/emoji/1f4da.svg +1 -0
  8. package/assets/emoji/1f4dd.svg +1 -0
  9. package/assets/emoji/1f4e5.svg +1 -0
  10. package/assets/emoji/1f501.svg +1 -0
  11. package/assets/emoji/1f50d.svg +1 -0
  12. package/assets/emoji/1f517.svg +1 -0
  13. package/assets/emoji/1f525.svg +1 -0
  14. package/assets/emoji/1f5c4.svg +1 -0
  15. package/assets/emoji/1f9e0.svg +1 -0
  16. package/assets/emoji/1f9ee.svg +1 -0
  17. package/assets/emoji/23f8.svg +1 -0
  18. package/assets/emoji/2699.svg +1 -0
  19. package/assets/emoji/26a1.svg +1 -0
  20. package/assets/emoji/2705.svg +1 -0
  21. package/assets/emoji/2753.svg +1 -0
  22. package/assets/inter-400.ttf +0 -0
  23. package/assets/inter-600.ttf +0 -0
  24. package/assets/inter-700.ttf +0 -0
  25. package/dist/adapters/baseline.d.ts +3 -0
  26. package/dist/adapters/baseline.d.ts.map +1 -0
  27. package/dist/adapters/baseline.js +196 -0
  28. package/dist/adapters/baseline.js.map +1 -0
  29. package/dist/adapters/elk.d.ts +3 -0
  30. package/dist/adapters/elk.d.ts.map +1 -0
  31. package/dist/adapters/elk.js +230 -0
  32. package/dist/adapters/elk.js.map +1 -0
  33. package/dist/adapters/emoji.d.ts +10 -0
  34. package/dist/adapters/emoji.d.ts.map +1 -0
  35. package/dist/adapters/emoji.js +80 -0
  36. package/dist/adapters/emoji.js.map +1 -0
  37. package/dist/adapters/fonts.d.ts +13 -0
  38. package/dist/adapters/fonts.d.ts.map +1 -0
  39. package/dist/adapters/fonts.js +27 -0
  40. package/dist/adapters/fonts.js.map +1 -0
  41. package/dist/adapters/satori-helpers.d.ts +48 -0
  42. package/dist/adapters/satori-helpers.d.ts.map +1 -0
  43. package/dist/adapters/satori-helpers.js +43 -0
  44. package/dist/adapters/satori-helpers.js.map +1 -0
  45. package/dist/adapters/satori.d.ts +3 -0
  46. package/dist/adapters/satori.d.ts.map +1 -0
  47. package/dist/adapters/satori.js +269 -0
  48. package/dist/adapters/satori.js.map +1 -0
  49. package/dist/adapters/sequence.d.ts +3 -0
  50. package/dist/adapters/sequence.d.ts.map +1 -0
  51. package/dist/adapters/sequence.js +136 -0
  52. package/dist/adapters/sequence.js.map +1 -0
  53. package/dist/adapters/svg.d.ts +43 -0
  54. package/dist/adapters/svg.d.ts.map +1 -0
  55. package/dist/adapters/svg.js +92 -0
  56. package/dist/adapters/svg.js.map +1 -0
  57. package/dist/application/registry.d.ts +43 -0
  58. package/dist/application/registry.d.ts.map +1 -0
  59. package/dist/application/registry.js +45 -0
  60. package/dist/application/registry.js.map +1 -0
  61. package/dist/application/router.d.ts +56 -0
  62. package/dist/application/router.d.ts.map +1 -0
  63. package/dist/application/router.js +59 -0
  64. package/dist/application/router.js.map +1 -0
  65. package/dist/constants.d.ts +25 -0
  66. package/dist/constants.d.ts.map +1 -0
  67. package/dist/constants.js +35 -0
  68. package/dist/constants.js.map +1 -0
  69. package/dist/domain/spec.d.ts +163 -0
  70. package/dist/domain/spec.d.ts.map +1 -0
  71. package/dist/domain/spec.js +17 -0
  72. package/dist/domain/spec.js.map +1 -0
  73. package/dist/domain/theme.d.ts +68 -0
  74. package/dist/domain/theme.d.ts.map +1 -0
  75. package/dist/domain/theme.js +60 -0
  76. package/dist/domain/theme.js.map +1 -0
  77. package/dist/domain/validate.d.ts +19 -0
  78. package/dist/domain/validate.d.ts.map +1 -0
  79. package/dist/domain/validate.js +69 -0
  80. package/dist/domain/validate.js.map +1 -0
  81. package/dist/index.d.ts +62 -0
  82. package/dist/index.d.ts.map +1 -0
  83. package/dist/index.js +83 -0
  84. package/dist/index.js.map +1 -0
  85. package/dist/ports/Technique.d.ts +69 -0
  86. package/dist/ports/Technique.d.ts.map +1 -0
  87. package/dist/ports/Technique.js +2 -0
  88. package/dist/ports/Technique.js.map +1 -0
  89. package/package.json +52 -0
@@ -0,0 +1,45 @@
1
+ export class TechniqueRegistry {
2
+ map = new Map();
3
+ /**
4
+ * Register a layout engine.
5
+ * Returns `this` for fluent chaining at the composition root.
6
+ *
7
+ * @param key stable engine identifier
8
+ * @param technique the Technique implementation
9
+ * @throws if the key is already registered (prevents silent overwrites)
10
+ */
11
+ register(key, technique) {
12
+ if (this.map.has(key)) {
13
+ throw new Error(`Technique "${key}" is already registered. Each engine key must be unique.`);
14
+ }
15
+ this.map.set(key, technique);
16
+ return this;
17
+ }
18
+ /**
19
+ * Look up a technique by engine key.
20
+ *
21
+ * @param key the engine identifier
22
+ * @throws if no technique is registered for that key
23
+ */
24
+ get(key) {
25
+ const t = this.map.get(key);
26
+ if (!t) {
27
+ throw new Error(`No technique registered for key "${key}". ` +
28
+ `Registered: ${[...this.map.keys()].join(', ')}`);
29
+ }
30
+ return t;
31
+ }
32
+ /** Whether a key is registered. */
33
+ has(key) {
34
+ return this.map.has(key);
35
+ }
36
+ /** All registered techniques in insertion order. */
37
+ techniques() {
38
+ return [...this.map.values()];
39
+ }
40
+ /** All registered engine keys in insertion order. */
41
+ keys() {
42
+ return [...this.map.keys()];
43
+ }
44
+ }
45
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/application/registry.ts"],"names":[],"mappings":"AAkBA,MAAM,OAAO,iBAAiB;IACX,GAAG,GAAG,IAAI,GAAG,EAAqB,CAAC;IAEpD;;;;;;;OAOG;IACH,QAAQ,CAAC,GAAW,EAAE,SAAoB;QACxC,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CACb,cAAc,GAAG,0DAA0D,CAC5E,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;OAKG;IACH,GAAG,CAAC,GAAW;QACb,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,CAAC,CAAC,EAAE,CAAC;YACP,MAAM,IAAI,KAAK,CACb,oCAAoC,GAAG,KAAK;gBAC1C,eAAe,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACnD,CAAC;QACJ,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC;IAED,mCAAmC;IACnC,GAAG,CAAC,GAAW;QACb,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAED,oDAAoD;IACpD,UAAU;QACR,OAAO,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IAChC,CAAC;IAED,qDAAqD;IACrD,IAAI;QACF,OAAO,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;IAC9B,CAAC;CACF"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Router — application-layer routing logic.
3
+ *
4
+ * HEXAGONAL ARCHITECTURE INVARIANT:
5
+ * This file MUST NEVER import from '../adapters/' or any concrete adapter.
6
+ * It depends on TechniqueRegistry (application layer) and the domain types.
7
+ * The routing table (KIND_ENGINE) is application policy, not adapter knowledge.
8
+ *
9
+ * The router takes a TechniqueRegistry via constructor injection.
10
+ * The registry is populated by the composition root (index.ts), which is the
11
+ * only place that is allowed to import concrete adapters.
12
+ */
13
+ import type { DiagramSpec } from '../domain/spec.js';
14
+ import type { Technique, RenderResult } from '../ports/Technique.js';
15
+ import type { TechniqueRegistry } from './registry.js';
16
+ /**
17
+ * Valid engine keys — extend this union when registering a new engine.
18
+ * Lives here because routing policy (which kind maps to which engine)
19
+ * is an application concern, not a domain or adapter concern.
20
+ */
21
+ export type EngineKey = 'baseline' | 'elk' | 'satori' | 'sequence';
22
+ /**
23
+ * The Router orchestrates rendering by resolving the right engine from the
24
+ * registry based on the spec's kind (or an explicit override).
25
+ *
26
+ * Constructed with a TechniqueRegistry injected from the composition root.
27
+ * Has no knowledge of which concrete adapters exist.
28
+ */
29
+ export declare class Router {
30
+ private readonly registry;
31
+ constructor(registry: TechniqueRegistry);
32
+ /**
33
+ * Select the engine key for a spec.
34
+ * An explicit `spec.renderer` override takes priority over the kind default.
35
+ *
36
+ * @param spec the diagram spec
37
+ * @returns the resolved engine key
38
+ */
39
+ selectEngineKey(spec: DiagramSpec): EngineKey;
40
+ /**
41
+ * Resolve the Technique that will render a spec.
42
+ *
43
+ * @param spec the diagram spec
44
+ * @returns the chosen Technique implementation
45
+ */
46
+ selectEngine(spec: DiagramSpec): Technique;
47
+ /**
48
+ * Render a spec with the routed engine.
49
+ * This is the primary use case entry point — what consumers call.
50
+ *
51
+ * @param spec the validated, coordinate-free diagram spec
52
+ * @returns the rendered SVG + metadata
53
+ */
54
+ renderDiagram(spec: DiagramSpec): RenderResult | Promise<RenderResult>;
55
+ }
56
+ //# sourceMappingURL=router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/application/router.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,WAAW,EAAe,MAAM,mBAAmB,CAAC;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEvD;;;;GAIG;AACH,MAAM,MAAM,SAAS,GAAG,UAAU,GAAG,KAAK,GAAG,QAAQ,GAAG,UAAU,CAAC;AAgBnE;;;;;;GAMG;AACH,qBAAa,MAAM;IACL,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,iBAAiB;IAExD;;;;;;OAMG;IACH,eAAe,CAAC,IAAI,EAAE,WAAW,GAAG,SAAS;IAO7C;;;;;OAKG;IACH,YAAY,CAAC,IAAI,EAAE,WAAW,GAAG,SAAS;IAI1C;;;;;;OAMG;IACH,aAAa,CAAC,IAAI,EAAE,WAAW,GAAG,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;CAGvE"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * The authoritative kind → engine mapping.
3
+ * One entry per DiagramKind — adding a new kind means adding one line here.
4
+ */
5
+ const KIND_ENGINE = {
6
+ concept: 'satori',
7
+ mindmap: 'satori',
8
+ sequence: 'sequence',
9
+ flow: 'elk',
10
+ architecture: 'elk',
11
+ state: 'elk',
12
+ er: 'elk',
13
+ };
14
+ /**
15
+ * The Router orchestrates rendering by resolving the right engine from the
16
+ * registry based on the spec's kind (or an explicit override).
17
+ *
18
+ * Constructed with a TechniqueRegistry injected from the composition root.
19
+ * Has no knowledge of which concrete adapters exist.
20
+ */
21
+ export class Router {
22
+ registry;
23
+ constructor(registry) {
24
+ this.registry = registry;
25
+ }
26
+ /**
27
+ * Select the engine key for a spec.
28
+ * An explicit `spec.renderer` override takes priority over the kind default.
29
+ *
30
+ * @param spec the diagram spec
31
+ * @returns the resolved engine key
32
+ */
33
+ selectEngineKey(spec) {
34
+ if (spec.renderer && this.registry.has(spec.renderer)) {
35
+ return spec.renderer;
36
+ }
37
+ return KIND_ENGINE[spec.kind] ?? 'elk';
38
+ }
39
+ /**
40
+ * Resolve the Technique that will render a spec.
41
+ *
42
+ * @param spec the diagram spec
43
+ * @returns the chosen Technique implementation
44
+ */
45
+ selectEngine(spec) {
46
+ return this.registry.get(this.selectEngineKey(spec));
47
+ }
48
+ /**
49
+ * Render a spec with the routed engine.
50
+ * This is the primary use case entry point — what consumers call.
51
+ *
52
+ * @param spec the validated, coordinate-free diagram spec
53
+ * @returns the rendered SVG + metadata
54
+ */
55
+ renderDiagram(spec) {
56
+ return this.selectEngine(spec).render(spec);
57
+ }
58
+ }
59
+ //# sourceMappingURL=router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../../src/application/router.ts"],"names":[],"mappings":"AAuBA;;;GAGG;AACH,MAAM,WAAW,GAAmC;IAClD,OAAO,EAAO,QAAQ;IACtB,OAAO,EAAO,QAAQ;IACtB,QAAQ,EAAM,UAAU;IACxB,IAAI,EAAU,KAAK;IACnB,YAAY,EAAE,KAAK;IACnB,KAAK,EAAS,KAAK;IACnB,EAAE,EAAY,KAAK;CACpB,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,OAAO,MAAM;IACY;IAA7B,YAA6B,QAA2B;QAA3B,aAAQ,GAAR,QAAQ,CAAmB;IAAG,CAAC;IAE5D;;;;;;OAMG;IACH,eAAe,CAAC,IAAiB;QAC/B,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YACtD,OAAO,IAAI,CAAC,QAAqB,CAAC;QACpC,CAAC;QACD,OAAO,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC;IACzC,CAAC;IAED;;;;;OAKG;IACH,YAAY,CAAC,IAAiB;QAC5B,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC;IACvD,CAAC;IAED;;;;;;OAMG;IACH,aAAa,CAAC,IAAiB;QAC7B,OAAO,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC9C,CAAC;CACF"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Tunable constants for the diagram lab. Kept out of logic files so a
3
+ * technique or metric never inlines a magic number — change layout/eval
4
+ * behaviour here, in one place.
5
+ */
6
+ export declare const AVG_CHAR_WIDTH_EM = 0.58;
7
+ export declare const DEFAULT_FONT_SIZE = 14;
8
+ export declare const NODE_LABEL_FONT_SIZE = 14;
9
+ export declare const NODE_SUBLABEL_FONT_SIZE = 11;
10
+ export declare const EDGE_LABEL_FONT_SIZE = 12;
11
+ export declare const NODE_PADDING_X = 16;
12
+ export declare const NODE_PADDING_Y = 12;
13
+ export declare const NODE_MIN_WIDTH = 72;
14
+ export declare const NODE_MIN_HEIGHT = 40;
15
+ export declare const NODE_MAX_WIDTH = 240;
16
+ export declare const LAYER_GAP = 90;
17
+ export declare const NODE_GAP = 36;
18
+ export declare const CANVAS_PADDING = 40;
19
+ export declare const SCORE_START = 100;
20
+ export declare const PENALTY_PER_OVERLAP_PAIR = 12;
21
+ export declare const PENALTY_PER_OFFCANVAS_BOX = 10;
22
+ export declare const PENALTY_PER_TEXT_OVERFLOW = 8;
23
+ export declare const PENALTY_PER_EDGE_CROSSING = 3;
24
+ export declare const TEXT_OVERFLOW_TOLERANCE_PX = 2;
25
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,eAAO,MAAM,iBAAiB,OAAO,CAAC;AACtC,eAAO,MAAM,iBAAiB,KAAK,CAAC;AACpC,eAAO,MAAM,oBAAoB,KAAK,CAAC;AACvC,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAC1C,eAAO,MAAM,oBAAoB,KAAK,CAAC;AAGvC,eAAO,MAAM,cAAc,KAAK,CAAC;AACjC,eAAO,MAAM,cAAc,KAAK,CAAC;AACjC,eAAO,MAAM,cAAc,KAAK,CAAC;AACjC,eAAO,MAAM,eAAe,KAAK,CAAC;AAClC,eAAO,MAAM,cAAc,MAAM,CAAC;AAGlC,eAAO,MAAM,SAAS,KAAK,CAAC;AAC5B,eAAO,MAAM,QAAQ,KAAK,CAAC;AAC3B,eAAO,MAAM,cAAc,KAAK,CAAC;AAKjC,eAAO,MAAM,WAAW,MAAM,CAAC;AAC/B,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAC3C,eAAO,MAAM,yBAAyB,KAAK,CAAC;AAC5C,eAAO,MAAM,yBAAyB,IAAI,CAAC;AAC3C,eAAO,MAAM,yBAAyB,IAAI,CAAC;AAC3C,eAAO,MAAM,0BAA0B,IAAI,CAAC"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Tunable constants for the diagram lab. Kept out of logic files so a
3
+ * technique or metric never inlines a magic number — change layout/eval
4
+ * behaviour here, in one place.
5
+ */
6
+ // ── Text measurement ────────────────────────────────────────────────────────
7
+ // We have no real font metrics in the baseline (no browser, no Satori yet),
8
+ // so width is estimated as `chars * AVG_CHAR_WIDTH_EM * fontSize`. ~0.58em is a
9
+ // reasonable mean advance width for a humanist sans at typical sizes. Real
10
+ // engines (Satori/resvg) will replace this estimate with true glyph metrics.
11
+ export const AVG_CHAR_WIDTH_EM = 0.58;
12
+ export const DEFAULT_FONT_SIZE = 14;
13
+ export const NODE_LABEL_FONT_SIZE = 14;
14
+ export const NODE_SUBLABEL_FONT_SIZE = 11;
15
+ export const EDGE_LABEL_FONT_SIZE = 12;
16
+ // ── Node sizing ─────────────────────────────────────────────────────────────
17
+ export const NODE_PADDING_X = 16;
18
+ export const NODE_PADDING_Y = 12;
19
+ export const NODE_MIN_WIDTH = 72;
20
+ export const NODE_MIN_HEIGHT = 40;
21
+ export const NODE_MAX_WIDTH = 240;
22
+ // ── Layout spacing (baseline layered layout) ────────────────────────────────
23
+ export const LAYER_GAP = 90; // gap between layers (rank direction)
24
+ export const NODE_GAP = 36; // gap between siblings within a layer
25
+ export const CANVAS_PADDING = 40; // margin around the whole drawing
26
+ // ── Eval thresholds + scoring weights ───────────────────────────────────────
27
+ // Composite score starts at 100; each problem subtracts its weight (clamped
28
+ // at 0). Weights encode "how bad is this for a reader."
29
+ export const SCORE_START = 100;
30
+ export const PENALTY_PER_OVERLAP_PAIR = 12; // boxes physically overlapping
31
+ export const PENALTY_PER_OFFCANVAS_BOX = 10; // box outside the viewBox
32
+ export const PENALTY_PER_TEXT_OVERFLOW = 8; // label wider than its box
33
+ export const PENALTY_PER_EDGE_CROSSING = 3; // two edges crossing
34
+ export const TEXT_OVERFLOW_TOLERANCE_PX = 2; // ignore sub-pixel rounding
35
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,+EAA+E;AAC/E,4EAA4E;AAC5E,gFAAgF;AAChF,2EAA2E;AAC3E,6EAA6E;AAC7E,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,CAAC;AACtC,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,CAAC;AACpC,MAAM,CAAC,MAAM,oBAAoB,GAAG,EAAE,CAAC;AACvC,MAAM,CAAC,MAAM,uBAAuB,GAAG,EAAE,CAAC;AAC1C,MAAM,CAAC,MAAM,oBAAoB,GAAG,EAAE,CAAC;AAEvC,+EAA+E;AAC/E,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,CAAC;AACjC,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,CAAC;AACjC,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,CAAC;AACjC,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,CAAC;AAClC,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,CAAC;AAElC,+EAA+E;AAC/E,MAAM,CAAC,MAAM,SAAS,GAAG,EAAE,CAAC,CAAC,sCAAsC;AACnE,MAAM,CAAC,MAAM,QAAQ,GAAG,EAAE,CAAC,CAAC,sCAAsC;AAClE,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,CAAC,CAAC,kCAAkC;AAEpE,+EAA+E;AAC/E,4EAA4E;AAC5E,wDAAwD;AACxD,MAAM,CAAC,MAAM,WAAW,GAAG,GAAG,CAAC;AAC/B,MAAM,CAAC,MAAM,wBAAwB,GAAG,EAAE,CAAC,CAAC,+BAA+B;AAC3E,MAAM,CAAC,MAAM,yBAAyB,GAAG,EAAE,CAAC,CAAC,0BAA0B;AACvE,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,CAAC,2BAA2B;AACvE,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,CAAC,qBAAqB;AACjE,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC,CAAC,4BAA4B"}
@@ -0,0 +1,163 @@
1
+ /**
2
+ * The DiagramSpec — a SEMANTIC, coordinate-free description of a diagram.
3
+ *
4
+ * This is the central contract of the lab and the thing that eventually ports
5
+ * into pragna2. The whole premise of #36 is: the model (or a hand-authored
6
+ * fixture) emits ONLY structure — what relates to what, how it's grouped, what
7
+ * to emphasise — and a deterministic layout engine computes every pixel. So
8
+ * there are deliberately NO x/y/width coordinates anywhere in this file. If a
9
+ * coordinate ever appears in a spec, the design has leaked the broken part
10
+ * (model-does-trig) back in.
11
+ *
12
+ * One schema spans ALL diagram kinds (flow, sequence, architecture, ER, state,
13
+ * and free-form concept/illustrative). A technique reads the same spec and
14
+ * lays it out however suits its engine.
15
+ */
16
+ /** What family of diagram this is. Drives default layout strategy + shapes. */
17
+ export type DiagramKind = 'flow' | 'sequence' | 'architecture' | 'er' | 'state' | 'mindmap' | 'concept';
18
+ /** Preferred primary flow direction. Engines may honour or override. */
19
+ export type Direction = 'TB' | 'BT' | 'LR' | 'RL';
20
+ /** Visual shape of a node. Semantic, not pixel-level. */
21
+ export type NodeShape = 'box' | 'rounded' | 'pill' | 'circle' | 'diamond' | 'cylinder' | 'actor' | 'note' | 'icon' | 'card' | 'checkpoint';
22
+ /**
23
+ * Visual weight. Lets the author say "this is the important one" without
24
+ * choosing colours — the renderer maps emphasis → theme tokens.
25
+ */
26
+ export type Emphasis = 'normal' | 'primary' | 'muted' | 'danger' | 'success' | 'accent';
27
+ /** Line treatment for an edge. */
28
+ export type EdgeStyle = 'solid' | 'dashed' | 'dotted';
29
+ /** Arrowhead treatment. */
30
+ export type ArrowKind = 'none' | 'open' | 'filled';
31
+ /**
32
+ * Semantic edge category. The renderer can style each consistently
33
+ * (e.g. dataflow vs dependency vs sequence-message) without per-edge styling
34
+ * from the author.
35
+ */
36
+ export type EdgeSemantic = 'default' | 'dependency' | 'dataflow' | 'message' | 'return' | 'association';
37
+ export interface DiagramNode {
38
+ /** Stable id, referenced by edges, groups, annotations. */
39
+ id: string;
40
+ /** Primary visible text. */
41
+ label: string;
42
+ /**
43
+ * Optional second line (role, type, short qualifier). For `card` shapes this
44
+ * is the tinted sub-line; render as `·`-joined when given as `sublabelParts`.
45
+ */
46
+ sublabel?: string;
47
+ /**
48
+ * Structured sub-line tokens for rich cards, rendered `·`-separated
49
+ * (e.g. ["Vector DB", "semantic search", "doc chunking"]). Preferred over
50
+ * `sublabel` for `card` shapes; the renderer joins them.
51
+ */
52
+ sublabelParts?: string[];
53
+ shape?: NodeShape;
54
+ emphasis?: Emphasis;
55
+ /**
56
+ * Optional leading glyph. May be a literal emoji (e.g. "🔍") for concept/card
57
+ * diagrams, or a semantic icon name the renderer maps. Never a URL.
58
+ */
59
+ icon?: string;
60
+ /** Id of the group this node belongs to, if any. */
61
+ group?: string;
62
+ /**
63
+ * Id of the colour `category` this node belongs to (legend-style colouring).
64
+ * Independent of `emphasis`: category drives the colour family + legend,
65
+ * emphasis is a per-node weight. When both are set, category wins for fill.
66
+ */
67
+ category?: string;
68
+ }
69
+ export interface DiagramEdge {
70
+ /** Source node id. */
71
+ from: string;
72
+ /** Target node id. */
73
+ to: string;
74
+ /** Optional edge text (condition, message, cardinality). */
75
+ label?: string;
76
+ style?: EdgeStyle;
77
+ arrow?: ArrowKind;
78
+ semantic?: EdgeSemantic;
79
+ }
80
+ /**
81
+ * A visual grouping / container (a subsystem boundary, a swimlane, a cluster).
82
+ * Members are node ids. Groups may nest via `parent`.
83
+ */
84
+ export interface DiagramGroup {
85
+ id: string;
86
+ label?: string;
87
+ members: string[];
88
+ emphasis?: Emphasis;
89
+ /** Optional parent group id for nested containers. */
90
+ parent?: string;
91
+ }
92
+ /** Where an annotation sits relative to its target. */
93
+ export type AnnotationPlacement = 'top' | 'bottom' | 'left' | 'right' | 'callout';
94
+ /**
95
+ * Free-floating explanatory text, optionally tied to a node/group. Central to
96
+ * the illustrative/concept kind ("build intuition" labels pointing at parts).
97
+ */
98
+ export interface DiagramAnnotation {
99
+ text: string;
100
+ /** Node or group id this annotation points at, if any. */
101
+ target?: string;
102
+ placement?: AnnotationPlacement;
103
+ }
104
+ /** Optional hints; renderer supplies defaults for anything omitted. */
105
+ export interface ThemeHints {
106
+ /** 'light' | 'dark' — renderer picks token set. */
107
+ mode?: 'light' | 'dark';
108
+ /** Rough density preference. */
109
+ density?: 'compact' | 'comfortable';
110
+ }
111
+ /**
112
+ * A named category for legend-style colour coding (e.g. "retrieval",
113
+ * "execution"). Added after the 2026-05-31 reference image, which colours nodes
114
+ * by CATEGORY (retrieval=blue, reasoning=purple, …) and renders a legend — a
115
+ * different axis from per-node semantic `emphasis`. A node points at a category
116
+ * via `DiagramNode.category`; the renderer maps category → colour and draws the
117
+ * legend from the categories actually used.
118
+ */
119
+ export interface DiagramCategory {
120
+ /** Stable id referenced by `DiagramNode.category`. */
121
+ id: string;
122
+ /** Legend label, e.g. "Retrieval / grounding". */
123
+ label: string;
124
+ /** Colour intent; renderer maps to a concrete token. */
125
+ emphasis?: Emphasis;
126
+ }
127
+ /**
128
+ * Column headers for the annotated two-column "concept" layout (the reference
129
+ * image's "Tool layer" / "Why it's mandatory"). Only meaningful when nodes
130
+ * carry right-placed annotations rendered as a paired second column.
131
+ */
132
+ export interface ColumnHeaders {
133
+ /** Heading over the node column. */
134
+ primary: string;
135
+ /** Heading over the annotation column. */
136
+ annotation: string;
137
+ }
138
+ export interface DiagramSpec {
139
+ /** Stable id for the spec (used in filenames / preview). */
140
+ id: string;
141
+ /** Optional diagram title rendered as a heading. */
142
+ title?: string;
143
+ kind: DiagramKind;
144
+ /** Preferred direction for directed kinds. Default per-kind in the renderer. */
145
+ direction?: Direction;
146
+ nodes: DiagramNode[];
147
+ edges: DiagramEdge[];
148
+ groups?: DiagramGroup[];
149
+ annotations?: DiagramAnnotation[];
150
+ /** Legend-style colour categories referenced by `DiagramNode.category`. */
151
+ categories?: DiagramCategory[];
152
+ /** Column headers for the annotated two-column concept layout. */
153
+ columns?: ColumnHeaders;
154
+ /**
155
+ * Optional engine override. Normally omitted — the renderer auto-routes by
156
+ * `kind` (panel/concept → Satori, graph kinds → elkjs). Set only for the rare
157
+ * case where the kind's default engine is the wrong fit. The model should not
158
+ * set this routinely; declaring the right `kind` is the intended path.
159
+ */
160
+ renderer?: 'satori' | 'elk' | 'sequence';
161
+ theme?: ThemeHints;
162
+ }
163
+ //# sourceMappingURL=spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec.d.ts","sourceRoot":"","sources":["../../src/domain/spec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,+EAA+E;AAC/E,MAAM,MAAM,WAAW,GACnB,MAAM,GACN,UAAU,GACV,cAAc,GACd,IAAI,GACJ,OAAO,GACP,SAAS,GACT,SAAS,CAAC;AAEd,wEAAwE;AACxE,MAAM,MAAM,SAAS,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAElD,yDAAyD;AACzD,MAAM,MAAM,SAAS,GACjB,KAAK,GACL,SAAS,GACT,MAAM,GACN,QAAQ,GACR,SAAS,GACT,UAAU,GACV,OAAO,GACP,MAAM,GACN,MAAM,GACN,MAAM,GACN,YAAY,CAAC;AAEjB;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;AAExF,kCAAkC;AAClC,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEtD,2BAA2B;AAC3B,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEnD;;;;GAIG;AACH,MAAM,MAAM,YAAY,GACpB,SAAS,GACT,YAAY,GACZ,UAAU,GACV,SAAS,GACT,QAAQ,GACR,aAAa,CAAC;AAElB,MAAM,WAAW,WAAW;IAC1B,2DAA2D;IAC3D,EAAE,EAAE,MAAM,CAAC;IACX,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oDAAoD;IACpD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,sBAAsB;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,sBAAsB;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,4DAA4D;IAC5D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,QAAQ,CAAC,EAAE,YAAY,CAAC;CACzB;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,sDAAsD;IACtD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,uDAAuD;AACvD,MAAM,MAAM,mBAAmB,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;AAElF;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,mBAAmB,CAAC;CACjC;AAED,uEAAuE;AACvE,MAAM,WAAW,UAAU;IACzB,mDAAmD;IACnD,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACxB,gCAAgC;IAChC,OAAO,CAAC,EAAE,SAAS,GAAG,aAAa,CAAC;CACrC;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,eAAe;IAC9B,sDAAsD;IACtD,EAAE,EAAE,MAAM,CAAC;IACX,kDAAkD;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,wDAAwD;IACxD,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,oCAAoC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,0CAA0C;IAC1C,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,4DAA4D;IAC5D,EAAE,EAAE,MAAM,CAAC;IACX,oDAAoD;IACpD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,WAAW,CAAC;IAClB,gFAAgF;IAChF,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,MAAM,CAAC,EAAE,YAAY,EAAE,CAAC;IACxB,WAAW,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAClC,2EAA2E;IAC3E,UAAU,CAAC,EAAE,eAAe,EAAE,CAAC;IAC/B,kEAAkE;IAClE,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,UAAU,CAAC;IACzC,KAAK,CAAC,EAAE,UAAU,CAAC;CACpB"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * The DiagramSpec — a SEMANTIC, coordinate-free description of a diagram.
3
+ *
4
+ * This is the central contract of the lab and the thing that eventually ports
5
+ * into pragna2. The whole premise of #36 is: the model (or a hand-authored
6
+ * fixture) emits ONLY structure — what relates to what, how it's grouped, what
7
+ * to emphasise — and a deterministic layout engine computes every pixel. So
8
+ * there are deliberately NO x/y/width coordinates anywhere in this file. If a
9
+ * coordinate ever appears in a spec, the design has leaked the broken part
10
+ * (model-does-trig) back in.
11
+ *
12
+ * One schema spans ALL diagram kinds (flow, sequence, architecture, ER, state,
13
+ * and free-form concept/illustrative). A technique reads the same spec and
14
+ * lays it out however suits its engine.
15
+ */
16
+ export {};
17
+ //# sourceMappingURL=spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec.js","sourceRoot":"","sources":["../../src/domain/spec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Colour tokens for the diagram renderer.
3
+ *
4
+ * Single source of truth for every colour value used across all rendering
5
+ * adapters. No hex string should appear in any adapter file — use these named
6
+ * constants instead so the visual language is tunable from one place.
7
+ *
8
+ * Tokens are grouped by concern. All values are hex strings or rgba() strings
9
+ * that SVG and Satori both accept.
10
+ */
11
+ export declare const COLOR_TEXT_PRIMARY = "#0f172a";
12
+ export declare const COLOR_TEXT_BODY = "#475569";
13
+ export declare const COLOR_TEXT_MUTED = "#64748b";
14
+ export declare const COLOR_TEXT_WHITE = "#ffffff";
15
+ export declare const COLOR_BORDER_LIGHT = "#e2e8f0";
16
+ export declare const COLOR_BORDER_DEFAULT = "#cbd5e1";
17
+ export declare const COLOR_EDGE_DEFAULT = "#64748b";
18
+ export declare const COLOR_EDGE_DASHED = "#94a3b8";
19
+ export declare const PALETTE_NORMAL: {
20
+ fill: string;
21
+ stroke: string;
22
+ text: string;
23
+ };
24
+ export declare const PALETTE_PRIMARY: {
25
+ fill: string;
26
+ stroke: string;
27
+ text: string;
28
+ };
29
+ export declare const PALETTE_ACCENT: {
30
+ fill: string;
31
+ stroke: string;
32
+ text: string;
33
+ };
34
+ export declare const PALETTE_MUTED: {
35
+ fill: string;
36
+ stroke: string;
37
+ text: string;
38
+ };
39
+ export declare const PALETTE_DANGER: {
40
+ fill: string;
41
+ stroke: string;
42
+ text: string;
43
+ };
44
+ export declare const PALETTE_SUCCESS: {
45
+ fill: string;
46
+ stroke: string;
47
+ text: string;
48
+ };
49
+ export declare const DARK_PRIMARY = "#1e3a5f";
50
+ export declare const DARK_ACCENT = "#3730a3";
51
+ export declare const DARK_SUCCESS = "#14532d";
52
+ export declare const DARK_DANGER = "#7f1d1d";
53
+ export declare const DARK_NORMAL = "#334155";
54
+ export declare const DARK_MUTED = "#475569";
55
+ export declare const ACTOR_CYCLE_FILLS: readonly ["#1e3a5f", "#14532d", "#3730a3", "#7c2d12", "#134e4a", "#4c1d95"];
56
+ export declare const CARD_PALETTE_PRIMARY = "#1e4e79";
57
+ export declare const CARD_PALETTE_ACCENT = "#4b3f9e";
58
+ export declare const CARD_PALETTE_DANGER = "#8a3a2c";
59
+ export declare const CARD_PALETTE_SUCCESS = "#3f6e26";
60
+ export declare const CARD_PALETTE_NORMAL = "#3b4250";
61
+ export declare const CARD_PALETTE_MUTED = "#64748b";
62
+ export declare const CHECKPOINT_FILL = "#6b5212";
63
+ export declare const CHECKPOINT_BORDER = "#b8923a";
64
+ export declare const CHECKPOINT_TEXT = "#ffd98a";
65
+ export declare const CONNECTOR_COLOR = "#cbd5e1";
66
+ export declare const ARROW_FILL = "#475569";
67
+ export declare const ARROW_STROKE = "#475569";
68
+ //# sourceMappingURL=theme.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../../src/domain/theme.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,eAAO,MAAM,kBAAkB,YAAe,CAAC;AAC/C,eAAO,MAAM,eAAe,YAAkB,CAAC;AAC/C,eAAO,MAAM,gBAAgB,YAAiB,CAAC;AAC/C,eAAO,MAAM,gBAAgB,YAAiB,CAAC;AAE/C,eAAO,MAAM,kBAAkB,YAAe,CAAC;AAC/C,eAAO,MAAM,oBAAoB,YAAa,CAAC;AAC/C,eAAO,MAAM,kBAAkB,YAAe,CAAC;AAC/C,eAAO,MAAM,iBAAiB,YAAgB,CAAC;AAI/C,eAAO,MAAM,cAAc;;;;CAAoE,CAAC;AAChG,eAAO,MAAM,eAAe;;;;CAA0D,CAAC;AACvF,eAAO,MAAM,cAAc;;;;CAA2D,CAAC;AACvF,eAAO,MAAM,aAAa;;;;CAA4D,CAAC;AACvF,eAAO,MAAM,cAAc;;;;CAA2D,CAAC;AACvF,eAAO,MAAM,eAAe;;;;CAA0D,CAAC;AAGvF,eAAO,MAAM,YAAY,YAAY,CAAC;AACtC,eAAO,MAAM,WAAW,YAAa,CAAC;AACtC,eAAO,MAAM,YAAY,YAAY,CAAC;AACtC,eAAO,MAAM,WAAW,YAAa,CAAC;AACtC,eAAO,MAAM,WAAW,YAAa,CAAC;AACtC,eAAO,MAAM,UAAU,YAAc,CAAC;AAGtC,eAAO,MAAM,iBAAiB,6EAOpB,CAAC;AAGX,eAAO,MAAM,oBAAoB,YAAY,CAAC;AAC9C,eAAO,MAAM,mBAAmB,YAAa,CAAC;AAC9C,eAAO,MAAM,mBAAmB,YAAa,CAAC;AAC9C,eAAO,MAAM,oBAAoB,YAAY,CAAC;AAC9C,eAAO,MAAM,mBAAmB,YAAa,CAAC;AAC9C,eAAO,MAAM,kBAAkB,YAAc,CAAC;AAG9C,eAAO,MAAM,eAAe,YAAc,CAAC;AAC3C,eAAO,MAAM,iBAAiB,YAAY,CAAC;AAC3C,eAAO,MAAM,eAAe,YAAc,CAAC;AAG3C,eAAO,MAAM,eAAe,YAAY,CAAC;AAGzC,eAAO,MAAM,UAAU,YAAc,CAAC;AACtC,eAAO,MAAM,YAAY,YAAY,CAAC"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Colour tokens for the diagram renderer.
3
+ *
4
+ * Single source of truth for every colour value used across all rendering
5
+ * adapters. No hex string should appear in any adapter file — use these named
6
+ * constants instead so the visual language is tunable from one place.
7
+ *
8
+ * Tokens are grouped by concern. All values are hex strings or rgba() strings
9
+ * that SVG and Satori both accept.
10
+ */
11
+ // ── Structural / neutral ──────────────────────────────────────────────────────
12
+ export const COLOR_TEXT_PRIMARY = '#0f172a'; // heading text
13
+ export const COLOR_TEXT_BODY = '#475569'; // body / label text
14
+ export const COLOR_TEXT_MUTED = '#64748b'; // secondary / muted labels
15
+ export const COLOR_TEXT_WHITE = '#ffffff'; // white text on dark fills
16
+ export const COLOR_BORDER_LIGHT = '#e2e8f0'; // dividers, subtle borders
17
+ export const COLOR_BORDER_DEFAULT = '#cbd5e1'; // lifelines, group outlines
18
+ export const COLOR_EDGE_DEFAULT = '#64748b'; // solid edge stroke
19
+ export const COLOR_EDGE_DASHED = '#94a3b8'; // dashed / return edge stroke
20
+ // ── Light semantic palette (outlined boxes — baseline + elk nodes) ────────────
21
+ // Fill + stroke + text per emphasis value.
22
+ export const PALETTE_NORMAL = { fill: '#f1f5f9', stroke: '#94a3b8', text: COLOR_TEXT_PRIMARY };
23
+ export const PALETTE_PRIMARY = { fill: '#dbeafe', stroke: '#3b82f6', text: '#0c2a5b' };
24
+ export const PALETTE_ACCENT = { fill: '#ede9fe', stroke: '#8b5cf6', text: '#3b1d80' };
25
+ export const PALETTE_MUTED = { fill: '#f8fafc', stroke: '#cbd5e1', text: '#475569' };
26
+ export const PALETTE_DANGER = { fill: '#fee2e2', stroke: '#ef4444', text: '#7f1d1d' };
27
+ export const PALETTE_SUCCESS = { fill: '#dcfce7', stroke: '#22c55e', text: '#14532d' };
28
+ // ── Dark semantic palette (sequence actor boxes — saturated fills + white text) ─
29
+ export const DARK_PRIMARY = '#1e3a5f'; // deep navy
30
+ export const DARK_ACCENT = '#3730a3'; // deep indigo / purple
31
+ export const DARK_SUCCESS = '#14532d'; // dark forest green
32
+ export const DARK_DANGER = '#7f1d1d'; // dark crimson
33
+ export const DARK_NORMAL = '#334155'; // dark slate
34
+ export const DARK_MUTED = '#475569'; // medium slate
35
+ // Cycling fills for actors with no explicit emphasis (distinct per slot).
36
+ export const ACTOR_CYCLE_FILLS = [
37
+ DARK_PRIMARY, // navy (slot 0)
38
+ DARK_SUCCESS, // green (slot 1)
39
+ DARK_ACCENT, // indigo (slot 2)
40
+ '#7c2d12', // rust (slot 3)
41
+ '#134e4a', // teal (slot 4)
42
+ '#4c1d95', // violet (slot 5)
43
+ ];
44
+ // ── Satori card palette (rich panel cards — always white text) ────────────────
45
+ export const CARD_PALETTE_PRIMARY = '#1e4e79';
46
+ export const CARD_PALETTE_ACCENT = '#4b3f9e';
47
+ export const CARD_PALETTE_DANGER = '#8a3a2c';
48
+ export const CARD_PALETTE_SUCCESS = '#3f6e26';
49
+ export const CARD_PALETTE_NORMAL = '#3b4250';
50
+ export const CARD_PALETTE_MUTED = '#64748b';
51
+ // ── Satori checkpoint pills ───────────────────────────────────────────────────
52
+ export const CHECKPOINT_FILL = '#6b5212';
53
+ export const CHECKPOINT_BORDER = '#b8923a';
54
+ export const CHECKPOINT_TEXT = '#ffd98a';
55
+ // ── Satori connector arrows (vertical between cards) ─────────────────────────
56
+ export const CONNECTOR_COLOR = '#cbd5e1';
57
+ // ── Arrow markers (graph edges) ───────────────────────────────────────────────
58
+ export const ARROW_FILL = '#475569'; // filled arrowhead
59
+ export const ARROW_STROKE = '#475569'; // open arrowhead stroke
60
+ //# sourceMappingURL=theme.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.js","sourceRoot":"","sources":["../../src/domain/theme.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,iFAAiF;AACjF,MAAM,CAAC,MAAM,kBAAkB,GAAM,SAAS,CAAC,CAAE,eAAe;AAChE,MAAM,CAAC,MAAM,eAAe,GAAS,SAAS,CAAC,CAAE,oBAAoB;AACrE,MAAM,CAAC,MAAM,gBAAgB,GAAQ,SAAS,CAAC,CAAE,2BAA2B;AAC5E,MAAM,CAAC,MAAM,gBAAgB,GAAQ,SAAS,CAAC,CAAE,2BAA2B;AAE5E,MAAM,CAAC,MAAM,kBAAkB,GAAM,SAAS,CAAC,CAAE,2BAA2B;AAC5E,MAAM,CAAC,MAAM,oBAAoB,GAAI,SAAS,CAAC,CAAE,4BAA4B;AAC7E,MAAM,CAAC,MAAM,kBAAkB,GAAM,SAAS,CAAC,CAAE,oBAAoB;AACrE,MAAM,CAAC,MAAM,iBAAiB,GAAO,SAAS,CAAC,CAAE,8BAA8B;AAE/E,iFAAiF;AACjF,2CAA2C;AAC3C,MAAM,CAAC,MAAM,cAAc,GAAI,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC;AAChG,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;AACvF,MAAM,CAAC,MAAM,cAAc,GAAI,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;AACvF,MAAM,CAAC,MAAM,aAAa,GAAK,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;AACvF,MAAM,CAAC,MAAM,cAAc,GAAI,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;AACvF,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;AAEvF,mFAAmF;AACnF,MAAM,CAAC,MAAM,YAAY,GAAG,SAAS,CAAC,CAAE,YAAY;AACpD,MAAM,CAAC,MAAM,WAAW,GAAI,SAAS,CAAC,CAAE,uBAAuB;AAC/D,MAAM,CAAC,MAAM,YAAY,GAAG,SAAS,CAAC,CAAE,oBAAoB;AAC5D,MAAM,CAAC,MAAM,WAAW,GAAI,SAAS,CAAC,CAAE,eAAe;AACvD,MAAM,CAAC,MAAM,WAAW,GAAI,SAAS,CAAC,CAAE,aAAa;AACrD,MAAM,CAAC,MAAM,UAAU,GAAK,SAAS,CAAC,CAAE,eAAe;AAEvD,0EAA0E;AAC1E,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,YAAY,EAAG,kBAAkB;IACjC,YAAY,EAAG,kBAAkB;IACjC,WAAW,EAAI,kBAAkB;IACjC,SAAS,EAAM,kBAAkB;IACjC,SAAS,EAAM,kBAAkB;IACjC,SAAS,EAAM,kBAAkB;CACzB,CAAC;AAEX,iFAAiF;AACjF,MAAM,CAAC,MAAM,oBAAoB,GAAG,SAAS,CAAC;AAC9C,MAAM,CAAC,MAAM,mBAAmB,GAAI,SAAS,CAAC;AAC9C,MAAM,CAAC,MAAM,mBAAmB,GAAI,SAAS,CAAC;AAC9C,MAAM,CAAC,MAAM,oBAAoB,GAAG,SAAS,CAAC;AAC9C,MAAM,CAAC,MAAM,mBAAmB,GAAI,SAAS,CAAC;AAC9C,MAAM,CAAC,MAAM,kBAAkB,GAAK,SAAS,CAAC;AAE9C,iFAAiF;AACjF,MAAM,CAAC,MAAM,eAAe,GAAK,SAAS,CAAC;AAC3C,MAAM,CAAC,MAAM,iBAAiB,GAAG,SAAS,CAAC;AAC3C,MAAM,CAAC,MAAM,eAAe,GAAK,SAAS,CAAC;AAE3C,gFAAgF;AAChF,MAAM,CAAC,MAAM,eAAe,GAAG,SAAS,CAAC;AAEzC,iFAAiF;AACjF,MAAM,CAAC,MAAM,UAAU,GAAK,SAAS,CAAC,CAAE,mBAAmB;AAC3D,MAAM,CAAC,MAAM,YAAY,GAAG,SAAS,CAAC,CAAE,wBAAwB"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Runtime validation for a DiagramSpec. The schema is the contract a model
3
+ * (later) must emit; the lab fails loud on a malformed spec so a technique
4
+ * never silently renders garbage. Pure, dependency-free.
5
+ */
6
+ import type { DiagramSpec } from './spec.js';
7
+ export interface ValidationIssue {
8
+ path: string;
9
+ message: string;
10
+ }
11
+ /**
12
+ * Validate structural integrity of a spec: unique node ids, edges/groups/
13
+ * annotations referencing real nodes, non-empty labels.
14
+ *
15
+ * @param spec the diagram spec to check
16
+ * @returns a list of issues; empty means valid
17
+ */
18
+ export declare function validateSpec(spec: DiagramSpec): ValidationIssue[];
19
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/domain/validate.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAE7C,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,WAAW,GAAG,eAAe,EAAE,CA+DjE"}