@arach/arc 0.5.0 → 0.7.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/lib/index.d.ts CHANGED
@@ -22,7 +22,21 @@ export declare interface ArcConnectorStyle {
22
22
  dashed?: boolean;
23
23
  }
24
24
 
25
- export declare function ArcDiagram({ data, className, interactive, mode, theme, label, labelPosition, defaultZoom, zoomLevels, showArcToggle, showAutoLayout, showControls, showMinimap, showLegend, showFocusStory, frame, hoverEffects, onNodeHover, titleBlock, maxFitZoom, }: ArcDiagramProps): JSX.Element;
25
+ export declare function ArcDiagram({ data, className, interactive, mode, theme, label, labelPosition, defaultZoom, zoomLevels, showArcToggle, showAutoLayout, showControls, showMinimap, showLegend, showFocusStory, frame, hoverEffects, onNodeHover, titleBlock, maxFitZoom, defaultViewMode, defaultIsoStyle, }: ArcDiagramProps): JSX.Element;
26
+
27
+ declare interface ArcDiagram_2 {
28
+ layout: DiagramLayout_2;
29
+ grid: GridConfig;
30
+ layoutHints?: LayoutHints_2;
31
+ nodes: Record<string, NodePosition_2>;
32
+ nodeData: Record<string, NodeData>;
33
+ connectors: Connector[];
34
+ connectorStyles: Record<string, ConnectorStyle_2>;
35
+ groups?: GroupShape_2[];
36
+ focusTargets?: Record<string, FocusTarget_2>;
37
+ images?: DiagramImage[];
38
+ exportZone?: ExportZone | null;
39
+ }
26
40
 
27
41
  export declare interface ArcDiagramData {
28
42
  id?: string;
@@ -86,6 +100,10 @@ declare interface ArcDiagramProps {
86
100
  onNodeHover?: (nodeId: string | null) => void;
87
101
  /** Override the engineering title-block fields (shown when the theme opts in). */
88
102
  titleBlock?: TitleBlockInfo;
103
+ /** Render the diagram in isometric projection. Default: '2d' */
104
+ defaultViewMode?: ViewMode_2;
105
+ /** Isometric render style — 'solid' | 'blueprint' | 'cyanotype'. Default: 'solid' */
106
+ defaultIsoStyle?: IsoStyleId;
89
107
  }
90
108
 
91
109
  declare interface ArcDiagramProps_2 {
@@ -108,6 +126,8 @@ export declare interface ArcNodeData {
108
126
  subtitle?: string;
109
127
  description?: string;
110
128
  color: DiagramColor;
129
+ /** Per-node silhouette. Omit to follow the theme's own node shape. */
130
+ shape?: NodeShape;
111
131
  }
112
132
 
113
133
  export declare interface ArcNodePosition {
@@ -282,7 +302,7 @@ export declare function deleteDiagramSession(id: string): void;
282
302
  /** Derive a URL-safe session ID from a diagram's source path or ID */
283
303
  export declare function deriveSessionId(source: string): string;
284
304
 
285
- export declare function DiagramCanvas({ onViewportChange, embedConfig, zoomConfig, themeOverride, isDark }: DiagramCanvasProps): JSX.Element;
305
+ export declare function DiagramCanvas({ onViewportChange, embedConfig, zoomConfig, surface, themeOverride, isDark }: DiagramCanvasProps): JSX.Element;
286
306
 
287
307
  declare interface DiagramCanvasProps {
288
308
  onViewportChange?: (bounds: {
@@ -293,6 +313,10 @@ declare interface DiagramCanvasProps {
293
313
  }) => void;
294
314
  embedConfig?: EmbedConfig;
295
315
  zoomConfig?: ZoomConfig;
316
+ /** Workspace backdrop: 'theme' paints the diagram theme's container (embeds,
317
+ * where the frame is part of the artifact), 'chrome' paints the app canvas
318
+ * so the editor's infinite surface matches the shell skin. */
319
+ surface?: 'theme' | 'chrome';
296
320
  /** Override canvas background with an Arc theme. */
297
321
  themeOverride?: string;
298
322
  isDark?: boolean;
@@ -368,6 +392,17 @@ export declare function DiagramEditor({ initialData, themeId, colorMode, session
368
392
  initialDiagramMeta?: Record<string, any>;
369
393
  }): JSX.Element;
370
394
 
395
+ declare interface DiagramImage {
396
+ id: string;
397
+ src: string;
398
+ name: string;
399
+ x: number;
400
+ y: number;
401
+ width: number;
402
+ height: number;
403
+ opacity: number;
404
+ }
405
+
371
406
  export declare interface DiagramLayout {
372
407
  width: number;
373
408
  height: number;
@@ -459,6 +494,13 @@ export declare interface EmbedConfig {
459
494
  showGrid?: boolean;
460
495
  }
461
496
 
497
+ declare interface ExportZone {
498
+ x: number;
499
+ y: number;
500
+ width: number;
501
+ height: number;
502
+ }
503
+
462
504
  export declare interface FocusConnectorRef {
463
505
  from: string;
464
506
  to: string;
@@ -511,6 +553,14 @@ export declare function getThemeList(): {
511
553
  description: string;
512
554
  }[];
513
555
 
556
+ declare interface GridConfig {
557
+ enabled: boolean;
558
+ size: number;
559
+ color: string;
560
+ opacity: number;
561
+ type: 'dots' | 'lines';
562
+ }
563
+
514
564
  export declare type GroupLayoutDirection = 'horizontal' | 'vertical';
515
565
 
516
566
  declare type GroupLayoutDirection_2 = 'horizontal' | 'vertical';
@@ -628,6 +678,8 @@ declare const initialState: {
628
678
  };
629
679
  };
630
680
 
681
+ export declare function isDiagramShape(value: unknown): boolean;
682
+
631
683
  /** Preset HSL palettes matching Arc's diagram colors. */
632
684
  export declare const ISO_COLORS: {
633
685
  violet: IsoColorDef;
@@ -748,6 +800,8 @@ declare interface NodeData {
748
800
  subtitle?: string;
749
801
  description?: string;
750
802
  color: DiagramColor_2;
803
+ /** Per-node silhouette. Omit to follow the theme's own node shape. */
804
+ shape?: NodeShape;
751
805
  }
752
806
 
753
807
  export declare interface NodeLayoutHint {
@@ -783,11 +837,13 @@ declare interface NodePosition_2 {
783
837
  size: NodeSize_2;
784
838
  }
785
839
 
840
+ declare type NodeShape = 'rounded' | 'square' | 'chamfer' | 'notch' | 'pill';
841
+
786
842
  export declare type NodeSize = 'xs' | 's' | 'm' | 'l';
787
843
 
788
844
  declare type NodeSize_2 = 'xs' | 's' | 'm' | 'l';
789
845
 
790
- declare type NodeSize_3 = 'large' | 'normal' | 'small';
846
+ declare type NodeSize_3 = 'xs' | 's' | 'm' | 'l';
791
847
 
792
848
  /**
793
849
  * Parse YAML config into DiagramConfig
@@ -936,6 +992,10 @@ declare interface TitleBlockInfo {
936
992
  sheet?: string;
937
993
  }
938
994
 
995
+ export declare function toExportFormat(diagram: ArcDiagram_2): ArcDiagramData_2;
996
+
997
+ export declare function toTypeScriptSource(diagram: ArcDiagram_2, name?: string): string;
998
+
939
999
  export declare function useColorMode(): string;
940
1000
 
941
1001
  export declare function useDiagram(): {
@@ -1005,8 +1065,13 @@ export declare function useThemeId(): string;
1005
1065
 
1006
1066
  export declare function useViewMode(): string;
1007
1067
 
1068
+ /** Human-readable reason this is not a diagram, or null if it is. */
1069
+ export declare function validateDiagramShape(value: unknown): string | null;
1070
+
1008
1071
  export declare type ViewMode = '2d' | 'isometric';
1009
1072
 
1073
+ declare type ViewMode_2 = '2d' | 'isometric';
1074
+
1010
1075
  declare interface ZoomConfig {
1011
1076
  defaultZoom?: number | 'fit';
1012
1077
  zoomLevels?: number[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arach/arc",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "type": "module",
5
5
  "packageManager": "bun@1.3.11",
6
6
  "workspaces": [
@@ -11,7 +11,14 @@
11
11
  "license": "MIT",
12
12
  "repository": {
13
13
  "type": "git",
14
- "url": "https://github.com/arach/arc.git"
14
+ "url": "git+https://github.com/arach/arc.git"
15
+ },
16
+ "homepage": "https://github.com/arach/arc#readme",
17
+ "bugs": {
18
+ "url": "https://github.com/arach/arc/issues"
19
+ },
20
+ "engines": {
21
+ "node": ">=18"
15
22
  },
16
23
  "publishConfig": {
17
24
  "access": "public",
@@ -27,13 +34,18 @@
27
34
  "isometric"
28
35
  ],
29
36
  "bin": {
30
- "arc-ascii": "./bin/arc-ascii.mjs"
37
+ "arc-ascii": "./bin/arc-ascii.mjs",
38
+ "arc-mcp": "./bin/arc-mcp.mjs"
31
39
  },
32
40
  "files": [
33
41
  "lib/*.js",
34
42
  "lib/*.d.ts",
35
43
  "lib/*.css",
36
- "bin/arc-ascii.mjs"
44
+ "bin/arc-ascii.mjs",
45
+ "bin/arc-mcp.mjs",
46
+ "docs/llm.txt",
47
+ "skills/arc-diagrams/SKILL.md",
48
+ "src/types/diagram.ts"
37
49
  ],
38
50
  "main": "./lib/arc.umd.js",
39
51
  "module": "./lib/arc.es.js",
@@ -50,13 +62,16 @@
50
62
  "dev": "vite",
51
63
  "build": "tsc && vite build && node scripts/generate-docs-html.js",
52
64
  "build:lib": "vite build --config vite.config.lib.js",
65
+ "build:mcp": "bun scripts/build-arc-mcp.mjs",
66
+ "mcp": "bun scripts/mcp/server.ts",
67
+ "mcp:http": "bun scripts/mcp/http-server.ts",
53
68
  "build:iso": "vite build --config vite.config.iso.js && vite build --config vite.config.iso-slim.js",
54
69
  "lint": "eslint .",
55
70
  "typecheck": "tsc --noEmit",
56
71
  "preview": "vite preview",
57
72
  "generate-og": "node scripts/generate-og.js",
58
73
  "check:dist": "attw --pack . --ignore-rules cjs-resolves-to-esm unexpected-module-syntax && publint && node scripts/check-packlist.mjs",
59
- "prepublishOnly": "bun run build:lib && bun run check:dist"
74
+ "prepublishOnly": "bun run build:lib && bun run build:mcp && bun run check:dist"
60
75
  },
61
76
  "peerDependencies": {
62
77
  "react": "^18.0.0 || ^19.0.0",
@@ -66,13 +81,24 @@
66
81
  "@arach/dewey": "^0.2.0",
67
82
  "@arethetypeswrong/cli": "^0.18.4",
68
83
  "@base-ui/react": "^1.0.0",
84
+ "@codemirror/commands": "^6.10.4",
85
+ "@codemirror/lang-css": "^6.3.1",
86
+ "@codemirror/lang-html": "^6.4.12",
87
+ "@codemirror/lang-javascript": "^6.2.5",
88
+ "@codemirror/lang-json": "^6.0.2",
89
+ "@codemirror/lang-markdown": "^6.5.2",
90
+ "@codemirror/language": "^6.12.4",
91
+ "@codemirror/state": "^6.7.1",
92
+ "@codemirror/view": "^6.43.8",
69
93
  "@eslint/js": "^9.39.1",
94
+ "@modelcontextprotocol/sdk": "^1.30.0",
70
95
  "@tailwindcss/vite": "^4.1.18",
71
96
  "@types/js-yaml": "^4.0.9",
72
97
  "@types/react": "^19.2.5",
73
98
  "@types/react-dom": "^19.2.3",
74
99
  "@types/three": "^0.182.0",
75
100
  "@vitejs/plugin-react": "^5.1.1",
101
+ "codemirror": "^6.0.2",
76
102
  "eslint": "^9.39.1",
77
103
  "eslint-plugin-react-hooks": "^7.0.1",
78
104
  "eslint-plugin-react-refresh": "^0.4.24",
@@ -91,7 +117,9 @@
91
117
  "tailwindcss": "^4.1.18",
92
118
  "three": "^0.182.0",
93
119
  "typescript": "^5.9.3",
120
+ "typescript-eslint": "^8.67.0",
94
121
  "vite": "^7.2.4",
95
- "vite-plugin-dts": "^4.5.4"
122
+ "vite-plugin-dts": "^4.5.4",
123
+ "zod": "^3.25.76"
96
124
  }
97
125
  }
@@ -0,0 +1,218 @@
1
+ ---
2
+ name: arc-diagrams
3
+ description: Create architecture diagrams using Arc's JSON format. Use when asked to "create an architecture diagram", "draw a system diagram", "visualize the architecture", or "make a diagram of".
4
+ ---
5
+
6
+ # Arc Diagrams
7
+
8
+ Arc is a visual diagram editor for creating architecture diagrams. This skill enables you to generate Arc-compatible diagram configs that can be rendered in React applications.
9
+
10
+ ## When to Use
11
+
12
+ Activate this skill when the user asks to:
13
+ - "Create an architecture diagram"
14
+ - "Draw a system diagram"
15
+ - "Visualize the architecture"
16
+ - "Make a diagram showing..."
17
+ - "Design a flow diagram"
18
+
19
+ ## Diagram Format
20
+
21
+ Arc diagrams are JSON objects with this structure:
22
+
23
+ ```typescript
24
+ interface ArcDiagramData {
25
+ layout: { width: number; height: number }
26
+ nodes: Record<string, NodePosition>
27
+ nodeData: Record<string, NodeData>
28
+ connectors: Connector[]
29
+ connectorStyles: Record<string, ConnectorStyle>
30
+ }
31
+ ```
32
+
33
+ ## Creating a Diagram
34
+
35
+ ### 1. Define Layout
36
+
37
+ Set canvas dimensions (default 1600x900 for editor, smaller for exports):
38
+
39
+ ```json
40
+ "layout": { "width": 860, "height": 400 }
41
+ ```
42
+
43
+ ### 2. Position Nodes
44
+
45
+ Each node needs an `x`, `y` position and `size`:
46
+
47
+ ```json
48
+ "nodes": {
49
+ "frontend": { "x": 50, "y": 100, "size": "l" },
50
+ "api": { "x": 300, "y": 100, "size": "m" },
51
+ "database": { "x": 550, "y": 100, "size": "m" }
52
+ }
53
+ ```
54
+
55
+ **Size options** (canonical — use these):
56
+ | Size | Key | Dimensions (px) |
57
+ |------|-----|-----------------|
58
+ | Extra Small | `xs` | 80 × 36 |
59
+ | Small | `s` | 110 × 48 |
60
+ | Medium | `m` | 160 × 75 |
61
+ | Large | `l` | 220 × 90 |
62
+
63
+ Source: `src/utils/constants.ts` → `NODE_SIZES`. Do **not** use `large`/`normal`/`small`.
64
+
65
+ ### 3. Define Node Data
66
+
67
+ Each node needs an icon, name, and color:
68
+
69
+ ```json
70
+ "nodeData": {
71
+ "frontend": {
72
+ "icon": "Monitor",
73
+ "name": "Frontend",
74
+ "subtitle": "React",
75
+ "description": "User interface",
76
+ "color": "violet"
77
+ },
78
+ "api": {
79
+ "icon": "Server",
80
+ "name": "API",
81
+ "subtitle": "Node.js",
82
+ "description": "REST endpoints",
83
+ "color": "emerald"
84
+ },
85
+ "database": {
86
+ "icon": "Database",
87
+ "name": "PostgreSQL",
88
+ "subtitle": "Storage",
89
+ "description": "Persistent data",
90
+ "color": "blue"
91
+ }
92
+ }
93
+ ```
94
+
95
+ **Available icons (from Lucide):**
96
+ - **Devices:** Monitor, Server, Smartphone, Watch, Cloud, Cpu, Database, HardDrive
97
+ - **Network:** Wifi, Globe
98
+ - **Users:** User, Users
99
+ - **Security:** Lock, Key, Shield
100
+ - **Media:** Mic, Camera, Speaker, Headphones
101
+ - **Code:** Code, Terminal, FileCode, Folder
102
+ - **Data:** Zap, Activity, BarChart, PieChart
103
+ - **Flow:** ArrowRight, ArrowDown, RefreshCw, Repeat
104
+ - **Structure:** Box, Package, Layers, Grid
105
+ - **UI:** Settings, Bell, Mail, MessageSquare, Search, Filter
106
+ - **Actions:** Download, Upload, Play, Pause, Square, Circle
107
+
108
+ **Available colors:**
109
+ `violet` | `emerald` | `blue` | `amber` | `sky` | `zinc` | `rose` | `orange`
110
+
111
+ ### 4. Connect Nodes
112
+
113
+ Define connections between nodes:
114
+
115
+ ```json
116
+ "connectors": [
117
+ {
118
+ "from": "frontend",
119
+ "to": "api",
120
+ "fromAnchor": "right",
121
+ "toAnchor": "left",
122
+ "style": "http"
123
+ },
124
+ {
125
+ "from": "api",
126
+ "to": "database",
127
+ "fromAnchor": "right",
128
+ "toAnchor": "left",
129
+ "style": "sql"
130
+ }
131
+ ]
132
+ ```
133
+
134
+ **Anchor positions:**
135
+ `top` | `bottom` | `left` | `right` | `bottomLeft` | `bottomRight` | `topLeft` | `topRight`
136
+
137
+ **Optional:** Add `"curve": "natural"` or `"curve": "step"` for curved connectors.
138
+
139
+ ### 5. Style Connectors
140
+
141
+ Define appearance for each connector style:
142
+
143
+ ```json
144
+ "connectorStyles": {
145
+ "http": { "color": "amber", "strokeWidth": 2, "label": "HTTP" },
146
+ "sql": { "color": "blue", "strokeWidth": 2, "label": "SQL" },
147
+ "async": { "color": "zinc", "strokeWidth": 1.5, "dashed": true }
148
+ }
149
+ ```
150
+
151
+ ## Complete Example
152
+
153
+ Here's a full diagram for a typical web application:
154
+
155
+ ```json
156
+ {
157
+ "layout": { "width": 700, "height": 300 },
158
+ "nodes": {
159
+ "client": { "x": 50, "y": 100, "size": "l" },
160
+ "api": { "x": 300, "y": 100, "size": "m" },
161
+ "cache": { "x": 300, "y": 220, "size": "s" },
162
+ "database": { "x": 520, "y": 100, "size": "m" }
163
+ },
164
+ "nodeData": {
165
+ "client": { "icon": "Monitor", "name": "Client", "subtitle": "React", "color": "violet" },
166
+ "api": { "icon": "Server", "name": "API", "subtitle": "Express", "color": "emerald" },
167
+ "cache": { "icon": "Zap", "name": "Cache", "subtitle": "Redis", "color": "amber" },
168
+ "database": { "icon": "Database", "name": "Database", "subtitle": "Postgres", "color": "blue" }
169
+ },
170
+ "connectors": [
171
+ { "from": "client", "to": "api", "fromAnchor": "right", "toAnchor": "left", "style": "http" },
172
+ { "from": "api", "to": "database", "fromAnchor": "right", "toAnchor": "left", "style": "sql" },
173
+ { "from": "api", "to": "cache", "fromAnchor": "bottom", "toAnchor": "top", "style": "cache" }
174
+ ],
175
+ "connectorStyles": {
176
+ "http": { "color": "amber", "strokeWidth": 2, "label": "HTTP" },
177
+ "sql": { "color": "blue", "strokeWidth": 2, "label": "SQL" },
178
+ "cache": { "color": "emerald", "strokeWidth": 2, "label": "cache" }
179
+ }
180
+ }
181
+ ```
182
+
183
+ ## Layout Tips
184
+
185
+ 1. **Prefer auto-layout** — use `autoLayout()` from `@arach/arc` when you don't need pixel-perfect placement
186
+ 2. **Grid alignment:** Position nodes on a ~50px grid for clean manual layouts
187
+ 3. **Spacing:** Leave ~150–200px between connected nodes horizontally
188
+ 4. **Flow direction:** Left-to-right or top-to-bottom for data flow
189
+ 5. **Grouping:** Use `groups` + `layoutHints` for framed sections (see `docs/group-layout.md`)
190
+ 6. **Large nodes:** Use `l` size for primary/entry-point components
191
+ 7. **Connectors:** Match connector colors to the source or destination node
192
+
193
+ ## Validation
194
+
195
+ Before handing off JSON, ensure every `nodes` key has a matching `nodeData` entry.
196
+ In the repo, `validateDiagramShape()` in `src/utils/diagramValidation.ts` returns a
197
+ human-readable error or `null`.
198
+
199
+ ## Output
200
+
201
+ When generating a diagram, output:
202
+ 1. The complete JSON config
203
+ 2. Brief explanation of the architecture shown
204
+ 3. Suggest the user save it as a `.arc.json` file or paste into the Arc editor
205
+
206
+ ## TypeScript Export
207
+
208
+ For React projects, diagrams can be exported as TypeScript:
209
+
210
+ ```typescript
211
+ import type { ArcDiagramData } from '@arach/arc'
212
+
213
+ const diagram: ArcDiagramData = {
214
+ // ... config here
215
+ }
216
+
217
+ export default diagram
218
+ ```
@@ -0,0 +1,197 @@
1
+ // Arc Diagram Types
2
+ // Shared format for Arc editor and consumers (Talkie docs, etc.)
3
+
4
+ import type { NodeShape } from '../utils/nodeShape'
5
+
6
+ export type { NodeShape }
7
+
8
+ export type NodeSize = 'xs' | 's' | 'm' | 'l'
9
+
10
+ export type AnchorPosition =
11
+ | 'left' | 'right' | 'top' | 'bottom'
12
+ | 'bottomLeft' | 'bottomRight' | 'topLeft' | 'topRight'
13
+
14
+ export type DiagramColor =
15
+ | 'violet' | 'emerald' | 'blue' | 'amber'
16
+ | 'sky' | 'zinc' | 'rose' | 'orange'
17
+
18
+ export interface NodePosition {
19
+ x: number
20
+ y: number
21
+ size: NodeSize
22
+ }
23
+
24
+ export interface NodeData {
25
+ icon: string
26
+ name: string
27
+ subtitle?: string
28
+ description?: string
29
+ color: DiagramColor
30
+ /** Per-node silhouette. Omit to follow the theme's own node shape. */
31
+ shape?: NodeShape
32
+ }
33
+
34
+ export interface Connector {
35
+ from: string
36
+ to: string
37
+ fromAnchor: AnchorPosition
38
+ toAnchor: AnchorPosition
39
+ style: string
40
+ curve?: 'natural' | 'step'
41
+ }
42
+
43
+ export interface ConnectorStyle {
44
+ color: DiagramColor
45
+ strokeWidth: number
46
+ label?: string
47
+ dashed?: boolean
48
+ }
49
+
50
+ export interface DiagramLayout {
51
+ width: number
52
+ height: number
53
+ }
54
+
55
+ export interface GridConfig {
56
+ enabled: boolean
57
+ size: number
58
+ color: string
59
+ opacity: number
60
+ type: 'dots' | 'lines'
61
+ }
62
+
63
+ export interface GroupShape {
64
+ id: string
65
+ x: number
66
+ y: number
67
+ width: number
68
+ height: number
69
+ type: 'rect' | 'circle'
70
+ color: DiagramColor
71
+ label?: string
72
+ dashed?: boolean
73
+ }
74
+
75
+ export interface FocusConnectorRef {
76
+ from: string
77
+ to: string
78
+ }
79
+
80
+ export interface FocusStep {
81
+ icon: string
82
+ label: string
83
+ }
84
+
85
+ /** A declarative highlight story activated by hovering or selecting a node. */
86
+ export interface FocusTarget {
87
+ /** `append` includes direct neighbors; `replace` uses only the explicit story. */
88
+ mode?: 'append' | 'replace'
89
+ nodes?: string[]
90
+ connectors?: FocusConnectorRef[]
91
+ caption?: string
92
+ steps?: FocusStep[]
93
+ }
94
+
95
+ export type LayoutAlignment = 'start' | 'center' | 'end'
96
+ export type GroupLayoutDirection = 'horizontal' | 'vertical'
97
+
98
+ /** Optional placement hints used by autoLayout when nodes belong to groups. */
99
+ export interface NodeLayoutHint {
100
+ /** ID of the group frame that owns this node. */
101
+ group?: string
102
+ /** Explicit layer within the group. Connected nodes are layered automatically otherwise. */
103
+ layer?: number
104
+ /** Stable ordering within a layer. Lower values render first. */
105
+ order?: number
106
+ }
107
+
108
+ /** Layout policy for the nodes inside one group frame. */
109
+ export interface GroupLayoutHint {
110
+ /** `horizontal` lays layers left-to-right; `vertical` lays them top-to-bottom. */
111
+ direction?: GroupLayoutDirection
112
+ padding?: number
113
+ layerGap?: number
114
+ itemGap?: number
115
+ align?: LayoutAlignment
116
+ justify?: LayoutAlignment | 'space-between'
117
+ }
118
+
119
+ export interface LayoutHints {
120
+ nodes?: Record<string, NodeLayoutHint>
121
+ groups?: Record<string, GroupLayoutHint>
122
+ }
123
+
124
+ export interface DiagramImage {
125
+ id: string
126
+ src: string
127
+ name: string
128
+ x: number
129
+ y: number
130
+ width: number
131
+ height: number
132
+ opacity: number
133
+ }
134
+
135
+ export interface ExportZone {
136
+ x: number
137
+ y: number
138
+ width: number
139
+ height: number
140
+ }
141
+
142
+ // Full diagram format (internal Arc state)
143
+ export interface ArcDiagram {
144
+ layout: DiagramLayout
145
+ grid: GridConfig
146
+ layoutHints?: LayoutHints
147
+ nodes: Record<string, NodePosition>
148
+ nodeData: Record<string, NodeData>
149
+ connectors: Connector[]
150
+ connectorStyles: Record<string, ConnectorStyle>
151
+ groups?: GroupShape[]
152
+ focusTargets?: Record<string, FocusTarget>
153
+ images?: DiagramImage[]
154
+ exportZone?: ExportZone | null
155
+ }
156
+
157
+ // Clean export format (for consumers)
158
+ export interface ArcDiagramData {
159
+ id?: string
160
+ layout: DiagramLayout
161
+ layoutHints?: LayoutHints
162
+ nodes: Record<string, NodePosition>
163
+ nodeData: Record<string, NodeData>
164
+ connectors: Connector[]
165
+ connectorStyles: Record<string, ConnectorStyle>
166
+ focusTargets?: Record<string, FocusTarget>
167
+ groups?: GroupShape[]
168
+ }
169
+
170
+ // Convert full diagram to clean export format
171
+ export function toExportFormat(diagram: ArcDiagram): ArcDiagramData {
172
+ return {
173
+ layout: diagram.layout,
174
+ layoutHints: diagram.layoutHints,
175
+ nodes: diagram.nodes,
176
+ nodeData: diagram.nodeData,
177
+ connectors: diagram.connectors,
178
+ connectorStyles: diagram.connectorStyles,
179
+ focusTargets: diagram.focusTargets,
180
+ groups: diagram.groups,
181
+ }
182
+ }
183
+
184
+ // Generate TypeScript source file content
185
+ export function toTypeScriptSource(diagram: ArcDiagram, name: string = 'diagram'): string {
186
+ const data = toExportFormat(diagram)
187
+ const json = JSON.stringify(data, null, 2)
188
+ .replace(/"([^"]+)":/g, '$1:') // Remove quotes from keys
189
+ .replace(/"/g, "'") // Use single quotes
190
+
191
+ return `import type { ArcDiagramData } from '@arach/arc'
192
+
193
+ const ${name}: ArcDiagramData = ${json}
194
+
195
+ export default ${name}
196
+ `
197
+ }
@@ -1,5 +0,0 @@
1
- const o = {};
2
- throw new Error('Could not resolve "@codemirror/commands" imported by "hudsonkit".');
3
- export {
4
- o as default
5
- };
@@ -1,5 +0,0 @@
1
- const o = {};
2
- throw new Error('Could not resolve "@lezer/highlight" imported by "hudsonkit".');
3
- export {
4
- o as default
5
- };
@@ -1,5 +0,0 @@
1
- const o = {};
2
- throw new Error('Could not resolve "@codemirror/lang-css" imported by "hudsonkit".');
3
- export {
4
- o as default
5
- };